详解vue组件之间的通信


Posted in Javascript onAugust 30, 2020

说明:下面我总结了比较常用的vue组件之前通信的方式,最近准备面试,所以有些总结贴上来分享

props和$emit

只有父子关系才可以用这种方式,父组件向子组件传递参数用props,子向父传递使用触发$emit自定义事件

1.props

<!-- parent.vue, 可以传递`静态`的props和`动态`的props, 静态的参数只能是个String类型的,如果是其他类型的一定要记得加`:`来表示这是一个 js 表达式而不是一个字符串 -->
<Child :name="name" :age="18" address="xxxxx"></Child>
...
data () {
 return {
  name: 'marry'
 }
}

<!-- 传一个参数所有props, 虽然目前我没有这个需求,使用不带参数的 v-bind -->
<blog-post v-bind="post"></blog-post>
post: {
 id: 1,
 title: 'My Journey with Vue'
}
//等价于下面
<blog-post
 v-bind:id="post.id"
 v-bind:title="post.title"
></blog-post>


<!-- child.vue -->
...
//以字符串数组形式列出的 prop
props: ['name', 'age', 'address']

//prop验证, 当 prop 验证失败的时候,(开发环境构建版本的) Vue 将会产生一个控制台的警告
//注意:以下类型不能写成'String'这种带引号的形式
props: {
 // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)
 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 ['success', 'warning', 'danger'].indexOf(value) !== -1
  }
 }
}
//注意那些 prop 会在一个组件实例创建之前进行验证,所以实例的 property (如 data、computed 等) 在 default 或 validator 函数中是不可用的。

2.$emit

<!-- parent.vue -->
<Child @my-event="myEvent"></Child>
...
methods: {
 myEvent(name){
 this.name = name
 }
}

<!-- child.vue -->
<div>
 <button @click="$emit('my-event', name)"></button>
</div>
//使用自定义事件将子组件的值抛给父组件

中央事件总线 bus

用于解决跨级和兄弟组件通信问题,巧妙的使用一个公共的vue实例,利用$on, $emit, $off(移除自定义事件监听器)

方法一:

可以在main.js中,在Vue的原型上挂载一个公共的Vue实例 $bus,这样全局任何一个地方都可以使用

Vue.prototype.$bus = new Vue()

然后在需要的地方注册自定义事件和接收参数的回调函数

this.$bus.$on('changeName', name => {
 this.name = name
})

在需要改变的时候触发事件并抛出参数

this.$bus.$emit('changeName', 'wzj')

方法二:

定义一个util.js文件

import Vue from 'vue'

const bus = new Vue()
export default bus

在需要用到bus的文件中引入

import bus from '../util' //文件路径不一定

//在一个文件定义事件
bus.$on('changeName', name => {
 this.name = name
})

//另一个文件抛出参数
bus.$emit('changeName', 'wzj')

vuex

对于项目比较复杂,多组件共享状态,不同层级需要通信

详解vue组件之间的通信

核心概念:

state, getter, mutation, action, module

//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export dafault new Vuex.Store({
 state: {
 name: '',
 age: 0
 },
 getters: {
 tranName(state){
  return 'name: ' + state.name
 }
 },
 mutations: {
 changeName(state, name){
  state.name = name
 }
 },
 /*Action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation,或者通过 context.state 和 context.getters 来获取 state 和 getters */
 actions: { //异步函数,但还是要通过提交commit触发mutations函数操作state
 changeName(context, name){
  context.commit('changeName', name)
 }
 },
 modules: {}
})

在组件中使用

方法一:

//访问state属性
this.$store.state.name
//访问getters属性
this.$store.getters.tranName
//访问mutations
this.$store.commit('changeName', 'wzj')
//访问actions
this.$store.dispatch('changeName', 'wzj')

方法二:使用辅助函数映射到本地,这里只列举了简便的方式,更多查阅官网吧

import {mapState, mapGetters, mapMutations, mapActions} from 'vuex'
//state 和 getters 映射到本地的computed属性中,作为计算属性使用
computed: {
 ...mapState(['name', 'age']),
 ...mapGetters(['tranName'])
}

//mutations 和 actions
methods: {
 // 将 `this.changeName()` 映射为 `this.$store.commit('changeName')`
 ...mapMutations(['changeName']) 
 // 将 `this.changeName()` 映射为 `this.$store.dispatch('changeName')`
 ...mapActions(['changeName'])
}

$attrs 和 $listeners

父组件与后代组件,用以上方法有点大材小用或者第一种有些不方便

  • $attrs 包含了父作用域中不作为 prop 被识别 (且获取) 的 attribute 绑定 ( class 和 style 除外)。当一个组件没有声明任何 prop 时,这里会包含所有父作用域的绑定 ( class 和 style 除外),并且可以通过 v-bind="$attrs" 传入内部组件。
  • $listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器。它可以通过 v-on="$listeners" 传入内部组件——在创建更高层次的组件时非常有用。

例子:

//app.vue
<div>
 <One name="wzj" :age="age" address="xian" @changeAge="changeAge"></One>
</div>
...
data(){
 return {
 age: 10
 }
},
methods: {
 changeAge(age){
 this.age = age
 }
}

//one.vue
<div>
 <div>姓名:{{ name }}</div>
 <div>年龄:{{ age }}</div>
 <Two v-bind="$attrs" v-on="$listeners"></Two>
 <button @click="change">点我2</button>
</div>
...
props: ['name', 'age'],

//two.vue
<div>
 <div>{{ address }}</div>
 <button @click="change">点我2</button>
</div>
...
props: ['address'], //用$attrs传递到最后的属性,在使用的时候还是要声明props
methods: {
 change(){
 this.$emit('changeAge', 30)
 }
}

理解:其实祖先组件的属性和事件还是一层层往下传,不过用$attrs 和 $listeners优化和简便了传递过程中书写,而且在传递的过程中,任何一个声明了 $listeners的组件都可以触发里面的所有事件,而声明了$attrs的组件只能使用之前未用props声明的剩下的属性。

以上就是vue组件之间的通信的详细内容,更多关于vue 组件通信的资料请关注三水点靠木其它相关文章!

Javascript 相关文章推荐
JavaScript中判断对象类型的几种方法总结
Nov 11 Javascript
js使用数组判断提交数据是否存在相同数据
Nov 27 Javascript
控制input输入框中提示信息的显示和隐藏的方法
Feb 12 Javascript
jquery 追加元素append、prepend、before、after用法与区别分析
Dec 02 Javascript
微信小程序 本地存储及登录页面处理实例详解
Jan 11 Javascript
在使用JSON格式处理数据时应该注意的问题小结
May 20 Javascript
移动设备手势事件库Touch.js使用详解
Aug 18 Javascript
JavaScript 判断对象中是否有某属性的常用方法
Jun 14 Javascript
详解如何从零开始搭建Express+Vue开发环境
Jul 17 Javascript
解决vue 打包发布去#和页面空白的问题
Sep 04 Javascript
微信小程序设置全局请求URL及封装wx.request请求操作示例
Apr 02 Javascript
JS实现图片切换特效
Dec 23 Javascript
如何阻止移动端浏览器点击图片浏览
Aug 29 #Javascript
JavaScript事件委托实现原理及优点进行
Aug 29 #Javascript
JS如何判断对象是否包含某个属性
Aug 29 #Javascript
JS获取当前时间戳方法解析
Aug 29 #Javascript
JS PHP字符串截取函数实现原理解析
Aug 29 #Javascript
JS访问对象两种方式区别解析
Aug 29 #Javascript
js在HTML的三种引用方式详解
Aug 29 #Javascript
You might like
PHP4(windows版本)中的COM函数
2006/10/09 PHP
php采集速度探究总结(原创)
2008/04/18 PHP
discuz论坛 用户登录 后台程序代码
2008/11/27 PHP
用PHP读取超大文件的实例代码
2012/04/01 PHP
php获取四位字母和数字的随机数的实现方法
2015/01/09 PHP
php中this关键字用法分析
2016/12/07 PHP
如何利用PHP实现上传图片功能详解
2020/09/24 PHP
关于JavaScript中的关联数组分析
2013/04/09 Javascript
js实现进度条的方法
2015/02/13 Javascript
解决jquery实现的radio重新选中的问题
2015/07/03 Javascript
基于JS实现导航条之调用网页助手小精灵的方法
2016/06/17 Javascript
jquery实现图片平滑滚动详解
2017/03/22 jQuery
基于Vue过渡状态实例讲解
2017/09/14 Javascript
ES6中javascript实现函数绑定及类的事件绑定功能详解
2017/11/08 Javascript
浅谈VUE监听窗口变化事件的问题
2018/02/24 Javascript
超出JavaScript安全整数限制的数字计算BigInt详解
2018/06/24 Javascript
微信小程序实现卡片层叠滑动效果
2019/06/21 Javascript
layui固定下拉框的显示条数(有滚动条)的方法
2019/09/10 Javascript
Vue 3.0中jsx语法的使用
2020/11/13 Javascript
简单的抓取淘宝图片的Python爬虫
2014/12/25 Python
Python的装饰器用法学习笔记
2016/06/24 Python
Python 编码处理-str与Unicode的区别
2016/09/06 Python
Python爬虫之pandas基本安装与使用方法示例
2018/08/08 Python
基于python检查SSL证书到期情况代码实例
2020/04/04 Python
opencv+python实现鼠标点击图像,输出该点的RGB和HSV值
2020/06/02 Python
eBay澳大利亚站:eBay.com.au
2018/02/02 全球购物
美国最大的存储市场:SpareFoot
2018/07/23 全球购物
Audible英国:有声读物,30天免费试用
2019/10/16 全球购物
12月红领巾广播稿
2014/02/13 职场文书
倡议书的写法
2014/08/30 职场文书
推普周国旗下讲话稿
2014/09/21 职场文书
基层党员群众路线整改措施及努力方向
2014/10/28 职场文书
先进工作者主要事迹材料
2015/11/03 职场文书
MySQL 如何限制一张表的记录数
2021/09/14 MySQL
Python实现对齐打印 format函数的用法
2022/04/28 Python
MYSQL常用函数介绍
2022/05/05 MySQL