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 相关文章推荐
提高代码性能技巧谈—以创建千行表格为例
Jul 01 Javascript
uploadify 3.0 详细使用说明
Jun 18 Javascript
简单几行JS Code实现IE邮件转发新浪微博
Jul 03 Javascript
jQuery实现淡入淡出二级下拉导航菜单的方法
Aug 28 Javascript
原生 JS Ajax,GET和POST 请求实例代码
Jun 08 Javascript
又一枚精彩的弹幕效果jQuery实现
Jul 25 Javascript
Vue数据驱动模拟实现4
Jan 12 Javascript
js实现简易聊天对话框
Aug 17 Javascript
Vue2.0结合webuploader实现文件分片上传功能
Mar 09 Javascript
vue与原生app的对接交互的方法(混合开发)
Nov 28 Javascript
详解Ant Design of React的安装和使用方法
Dec 27 Javascript
vue+springboot实现登录验证码
May 27 Vue.js
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中将地址生成迅雷快车旋风链接的代码[测试通过]
2011/04/20 PHP
Mac下php 5升级到php 7的步骤详解
2017/04/26 PHP
Laravel 对某一列进行筛选然后求和sum()的例子
2019/10/10 PHP
laravel框架使用FormRequest进行表单验证,验证异常返回JSON操作示例
2020/02/18 PHP
JavaScript弹簧振子超简洁版 完全符合能量守恒,胡克定理
2009/10/25 Javascript
利用腾讯的ip地址库做ip物理地址定位
2010/07/24 Javascript
Javascript实现的类似Google的Div拖动效果代码
2011/08/09 Javascript
Ubuntu 11.10 安装Node.js的方法
2011/11/30 Javascript
JS仿百度搜索自动提示框匹配查询功能
2013/11/21 Javascript
jquery列表拖动排列(由项目提取相当好用)
2014/06/17 Javascript
javascript学习笔记(二)数组和对象部分
2014/09/30 Javascript
jquery树形菜单效果的简单实例
2016/06/06 Javascript
基于jQuery实现的查看全文功能【实用】
2016/12/11 Javascript
vue+element实现动态加载表单
2020/12/13 Vue.js
python友情链接检查方法
2015/07/08 Python
Python实现脚本锁功能(同时只能执行一个脚本)
2017/05/10 Python
Python单体模式的几种常见实现方法详解
2017/07/28 Python
Python切片索引用法示例
2018/05/15 Python
详解Django 中是否使用时区的区别
2018/06/14 Python
python2.x实现人民币转大写人民币
2018/06/20 Python
浅谈Python中的bs4基础
2018/10/21 Python
浅谈python requests 的put, post 请求参数的问题
2019/01/02 Python
使用Python实现跳帧截取视频帧
2019/05/31 Python
Pyinstaller 打包exe教程及问题解决
2019/08/16 Python
python实现将两个文件夹合并至另一个文件夹(制作数据集)
2020/04/03 Python
python 输入字符串生成所有有效的IP地址(LeetCode 93号题)
2020/10/15 Python
施华洛世奇天猫官方旗舰店:SWAROVSKI
2017/04/17 全球购物
数据库设计的包括哪两种,请分别进行说明
2016/07/15 面试题
Ajax实现页面无刷新留言效果
2021/03/24 Javascript
简历上的自我评价怎么写
2014/01/28 职场文书
计算机专业毕业生自荐信范文
2014/03/06 职场文书
保险公司晨会主持词
2014/03/22 职场文书
教师文明餐桌光盘行动倡议书
2015/04/28 职场文书
行政处罚听证告知书
2015/07/01 职场文书
告诉你创业计划书的8个实用技巧
2019/07/12 职场文书
python井字棋游戏实现人机对战
2022/04/28 Python