问题:有时我们需要父组件访问子组件、子组件直接访问父组件、或者子组件访问根组件:
- 父组件访问子组件:使用$children或$refs
- 子组件访问父组件:使用$parent
- 子组件访问根组件:$root
先看一张图:
此图可以理解为:
当我们需要数据在组件中来回传递时,我们可以通过props和$emit进行双向传递,如此循环往复。(以前文章有讲过,有兴趣的可以移步瞅瞅:(41条消息) 组件通信、传值(父子、爷孙、多层级)(vue)_秃秃秃了的博客-CSDN博客)
但在另外一些场景下,我们可能想要比如(在父组件中)拿到子组件对象,然后直接操作其中数据,实现功能,例如方法的调用,我们就可以用到$children、$refs、$parent、$root等等
父访问子组件的方式之: $children
children比较特殊,this. $children返回的是一个数组,也就是返回了所有的子组件的实例
<body> <div id="app"> <mxc></mxc> <mxc></mxc> <mxc></mxc> <button @click="btnClick">颤抖吧</button> </div> <template id="mxc"> <div>我是子组件啊</div> </template> <script> const app=new Vue({ el:'#app', data:{ message:'你好' }, methods:{ btnClick(){ console.log(this.$children) } }, components:{ mxc:{ template:'#mxc', methods:{ showMessage(){ console.log('mxcnb') } } } } }) </script> </body>
<body> <div id="app"> <mxc></mxc> <mxc></mxc> <mxc></mxc> <button @click="btnClick">颤抖吧</button> </div> <template id="mxc"> <div>我是子组件啊</div> </template> <script> const app=new Vue({ el:'#app', data:{ message:'你好' }, methods:{ btnClick(){ console.log(this.$children) for(let c of this.$children){ console.log(c.name) } } }, components:{ mxc:{ template:'#mxc', data(){ return{ name:'我是子组件的name' } }, methods:{ showMessage(){ console.log('mxcnb') } } } } }) </script> </body>
但是使用$children有一个问题,一旦子组件增加或者减少,我们所取的还是原来那个吗?
所以,这就到了vue-DOM之光了:$refs
为什么叫“DOM之光”呢?因为它和原生JS的document.querySelector(' ')功能一样
<body> <div id="app"> <mxc></mxc> <mxc></mxc> <mxc ref="aaa"></mxc> <button @click="btnClick">颤抖吧</button> </div> <template id="mxc"> <div>我是子组件啊</div> </template> <script> const app=new Vue({ el:'#app', data:{ message:'你好' }, methods:{ btnClick(){ console.log(this.$refs) console.log(this.$refs.aaa) } }, components:{ mxc:{ template:'#mxc', data(){ return{ name:'我是子组件的name' } }, methods:{ showMessage(){ console.log('mxcnb') } } } } }) </script> </body>
子访问父组件:$parent
实际中$parent用的比较少——考虑到耦合度的原因,另外,它找寻父组件是一层一层往上找的,且容易被引用的一些比如element组件干扰,所以慎用。
<body> <div id="app"> <mxc></mxc> </div> <template id="mxc"> <div>我是子组件啊</div> <button @click="btnClick">更加颤抖的child</button> </template> <script> const app=new Vue({ el:'#app', data:{ message:'你好' }, components:{ mxc:{ template:'#mxc', methods:{ btnClick(){ console.log(this.$parent) } } } } }) </script> </body>
子组件访问根组件:$root
直接访问到根组件App.vue的实例
<body> <div id="app"> <mxc></mxc> </div> <template id="mxc"> <div> <div>我是mxc组件</div> <cdn></cdn> </div> </template> <template id="mxca"> <div> <div>我是子子组件啊</div> <button @click="btnClick">巨颤祖child</button> </div> </template> <script> const app=new Vue({ el:'#app', data:{ message:'你好' }, components:{ mxc:{ template:'#mxc', data(){ return{ name:'我是中间子组件的name' } }, components:{ cdn:{ template:'#mxca', methods:{ btnClick(){ console.log(this.$parent.name) console.log(this.$root.message) } } } } } } }) </script> </body>