vue组件通信大总结
文章目录
- 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
被识别 (且获取) 的属性绑定 (class
和 style
除外)。
$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/update
;provide/inject
;$parent / $children
;ref/refs
;$attrs/$listeners
非父子组件/兄弟组件通信:
EventBus
;Vuex
;localStorage/sessionStorage
vue组件通信大总结相关推荐
- 超实用的 Vue 组件通信方式大汇总(8种)
文章目录 前言 一.Vue组件关系 二.Vue组件通信方式 1. props / $emit 1.1 props 父传子 1.2 $emit 子传父 1.3 父子组件双向绑定 1.3.1 v-mode ...
- vue 组件通信的几种方式
前言 在vue中, 组件的关系不外乎以下三种: 组件是需要通信的,在开发中,常用到的通信方式有:vuex.eventBus.以及props与emit.$parent与$children,除此之外,还 ...
- vue组件通信案例练习(包含:父子组件通信及平行组件通信)
文章目录 一.案例概述 二.代码 准备工作: 案例1.1:父组件向子组件传值(或者叫:子组件使用父组件属性),采用v-bind方式实现 案例1.2:子组件向父组件传值(或者叫:子组件调用父组件方法), ...
- Vue组件通信的五种方式
Vue组件通信的五种方式 文章目录 Vue组件通信的五种方式 一. props/$emit(父子通信) 二. vuex(组件之间通信) 三. 事件总线EventBus(组件之间通信) 四. provi ...
- vue组件通信(传值)
vue组件通信有以下几种方式可以实现(个人总结) 一.父组件到子组件传值方式: 一般通过在父组件中给子组件绑定属性的方式进行传值,子组件通过props来接收. 实例: //父组件 <templa ...
- 【Vue】Vue全家桶(三)Vue组件通信+Vue组件插槽+动画与过渡+使用vue-cli解决Ajax跨域问题
1 Vue组件通信 1.1 组件间通信基本原则 不要在子组件中直接修改父组件的状态数据 数据在哪, 更新数据的行为(函数)就应该定义在哪 1.2 vue 组件间通信方式 props vue 的自定义事 ...
- vue组件通信的几种方法
vue中我们最常使用的就是父子之间的通信还有全局数据管理vuex了,下面粗略说一下vue组件通信的几种方法 组件通信的几种方式 1.父子组件通信 2.兄弟组件通信 3.跨多层级组件通信 4.任意组件( ...
- vue组件通信的几种方式
vue组件通信的几种方式 最近用vue开发项目,记录一下vue组件间通信几种方式 第一种,父子组件通信 一.父组件向子组件传值 1.创建子组件,在src/components/文件夹下新建一个Chil ...
- Vue 组件通信之 Bus
关于组件通信我相信小伙伴们肯定也都很熟悉,就不多说了,对组件通信还不熟悉的小伙伴移步这里. 在vue2.0中 $dispatch 和 $broadcast 已经被弃用.官方文档中给出的解释是: 因为基 ...
最新文章
- Contest2071 - 湖南多校对抗赛(2015.03.28)
- java 成员变量的初始化_Java类变量和成员变量初始化过程
- 压力测试以及编译安装httpd2.4
- nb模块不能接收公网消息_物联网连接技术之NB-IOT无线技术介绍
- docker portainer_Docker可视化管理:Portainer中文版
- html做自我介绍模板,应聘自我介绍模板简短
- php做推送服务端实现ios消息推送
- Linux下解压和压缩jar文件
- 74HC595芯片级联的测试万能代码
- jupyter notebook中Nbextensions插件功能大全
- Win11系统一些功能修改并不令人满意,盘点不尽人意之处
- keep-alive实现原理
- 计算机 文笔不好的论文,文笔差怎么写出好文章
- 电话簿管理系统(超详细)
- python做工控机_[Micropython]TPYBoard v202 利用单片机快速实现家庭智能控制平台
- 给黑白照片上色软件神器
- oracle的快捷方式,键盘快捷方式
- 哈尔滨火车站下面有三个火车票代售点,假如哈尔滨到北京的火车票总共是200张,如何用程序来实现三个售票点同时卖票的功能。
- [logback] 关于logback.xml加载非类路径配置文件 - 问题排查与解决
- 不知道多张照片拼图哪个好?这个我一直不舍得删!