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

 更新时间:2021年03月11日 09:48:12   作者:沵算what  
这篇文章主要给大家介绍了关于Vue组件化常用方法之组件传值与通信的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

相关知识点

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

父组件传值到子组件

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

  • 属性 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组件传值与通信内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解从新建vue项目到引入组件Element的方法

    详解从新建vue项目到引入组件Element的方法

    本篇文章主要介绍了详解从新建vue项目到引入组件Element的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-08-08
  • vue使用blob下载文件遇到的问题小结

    vue使用blob下载文件遇到的问题小结

    Blob 对象表示一个不可变、原始数据的类文件对象,这篇文章主要介绍了vue使用blob下载文件遇到的问题记录,需要的朋友可以参考下
    2024-02-02
  • Vue导出el-table表格为Excel文件的两种方式

    Vue导出el-table表格为Excel文件的两种方式

    在开发过程中,我们经常需要将表格数据导出为 Excel 文件,大多数情况下,由后端处理即可,但是当数据量不大、需要快速响应用户操作、或者数据已经在前端进行处理和展示时,前端该如何实现呢,本文将介绍两种方法,需要的朋友可以参考下
    2024-09-09
  • vue中引用swiper轮播插件的教程详解

    vue中引用swiper轮播插件的教程详解

    这篇文章主要介绍了vue中引用swiper轮播插件的方法,在需要使用swiper的组件里引入swiper,swiper的初始化放在mounted里。具体实例代码大家跟随脚本之家小编一起看看吧
    2018-08-08
  • vue3中el-table实现表格合计行的示例代码

    vue3中el-table实现表格合计行的示例代码

    这篇文章主要介绍了vue3中el-table实现表格合计行,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2024-01-01
  • Vue组件生命周期三个阶段全面总结讲解

    Vue组件生命周期三个阶段全面总结讲解

    Vue的生命周期就是vue实例从创建到销毁的全过程,也就是new Vue() 开始就是vue生命周期的开始。Vue 实例有⼀个完整的⽣命周期,也就是从开始创建、初始化数据、编译模版、挂载Dom -> 渲染、更新 -> 渲染、卸载 等⼀系列过程,称这是Vue的⽣命周期
    2022-11-11
  • vue3实现图片缩放拖拽功能的示例代码

    vue3实现图片缩放拖拽功能的示例代码

    v3-drag-zoom 是基于 vue3 开发的一个缩放拖拽组件,方便开发者快速实现缩放拖拽功能,效果类似地图的缩放与拖拽,本文给大家介绍了vue3如何快速实现图片缩放拖拽功能,感兴趣的朋友可以参考下
    2024-04-04
  • vue时间格式化实例代码

    vue时间格式化实例代码

    本篇文章主要介绍了vue时间格式化实例代码,这里整理了详细的代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-06-06
  • vue通过路由实现页面刷新的方法

    vue通过路由实现页面刷新的方法

    本篇文章主要介绍了vue通过路由实现页面刷新的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • 35个最好用的Vue开源库(史上最全)

    35个最好用的Vue开源库(史上最全)

    无论是开发新手还是经验丰富的老手,我们都喜欢开源软件包。本文主要介绍了35个最好用的Vue开源库,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01

最新评论