组件 (Component) 是 Vue.js 最强大的功能之一。组件可以扩展 HTML 元素,封装可重用的代码。
组件是自定义元素,Vue.js 的编译器为它添加特殊功能。
使用组件
组件的注册与使用
全局注册
我们需要通过一个全局的API来构造。
Vue.extend(options)
用法:使用基础 Vue 构造器,创建一个“子类”。参数是一个包含组件选项的对象。
同时还需要一个API通过这个构造器来注册组件,之后才能使用。
Vue.component(id, [definition])
用法:注册或获取全局组件。注册还会自动使用给定的id设置组件的名称。注意:他仅仅是个构造器而已。
示例:
<div id="app">
<my-global></my-global>
</div>
var myComponent = Vue.extend({
template:‘<div><h2>This is the use of a global component</h2></div>‘
});
Vue.component(‘my-global‘,myComponent);
通过测试后,我们发现<my-global></myglobal>最终被渲染为:
<div>
<h2>This is the use of a global component</h2>
</div>
<my-global></my-global>就可以使用组件。
template属性就是模板,该组件将被渲染后代替。
你可以写两个标签
<my-global></my-global>
<my-global></my-global>
但是注意:这两个组件是相互独立的,虽然是通过各构造器注册的,但各自独立,局部的注册也是一样的。
这样写,又定义构造器,又注册,再使用,未免有些麻烦,也不常用。可以简短点写。
//我们是直接可以这样写的,也是全局注册最常用的方式
Vue.component(‘my-global‘,{
template:‘<div><h2>This is the use of a global component</h2></div>‘
});
局部注册
即在某个Vue实例中通过components选项中注册。
示例:
data:{
msg:‘Hello Vue2.0‘
},
components:{
‘my-local‘:{
data:function(){
return {
msg:‘Hello Vue2.0---Local‘
}
},
template:‘<div><h2>{{msg}}</h2></div>‘
}
}
好了,这就是局部的注册,我们这里在template属性里使用了模板语法{{}},而不过要在子组件中使用模板的到属性值得话,就必须使用子组件自己的data,虽然是子组件,但也不能直接使用父组件的data。需要定义data,注意,组件的data必须是一个函数,属性由函数返回,多个属性使用对象{}的方式。
官方原话:构造 Vue 实例时传入的各种选项大多数都可以在组件里使用。只有一个例外:data 必须是函数
如果这么做,那么 Vue 会停止运行,并在控制台发出警告,告诉你在组件实例中 data 必须是一个函数
所以此时,打印的语句为Hello Vue2.0---Local。
如果有Vue的开发工具插件vue-devtools,我们就可以看到。
应官方的要求,这个id,即组件定义的这个标签名不强制遵循 W3C 规则 (小写,并且包含一个短杠)。但是在vue-devtool中就被改成这种名字了,驼峰命名法吧。当然我们可以定义name属性,它是通过name属性来显示的,默认的值就是id变成驼峰,我们可以自己写name。依然是没问题的。
引用模板
如果我们的template属性中的内容太多,未免会造成麻烦,不仅影响美感,还容易出错,所以我们通过template标签定义引用。
//挂载元素div外定义的模板
<template id="templ">
<ul>
<li v-for="(val,key) in arr">{{val}}</li>
</ul>
</template>
components:{
‘my-local‘:{
name:‘MyLocal2‘,
data:function(){
return {
msg:‘Hello Vue2.0---Local‘,
arr:[‘what‘,‘are‘,‘you‘,‘doing‘]
}
},
template:‘#templ‘
}
}
我们在挂载元素div外定义模板元素template,然后添加一个id元素,在子组件template属性中,通过‘#templ‘对其引用。
然而有一中易错误现象,当在template元素中使用两个独立的标签时会出错。
<template id="templ">
<ul>
<li v-for="(val,key) in arr">{{val}}</li>
</ul>
<p>你好,你是谁</p><!-- 或是{{msg}} -->
</template>
此时它会给你一个错误,这个错误主要说的就是,“模板中有且仅有一个根元素”,就是说要么你template标签中有一个ul,要么有一个p,你只能在template中有一个根元素,所以你需要做的是添加一个div标签在所有标签的最外层作为根元素。
DOM 模板解析注意事项
这篇就不写了,看官网的DOM 模板解析注意事项来详细看,最后的要求就是说尽可能使用字符串模板。
动态组件的渲染
有时候你可能由于一个if判断,根据数据该选择到底显示渲染哪个组件。此时就需要动态渲染。
动态渲染需要使用到内置的组件component,如果可能的话还有keep-alive。
component的作用就是渲染一个“元组件”为动态组件。依 is 的值,来决定哪个组件被渲染。
我们需要做的就是设置这个is的值,值得内容是什么,就显示名字叫什么组件。
component
示例:
//我们再定义一个子组件
‘my-chen‘:{
data:function(){
return {
msg:‘My name is Xiaoxiaochen Xiansen‘
}
},
template:‘<p>{{msg}}</p>‘
}
//同时,为Vue实例添加一个currentView属性
data:{
currentView:‘my-local‘
}
//Vue实例挂载处。:is就是v-bind:is的简写
<div id="app">
<component :is="currentView"></component>
</div>
然后测试,默认显示的就是my-local组件的模板内容,通过按钮点击的方式改变currentView的值就可以动态的改变组件了。
keep-alive
如果你想把切换出去的组件保留在内存中,可以保留它的状态或避免重新渲染,那么你就可以使用keep-alive内置组件了。
<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。
只需要把这个标签套在component标签的外边就好了。
<keep-alive>
<component :is="currentView">
<!-- 非活动组件将被缓存! -->
</component>
</keep-alive>
2.它有两个属性可以设置“include”和“exclude”,值为字符串或正则表达式,只有匹配的组件才会被缓存或不缓存。
示例:
<!-- 逗号分隔字符串 -->
<keep-alive include="a,b">
<component :is="view"></component>
</keep-alive>
<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="[‘a‘, ‘b‘]">
<component :is="view"></component>
</keep-alive>
匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。
<keep-alive> 不会在函数式组件中正常工作,因为它们没有缓存实例。
原文地址:http://blog.51cto.com/zouzhelu/2106177