文章目录

  • 1. props / $emit
  • 2. sync / update
  • 3. provide / inject
  • 4. $attrs / $listeners
  • 5. $children / $parent
  • 6. ref / refs
  • 7. Vuex
  • 8. EventBus
  • 9. localStorage/sessionStorage
  • 总结

1. props / $emit

父组件给子组件添加属性:msg="msg"传值,子组件通过props:['msg']接收;
子组件可以通过this.$emit('changeMsg','Welcome')向父组件发送事件和数据,
父组件通过 @changeMsg="change" 监听事件和传递过来的数据。

代码

<!-- Parent.vue -->
<template><div><son :msg="msg" @changeMsg="change" /></div>
</template><script>
import Son from './Son.vue'
export default {name: 'Parent',data () {return {msg: '你好'}},components: {Son},methods: {change (msg) {this.msg = msg}}
}
</script>
<!-- Son.vue -->
<template><div>{{ msg }}<button @click="sendToParent">传递到Parent</button></div>
</template><script>
export default {name: 'Son',props: ['msg'],methods: {sendToParent () {this.$emit('changeMsg', 'Welcome')}}
}
</script>

效果

适用于父子组件通信

2. sync / update

v2.3新增语法糖,会扩展成一个更新父组件绑定值的 v-on侦听器;

<son :msg.sync="msg" />
子组件update:msg直接修改数据,父组件无需定义监听事件来接收数据;

适合基本数据类型的传递和修改

<!-- Parent.vue -->
<template><div><son :msg.sync="msg" /></div>
</template><script>
import Son from './Son.vue'
export default {name: 'Parent',data () {return {msg: '你好'}},components: {Son}
}
</script>
<!-- Son.vue -->
<template><div>{{ msg }}<button @click="sendToParent">传递到Parent</button></div>
</template><script>
export default {name: 'Son',props: ['msg'],methods: {sendToParent () {this.$emit('update:msg', 'Welcome')}}
}
</script>

3. provide / inject

父组件通过provide传值,子组件通过inject:["msg"]接收,provide传递的数据, 不仅所有子组件都可以接收,所有后代组件均可以通过inject接收到。

<!-- Parent.vue -->
<template><div><son /></div>
</template><script>
import Son from './Son.vue'
export default {name: 'Parent',provide () {return {pdata: this}},data () {return {msg: '你好'}},components: {Son}
}
</script>
<!-- Son.vue -->
<template><div>{{ text }}<button @click="sendToParent">修改</button></div>
</template><script>
export default {name: 'Son',inject: ['pdata'],computed: {text () {return this.pdata.msg}},methods: {sendToParent () {this.pdata.msg = 'hello'}}
}
</script>

4. $attrs / $listeners

v2.4新增

$attrs包含了父作用域中不作为prop 被识别 (且获取) 的属性绑定 (classstyle 除外)。
$listeners 包含了父作用域中的 (不含 .native 修饰器的) v-on 事件监听器,它可以通过 v-on="$listeners" 传入内部组件。

<!-- Home.vue -->
<template><div class="home"><father :name="name" :age="age" @changeName="changeName" @changeAge="changeAge" /></div>
</template><script>
import Father from './Father.vue'export default {name: 'Home',components: {Father},data () {return {name: '张三',age: 30}},methods: {changeName (name) {this.name = name},changeAge (age) {this.age = age}}
}
</script>
<!-- Father.vue -->
<template><div>{{ age }}Father Comp: {{ $attrs }}<button @click="updateName">修改Name</button><son v-bind="$attrs" v-on="$listeners" /></div>
</template><script>
import Son from './Son'
export default {name: 'Father',props: ['age'],components: {Son},methods: {updateName () {this.$emit('changeName', '李四')}}
}
</script>
<!-- Son.vue -->
<template><div>Son Comp:{{ $attrs }}<button @click="updateAge">修改Age</button></div>
</template><script>
export default {name: 'Son',methods: {updateAge () {this.$emit('changeAge', 40)}}
}
</script>

效果

5. $children / $parent

父组件通过$children访问子组件属性和方法,子组件通过$parent访问父组件属性和方法, this.$children[0].age=2修改子组件数据,同理this.$parent.age=30 修改父组件数据。

<!-- Father.vue -->
<template><div>Father Age: {{ age }}<button @click="updateSonAge">修改Son的Age</button><son /></div>
</template><script>
import Son from './Son'
export default {name: 'Father',components: {Son},data () {return {age: 30}},methods: {updateSonAge () {this.$children[0].age = 15}}
}
</script>
<!-- Son.vue -->
<template><div>Son Age: {{ age }}<button @click="updateFatherAge">修改Father的Age</button></div>
</template><script>
export default {name: 'Son',data () {return {age: 10}},methods: {updateFatherAge () {this.$parent.age = 35}}
}
</script>

效果

6. ref / refs

子组件绑定ref属性,父组件通过this.$refs['xxx']访问子组件,用法和 $children 相同。
this.$refs['son']===this.$children[0] //true

<!-- Father.vue -->
<template><div>Father Age: {{ age }}<button @click="updateSonAge">修改Son的Age</button><son ref='son' /></div>
</template><script>
import Son from './Son'
export default {name: 'Father',components: {Son},data () {return {age: 30}},methods: {updateSonAge () {this.$refs.son.age = 20}}
}
</script>
<!-- Son.vue -->
<template><div>Son Age: {{ age }}</div>
</template><script>
export default {name: 'Son',data () {return {age: 10}}
}
</script>

7. Vuex

vuex可以说是万金油,因为它是vue的一个状态管理库,任何数据都可以存在这个库里,缺点就是使用方法略微麻烦一点,优点就是不用管什么层级之间的传递数据都是可以的,而且是共享数据,所以还是要看有没有必要使用这个方式,如果数据会在不同的层级,很多地方都需要使用或修改,且数据都是共享的,那么这种方式就是最好的。

<template><div id="app"><ChildA/><ChildB/></div>
</template><script>import ChildA from './components/ChildA'import ChildB from './components/ChildB'export default {name: 'App',components: {ChildA, ChildB}}
</script>
<template><div id="childA"><h1>我是A组件</h1><button @click="transform">点我让B组件接收到数据</button><p>{{BMessage}}</p></div>
</template><script>export default {data() {return {AMessage: 'Hello,B组件,我是A组件'}},computed: {BMessage() {return this.$store.state.BMsg}},methods: {transform() {this.$store.commit('receiveAMsg', {AMsg: this.AMessage})}}}
</script>
<template><div id="childB"><h1>我是B组件</h1><button @click="transform">点我让A组件接收到数据</button><p>{{AMessage}}</p></div>
</template><script>export default {data() {return {BMessage: 'Hello,A组件,我是B组件'}},computed: {AMessage() {return this.$store.state.AMsg}},methods: {transform() {this.$store.commit('receiveBMsg', {BMsg: this.BMessage})}}}
</script>
/*** store.js */
import Vue from 'vue'
import Vuex from 'vuex'Vue.use(Vuex)const state = {AMsg: '',BMsg: ''
}
const mutations = {receiveAMsg(state, payload) {state.AMsg = payload.AMsg},receiveBMsg(state, payload) {state.BMsg = payload.BMsg}
}export default new Vuex.Store({state,mutations
})

8. EventBus

eventBus又称为事件总线,在vue中可以使用它来作为沟通桥梁的概念, 就像是所有组件共用相同的事件中心,可以向该中心注册发送事件或接收事件, 所有组件都可以通知其他组件。(维护困难,eventName起名字困难,不易维护,不及时注销事件会产生各种问题,复杂项目中还是使用Vuex

//新建一个Vue实例作为中央事件总线
let EventBus = new Vue();
//监听事件
EventBus.$on('eventName', (val) => {//......do something
});
//触发事件
EventBus.$emit('eventName', 'this is a message.');
//移除事件
EventBus.$off('eventName', {})

9. localStorage/sessionStorage

本地存储,某些业务中使用较多,比如记住用户token用户信息系统设置
window.localStorage.getItem(key)获取数据,通过 window.localStorage.setItem(key,value) 存储数据;

注意:value只能是字符串类型,需要用JSON.parse() / JSON.stringify()转换
sessionStorage同理。

总结

特点
props / $emit 最常用的父子组件通信
sync/update 父子组件基本数据类型,适用于子组件修改父组件数据
provide/inject 多层级传递,不受子孙组件的影响,适用于插槽,嵌套插槽;不适合兄弟通讯,父级组件无法主动通信
$attrs / $listeners 主要时解决了props传递数据不能跨层的缺点,但无法兄弟传参
$children / $parent 方便直接,但 this.$children不可控性大,有一定风险。(尽量不用)
ref / refs 渲染完成后才可使用,不是响应式的,时不时配合$nextTick
vuex 处理复杂的组件通信的最佳方案,支持异步组件通信,缺点是流程相比稍微复杂
EventBus 简单灵活,父子兄弟通信不受限制,通信方式不受框架影响,但维护困难,需要谨小慎微的命令规范,不利于组件化开发
localStorage / sessionStorage 常用于存储用户信息,系统设置,token等
  • 父子组件通信: props / $emit; .sync/updateprovide/inject; $parent / $children; ref/refs; $attrs/$listeners

  • 非父子组件/兄弟组件通信: EventBus ; VuexlocalStorage/sessionStorage

vue组件通信大总结相关推荐

  1. 超实用的 Vue 组件通信方式大汇总(8种)

    文章目录 前言 一.Vue组件关系 二.Vue组件通信方式 1. props / $emit 1.1 props 父传子 1.2 $emit 子传父 1.3 父子组件双向绑定 1.3.1 v-mode ...

  2. vue 组件通信的几种方式

    前言 在vue中,​ 组件的关系不外乎以下三种: 组件是需要通信的,在开发中,常用到的通信方式有:vuex.eventBus.以及props与emit.$parent与$children,除此之外,还 ...

  3. vue组件通信案例练习(包含:父子组件通信及平行组件通信)

    文章目录 一.案例概述 二.代码 准备工作: 案例1.1:父组件向子组件传值(或者叫:子组件使用父组件属性),采用v-bind方式实现 案例1.2:子组件向父组件传值(或者叫:子组件调用父组件方法), ...

  4. Vue组件通信的五种方式

    Vue组件通信的五种方式 文章目录 Vue组件通信的五种方式 一. props/$emit(父子通信) 二. vuex(组件之间通信) 三. 事件总线EventBus(组件之间通信) 四. provi ...

  5. vue组件通信(传值)

    vue组件通信有以下几种方式可以实现(个人总结) 一.父组件到子组件传值方式: 一般通过在父组件中给子组件绑定属性的方式进行传值,子组件通过props来接收. 实例: //父组件 <templa ...

  6. 【Vue】Vue全家桶(三)Vue组件通信+Vue组件插槽+动画与过渡+使用vue-cli解决Ajax跨域问题

    1 Vue组件通信 1.1 组件间通信基本原则 不要在子组件中直接修改父组件的状态数据 数据在哪, 更新数据的行为(函数)就应该定义在哪 1.2 vue 组件间通信方式 props vue 的自定义事 ...

  7. vue组件通信的几种方法

    vue中我们最常使用的就是父子之间的通信还有全局数据管理vuex了,下面粗略说一下vue组件通信的几种方法 组件通信的几种方式 1.父子组件通信 2.兄弟组件通信 3.跨多层级组件通信 4.任意组件( ...

  8. vue组件通信的几种方式

    vue组件通信的几种方式 最近用vue开发项目,记录一下vue组件间通信几种方式 第一种,父子组件通信 一.父组件向子组件传值 1.创建子组件,在src/components/文件夹下新建一个Chil ...

  9. Vue 组件通信之 Bus

    关于组件通信我相信小伙伴们肯定也都很熟悉,就不多说了,对组件通信还不熟悉的小伙伴移步这里. 在vue2.0中 $dispatch 和 $broadcast 已经被弃用.官方文档中给出的解释是: 因为基 ...

最新文章

  1. Contest2071 - 湖南多校对抗赛(2015.03.28)
  2. java 成员变量的初始化_Java类变量和成员变量初始化过程
  3. 压力测试以及编译安装httpd2.4
  4. nb模块不能接收公网消息_物联网连接技术之NB-IOT无线技术介绍
  5. docker portainer_Docker可视化管理:Portainer中文版
  6. html做自我介绍模板,应聘自我介绍模板简短
  7. php做推送服务端实现ios消息推送
  8. Linux下解压和压缩jar文件
  9. 74HC595芯片级联的测试万能代码
  10. jupyter notebook中Nbextensions插件功能大全
  11. Win11系统一些功能修改并不令人满意,盘点不尽人意之处
  12. keep-alive实现原理
  13. 计算机 文笔不好的论文,文笔差怎么写出好文章
  14. 电话簿管理系统(超详细)
  15. python做工控机_[Micropython]TPYBoard v202 利用单片机快速实现家庭智能控制平台
  16. 给黑白照片上色软件神器
  17. oracle的快捷方式,键盘快捷方式
  18. 哈尔滨火车站下面有三个火车票代售点,假如哈尔滨到北京的火车票总共是200张,如何用程序来实现三个售票点同时卖票的功能。
  19. [logback] 关于logback.xml加载非类路径配置文件 - 问题排查与解决
  20. 不知道多张照片拼图哪个好?这个我一直不舍得删!

热门文章

  1. 【nginx】关于Nginx的一些优化(突破十万并发)
  2. VS Code前端开发利器-常用快捷键
  3. shell:判断一个进程是否存在
  4. 电信业的100个随想
  5. When we use PdfStamper to merge fields.
  6. 一个大屏监控380个泵房,13000个设备,智能水务是怎么实现的?
  7. 在mount里看到哪个设备文件的一些笔记
  8. 7年专科生程序员同时去腾讯和微软面试,问HR结果以为听错了,结局反转!!
  9. 我的年终奖是大饼+鸡汤,and you?
  10. 一晚浓浓的程序员鸡汤,先干为敬