如何在Vue.js中动态安装单个文件组件

时间:2017-05-05 07:53:04

标签: javascript vue.js

我有一个文件组件 Main.Vue

我还有其他三个单一文件组件 A.vue B.vue C.vue

我希望每次都能在Main.Vue中显示一个不同的组件。我做的是这个:

<template>
<div>
<a v-if="isAVisible" ></a>
<b v-if="isBVisible" ></a>
</div>
</template>

<script>
import A from './A.vue';
import B from './B.vue';
...

这可行但不完全是我想要的。我想要一个不同的文件 Factory.js ,它会导入所有组件 A B C ,..并且具有返回我的组件的功能,我可以在 Main.vue 中以某种方式使用它。这是我试过Factory.js的样子:

import A from './A.vue';
import B from './B.vue';
function getComponent(){
  if (..)
    return new A();
  else if (..)
    return new B();
  ...
}

这根本不起作用。 我想要工厂文件方法,因为:

1)我想将其拆分为不同的工厂文件

2)我想将数据“附加”到每个组件。所以我将有一个对象,其中包含返回实际组件的函数+一些其他数据,如“name”

任何想法如何做到这一点?

2 个答案:

答案 0 :(得分:7)

使用Vue的动态组件

您可以使用Dynamic Components在组件之间动态切换。您需要将组件定义对象绑定到is元素的component属性 - Vue的文档对此非常自我解释。以下是一个简短的例子:

<template>
  <component :is="activeComponent"></component>
</template>
import componentA from 'component/a';
import componentB from 'component/b';

export default {
  components: {
    componentA,
    componentB,
  },

  data() {
    return {
      activeComponent: 'componentA',
    },
  },
};

您可以直接将组件定义对象绑定到data属性本身:

import componentA from 'component/a';
import componentB from 'component/b';

export default {
  data() {
    return {
      activeComponent: componentA,
    };
  },
};

要切换组件,您可以通过编程方式更改activeComponent

的值

使用渲染功能

使用组件render functions可以实现动态安装组件的更强大方法。要做到这一点,我们必须创建Vue component元素的我们自己的版本 - 我们称之为ElementProxy

import componentA from 'component/a';
import componentB from 'component/b';

export default {
  components: {
    componentA,
    componentB,
  },

  props: {
    type: {
      type: String,
      required: true,
    },
    props: {
      type: Object,
      default: () => ({}),
    },
  },

  render(createElement) {
    const { props: attrs } = this;
    return createElement(element, { attrs });
  },
};

您现在可以使用ElementProxy代理元素。这样做的另一个好处是,您可以将道具作为对象传递,这将解决将道具传递给具有不同模型的动态组件的问题。

<template>
  <element-proxy :type="activeComponent" :props="props"></element-proxy>
</template>
import ElementProxy from 'components/elementProxy';

export default {
  components: {
    ElementProxy,
  },

  data() {
    return {
      activeComponent: 'componentA',
      props: { ... },
    };
  },
};

进一步阅读

答案 1 :(得分:2)

是的,您需要动态组件:

<template>
  <div>
    <component v-bind:is="currentView">
    <!-- component changes when vm.currentView changes! -->
    </component>
  </div>
</template>

<script>
import A from './A.vue';
import B from './B.vue';

export default {
  data: {
    currentView: 'A'
  },
  components: {
    A,
    B,
  }
})

然后

function getComponent(){
  if (..)
    this.currentView = 'A';
  else if (..)
    this.currentView = 'B'
  ...
}

您还可以根据手册直接绑定组件:

https://vuejs.org/v2/guide/components.html#Dynamic-Components