vue-learning:30 - component - 组件实例的引用方式
组件实例的引用方式
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 - 组件实例的引用方式的更多相关文章
- VUE 动态加载组件的四种方式
动态加载组件的四种方式: 1.使用import导入组件,可以获取到组件 var name = 'system'; var myComponent =() => import('../compon ...
- vue中js获取组件实例
获取到的VM实例,外部js仍然能自由调用VM的一切属性和方法. <template> </template> <script> // 声明变量currVM let ...
- Vue中封装axios组件实例
首先要创建一个网络模块network文件夹 里面要写封装好的几个组件 在config.js里面这样写 在index.js要这样写 core.js文件里面内容如下 然后要在main.js文件里面要设置 ...
- Vue加载组件、动态加载组件的几种方式
https://cn.vuejs.org/v2/guide/components.html https://cn.vuejs.org/v2/guide/components-dynamic-async ...
- vue动态加载组件
vue动态加载组件,可以使用以下方式 <component :is="propertyname" v-for="tab in tabs"></ ...
- 在被vue组件引用的 js 文件里获取组件实例this
思路: 通过调用函数 把 组件实例this 传递 到 被应用的 js文件里 实例: 文件结构 在SendThis.vue 文件中引用 了modalConfig.js import modalConf ...
- 二、Vue组件(component):组件的相互引用、通过props实现父子组件互传值
一.组件各部分说明及互相引用 1.一个vue组件由三个部分组成 Template 只能存在一个根元素 2.Script 3.Style scoped:样式只在当前组件内生效 1.1 组件的基本引用代码 ...
- 第七十七篇:ref引用(在vue中引用组件实例)
好家伙, 为方便理解, 我们先来写一个经典自增一按钮, 再加上一个count清零按钮, Left.vue组件中: <template> <div > <h1>我是L ...
- vue构造函数(根实例化时和组件实例对象选项)参数:选项详解
实例选项(即传给构造函数的options):数据,DOM,生命周期钩子函数,资源,组合,其他 数据 data 属性能够响应数据变化,当这些数据改变时,视图会进行重渲染. 访问方式: 1.通过 vm.$ ...
随机推荐
- Python中if __name__ == '__main__':理解
在很多python脚本中在最后的部分会执行一个判断语句if __name__ == "__main__:",之后还可能会有一些执行语句.那添加这个判断的目的何在? 在python编 ...
- docker-compose进入容器出现unable to find user root: no matching entries in passwd file
解决办法: 先docker-compose stop 容器,再docker-compose start 容器.虽然这样可以很快 解决问题,但并非长久之计.
- mysql 使用concat模糊查询
如果这三个字段中有值为NULL,则返回的也是NULL,那么这一条记录可能就会被错过,使用IFNULL进行判断 SELECT * FROM `magazine` WHERE CONCAT(IFNULL( ...
- linux查看用户组所有成员
1.grep 'user1' /etc/group //找出用户组的gid user1:x:1004://得出gid=1004 2. awk -F":" '{print $1&qu ...
- typeof操作符,返回数据类型Array.isArray()、Object.prototype.toString.call()
源地址https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Operators/typeof typeof操作符 // N ...
- TIJ——Chapter Four:Controlling Execution
同上一章,本章依然比较简单.基础,因此只是做一些总结性的笔记. 1. 不像C和C++那样(0是假,非零为真),Java不允许用一个数字作为boolean值. 2. C中,为了给变量分配空间,所有变量的 ...
- WebLogic Server再曝高风险远程命令执行0day漏洞,阿里云WAF支持免费应急服务
6月11日,阿里云安全团队发现WebLogic CVE-2019-2725补丁绕过的0day漏洞,并第一时间上报Oracle官方, 6月12日获得Oracle官方确认.由于Oracle尚未发布官方补丁 ...
- Laravel 的HTTP请求#
获取请求# 要通过依赖注入的方式来获取当前HTTP请求的实例,你应该在控制器方法中类型提示Illuminate\Http\Request 传入的请求的实例通过 服务容器自动注入: <?php n ...
- Pytorch - GPU ID 指定 pytorch gpu 指定
PyTorch 关于多 GPUs 时的指定使用特定 GPU. PyTorch 中的 Tensor,Variable 和 nn.Module(如 loss,layer和容器 Sequential) 等可 ...
- pytorch bert 源码解读
https://daiwk.github.io/posts/nlp-bert.html 目录 概述 BERT 模型架构 Input Representation Pre-training Tasks ...