Vue组件间通信 -- 整理

Vue组件间通信

参考:
Vue组件间通信的6种方式

几种场景预览

  • 父子 组件 之间的数据传递
  • 兄弟 组件 之间的数据传递
  • 祖先 组件 与 子组件之间的数据传递
- props / $emit
- $parent / $children and ref
- $emit / $on
- vuex
- $attrs / $listeners
- provide / inject

几种组件通信方法更好的地选用

  • 当项目比较大的时候,使用vuex
  • 节制的使用$parent 和 $children,他们的目的是作为访问组件的应急方法,更加推荐使用props和events实现父子组件通信
  • 如果只是传递数据,使用 a t t r s / attrs/ attrs/listeners好点
  • 如果不仅传递数据,还做中间处理,用vuex好点

方法一:props/$emit

  • 父组件A 向 子组件B 传递数据 通过props方法
  • 子组件B 向 父组件A 发送数据 通过emit

父 —> 子
sonList: [‘white’,‘red’,‘blue’,‘green’]

父组件

<template>
    <div class="father">
        <com-son :sons="sonList"></com-son>
    </div>
</template>

<script>
    import comSon from './son'
    export default {
        name:"helloworld",
        components: {comSon},
        data(){
            return {
                sonList: ['white','red','blue','green']
            }
        }
    }
</script>

子组件 son.vue

<template>
  <div>
    <span v-for="(item, index) in sons" :key="index">{{item}}</span>
  </div>
</template>

<script>
export default {
  props: ['sons']
}
</script>

注意:

  • 子组件中从上一级组件传递到下一级组件,也就是父子组件,这就是单向数据流
  • props是只读,不可以被修改,所有的修改都会失效和被警告

子组件向父组件传递数据

父组件father.vue

<template>
  <div class="father">
    <com-son :sons="sonList" @onEmitIndex="onEmitIndex"></com-son>
    <p>{{currentIndex}}</p>
  </div>
</template>

<script>
import comSon from './son'
export default {
  name: 'HelloWorld',
  components: { comSon },
  data() {
    return {
      currentIndex: -1,
      sonList: ['小白', '小红', '小蓝','小绿']
    }
  },
  methods:{
    onEmitIndex(idx){
      this.currentIndex = idx
    }
  }
}
</script>

子组件son.vue

<template>
  <div>
    <span v-for="(item, index) in sons" :key="index" @click="emitIndex(index)">{{item}}</span>
  </div>
</template>

<script>
export default {
  props: ['sons'],
  methods: {
    emitIndex(index){
      this.$emit('onEmitIndex',index)
    }
  }
}
</script>

为何使用vuex

不使用vuex的话

  • 父子组件依赖同一个state

在这里插入图片描述

  • 兄弟组件依赖同一个state
    在这里插入图片描述
    用了vuex

在这里插入图片描述

Vuex各个模块

state

state中存放页面共享的状态字段

getters

相当于当前模块state的计算属性

mutations

如果想更新state中的字段,提交mutations中定义的事件的唯一的方式(key为事件名,value是一个函数),但是change事件函数必须是同步执行的

actions

可以定义异步函数,并在回调函数中提交mutation,就相当于异步更新了state中的字段

modules

类似于命名空间(namespace),用于项目中各个模块的状态分开定义和操作,便于维护

$attrs / $listeners

用在父组件传递数据给子组件或者孙组件

如果仅仅是传递数据,就用$attrs / $listeners好点

如何不仅传递数据,还做中间处理,就用vuex好点

$attrs:

  • $attrs继承所有的父组件属性(除了props传递的属性,class和style)
  • 当一个组件没有声明任何prop时,这里会包含所有父作用域

$listeners

  • 一个对象,包含了父作用域中的v-on事件监听器,可以配合v-on="$listeners"将所有的事件监听指向特定的子元素

provide / inject API

祖先组件中通过provider来提供变量,然后在孙组件中通过inject来注入变量

provide / inject API 主要解决了跨域组件的通讯问题,不过他的使用场景主要是子组件或去商机组件的状态,跨级组件间建立了一种主动提供与依赖注入的关系

  • 父组件
<template>
	<div>
		<son prop="data"></son>
	</div>
</template>
<script>
	export default {
		provide: {
			name: 'TOM'
		}
	}

然后孙子组件中,这里的孙子指的是父,子,孙子

<template>
    <div>
        {{name}}
    </div>
</template>
 
<script>
export default {
    name: 'grandson',
    inject: [name]
}
</script>

这样可以通过inject访问两个层次以上的数据,用法与props完全相同

总结

vue组件间通信大致分为三类

父子通讯

props/emit, parent/children, attrs/$listeners, provide/inject API, ref

父向子传递数据通过props

子向父传递通过$emit, event

子实例访问父通过$parent

父实例访问子实例通过$children

$attrs用父组件传递数据给子组件或孙组件
(包含了父作用域中不作为 prop 被识别 (且获取) 的特性绑定 (class 和 style 除外))

listeners用父组件传递数据给子组件或孙组件
包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器

祖先组件通过provider提供变量给子孙组件

子孙组件通过inject注入变量给祖先组件

ref用来访问组件实例

兄弟通讯

vuex用来作为兄弟之间和跨级之间的通讯

跨级通讯

Vuex, attrs/listeners, provide/inject API

vuex作为兄弟之间和跨级之间的通讯

$attrs用父组件传递数据给子组件或者孙组件
(包含了父作用域中不作为prop被识别的特性绑定(class和style除外))

listeners用父组件传递数据给子组件或孙组件
包含了父作用域中的(不含.native修饰器)v-on事件监听器

祖先组件通过provider提供变量给子孙组件

子孙组件通过inject注入变量给祖先组件

  • 父组件向子组件传递数据,使用props属性;子组件向父组件中传递数据,在子组件中使用$emit派发事件,父组件中使用v-on监听事件;
    • 缺点:组件嵌套层次多的话,传递数据比较麻烦。
  • 祖先组件通过依赖注入(inject / provide)的方式,向其所有子孙后代传递数据;
    • 缺点:无法监听数据修改的来源,不支持响应式。
  • 通过属性$root / $parent / $children / ref, 访问根组件,父级组件,子组件中的数据
    • 缺点:不支持响应式,vue2已经放弃
  • 通过 VueJs 的状态管理模式 Vuex,实现多个组件进行数据共享,推荐使用这种方式进行项目中各组件间的数据传递。

当然,除了数据以外我们还可以在组件之间传递方法

方法

  1. 父组件调用子组件:ref
  2. 子组件调用父组件:emit

数据

  1. 父传子:props
  2. 子传父:emit
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值