1.组件的注册
在Vue中组件的注册方式有两种,一种全局注册,一种是局部注册。
我这里截了两张官方文档的图,里面也对组件的注册给出了详细的解释。
我们来看例子:
import Vue from 'vue'
// 对象
const Test = {
template: '<h1>{{msg}}</h1>',
data() {
return {
msg: 'hello world'
}
}
}
// 注册组件
Vue.component('Test', Test)
new Vue({
el: '#app',
template: '<Test />'
})
上个例子中,我们注册了一个全局的组件。想要变成局部组件其实也很简单。只要把组件放到vue实例的components属性中就行。
import Vue from 'vue'
// 对象
const Test = {
template: '<h1>{{msg}}</h1>',
data() {
return {
msg: 'hello world'
}
}
}
// 注册组件
// Vue.component('Test', Test)
new Vue({
el: '#app',
components: {
Test
},
template: '<Test />'
})
我们可以发现,在组件中我们的data是一个函数,而不是data对象,这么些的原因是防止组件之间的数据相互干扰,从而保证每个数据的data都是独有的。
2.组件的继承(extend)
在上面我们已经说过,Vue.component是注册一个组件,而Vue.extend则是扩展一个组件。Vue.extend相当于Vue的一个子集,当我们使用new Vue创建实例的时候,是一个空的实例,里面没有template,没有data,而使用extend则是在原有的基础上进行扩展。
举个例子。
import Vue from 'vue'
// 对象
const Test = {
template: '<h1>{{msg}}</h1>',
data() {
return {
msg: 'hello world'
}
}
}
const Comp = Vue.extend(Test)
new Comp({
el: '#app'
})
这段代码的结果跟上面的是一样的。而且我们可以覆盖原来的模板。
new Comp({
el: '#app',
data: {
msg: 'this is Comp'
}
})
结果会显示this is Comp。注意:如果需要覆盖props,不能直接使用props,而要用propsData,如果有生命周期函数,则两个都会执行,执行顺序是先执行模板中的方法。
还有一种用法,也是我们最常用的一种用法。
import Vue from 'vue'
const loading = {
template: '<h1>{{msg}}</h1>',
data () {
return {
msg: 'loading'
}
}
}
const Test = {
extends: loading,
data () {
return {
msg: 'test'
}
}
}
new Vue({
el: '#app',
components: {
Test
},
template: '<Test />'
})
当我们有一些类似的组件,但每个组件又有自己单独的配置的时候,我们就可以使用组件继承,而不需要重新写新的组件。
3.组件的插槽(slot)
有些组件我们需要在自定义组件里面的内容,所有我们就需要使用插槽。
看一个例子:
import Vue from 'vue'
const Test = {
template: `
<div>
this is test
<p>
<slot></slot>
</p>
</div>
`
}
new Vue({
el: '#app',
components: {
Test
},
template: `
<div>
<Test>
这是父组件的内容
</Test>
</div>
`
})
比如我们要把父组件的这句话写到子组件的容器里面,只需要在子组件需要放内容的地方写一个slot标签就行(相当于占位符)
如果需要使用多个,我们就需要使用具名插槽(给插槽做个标记)。
import Vue from 'vue'
const Test = {
template: `
<div>
this is test
<p>
<slot name="header"></slot>
</p>
<p>
<slot name="body"></slot>
</p>
</div>
`
}
new Vue({
el: '#app',
components: {
Test
},
template: `
<div>
<Test>
<span slot="header">这是父组件的header</span>
<span slot="body">这是父组件的内容</span>
</Test>
</div>
`
})
``
那如果插槽中需要使用变量怎么办?
import Vue from 'vue'
const Test = {
template: <div> this is test <p> {{msg}}<slot></slot> </p> </div>
,
data () {
return {
msg: '1111'
}
}
}
new Vue({
el: '#app',
components: {
Test
},
template: <div> <Test> <span>这是父组件的内容{{msg}}</span> </Test> </div>
,
data: {
msg: '2222'
}
})
![](https://img.haomeiwen.com/i2189687/4afc30437132d012.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
插槽中的变量是互不干扰的,那如果我在父组件中想要使用子组件的变量,怎么办呢?
这时就可以使用slot-scope,在子组件中定义的属性,会通过props传到父组件。
import Vue from 'vue'
const Test = {
template: <div> this is test <p> {{msg}}<slot msg="3333"></slot> </p> </div>
,
data () {
return {
msg: '1111'
}
}
}
new Vue({
el: '#app',
components: {
Test
},
template: <div> <Test> <span slot-scope="props">这是父组件的内容{{props.msg}}</span> </Test> </div>
,
data: {
msg: '2222'
}
})
![](https://img.haomeiwen.com/i2189687/c40935240c01068b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
网友评论