组件实例的引用方式

  • 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. AI种黄桃AI卖黄桃 阿里巴巴推进一站式政务服务

    7月11日,武汉城市峰会期间,武汉.枣阳.荆门等多个城市发布了同阿里巴巴的最新合作.这些合作包括用人工智能改善武汉交通拥堵.降低枣阳黄桃种植成本.提升荆门城市治理和市民服务水平等.阿里云.蚂蚁金服.高 ...

  2. JavaScript--关于变量提升思考

    下面例子仅仅是思考变量提升使用: 在实际开发中并不推荐使用相同名字的变量和函数! // 如果变量和函数同名的话,函数优先提升 console.log(a); function a() { consol ...

  3. 小爬爬7:回顾&&crawlSpider

    1.回顾昨日内容 回顾 - 全站数据爬取(分页) - 手动请求的发送Request(url,callback) - post请求和cookie处理 - start_requests(self) - F ...

  4. 2016 Asia Jakarta Regional Contest L - Tale of a Happy Man UVALive - 7722

    UVALive - 7722 一定要自己做出来!

  5. EL表达式多条件或判断用法

    简单记录一EL表达式的判断用法 <c:if test="${(order.status == '06'&& order.type=='02') || (order.st ...

  6. 为什么不喜欢在 QQ 群里回答问题?

    为什么不喜欢在 QQ 群里回答问题? 没有主题,主题随时都在变. 回答后无法备份,当然自己有心可以总结一下. 实时性要求太强,可能回答但是突然有事离开,再回头看已经是 几十条的留言. QQ 群用来闲聊 ...

  7. jq 监听返回事件

    <script> $(document).ready(function(e) {             var counter = 0;            if (window.hi ...

  8. oracle函数 add_months(d1,n1)

    [功能]:返回在日期d1基础上再加n1个月后新的日期. [参数]:d1,日期型,n1数字型 [返回]:日期

  9. H3C 各种视图之间的关系

  10. Python基础之(三)----PyGame安装步骤

    http://blog.csdn.net/qq_33166080/article/details/68928563 如果你已经有一定的编程经验,那么学习一门新语言最快的方式就是拿着一个比较中型的项目, ...