# 文档初探(十): 处理 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("你调用了根元素的方法"); } } });
Copied!
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访问到子组件的属性 } } });
Copied!
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 }; } });
Copied!
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