Vue组件实例间的直接访问实现代码


Posted in Javascript onAugust 20, 2017

前面的话

有时候需要父组件访问子组件,子组件访问父组件,或者是子组件访问根组件。 在组件实例中,Vue提供了相应的属性,包括$parent、$children、$refs和$root,这些属性都挂载在组件的this上。本文将详细介绍Vue组件实例间的直接访问

$parent 

$parent表示父组件的实例,该属性只读

下面是一个简易实例

<div id="example">
 <parent-component></parent-component>
</div>
<template id="parent-component">
 <div class="parent">
 <h3>我是父组件</h3>
 <input v-model="parentMsg">
 <p>{{parentMsg}}</p>
 <child-component></child-component> 
 </div>
</template>
<template id="child-component">
 <div class="child">
 <h3>我是子组件</h3>
 <p>{{msg}}</p>
 <button v-on:click="showData">显示父组件数据</button> 
 </div>
</template>
<script>
// 注册
Vue.component('parent-component', {
 template: '#parent-component',
 data(){
 return{
  parentMsg:'我是父组件的数据'
 }
 },
 components:{
 'child-component':{
  template:'#child-component',
  data(){
  return{
   msg:''
  }
  },
  methods:{
  showData(){
   this.msg = this.$parent.parentMsg;
  }
  }
 }
 }
})
// 创建根实例
new Vue({
 el: '#example'
})
</script>

$root 

$root表示当前组件树的根 Vue 实例。如果当前实例没有父实例,此实例将会是其自己。该属性只读

<div id="example">
 <h3>我是根组件</h3>
 <input v-model="rootMsg">
 <p>{{rootMsg}}</p> 
 <parent-component></parent-component>
</div>
<template id="parent-component">
 <div class="parent">
 <h3>我是父组件</h3>
 <input v-model="parentMsg">
 <p>{{parentMsg}}</p>
 <child-component></child-component> 
 </div>
</template>
<template id="child-component">
 <div class="child">
 <h3>我是子组件</h3>
 <p>
  <button v-on:click="showRootData">显示根组件数据</button><span>{{rootMsg}}</span>
 </p>  
 <p>
  <button v-on:click="showParentData">显示父组件数据</button><span>{{parentMsg}}</span>
 </p>
 </div>
</template>
<script>
// 注册
Vue.component('parent-component', {
 template: '#parent-component',
 data(){
 return{
  parentMsg:'我是父组件的数据'
 }
 },
 components:{
 'child-component':{
  template:'#child-component',
  data(){
  return{
   parentMsg:'',
   rootMsg:''
  }
  },
  methods:{
  showParentData(){
   this.parentMsg = this.$parent.parentMsg;
  },
  showRootData(){
   this.rootMsg = this.$root.rootMsg;
  },  
  }
 }
 }
})
// 创建根实例
new Vue({
 el: '#example',
 data:{
 rootMsg:'我是根组件数据'
 }
})
</script>

$children 

$children表示当前实例的直接子组件。需要注意$children并不保证顺序,也不是响应式的。如果正在尝试使用$children来进行数据绑定,考虑使用一个数组配合v-for来生成子组件,并且使用Array作为真正的来源

<div id="example">
 <parent-component></parent-component>
</div>
<template id="parent-component">
 <div class="parent">
 <h3>我是父组件</h3>
 <button @click="getData">获取子组件数据</button>
 <br>
 <div v-html="msg"></div>
 <child-component1></child-component1> 
 <child-component2></child-component2> 
 </div>
</template>
<template id="child-component1">
 <div class="child">
 <h3>我是子组件1</h3>
 <input v-model="msg">
 <p>{{msg}}</p>
 </div>
</template>
<template id="child-component2">
 <div class="child">
 <h3>我是子组件2</h3>
 <input v-model="msg">
 <p>{{msg}}</p>
 </div>
</template>
<script>
// 注册
Vue.component('parent-component', {
 template: '#parent-component',
 data(){
 return{
  msg:'',
 }
 },
 methods:{
 getData(){
  let html = '';
  let children = this.$children;
  for(var i = 0; i < children.length;i++){
  html+= '<div>' + children[i].msg + '</div>';
  }
  this.msg = html;
 }
 },
 components:{
 'child-component1':{
  template:'#child-component1',
  data(){
  return{
   msg:'',
  }
  },
 },
 'child-component2':{
  template:'#child-component2',
  data(){
  return{
   msg:'',
  }
  },
 }, 
 } 
})
// 创建根实例
new Vue({
 el: '#example',
})
</script>

$refs

组件个数较多时,难以记住各个组件的顺序和位置,通过序号访问子组件不是很方便

在子组件上使用ref属性,可以给子组件指定一个索引ID:

<child-component1 ref="c1"></child-component1>
<child-component2 ref="c2"></child-component2>

在父组件中,则通过$refs.索引ID访问子组件的实例

this.$refs.c1

this.$refs.c2

<div id="example">
 <parent-component></parent-component>
</div>
<template id="parent-component">
 <div class="parent">
 <h3>我是父组件</h3>
 <div>
  <button @click="getData1">获取子组件c1的数据</button>
  <p>{{msg1}}</p>
 </div>
 <div>
  <button @click="getData2">获取子组件c2的数据</button>
  <p>{{msg2}}</p>
 </div>
 <child-component1 ref="c1"></child-component1> 
 <child-component2 ref="c2"></child-component2> 
 </div>
</template>
<template id="child-component1">
 <div class="child">
 <h3>我是子组件1</h3>
 <input v-model="msg">
 <p>{{msg}}</p>
 </div>
</template>
<template id="child-component2">
 <div class="child">
 <h3>我是子组件2</h3>
 <input v-model="msg">
 <p>{{msg}}</p>
 </div>
</template>
<script>
// 注册
Vue.component('parent-component', {
 template: '#parent-component',
 data(){
 return{
  msg1:'',
  msg2:'',
 }
 },
 methods:{
 getData1(){
  this.msg1 = this.$refs.c1.msg;
 },
 getData2(){
  this.msg2 = this.$refs.c2.msg;
 }, 
 },
 components:{
 'child-component1':{
  template:'#child-component1',
  data(){
  return{
   msg:'',
  }
  },
 },
 'child-component2':{
  template:'#child-component2',
  data(){
  return{
   msg:'',
  }
  },
 }, 
 } 
})
// 创建根实例
new Vue({
 el: '#example',
})
</script>

总结 

虽然vue提供了以上方式对组件实例进行直接访问,但并不推荐这么做。这会导致组件间紧密耦合,且自身状态难以理解,所以尽量使用props、自定义事件以及内容分发slot来传递数据。

Javascript 相关文章推荐
javascript淡入淡出效果的实现思路
Mar 31 Javascript
js判断屏幕分辨率的代码
Jul 16 Javascript
javascript中apply和call方法的作用及区别说明
Feb 14 Javascript
JavaScript对象的property属性详解
Apr 01 Javascript
jQuery中ajax的post()方法用法实例
Dec 26 Javascript
jQuery中[attribute!=value]选择器用法实例
Dec 31 Javascript
JS正则表达式之非捕获分组用法实例分析
Dec 28 Javascript
微信小程序 定位到当前城市实现实例代码
Feb 23 Javascript
Angular.js前台传list数组由后台spring MVC接收数组示例代码
Jul 31 Javascript
AngularJS实现的base64编码与解码功能示例
May 17 Javascript
Three.js实现3D机房效果
Dec 30 Javascript
vue组件内部引入外部js文件的方法
Jan 18 Javascript
JavaScript贪吃蛇小组件实例代码
Aug 20 #Javascript
React Native 环境搭建的教程
Aug 19 #Javascript
ionic App问题总结系列之ionic点击系统返回键退出App
Aug 19 #Javascript
浅谈关于.vue文件中style的scoped属性
Aug 19 #Javascript
如何理解Vue的作用域插槽的实现原理
Aug 19 #Javascript
Vue Transition实现类原生组件跳转过渡动画的示例
Aug 19 #Javascript
JavaScript文件的同步和异步加载的实现代码
Aug 19 #Javascript
You might like
PHP小程序自动提交到自助友情连接
2009/11/24 PHP
深入探讨:Nginx 502 Bad Gateway错误的解决方法
2013/06/03 PHP
Yii2使用$this-&gt;context获取当前的Module、Controller(控制器)、Action等
2017/03/29 PHP
javascript encodeURI和encodeURIComponent的比较
2010/04/03 Javascript
轻轻松松学JS调试(不下载任何工具)
2010/04/14 Javascript
用apply让javascript函数仅执行一次的代码
2010/06/27 Javascript
关于IE浏览器以及Firefox下的javascript冒泡事件的响应层级
2010/10/14 Javascript
js对象数组按属性快速排序
2011/01/31 Javascript
jQuery EasyUI API 中文文档 - Draggable 可拖拽
2011/09/29 Javascript
如何让DIV可编辑、可拖动示例代码
2013/09/18 Javascript
jquery中页面Ajax方法$.load的功能使用介绍
2014/10/20 Javascript
jQuery的context属性用法实例
2014/12/27 Javascript
javascript弹出页面回传值的方法
2015/01/28 Javascript
基于JS2Image实现圣诞树代码
2015/12/24 Javascript
Three.js学习之几何形状
2016/08/01 Javascript
React-native桥接Android原生开发详解
2018/01/17 Javascript
Vue实现商品分类菜单数量提示功能
2019/07/26 Javascript
Openlayers绘制地图标注
2020/09/28 Javascript
JS+JQuery实现无缝连接轮播图
2020/12/30 jQuery
JavaScript实现点击自制菜单效果
2021/02/02 Javascript
[04:32]玩具屠夫中文语音节选
2020/08/23 DOTA
python使用xauth方式登录饭否网然后发消息
2014/04/11 Python
python中global用法实例分析
2015/04/30 Python
详解python时间模块中的datetime模块
2016/01/13 Python
python+selenium实现京东自动登录及秒杀功能
2017/11/18 Python
pyecharts绘制中国2020肺炎疫情地图的实例代码
2020/02/12 Python
将labelme格式数据转化为标准的coco数据集格式方式
2020/02/17 Python
CSS3实现曲线阴影和翘边阴影
2016/05/03 HTML / CSS
购买大码女装:Lane Bryant
2016/09/07 全球购物
匡威比利时官网:Converse Belgium
2017/04/13 全球购物
运动会邀请函范文
2014/01/31 职场文书
安全责任书范文
2014/03/12 职场文书
组工干部对照检查材料
2014/08/25 职场文书
年度考核登记表个人总结
2015/03/06 职场文书
机器人瓦力观后感
2015/06/12 职场文书
2016党员党课心得体会
2016/01/07 职场文书