一起来学习Vue的组件间通信方式

props

父组件可以通过props向下传递数据给子组件

静态的Props

通过为子组件在父组件中的占位符添加特性的方式来达到传值的目的

动态Props

在模版中要动态的绑定父组件的数据到子模版的props,与绑定任何普通的HTML特性相类似,用v-bind,每当父组件的数据发生变化的时候,该变化会传导给子组件

props验证

可以为组件的props指定验证规则,如果传入的数据不符合规则,Vue会发出警告

props: {
    // 基础类型检测 (`null` 意思是任何类型都可以)
    propA: Number,
    // 多种类型
    propB: [String, Number],
    // 必传且是字符串
    propC: {
      type: String,
      required: true
    },
    // 数字,有默认值
    propD: {
      type: Number,
      default: 100
    },
    // 数组/对象的默认值应当由一个工厂函数返回
    propE: {
      type: Object,
      default: function () {
        return { message: 'hello' }
      }
    },
    // 自定义验证函数
    propF: {
      validator: function (value) {
        return value > 10
      }
    }
  }

type 可以是(String,Number,Boolean,Function,Object,Array,Symbol)原生构造器

type也可以是自定义构造函数,使用instenceof检测

prop是当先绑定的,当父组件的属性变化是,将传导给子组件,但是不会反过来,这是为了防止子组件无意修改了父组件的状态。

修改prop数据

  • prop 作为初始值传入后,子组件想把他当作局部数据来用
  • prop 作为初始值传入,有子组件处理成其他数据输出
  • 注意:js中对象和数组是引用类型,指向同一个内存空间,如果prop是一个对象或数组,在子组件内部改变它会影响父组件的状态
    • 处理方法1:这个时候需要定义一个局部变量,并用prop初始化它,但是局部变量只能接受prop初始值,当父组件的值发生变化的时候,无法接收到最新值
    • 处理方法2:定义一个计算属性,处理prop值并返回
    • 初始方法3:使用变量存储prop的初始值,并使用watch来观察prop的值的变化,当发生变化的时候更新变量的值

$emit

$emit(‘自定义时间名’,要传送的数据)触发当前实例上的事件

父组件

<template>
    <children @addCount="addCount" :count="count"/>
<template>
<script>
  import children from "./children";
  export default {
    name:'index',
    components: {Children},
    data () {
      return {
        count:0
      }
    },
    methods:{
      addCount(data){
        this.count = data.count;
      }
    }
  }
</script>

子组件

<template>
  <div>
    <h3>计数器:{{count}}</h3>
    <button @click='add'>+++</button>
  </div>
</template>
<script>
  export default {
    name:'children',
    props:['count'], // 用来接收父组件传给子组件的数据
    methods:{
      add() {
        // 触发父组件的方法
        this.$emit('addCount',{count: count + 1});
      }
    }
  }
</script>

$on

$on(‘事件名’,callback)监听事件,监听当前实例上的自定义事件

父组件

<template>
   <div>
        <span>{{count}}</span>
        <children/>
   </div>
<template>
<script>
  import { bus } from '../main.js';
  import children from "./children";
  export default {
    name:'index',
    components: {Children},
    data () {
      return {
        count:0
      }
    },
    mounted(){
        bus.$on('addCount',(val)=>{
            this.count++;
        })
    }
  }
</script>

子组件

<template>
    <button @click='add'>count+++</button>
</template>
<script>
import { bus } from '../main.js';
export default {
    name:'children',
    methods:{
      add() {
        // 触发父组件的方法
        bus.$emit('addCount',{});
      }
    }
}
</script>

main文件

export var bus = new Vue();

注意: e m i t 和 emit和 emit和on的事件必须在一个公共的实例上, e m i t 触 发 的 事 件 emit触发的事件 emit触发的事件on才能监听到。

$parent(不常用)

指向当前组件树的根实例,如果当前实例没有父实例,则实例将会指向自己。

  • $parent既可以接受父组件数据,又可以修改父组件数据,是双向的。
  • $parent可以调用父组件的方法

子组件

<template>
    <button @click='actionParent'>触发父组件发方法</button>
</template>
<script>
export default {
    name:'children',
    methods:{
      actionParent() {
        console.log(this.$parent.name);
        this.$parent.parentPrint(); // 触发父组件的方法
      }
    }
}
</script>

$children(不常用)

指向当前实例的直接子组件,返回的是一个组件的集合。

需要注意: children 并 不 保 证 顺 序 , 也 不 是 响 应 式 的 。 如 果 你 发 现 自 己 正 在 尝 试 使 用 children并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用 children并不保证顺序,也不是响应式的。如果你发现自己正在尝试使用children进行数据绑定,考虑使用一个数组配合v-for来生成子组件,并且使用Array作为真正的来源。

for(let i=0; i<this.$children.length; i++){
    console.log(this.$children[i].name); // 输出子组件的name
}

$attrs

包含了父作用域中不作为prop被识别(且获取)的特性绑定(class,style除外)。当一个组件没有声明任何prop时,这里会包含所有父作用域的绑定,并且可以通过v-bind="$attrs"传入内部组件–在创建高级别的组件时非常有用。

简单说:接收除了props声明外的所有绑定属性(calss,style除外)

上图的$attrs中只有age,gender两个属性{ age: “20”, gender: “man” }

在grandson上通过v-bind="$attrs",可以将属性继续向下传递,让grendson也能访问到父组件的属性。
这种方式当传递多个属性时会显得很便捷,不需要一条一条进行绑定。

如果想要添加其他属性,可继续绑定属性,注意:继续绑定的属性和$attr中的属性有重复时,继续绑定的属性优先级会更高

$listeners

包含了父级作用域中的(不含.native修饰器的)v-on事件监听器,他可以通过v-on="$listeners"传入内部组件–在创建更高层次的组件时非常有用。

简单说:接收除了带有.native事件修饰符的所有事件监听器

child组件绑定了带有.native的click事件和一个自定义事件,$listeners输出的结果为:{customEvent:fn}

通过v-on="  listeners"将事件监听器继续向下传递,让grandson访问到事件。并且可以使用emit触发传递下来的事件。

如果想要添加其他事件监听器,可以继续绑定事件

注意:继续绑定的事件和$listeners中的事件有重复的时候,不会被覆盖。当grandson触发customEvent时,child和parent的事件都会被触发,触发顺序类似于冒泡。

使用场景

  • 组件传值时使用,父亲,儿子,孙子三级传递参数交互。
  • 对一些UI库进行二次封装的时候使用,比如element-ui中的组件不能满足自己的使用场景时,会二次封装,但是又想保留它自己的属性和方法,这个时候使用。

$refs

this.$refs是一个对象,持有当前组件中注册过ref特性的所有DOM元素和子组件实例

注意:$refs只有在组件渲染完成之后才填充,在初始渲染的时候不能访问他们,并且它是非响应式的,因此不能用它在模版中做数据绑定。

父组件

<template>
    <div>
       <div ref="testDom">123</div>
       <child ref="child" />
       <button @click="openChild" >触发子组件</button>
    </div>
</template>
<script>
import Child form './child.vue'
export default {
    components:{
        Child
    },

    mounted(){
        console.log(this.$refs.testDom) // <div>123</div>
        console.log(this.$refs.child.name) // 粉刷匠
    },
    methods:{
        openChild(){
            this.$refs.child.open();
        }
    }

}
</script>

子组件

<template>
   <div>{{name}}</div>
</template>
<script>
export default {
   data(){
      return {
        name:"粉刷匠"
      }
   },
   methods:{
        open(){
            alter("点击了")
        }
   }
}
</script>

注意:当ref和v-for一起使用的时候,获取到的将会是一个数组,包含循环数组源。

provide && inject

provide/inject是vue2.2版本之后新增的高级组件,这两个组件要一起使用。
允许一个祖先组件向其所有的子孙后代注入一个依赖。无论组件层次有多深,并在其上下游关系成立的事件里始终有效。类似于React的上下文。

provide选项是一个对象 或返回一个对象的函数。该对象包含可注入其子孙的property。

inject有下面两种:

  • 一个字符串数组
  • 一个对象
    • 对象的key是本地的绑定名,
    • value
      • 在可用的注入内容中搜索用的key(字符串/Symbol)
      • 或一个对象
        • from property是在可用的注入内容中搜索用的key(字符串/Symbol)
        • default property是降级情况下使用的value

provide和inject绑定并不是可响应的,这是vue官方刻意为之的。如果你传入一个可监听的对象,那么其对象的property还是可响应的。

缺点:在任意层级都能访问导致数据追踪比较难,所以provide/inject能不使用就不使用,尽量使用vuex。在组件库开发的可以使用

副组件

<template>
	<div class="test">
		<son prop="data"></son>
	</div>
</template>

<script>
export default {
	name: 'Father',
	provide: {
		chontrol: this
	}
    data(){
        return {
            name:"啊哈哈"
        }
    }
}

// 某一级子组件/孙子组件

<template>
	<div>
		{{name}}
	</div>
</template>

<script>
export default {
	name: 'son',
	inject: ["chontrol"]
    props: {
        name: {
          type: Object,
          default: () => ({}),
        },
    }
  },
}
</script>

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注我们的更多内容!

(0)

相关推荐

  • Vue中父子组件通信与事件触发的深入讲解

    目录 一.组件 子组件 父组件 二.父子组件通信 父组件给子组件通信 子组件向父组件通信 三.父子组件事件触发 父组件调用子组件中的事件方法 子组件调用父组件中的事件方法 四.总结 一.组件 子组件 <template> <div style="border:1px solid black;width:400px; height: 130px;"> <h3>我是子组件</h3> <button>子组件将值传递给父组件</

  • Vue3的10种组件通信方式总结

    目录 引言 Props emits expose/ref Non-Props 单个根元素的情况 多个元素的情况 v-model 单值的情况 多个v-model绑定 v-model修饰符 插槽slot 默认插槽 具名插槽 作用域插槽 provide/inject 总线bus getCurrentInstance Vuex 安装 使用 State Getter Mutation Action Module Pinia 安装 注册 在组件中使用 啰嗦两句 mitt.js 安装 使用 总结 引言 本文讲

  • vue父子组件进行通信方式原来是这样的

    目录 一.props 二.细节三props大小写命名 三.非props的attributes属性 四.子组件传递给父组件 五.简单例子 总结 在vue中如何实现父子组件通信,本篇博客将会详细介绍父子组件通信的流程. 如图所示,父组件向子组件传递数据,可以通过props,子组件向父组件传递数据可以通过触发事件来进行. 一.props 父组件向子组件传递的数据,通过props进行传递,我们可以把props理解为属性.props传递存在两种格式,一种是数组格式,另一种是对象类型格式.其中第二种对象类型

  • vue中组件之间相互通信传值的几种方法详解

    目录 vue中组件之间相互通讯传值的方式 1.子组件和父组件通讯,通过调用父组件给组件自定义属性值来实现 2.父组件主动获取子组件数据 3.使用provide/inject方法实现 4.使用事件总线 5.vuex\localStorage\sessionStorage 总结 vue中组件之间相互通讯传值的方式 我们在使用vue进行项目开发的时候为了更好地管理项目,我们会把每个功能封装成一个个的组件,在使用的时候直接引入并且调用组件来实现代码的复用. 我们在封装组件的时候经常会留有一些预留的接口,

  • Vue组件之间的通信你知道多少

    目录 Vue组件间通信 1.父向子传递数据 1.props的大小写 2.props的两种写法 3.传递动态props 2.子向父传递数据 3.兄弟(任意)组件间的传值 3.1全局事件总线 3.2消息订阅与发布 总结 Vue组件间通信 vue组件间通信分为以下几种: 父向子传递数据,用自定义属性 子向父传递数据,用自定义事件 兄弟(任意)组件间传递数据,用全局事件总线或者消息订阅与发布 背吧,面试题要是说让你简述一下,就上面这段话拿过来回答呗.下面就介绍一下这几种通信方式的简单用法 1.父向子传递

  • vue 组件通信的多种方式

    目录 前言 一.vuex 二.eventBus 三.props/emit 四.$parent/$children 五.$attrs/$listeners 六.provide/inject 前言 在vue中,​ 组件的关系不外乎以下三种: 组件是需要通信的,在开发中,常用到的通信方式有:vuex.eventBus.以及props与emit.$parent与$children,除此之外,还有provide与inject.$attrs与$listeners等. 一.vuex 这个相信大家用的很多了,简

  • 一起来学习Vue的组件间通信方式

    props 父组件可以通过props向下传递数据给子组件 静态的Props 通过为子组件在父组件中的占位符添加特性的方式来达到传值的目的 动态Props 在模版中要动态的绑定父组件的数据到子模版的props,与绑定任何普通的HTML特性相类似,用v-bind,每当父组件的数据发生变化的时候,该变化会传导给子组件 props验证 可以为组件的props指定验证规则,如果传入的数据不符合规则,Vue会发出警告 props: { // 基础类型检测 (`null` 意思是任何类型都可以) propA:

  • Vue.js组件间通信方式总结【推荐】

    平时在使用Vue框架的业务开发中,组件不仅仅要把模板的内容进行复用,更重要的是组件之间要进行通信.组件之间通信分为三种:父-子:子-父:跨级组件通信.下面,就组件间如何通信做一些总结. 1.父组件到子组件通过props通信 在组件中,使用选项props来声明需要从父级组件接受的数据,props的值可以是两种:一种是字符串数组,一种是对象.props中声明的数据与组件data函数return的主要区别在于props来自父级,而data中的组件是自己的数据,作用域是组件本身,这两种数据都可以在模板t

  • vue综合组件间的通信详解

    本文实例为大家分享了vue综合组件间的通信,供大家参考,具体内容如下 实现一个ToDoList. ①完成所有的组件的创建和使用 ②add 点击add按钮时候,将用户输入的内容(todoinput),显示在(todolist) 核心代码:兄弟组件间通信 步骤1:var bus = new Vue() 步骤2:在准备接受数据的组件 bus.$on('addEvent',function(){ }) 步骤3:触发事件 bus.$emit('addEvent',123) 将todolist中数组的元素

  • Vue实现组件间通信的几种方式(多种场景)

    目录 1.Props 父 >>> 子  (Props) 子 >>> 父 ($emit) 2.Bus事件总线 3.Vuex状态管理库 4.Router 5.缓存 以下是我在开发中用到过的vue组件之间的通信方式,不同的场景使用不同的方式,基本满足所有开发场景中的通信需求,从最简单的事例着手,讲述如何使用,话不多说直接开始,满满的干货,建议看完. 1.Props 父 >>> 子  (Props) 一个组件里面引入另外一个组件,此时构成了一种"父子

  • Vue常见组件间通信方案及典型应用场景详解

    目录 什么是组件通信 1.父子组件通信场景 2.兄弟组件通信场景 3.根组件和后代组件通信场景 4.插槽通信场景 5 无直接关系的组件通信场景 6 大型项目中的复杂组件通信场景 - Vuex状态管理 7 其他的一些组件通信方案 总结 什么是组件通信 所谓组件通信,就是组件之间的数据交互,也就是把一个组件A里面的数据传递到另一个组件B,并能够让组件B根据这个数据更新界面. 在 Vue中,可用的通信方案有很多,下面给大家描述几个常用的组件通信方案及其典型的应用场景. 1.父子组件通信场景 父子组件通

  • vue父子组件间引用之$parent、$children

    vue中提到[父子组件],则一定会想到我们常用的父子组件通信:props+$on().$emit() ,如图: 也就是说,虽然在一般情况下,子组件是不能引用父组件或者Vue实例的数据,但是对于在开发中出现的"数据需要在组件中来回传递",我们最简单的解决办法就是通过props(和v-on)将数据从父组件传到子组件,再用$emit将数据从子组件传到父组件,以此循环引用. 但是在另一些场景下,我们可能想要比如(在父组件中)拿到子组件对象,然后直接操作其中数据,去实现一些功能,比如方法的调用.

  • 浅谈Vue的组件间传值(包括Vuex)

    目录 父传子: 子传父: 在不使用Vuex的情况下,组件间传值的方式是通过父传子的方式或者兄弟组件传值. 父传子: fatherComponent: <template> <div> <HELLOWORLD :needData="content"></HELLOWORLD> </div> </template> <script> import HELLOWORLD from '../components

  • vue两组件间值传递 $router.push实现方法

    两组件间传值,可能包含多种情况,有父子组件和非父子组件,对于父子组件网上有很详细的方法讲解,但非父子组件传值有用bus总线,还有一些其他方法,其中的使用路由跳转的方法讲解太过简洁,难以理解.因为是公司项目,采用的是公司封装的UI框架,但基本上还是采用vue框架,ts编写.所以一些样式结构可能没有参考价值,但我会讲解清楚每一部分作用,主要是路由跳转部分的代码实现. 首先,需求如下图,树状列表每一项有一个编辑按钮,点击按钮之后跳转到另一个路由页面,会将树状列表中每一项数据带过来. vue文件部分:

  • Vue.js组件间的循环引用方法示例

    什么是组件: 众所周知组件是Vue.js最强大的功能之一.组件可以扩展HTML元素,封装可重用的代码.在较高层面上,组件是自定义的元素,Vue.js的编译器为它添加特殊功能.在有些情况下,组件也可以是原生HTML元素的形式,以is特性扩展.下面话不多说了,来一起看看本文的正文内容. 引言 写了大大小小不少基于vue的项目,但是基本没用到过组件循环引用的知识. 为了查缺补漏,照着官方文档撸一个DEMO:组件之间的循环引用 本人的运行版本为 vue-cli@2.8.1,启用项目后,将以下 js 文件

  • 一起来学习Vue的组件化

    目录 背景 定义 分类 优势 首屏加载优化 组件之间的关系 总体上可以分为两大类: 常见使用场景可以分为三类: 总结 说起组件化,我毕设写的就是和组件化相关的. 当时还拿了优,运气! 话不多说,直接进入正文.对于组件化,可以从背景,定义,分类,优势,首屏加载优化,组件之间的关系等方面扯扯,哦不对,是阐述. 背景 假设说采取传统开发网页的方式去开发一个系统,在一定程度上,会造成资源上的严重浪费,编程代码上的冗余等弊端缺陷,会给开发者在增加功能上.版本迭代上.处理业务变更上带来很大的不便.为了避免这

随机推荐