$parent/$children的使用场景 -- vue组件通信系列

简介: $parent/$children的使用场景 -- vue组件通信系列

$parent/$children的使用场景 -- vue组件通信系列


vue 组件的数据通信方式很多,本篇着重讲$parent/$children,神助是$broadcast/$dispatch

$parent/$children的常用场景:封装嵌套组件时,直接使用长辈或者子孙组件的方法,该方法并不改变数据,常常结合$broadcast/$dispatch使用。

什么是$parent/$children

先问一句,div标签,其父元素和子元素是谁?

这其实没有答案。

父元素和子元素是谁,取决于运行时div的位置。

试着说说,以下div的父元素和子元素。

<body>
  <div id="div1">
    <main>
      <div id="div2">
        <h1>一级标题<h1>
        <p>段落<p>
      </div>
    <main>
  </div>
</body>

div1:

  • 父元素是,body
  • 子元素是,main。注意是子元素是指直接后代。

div2:

  • 父元素是,main
  • 子元素是,h1和p。注意是子元素是指直接后代。

总结下:

  • 元素本身没有父元素和子元素,而是在运行时,每个元素实例的位置,决定其父元素和子元素
  • 每个元素实例有且只有一个父元素(顶级元素实例没有哈)
  • 但每个元素实例可能没有子元素,可能有一个,也可能有多个,所以一般children是数组,没有的时候是空数组
  • js 运行时,若添加或者删除元素实例,那些发生位置变化的元素实例们,父元素和子元素也会发生变化。

正文来了!!!组件也是一样滴!!!

因为本来组件就是模仿元素的嘛!!!

把上面的元素成组件即可!

  • 组件本身没有父组件和子组件,而是在运行时,每个组件实例的位置,决定其父组件和子组件
  • 每个组件实例有且只有一个父组件(顶级组件实例没有哈)
  • 但每个组件实例可能没有子组件,可能有一个,也可能有多个,所以一般children是数组,没有的时候是空数组
  • js 运行时,若添加或者删除组件实例,那些发生位置变化的组件实例们,父组件和子组件也会发生变化。

其实属性和事件这种机制,也可以类比元素理解,当然这是后话。

举例说明$parent/$children

写一个页面组件,里面放些组件,打印下$parent/$children

网络异常,图片无法展示
|

<template lang="pug">
//- 页面组件
div
  list-item
  list-item
</template>
<script>
import ListItem from "@/components/ListItem";
export default {
  name: "List",
  components: { ListItem },
  mounted() {
    console.log("页面的$parent", this.$parent);
    console.log("页面的$children", this.$children);
  }
};
</script>

其实还能看到,渲染的时候先子组件的mounted,然后再是自己的mounted.

要是想在子组件里获取父组件的元素之类的,必须使用nextTick

$dispatch

在使用element-ui的时候,有个el-form,大约是这么用的:

<template lang="pug">
el-form
  el-form-item
    el-input
</template>

假设el-input想要执行el-form上的方法,就会这样this.$parent.$parent.methodXx(),更多层级可能更复杂,于是$dispatch就诞生了。

// main.js
// 向上某个组件,派发事件
Vue.prototype.$dispatch = function(eventName, componentName, ...args) {
  let parent = this.$parent;
  while (parent) {
    // 只有是特定组件,才会触发事件。而不会一直往上,一直触发
    const isSpecialComponent = parent.$options.name === componentName;
    if (isSpecialComponent) {
      // 触发了,就终止循环
      parent.$emit(eventName, ...args);
      return;
    }
    parent = parent.$parent;
  }
};

这样在el-input里想要触发el-form里的方法,this.$dispatch('changeSort','el-form',{isAsc:true})

$broadcast

同理,假设el-form想要执行el-input上的方法,就会这样this.$children[0].$children[0].methodXx(),更多层级可能更复杂,于是$broadcast就诞生了,使用的时候this.$broadcast('changeValue','el-input','hello')

注意,$children 是数组,所以当只有一个子组件时,使用[0]获取。当有多个子组件时,它并不保证顺序,也不是响应式的。

// 向下通知某个组件,触发事件
Vue.prototype.$broadcast = function(eventName, componentName, ...args) {
  // 这里children是所有子组件,是子组件不是后代组件哈
  let children = this.$children;
  broadcast(children);
  // 这里注意,抽离新的方法递归,而不是递归$broadcast
  function broadcast(children) {
    for (let i = 0; i < children.length; i++) {
      let child = children[i];
      const isSpecialComponent = child.$options.name === componentName;
      if (isSpecialComponent) {
        // 触发了,就终止循环
        child.$emit(eventName, ...args);
        return;
      }
      // 没触发的话,就看下有没有子组件,接着递归
      child.$children.length &&
        child.$broadcast(eventName, componentName, ...args);
    }
  }
};

更新

感谢评论区,以上可以作为思路拓展,但官方文档不建议使用broadcast/broadcast/broadcast/dispatch,而是倾向于用eventBus的模式。

目录
相关文章
|
1月前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
28天前
|
缓存 JavaScript UED
Vue3中v-model在处理自定义组件双向数据绑定时有哪些注意事项?
在使用`v-model`处理自定义组件双向数据绑定时,要仔细考虑各种因素,确保数据的准确传递和更新,同时提供良好的用户体验和代码可维护性。通过合理的设计和注意事项的遵循,能够更好地发挥`v-model`的优势,实现高效的双向数据绑定效果。
128 64
|
7天前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
28天前
|
前端开发 JavaScript 测试技术
Vue3中v-model在处理自定义组件双向数据绑定时,如何避免循环引用?
Web 组件化是一种有效的开发方法,可以提高项目的质量、效率和可维护性。在实际项目中,要结合项目的具体情况,合理应用 Web 组件化的理念和技术,实现项目的成功实施和交付。通过不断地探索和实践,将 Web 组件化的优势充分发挥出来,为前端开发领域的发展做出贡献。
32 8
|
28天前
|
JavaScript
在 Vue 3 中,如何使用 v-model 来处理自定义组件的双向数据绑定?
需要注意的是,在实际开发中,根据具体的业务需求和组件设计,可能需要对上述步骤进行适当的调整和优化,以确保双向数据绑定的正确性和稳定性。同时,深入理解 Vue 3 的响应式机制和组件通信原理,将有助于更好地运用 `v-model` 实现自定义组件的双向数据绑定。
|
1月前
|
JavaScript 前端开发 开发者
Vue是如何劫持响应式对象的
Vue是如何劫持响应式对象的
29 1
|
1月前
|
JavaScript 前端开发 API
介绍一下Vue中的响应式原理
介绍一下Vue中的响应式原理
32 1
|
1月前
|
JavaScript 前端开发 开发者
vue 数据驱动视图
总之,Vue 数据驱动视图是一种先进的理念和技术,它为前端开发带来了巨大的便利和优势。通过理解和应用这一特性,开发者能够构建出更加动态、高效、用户体验良好的前端应用。在不断发展的前端领域中,数据驱动视图将继续发挥重要作用,推动着应用界面的不断创新和进化。
|
1月前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
1月前
|
存储 JavaScript 前端开发
介绍一下Vue的核心功能
介绍一下Vue的核心功能

热门文章

最新文章