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 相关文章推荐
jquery animate图片模向滑动示例代码
Jan 26 Javascript
JQuery扩展插件Validate 2通过参数设置验证规则
Sep 05 Javascript
Extjs4 类的定义和扩展实例
Jun 28 Javascript
js中的for如何实现foreach中的遍历
May 31 Javascript
jQuery基于扩展实现的倒计时效果
May 14 Javascript
jQuery实现iframe父窗体和子窗体的相互调用
Jun 17 Javascript
学习Bootstrap滚动监听 附调用方法
Jul 02 Javascript
js禁止浏览器的回退事件
Apr 20 Javascript
浅谈Vue下使用百度地图的简易方法
Mar 23 Javascript
bootstrap table表格插件之服务器端分页实例代码
Sep 12 Javascript
微信小程序常用简易小函数总结
Feb 01 Javascript
Vue项目中Api的组织和返回数据处理的操作
Nov 04 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过滤表单提交的html等危险代码
2014/11/03 PHP
php 修改上传文件大小限制实例详解
2016/10/23 PHP
Laravel 关联模型-关联新增和关联更新的方法
2019/10/10 PHP
javascript对象的使用和属性操作示例详解
2014/03/02 Javascript
jquery中获得元素尺寸和坐标的方法整理
2014/05/18 Javascript
JavaScript显示当前文档最后修改日期的方法
2015/03/19 Javascript
jQuery制作简洁的图片轮播效果
2015/04/03 Javascript
Bootstrap modal 多弹窗之叠加显示不出弹窗问题的解决方案
2017/02/23 Javascript
div中文字内容溢出常见的解决方法
2017/03/16 Javascript
360提示[高危]使用存在漏洞的JQuery版本的解决方法
2017/10/27 jQuery
Vue基础配置讲解
2019/11/29 Javascript
利用JS如何获取form表单数据
2019/12/19 Javascript
浅谈TypeScript的类型保护机制
2020/02/23 Javascript
vue倒计时刷新页面不会从头开始的解决方法
2020/03/03 Javascript
javascript设计模式 ? 适配器模式原理与应用实例分析
2020/04/13 Javascript
解决vue项目router切换太慢问题
2020/07/19 Javascript
vue中渲染对象中属性时显示未定义的解决
2020/07/31 Javascript
Python中urllib+urllib2+cookielib模块编写爬虫实战
2016/01/20 Python
Python编写简单的HTML页面合并脚本
2016/07/11 Python
Python处理JSON数据并生成条形图
2016/08/05 Python
Python爬虫获取图片并下载保存至本地的实例
2018/06/01 Python
pandas分区间,算频率的实例
2019/07/04 Python
python pygame实现滚动横版射击游戏城市之战
2019/11/25 Python
django使用channels实现通信的示例
2020/10/19 Python
python UIAutomator2使用超详细教程
2021/02/19 Python
Topshop法国官网:英国快速时尚品牌
2018/04/08 全球购物
土耳其玩具商店:Toyzz Shop
2019/08/02 全球购物
过滤器的用法
2013/10/08 面试题
村优秀党员事迹材料
2014/01/15 职场文书
门前三包责任书
2014/04/15 职场文书
技术负责人任命书
2014/06/05 职场文书
工商管理专业毕业生自我鉴定2014
2014/10/04 职场文书
2015共产党员公开承诺书
2015/01/22 职场文书
红色影片观后感
2015/06/18 职场文书
保护环境建议书作文300字
2015/09/14 职场文书
Mysql中mvcc各场景理解应用
2022/08/05 MySQL