您现在的位置是:网站首页> 编程资料编程资料

Vue组件间传值的实现解析_vue.js_

2023-05-24 251人已围观

简介 Vue组件间传值的实现解析_vue.js_

1. 父组件向子组件传值

1.1 描述

父组件以属性的形式绑定值到子组件身上。

子组件通过使用属性 props 接收(props 是单向数据流【只读属性】:当父组件的属性变化时,将传导给子组件,但是反过来不会,即子组件中不可以修改父组件的值,应该通过给子组件传数据的父组件修改)

1.2 props接收数据

语法:

props: 数组 | 对象

数组方式接收:

此方式,一般用于你自己定义组件给自己所用,是一种简写方式

数组中的元素就是你自定义的属性名称(注意这里是自定义的属性名称,而不是父组件数据源中的数据名称)

示例:

子组件(child.vue):

父组件(App.vue):

对象方式接收:

一般用于,封装的组件提供给别人使用,它可以限制属性的类型和默认值

示例:

子组件(child.vue):

父组件(App.vue):

2. 子组件向父组件传值

上文提到props 是单向数据流,子组件中不可以修改父组件的值,应该通过给子组件传数据的父组件修改,这样设计是为了防止子和父在修改数据时,造成的数据混乱。

在 Vue 中,如果子组件修改了父组件传过来的数据,控制台会报一个警告,但在 React 中会直接报错。

那么子组件要怎么向父组件传值呢?

有两种方式:

  • 子组件用$emit()定义自定义事件,$emit()第一个参数为 自定义的事件名称 第二个参数为需要传递的数据;父组件用v-on(@)绑定子组件定义的自定义事件名,监听子组件的事件,实现通信
  • 父组件直接把修改数据的方法以属性的方式传给子组件(通过形参方式传递)

方法2实现:

父组件:

子组件:

方法1实现:

子组件:

父组件:

3. 兄弟组件间传值

概述:

兄弟间组件传值,通过公共的父组件来进行。这种方式使得两个兄弟组件共用的数据得到提升,即状态提升。

子组件通过修改父组件中自己和兄弟的公共数据,来和自己的兄弟组件传值。

示例:

子组件1:

子组件2:

父组件:

4. 事件总线

概述:

兄第组件间通过状态提升的方式来进行传值,适用于父子场景中,一旦涉及到子孙场景,状态提升的操作就变得很复杂,这时候我们就要用到 Vue2 中给我们提供的事件总线来处理。

什么是事件总线?

非父子组件或更多层级间组件间传值,在Vue中通过单独的事件中心来管理组件间的传值。

它相当于一个全局的仓库,任何组件都可以去这个仓库里获取事件,它就类似沟通桥梁的概念,就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件,所以组件都可以上下平行的通知其他组件来进行通信。

简单来说就是,假设现在有一个组件 a 往全局仓库中塞数据,另一个组件 b 只要订阅了全局仓库,就可以收到更新的数据。

事件总线只能进行通知,不能进行数据的存储功能。

注意:实现事件总线的前提条件是,必须先订阅和发布

语法:

  • 建立统一的事件中心:const bus = new Vue()
  • 传递数据方,通过一个事件触发:bus.$emit(方法名,传递的数据)
  • 接收数据方,在生命周期函数中,通过bus.$on(方法名,(参数)=>{})来监听
  • 销毁事件,在接受数据方,通过bus.$off(方法名)销毁,销毁之后无法监听数据

示例:

建立统一的事件中心(即全局对象)可以在主 js 文件中写入如下代码:

import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false // 事件总线 --- 是当前文件的私有变量 // 因为所有组件对象都能看到 Vue 原型对象上的属性和方法,所以我们可以在Vue的原型对象上通过设定一个eventBus对象, // Vue.prototype.bus = new Vue(),此时所有的组件对象都能看到eventBus属性对象。 const eventBus = new Vue() Vue.prototype.$eventBus = eventBus new Vue({ render: h => h(App), }).$mount('#app')

也可以使用插件的方式,建立全局对象:

新建一个 bus.js 文件:

export default Vue => { Vue.prototype.$eventBus = new Vue() } 

在 main.js 中导入:

import Vue from 'vue' import App from './App.vue' import bus from './plugin/bus' Vue.config.productionTip = false Vue.use(bus) new Vue({ render: h => h(App), }).$mount('#app')

父组件: