前面我们知道,Vue实例可以通过el跟某个视图进行绑定,也就是它充当了ViewModel的角色,其实Vue实例不仅可以充当一个ViewModel的角色,而且可以看到一个组件,也就是说既包括View,也包含ViewModel,从而可以形成一个独立的个体,方便复用。
自定义组件主要分为三个部分:
1、构造组件
2、注册组件
3、使用组件
构造组件
我们可以通过Vue.extend( options )得到一个组件构造器。
var myComponent = Vue.extend({ template: '<div id="bComponent">{{message}}</div>', data () { return { message: 'Hello, DroidMind!' } } });从上面我们可以看到,这个组件构建器中template对应的是视图,data对应的是ViewModel,并且实现了视图跟Model的绑定。
另外,其实我们也可以省略Vue.extend()函数,直接使用如下形式:
const myComponent = { template: '<div id="bComponent">{{message}}</div>', data () { return { message: 'Hello, DroidMind!' } } };Vue.js在背后会自动调用Vue.extend()。
上面的组件的构造器的定义中,组件的模板template只能有一个根元素,组件中的data必须是函数。
这里需要说明的是:当组件业务逻辑比较复杂的时候,我们需要将组件进行单独的封装,所以需要将它放在一个单独的的文件,我们可以把组件代码按照template、style、script的拆分方式,放置到对应的.vue文件中。这样每个vue文件对应一个组件,template对应组件的视图View,style对应的组件的视图样式,script对应组件的Model并且与template视图进行绑定。这个这里先不做展开。
当我们得到自定义组件构造器之后,我们就可以实例化一个组件并且将这个组件挂载到指定的DOM上了。
<body> <div id="app"></div> <!-- built files will be auto injected --> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> var myComponent = Vue.extend({ template: '<div id="bComponent">{{message}}</div>', data () { return { message: 'Hello, DroidMind!' } } }); new myComponent().$mount('#app') </script>上面就是将myComponent实例挂载到id为app的DOM节点上面。
其实我们也可以通过template完成组件的渲染和挂载。
<body> <div id="app"> </div> <!-- built files will be auto injected --> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> const myComponent = { template: '<div id="bComponent">{{message}}</div>', data () { return { message: 'Hello, DroidMind!' } } }; const app = new Vue({ el: '#app', components: { 'b-component': myComponent }, template: '<div class="app"><b-component></b-component></div>' }) </script>在上面代码中,el属性指定的是Vue实例绑定的DOM节点,components指定的是在这个DOM节点内部可以使用的组件,也就是组件的局部注册,这个下面会讲到,b-component是组件标签名,myComponent指定的是标签名对应的组件构造器,template指定一个视图模板,用来挂载在这个DOM节点下面,在template里面就是使用到了components里面注册的组件了,就是使用组件的那个标签名。
其实,我们也可以写成如下形式:
<body> <div id="app"> </div> <!-- built files will be auto injected --> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> const myComponent = { template: '<div id="bComponent">{{message}}</div>', data () { return { message: 'Hello, DroidMind!' } } }; const app = new Vue({ el: '#app', components: { myComponent }, template: '<div class="app"><myComponent></myComponent></div>' }) </script>这个跟前面的区别就是不需要显示的指定components里面的组件名,直接使用组件构造器的名称作为标签就可以。
这里需要说明一下Vue 选项对象中的 el 属性、template属性和 render 渲染函数的关系,当 Vue 选项对象中有 render 渲染函数时,Vue 构造函数将直接使用渲染函数渲染 DOM 树,当选项对象中没有 render 渲染函数时,Vue 构造函数首先通过将 template 模板编译生成渲染函数,然后再渲染 DOM 树,而当 Vue 选项对象中既没有 render 渲染函数,也没有 template 模板时,会通过 el 属性获取挂载元素的 outerHTML 来作为模板,并编译生成渲染函数。
前面是使用挂载的方式使用自定义组件的和局部注册然后使用标签的方式,如果我们需要全局的使用标签来使用组件,在使用该组件之前,需要进行组件的全局注册。
注册组件
全局注册
全局注册就是使用下面的代码
Vue.component('b-component', myComponent)
我们也可以直接写成如下格式:
Vue.component('b-component',{ template: `<div id="bComponent">{{message}}</div>`, data () { return { message: 'Hello, DroidMind!' } } })如上面代码所示,直接传入了组件的内容,这个前面已经说过,其实Vue.js在背后自动调用Vue.extend()。
局部注册
局部注册其实前面在组件的构造中有涉及到,局部注册跟全局注册的区别就是局部注册的组件只能在注册的那个实例对应的DOM节点内部使用。。
var app = new Vue({ el: '#app', data: { }, components: { 'b-component': { template: `<div id="bComponent">{{message}}</div>`, data () { return { message: 'Hello, DroidMind!' } } } } })如上面代码所示,这个代码前面已经见过,通过components其实就是进行局部组件注册,所以它只能在Vue绑定的这个DOM里面使用。
注册完成之后,我们就可以直接使用上面声明的b-component标签了。在使用之前需要有一个Vue的实例,组件必须要在Vue的实例绑定的DOM里面使用。
整个过程代码如下:
全局注册
<body> <div id="app"> <b-component></b-component> </div> <!-- built files will be auto injected --> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script> // 1.创建组件构造器 var myComponent = Vue.extend({ template: '<div id="bComponent">{{message}}</div>', data () { return { message: 'Hello, DroidMind!' } } }); //2.注册组件到vue里面 Vue.component('b-component', myComponent) //3.创建Vue的实例,组件必须要在Vue的实例里面使用 new Vue({ el: '#app', });
</script> <body> <div id="vm" action="#"> <b-component></b-component> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script type="text/javascript"> // 将上面第一步和第二步合并 Vue.component('b-component',{ template: `<div id="bComponent">{{message}}</div>`, data () { return { message: 'Hello, DroidMind!' } } }) //创建Vue的实例,组件必须要在Vue的实例里面使用 new Vue({ el: '#vm', }); </script>
局部注册
<body> <div id="vm" action="#"> <b-component></b-component> </div> </body> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script type="text/javascript"> var app = new Vue({ el: '#vm', data: { }, components: { 'b-component': { template: `<div id="bComponent">{{message}}</div>`, data () { return { message: 'Hello, DroidMind!' } } } } }) </script>
欢迎关注我的公众号:DroidMind
精品内容,独家发布