前言
在深入了解Vue动态创建Component前先了解一下常规组件声明形式。
Vue 的组件通常可以通过两种方式来声明,一种是通过 Vue.component,另外一种则是 Single File Components(SFC) 单文件组件 。
常规组件声明与注册
// 定义一个名为 button-counter 全局注册的组件Vue.component("button-counter", { template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>', data() { return { count: 0 } }});new Vue({ template: ` <div id="app"> <h1>App Component</h1> <button-counter></button-counter> </div> `}).$mount("#app");
在上面的代码中我们声明了一个叫做 button-counter 的组件。如果在常规情况下使用的话,只需要在页面上写对应的 <button-counter></button-counter> 标签就够了。
全局创建注册组件可以实现动态创建,但是我们必须在 template 声明使用该组件,而且如果把所有组件都全局注册这并不是一个好办法。
在官方文档中我们可以看到,我们可以通过 Vue.component('component-name') 的方式来注册一个组件。
而组件实例又有 $mount 这样一个方法,官方对于 $mount 的解释如下:
vm.$mount( [elementOrSelector] )
Arguments:
{Element | string} [elementOrSelector]
{boolean} [hydrating]
Returns: vm - the instance itself
Usage:
If a Vue instance didn't receive the el option at instantiation, it will be in “unmounted” state, without an associated DOM element. vm.$mount() can be used to manually start the mounting of an unmounted Vue instance.
If elementOrSelector argument is not provided, the template will be rendered as an off-document element, and you will have to use native DOM API to insert it into the document yourself.
The method returns the instance itself so you can chain other instance methods after it.
那我们是否可以通过这种方式来达到我们的需求呢?
还不够!
为什么???
因为 Vue.component 返回的结果是一个 function!它返回的并不是 组件实例,而是一个构造函数。
那到这里其实我们就清楚了。 对于 Vue.component 声明的组件,我们先通过 Vue.component 获取它的构造函数,再 new 出一个组件实例,最后 通过 $mount 挂载到 html 上。
// 定义一个名为 button-counter 全局注册的组件Vue.component("button-counter", { template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>', data() { return { count: 0 } }});new Vue({ template: ` <div id="app"> <h1>App Component</h1> <button @click="insert">click to insert button-counter comonent</button> <div id="insert-container"></div> </div> `, methods: { insert() { const ButtonCounter = Vue.component("button-counter"); // 只能查找到全局注册到组件 const instance = new ButtonCounter(); instance.$mount("#insert-container"); } }}).$mount("#app");
新闻热点
疑难解答
图片精选