Vue组件化常用方法之组件传值与通信

2022-04-15 0 1,007

相关知识点

  • 父组件传值到子组件
  • 子组件传值到父组件
  • 兄弟组件之间传值
  • 祖代和后代之间传值
  • 任意两个组件之间传值

父组件传值到子组件

父组件传值到子组件基本方法有三个,分别为:

  • 属性 props
  • 引用 $refs
  • 子元素 $children

日常开发中,我们用到 props 和 $refs 频率比较多,$children 相对较少些(我就没怎么使用过~)。

属性 props

在父组件中添加属性,在子组件中接收使用,例如:

父组件:

<HelloWorld msg="Welcome to Your Vue.js App" />

子组件:

<h1>{{ msg }}</h1>

props: {
 msg: String
}

引用 $refs

在父组件中可以使用 this.$refs.xxx 获取子组件中定义的数据或者方法,并使用。

父组件:

<HelloWorld ref="hw" />

mounted() {
 this.$refs.hw.foo = "bar";
}

子组件:

<p>{{ foo }}</p>

data() {
 return {
 foo: "foo"
 };
}

注意事项:

this.$refs.xxx 不能在 created 生命周期中使用,因为真实的 DOM 还没有挂载完毕,如果非要想,可以使用 vm.$nextTick 来访问 DOM。或者也可以这样理解,父组件先于子组件创建,在父组件的 created 生命周期中子组件还没有创建,所以获取不到子组件。

在 Vue 中组件生命周期调用顺序如下:

组建的调用顺序都是 先父后子,渲染完成的顺序是 先子后父

组件的销毁操作是 先父后子,销毁完成的顺序是 先子后父

加载渲染过程

  • 父 beforeCreate
  • 父 created
  • 父 beforeMount
  • 子 beforeCreate
  • 子 created
  • 子 beforeMount
  • 子 mounted
  • 父 mounted

子组件更新过程

  • 父 beforeUpdate
  • 子 beforeUpdate
  • 子 updated
  • 父 updated

父组件更新过程

  • 父 beforeUpdate
  • 父 updated

销毁过程

  • 父 beforeDestroy
  • 子 beforeDestroy
  • 子 destroyed
  • 父 destroyed
created() {
 console.log("第一个执行");
 console.log(this.$refs.hw); // undefined
 this.$nextTick(() => {
 console.log("第三个执行");
 console.log(this.$refs.hw); // 此时可以获取到
 });
}

mounted() {
 console.log("第二个执行");
 this.$refs.hw.foo = "bar";
}

子元素 $children

父组件:

this.$children[0].xx = "xxx";

注意事项:

$children 获取当前实例的直接子组件。如果父组件中存在多个子组件,需要注意 $children 并不保证顺序,也不是响应式的。

子组件传值到父组件

子组件传值到父组件使用的方法是自定义事件。在子组件中派发,在父组件中监听。

注意事项: 事件的派发者是谁,事件的监听者就是谁,只不过声明的时候声明在父组件中了。

分为三种情况:不传递参数、传递一个参数、传递多个参数。

不传递参数

子组件:

this.$emit('childFoo');

父组件:

<HelloWorld2 @childFoo="onChildFoo"></HelloWorld2>

methods: {
 onChildFoo() {
 console.log("====== onChildFoo ========");
 }
}

传递一个参数

在父组件中使用 $event 接收参数。

子组件:

this.$emit('childFooSingle', 'foo');

父组件:

<HelloWorld2 @childFooSingle="onChildFooSingle($event)"></HelloWorld2>

methods: {
 onChildFooSingle(e) {
 console.log(e); // foo
 }
}

传递多个参数

在父组件中使用 arguments 接收参数,会以数组的形式传递。

子组件:

this.$emit('childFooMultiple', 'foo', 'bar', 'dong');

父组件:

<HelloWorld2 @childFooSingle="onChildFooMultiple(arguments)"></HelloWorld2>

methods: {
 onChildFooMultiple(msg) {
 console.log(msg[0]); // foo
 console.log(msg[1]); // bar
 console.log(msg[2]); // dong
 }
}

兄弟组件之间传值

兄弟组件之间传值可以通过共同的父辈组件搭桥进行传递,例如:$parent、$root。

兄弟组件1:

this.$parent.$on('foo', handle);

兄弟组件2:

this.$parent.$emit('foo');

祖代和后代之间传值

由于组件嵌套层数过多,使用 props 进行传递不切实际,vue 提供了 provide/inject API 完成该任务。

provide/inject 能够实现祖先给后代传值。

祖代:

provide() {
 return {foo: 'foo'}
}

后代:

inject: ['foo']

注意:provide 和 inject 主要为高阶组件/组件库提供用例,并不推荐直接用于应用程序代码中,我们更多会在开源组件库中见到。但是,反过来想要后代给祖代传值,这种方案就不行了!!!

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

祖代:

provide() {
 return {
 dong: this.home
 };
},
data() {
 return {
 home: ["App home"]
 };
}

后代:

inject: ["dong"]

this.dong = ["App data"]; // 会报错,Avoid mutating an injected value directly since the changes will be overwritten whenever the provided component re-renders
this.dong.push("App data"); // 可以修改成功

任意两个组件之间传值

任意两个组件之间传值有两种方案:事件总线、Vuex。

事件总线

创建一个 Bus 类负责事件派发、监听和回调管理。

首先创建一个 bus.js,并在 main.js 中引入,然后在组件中使用:

第一步:新建 plugins/bus.js

class Bus{
 constructor(){
 this.callbacks = {}
 }
 $on(name, fn){
 this.callbacks[name] = this.callbacks[name] || []
 this.callbacks[name].push(fn)
 }
 $emit(name, args){
 if(this.callbacks[name]){
  this.callbacks[name].forEach(cb => cb(args))
 }
 }
}

export default Bus;

第二步:main.js 中引入

import Bus from "./plugins/bus";
Vue.prototype.$bus = new Bus()

第三步:在组件中使用

组件1:

this.$bus.$on('foo', handle)

组件2:

this.$bus.$emit('foo')

Vuex

创建唯一的全局数据管理者 store,通过它管理数据并通知组件状态变更。可以自行先了解一下官方文档Vuex,具体详细使用后续会写一个专题~

总结

到此这篇关于Vue组件化常用方法之组件传值与通信的文章就介绍到这了,更多相关Vue组件传值与通信内容请搜索NICE源码以前的文章或继续浏览下面的相关文章希望大家以后多多支持NICE源码!

免责声明:
1、本网站所有发布的源码、软件和资料均为收集各大资源网站整理而来;仅限用于学习和研究目的,您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。 不得使用于非法商业用途,不得违反国家法律。否则后果自负!

2、本站信息来自网络,版权争议与本站无关。一切关于该资源商业行为与www.niceym.com无关。
如果您喜欢该程序,请支持正版源码、软件,购买注册,得到更好的正版服务。
如有侵犯你版权的,请邮件与我们联系处理(邮箱:skknet@qq.com),本站将立即改正。

NICE源码网 JavaScript Vue组件化常用方法之组件传值与通信 https://www.niceym.com/32152.html