组件实例的引用方式

  • ref / $refs
  • $root
  • $parent
  • $children
  • 扩展查找任意组件实例的方法

在vue开发的项目中,通常会以一棵嵌套的组件树的形式来组织项目。

  • 都存在着一个根组件
  • 组件同时也都是 Vue 实例,组件间可以嵌套使用,形成了树状的级联形式,也就形成了父子组件、兄弟组件、祖先或后代组件这些关系。

在实际开发中,有时需要获取某个组件实例来引用其数据或方法。在前面讲解组件API的event时,通过ref / $refs调用组件实例来进行事件监听和触发。但$refs只能引用该组件下的子组件。

但实际上vue还提供其它几个API来获取组件实例$root / $parent / $children,我们也可以基于这些来扩展查找组件实例的便捷方法。

<div id="app">
<child1></child1>
</div>
const child1 = Vue.extend({template: `<div>子组件1<child1_1></child1_1></div>`})
const child1_1 = Vue.extend({
template: `<div>
<button @click="handleClick">子组件1_1,点击打印</button>
<child1_1_1></child1_1_1>
<child1_1_2 ref="child1_1_2"></child1_1_2/>
</div>`,
methods: {
handleClick() {
console.log('this:',this.$vnode.tag)
console.log('this.$root:',this.$root)
console.log('this.$parent:',this.$parent.$vnode.tag)
console.log('this.$children:',this.$children)
console.log('this.$children[0]:',this.$children[0].$vnode.tag)
console.log('this.$children[1]:',this.$children[1].$vnode.tag)
console.log('this.$refs.child1_1_2:',this.$refs.child1_1_2.$vnode.tag)
}
}
})
const child1_1_1 = Vue.extend({template: `<div>子组件1_1_1</div>`})
const child1_1_2 = Vue.extend({template: `<div>子组件1_1_2</div>`}) Vue.component('child1',child1)
Vue.component('child1_1',child1_1)
Vue.component('child1_1_1',child1_1_1)
Vue.component('child1_1_2',child1_1_2) const vm = new Vue({
el: "#app",
})
this: vue-component-2-child1_1
this.$root: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
this.$parent: vue-component-1-child1
this.$children: [VueComponent, VueComponent]
this.$children[0]: vue-component-3-child1_1_1
this.$children[1]: vue-component-4-child1_1_2
this.$refs.child1_1_2: vue-component-4-child1_1_2

根据组件名称查找任意组件实例

点击查看参考链接:https://github.com/icarusion/vue-component-book

场景:

  • 由一个组件,向上找到最近的指定组件
  • 由一个组件,向上找到所有的指定组件
  • 由一个组件,向下找到最近的指定组件
  • 由一个组件,向下找到所有指定的组件
  • 由一个组件,找到指定组件的兄弟组件

实现:

结合$parent / $children,通过递归、遍历查找与指定组件的name选项匹配的组件实例。

// 由一个组件,向上找到最近的指定组件
function findComponentUpward (context, componentName) {
let parent = context.$parent;
let name = parent.$options.name; while (parent && (!name || [componentName].indexOf(name) < 0)) {
parent = parent.$parent;
if (parent) name = parent.$options.name;
}
return parent;
}
// 由一个组件,向上找到所有的指定组件
function findComponentsUpward (context, componentName) {
let parents = [];
const parent = context.$parent; if (parent) {
if (parent.$options.name === componentName) parents.push(parent);
return parents.concat(findComponentsUpward(parent, componentName));
} else {
return [];
}
}
// 由一个组件,向下找到最近的指定组件
function findComponentDownward (context, componentName) {
const childrens = context.$children;
let children = null; if (childrens.length) {
for (const child of childrens) {
const name = child.$options.name; if (name === componentName) {
children = child;
break;
} else {
children = findComponentDownward(child, componentName);
if (children) break;
}
}
}
return children;
}
// 由一个组件,向下找到所有指定的组件
function findComponentsDownward (context, componentName) {
return context.$children.reduce((components, child) => {
if (child.$options.name === componentName) components.push(child);
const foundChilds = findComponentsDownward(child, componentName);
return components.concat(foundChilds);
}, []);
}
// 由一个组件,找到指定组件的兄弟组件
// 每个vue组件实例都有一个唯一的_uid
function findBrothersComponents (context, componentName, exceptMe = true) {
let res = context.$parent.$children.filter(item => {
return item.$options.name === componentName;
});
let index = res.findIndex(item => item._uid === context._uid);
if (exceptMe) res.splice(index, 1);
return res;
}

vue-learning:30 - component - 组件实例的引用方式的更多相关文章

  1. VUE 动态加载组件的四种方式

    动态加载组件的四种方式: 1.使用import导入组件,可以获取到组件 var name = 'system'; var myComponent =() => import('../compon ...

  2. vue中js获取组件实例

    获取到的VM实例,外部js仍然能自由调用VM的一切属性和方法. <template> </template> <script> // 声明变量currVM let ...

  3. Vue中封装axios组件实例

    首先要创建一个网络模块network文件夹  里面要写封装好的几个组件 在config.js里面这样写 在index.js要这样写 core.js文件里面内容如下 然后要在main.js文件里面要设置 ...

  4. Vue加载组件、动态加载组件的几种方式

    https://cn.vuejs.org/v2/guide/components.html https://cn.vuejs.org/v2/guide/components-dynamic-async ...

  5. vue动态加载组件

    vue动态加载组件,可以使用以下方式 <component :is="propertyname" v-for="tab in tabs"></ ...

  6. 在被vue组件引用的 js 文件里获取组件实例this

    思路: 通过调用函数 把 组件实例this  传递 到 被应用的 js文件里 实例: 文件结构 在SendThis.vue 文件中引用 了modalConfig.js import modalConf ...

  7. 二、Vue组件(component):组件的相互引用、通过props实现父子组件互传值

    一.组件各部分说明及互相引用 1.一个vue组件由三个部分组成 Template 只能存在一个根元素 2.Script 3.Style scoped:样式只在当前组件内生效 1.1 组件的基本引用代码 ...

  8. 第七十七篇:ref引用(在vue中引用组件实例)

    好家伙, 为方便理解, 我们先来写一个经典自增一按钮, 再加上一个count清零按钮, Left.vue组件中: <template> <div > <h1>我是L ...

  9. vue构造函数(根实例化时和组件实例对象选项)参数:选项详解

    实例选项(即传给构造函数的options):数据,DOM,生命周期钩子函数,资源,组合,其他 数据 data 属性能够响应数据变化,当这些数据改变时,视图会进行重渲染. 访问方式: 1.通过 vm.$ ...

随机推荐

  1. c# 日期函数

    DateTime dt = DateTime.Now;Label1.Text = dt.ToString();//2005-11-5 13:21:25Label2.Text = dt.ToFileTi ...

  2. Directx教程(28) 简单的光照模型(7)

    原文:Directx教程(28) 简单的光照模型(7)        现实生活中的点光源都是随着距离衰减的,比如一个电灯泡在近处会照的很亮,远处光线就很弱.本节中我们在前面光公式的基础上,再给漫反射和 ...

  3. Directx11教程(7) 画一个颜色立方体

    原文:Directx11教程(7) 画一个颜色立方体       前面教程我们通过D3D11画了一个三角形,本章我们将画一个颜色立方体,它的立体感更强.主要的变动是ModelClass类,在Model ...

  4. python 对象(object)

  5. 阿里云应用高可用 AHAS 正式商用,可一键提升云上应用可用性

    在分布式架构环境下,服务间的依赖日益复杂,可能没有人能说清单个故障对整个系统的影响,构建一个高可用的分布式系统面临着很大挑战. 7月17日,阿里云应用高可用服务AHAS 正式商用,包含架构感知.流控降 ...

  6. 让超出div内容的显示滚动条:overflow:auto,以及overflow其它属性

    css的属性,以前没用过遇到了,记录一下: 虽然layui本来自带这个处理,但是为了灵活,抛弃layui原有的加载,只是用layui的样样式,就要使用到这个css属性 总结overflow属性: /* ...

  7. c++11的新特性

    好奇心来源于下面的一段代码, 一个是unordered_map, 这是c++11新加的container. 另外还有unordered_set, unordered_multimap, unorder ...

  8. zabbix概述篇

    zabbix监控系统概述 监控系统 决不允许未经监控的业务和服务的上线 基本功能 采样:获取客户端数据(主动和被动模式) 存储 展示 告警 监控通道 ssh/telnet:无agent snmp:简单 ...

  9. 开发者总结的WatchKit App提交技巧

    苹果4月初宣布所有注册开发者已经可以向App Store提交基于WatchKit开发的Apple Watch app了,不过不少开发者遇到了模拟器中没有发现的问题.这篇文章主要收集了一些提交tips和 ...

  10. Visual Studio中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法

    解决方案:选中项目中引入的dll,鼠标右键,选择属性,把“嵌入互操作类型”设置为False,问题轻松解决. 问题分析: 1.”嵌入互操作类型”中的嵌入就是引进.导入的意思,类似于c#中using,c中 ...