# 文档初探(十): 处理 Edge Cases
# 访问元素&组件
# 访问根实例
Vue.component("sub-1", {
template: `
<p>
{{bar}}
<button @click="getBaz">get baz</button>
{{placeholder}}
</p>`,
data() {
return {
placeholder: 0
};
},
computed: {
bar() {
return this.$root.foo;
}
},
methods: {
getBaz() {
this.placeholder = this.$root.bar;
this.$root.baz();
}
}
});
new Vue({
el: "#app",
template: `
<div>
<sub-1 />
</div>
`,
data() {
return {
foo: 1
};
},
computed: {
bar() {
return "bar";
}
},
methods: {
baz() {
alert("你调用了根元素的方法");
}
}
});
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
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
# 访问父组件
和$root
一样, 访问父组件只需要使用$parent
.
# 访问子组件
使用$refs
访问子组件, 同时要给子组件加上ref
属性.
Vue.component("sub-1", {
template: `
<p>
sub-1
</p>`,
data() {
return {
placeholder: 0
};
}
});
new Vue({
el: "#app",
template: `
<div>
<sub-1 ref="sub"/> <!-- 子组件的ref是sub-->
<button @click="fetchRefs">获取refs.sub.placeholder</button>
<p>{{placeholder}}</p>
</div>
`,
data() {
return {
placeholder: ""
};
},
methods: {
fetchRefs() {
this.placeholder = this.$refs.sub.placeholder; //在这里才可以根据子组件的ref访问到子组件的属性
}
}
});
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
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
WARNING
$refs
只有在所有组件渲染好后才能访问得到, 并且$refs
不是响应式的. 它只是作为操纵子组件的备胎方案. 而且必须避免在template
里或者在computed
属性里访问$refs
, 否则都会返回undefined
.
# 依赖注入
当父组件的某个状态都被它的子组件和孙子组件们需要, 我们可以使用props
, $parent
, $root
来获取到, 但是这些方法都有一个缺点, 就是需要按照组件的层级关系一层一层往下传递. 如果组件解构很复杂, 那么给后续的维护带来很大的困难. 依赖注入可以让我们跳过层级关系, 让状态直接从提供一方到需要的一方.
Vue.component("son", {
template: `
<div style="border: 1px solid red">
<p>I'm son</p>
<p>全局状态: {{globalState}}</p>
<slot></slot>
</div>
`,
inject: ["globalState"]
});
Vue.component("grandSon", {
template: `
<div style="border: 1px solid black; width: 50%; margin: 10px">
<p>I'm grandSon</p>
<p>全局状态: {{globalState}}</p>
</div>
`,
inject: ["globalState"]
});
new Vue({
el: "#app",
template: `
<div>
<son>
<grandSon />
</son>
</div>
`,
data() {
return {
globalState: 1
};
},
provide() {
return {
globalState: this.globalState
};
}
});
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
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