Vue组件、插槽、Ref
组件化规范
Web Components 通过创建封装好功能的定制元素解决上述问题
- 尽可能多 的重用代码
- 自定义组件的方式不太容易(html、css和js)
- 多次使用组件可能导致冲突
一些创建规则:
- data需要使用一个函数来返回对象
- 组件模板内容必须是单个 根元素(只能有一个根元素,内部可以写其他元素)
全局组件注册
语法
Vue.component(组件名称, {
data: 组件数据,
template: 组件模板内容
})
例如:
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function(){
return {
count: 0
}
},
template: "<button @click='count++'>点击了{{count}}次</button>"
})
上面直接写在点击事件里的语句,其实可以通过调用函数来完成
// 定义一个名为 button-counter 的新组件
Vue.component('button-counter', {
data: function(){
return {
count: 0
}
},
template: "<button @click='handle'>点击了{{count}}次</button>",
methods: {
handle: function(){
this.count++
}
}
})
使用
<button-counter></button-counter>
<!-- 不同的组件,相互之间的 数据是独立的 -->
<button-counter></button-counter>
局部组件注册
局部组件只能在注册它的父组件里使用
let componentA = {
data: function () {
return {
count: 0
}
},
template: `
<div>
<button @click='count++'>点击了{{count}}次</button>
<button>测试</botton>
</div>
`
}
let vm = new Vue({
el: '#app',
components: {
'component-a': componentA
}
})
组件里的 data
为什么在vue的组件中,data要用function返回对象呢?
在创建或注册模板的时候,传入一个data属性作为用来绑定的数据。但是在组件中,data必须是一个函数,而不能直接把一个对象赋值给它。这是vm实例和组件的最大区别
Vue.component('my-component', {
template: '<div>OK</div>',
data() {
return {} // 返回一个唯一的对象,不要和其他组件共用一个对象进行返回
},
})
当一个组件被定义, data 必须声明为返回一个初始数据对象的函数,因为组件可能被用来创建多个实例。如果 data 仍然是一个纯粹的对象,则所有的实例将共享引用同一个数据对象!通过提供 data 函数,每次创建一个新实例后,我们能够调用 data 函数,从而返回初始数据的一个全新副本数据对象。
模板字符串
因为直接在template里通过文本写html可读性比较差,所以使用 模板字符串 (就是 ` 符号)
这个是ES6的新特性,优点就是可以换行和使用 ${ }
Vue.component('button-counter', {
data: function () {
return {
count: 0
}
},
template: `
<div>
<button @click='count++'>点击了{{count}}次</button>
<button>测试</botton>
</div>
`
})
x-template 模板
就是以 # 开始,则它将被用作选择符,并使用匹配元素的 innerHTML 作为模板。常用的技巧是用 <script type="x-template"> 包含模板。
好处就是不用写字符串了(字符串无法整理代码)
<script type="text/x-template" id="my-component">
<div>这是组件的内容</div>
</script>
组件的命名方式
短横线方式
Vue.component('my-component',{ /* ... */})
驼峰式方式(少用)
Vue.component('MyComponent',{ /* ... */})
注意:如果使用驼峰式命名组件,那么在使用组件的时候,只能在字符串模板中使用驼峰式命名,而不能直接写在页面上,因为 dom元素是不区分大小写的,所以会自动把命名转化成小写
例如MyComponent会被转成mycomponent
这样Vue就无法找到这个组件了,因此尽量使用短横线的方式
组件的使用
因为不同的组件就是不同的实例,所以无法直接传值,需要通过其他的方法接收到外部的数据
- 父组件向子组件传值:通过属性来传值
- 子组件向父组件传值:通过自定义事件来传值