前言
前文我们讲了父子之间传递数据的方式,但是现在父组件想访问子组件怎么实现呢?很简单的一个需求,父组件如果想调用子组件中的方法实现呢?那就得通过父子之间的访问来实现。
模拟实例
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="./js/vue.js"></script>
</head>
<body>
<div id="app">
<h1>grandFather</h1>
<child1></child1>
<child2></child2>
</div>
<script>
const app = new Vue({
el:"#app",
components:{
child1:{
template:`<h3>Father
<son></son>
</h3>
`,
components:{
son:{
template:`<h6>son</h6>`,
methods:{
showMe()
{
console.log("iamson");
}
}
}
},
methods:{
showMe()
{
console.log("iamFather");
}
}
},
child2:{
template:`<h3>Mother</h3>`,
methods:{
showMe()
{
console.log("iamMother");
}
}
}
},
methods:{
showMe()
{
console.log("iamgrandFa");
},
accessChild()
{
console.log(this.$children);
}
}
})
</script>
</body>
</html>
这里我构建出了一颗很简单的组件树。来模拟实际问题中的组件层级关系。最上层是grandFa,中层是Father和Mother,底层是son.接下来我都通过这个example进行剖析。
父组件访问子组件
父组件访问子组件有两种方式
- 通过$children进行访问
- 通过$refs进行访问
通过$children进行访问
在控制台可以直接看到vue实例app中就有这个$children属性。它对应的是一个数组。它是一个子组件对象构成的一个数组。那这里就有两个元素:Mother子组件对象和Father子组件对象。
同理,Father子组件对象中又有一个子组件对象:son。所以Father组件对象的$children属性对应的数组应该有一个元素
而Mother组件没有子组件所以它的$children属性对应的是一个空数组。
总结
通过$children
属性获取的是所有子组件对象的集合(数组),如果我们要单独访问某一个组件只能通过下标的方式来访问,比如this.$children[0]
===>Father组件,this.$children[1]
===>Mother组件。这种访问方式特别的呆,为什么呢?万一父组件的子组件有任何变动,你就获取不到想要的子组件对象了。所以这种访问子组件的方式特别不常用。
通过refs访问
这是上一种访问方式的改进式,基本原理就是父组件给子组件打个标记,然后呢,通过这个标记来锁定特定的子组件,这种方式用的非常多。因为妈妈再也不用担心组件结构的变化了,精准定位。
- 通过ref属性给子组件打标记
对上面的example进行改进
<div id="app">//根实例app
<h1>grandFather</h1>
<child1 ref="fa"></child1>//根实例给子组件起了一个小名:fa
<child2 ref="Mo"></child2>//根实例给子组件起了一个小名:mo
</div>
- 通过调用实例或组件的
$refs
属性访问所有打了标记的子组件
当你通过ref属性给子组件打标记之后,那么所有有标记的子组件对象,和他们的标记名组成了一个对象。存放在父组件的$refs
属性中。如下: 那么我们就可以通过父组件.$refs.特有标记名
在父组件中访问到特定组件了。
子组件访问父组件
通过$parent访问父组件
这个我觉得没啥好说的,就是绝大多数实例或者组件都有这个$parent
属性,这个属性对应的就是它的父组件对象
比如这里的father子组件的$parent
属性对应的就是根实例grandFa
通过$root访问根组件
这个更简单了,每个实例或者组件都有一个$root
属性,指向该组件对应的根组件(最开始的祖先)。根实例的$root
属性就是其本身。
比如这里的son子组件的$root
属性指向的就是根实例对象grandFa.
总结
其实子组件访问父组件在开发中用的非常少,原因很简单:这样的话父子组件的耦合度太高了,比如说我子组件要访问父组件的name数据,那么它就要求这个子组件只能在有name数据的父组件环境下存活。也就是说子组件和父组件依赖度太高了,导致子组件的复用性不强。所以这个用法相当少。