组件的继承

1、组件的继承

通过组件的继承我们可以利用已定义的组件的一些特性。首先先看第一种定义的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import Vue from 'vue'
const component = {
// props:['active','propOne','onChange'],
props:{
active:Boolean,
propOne:{
require:true
}
},
template:`
<div>
<input type="text" v-model="text">
<span @click="handleChange">{{propOne}}</span>
<span v-show="active">show</span>
</div>
`,
data(){
return {
text:0
}
},
mounted(){
console.log('comp instance');
},
methods:{
handleChange(){
//this.onChange()
this.$emit('change')
}
}
}

const CompVue = Vue.extend(component)

new CompVue({
el:'#root',
propsData:{
propOne:123,
active:true
},
data(){
return {
text:123
}
},
mounted(){
console.log('this instance');
}
})

​ 在这个里面,CompVue继承了名为component这样的一个组件,并且在里面实现了自己的一些方法。首先,如果这个时候需要和被继承组件中的子组件通信的时候,需要利用propsData进行传递,利用原来的props是没有效果的。然后就是在继承的组件当中,data会自动覆盖掉原先的data。但是对于mounted而言是不会被覆盖的,而是先执行被继承对象中的mounted方法,再调用自己的mounted方法。

当然,还有一种定义继承的方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const comp2 = {
extends:component,
data(){
return{
text:555
}
}
}

new Vue({
el:'#root',
components:{
comp:comp2
},
template:`<comp></comp>`
})

二、组件的parent

利用$parent这个变量可以找到一个组件的父组件,并且通过this. $parent.$options.name可以查到他父组件的名字。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const comp2 = {
extends:component,
data(){
return{
text:555
}
},
mounted(){
console.log(this.$parent.$options.name)
}
}

new Vue({
name:'myTest',
el:'#root',
components:{
comp:comp2
},
data(){
return {
text:2333
}
},
template:`
<div>
<span>{{text}}</span>
<comp></comp>
</div>`
})

当然,也可以通过$parent来改变响应的值。但是尽量不要去这样做。父组件也是可以进行设置的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const parent = new Vue({
name:'parent'
})

const comp2 = {
parent:parent,
extends:component,
data(){
return{
text:555
}
},
mounted(){
console.log(this.$parent.$options.name)
}
}

这样声明是没有用的,结果还将是parent为调用该组件的名称,这时候想要定义父组件必须在new一个Vue的时候声明才有效果。

接下来看一个多层调用的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import Vue from 'vue'
const childComponents = {
template:`
<div>child child {{value}}</div>
`,
inject:['yeye','value'],
mounted(){
console.log(this.yeye)
}
}
const component = {
props:{
active:Boolean,
propOne:{
require:true
}
},
data(){
return {
text:0,
style:{
width:'200px',
height:'200px',
border:'1px black solid'
}
}
},
mounted(){
console.log('comp instance');
},
components:{
childComponents
},
template:`
<div :style="style">
<slot></slot>
<child-components></child-components>
</div>
`
}
new Vue({
name:'myTest',
el:'#root',
components:{
comp:component
},
provide(){
return{
yeye:this,
value:this.value
}
},
data(){
return {
text:2333,
value:222222
}
},
mounted(){
// console.log(this.$parent.$options.name)
},
template:`
<div>
<comp>
<span>{{text}}</span>
</comp>
<input type="text" v-model="value"/>
</div>`
})

但是是没有办法访问越级的组件的,这个时候就需要去做一些处理。

首先在”爷爷辈“的组件中,声明一个provide方法,这样才会在Vue对象初始化的过程中得到里面的值。

1
2
3
4
5
6
provide(){
return{
yeye:this,
value:this.value
}
},

然后在”孙子辈“里面再去利用inject调用:

1
2
3
4
5
6
7
8
9
const childComponents = {
template:`
<div>child child {{value}}</div>
`,
inject:['yeye','value'],
mounted(){
console.log(this.yeye)
}
}

但是这时候,如果在input中输入一个数的话,孙子中绑定的值是不会变化的,这是因为默认情况下provide是不提供Vue的react属性的,可以做下面的处理:

1
2
3
4
5
6
7
8
9
10
11
provide(){
const data = {}
Object.defineProperty(data,'value',{
get: ()=> this.value,
enumerable:true
})
return{
yeye:this,
data
}
},

也就是子组件在每次访问value这个属性的时候,实际上是在访问get方法,然后访问到value值的变化,这也就是Vue实现的一个原理,但是Vue官方文档中可能之后会被移除。

0%