vue组件通信的8种实现方式
2021-07-24 本文已影响0人
小溪流jun
在vue中组件通信方式可分为3种:父==>子、子==>父、兄弟==>兄弟(非父子)
/*
组件中的通信方式,可以分为
父==>子:
1、通过props传值
2、ref通信
3、$children通信
子==>父:
1、自定义事件this.$emit()
兄弟==>兄弟:
1、$parent
2、事件总线通信eventBus
3、provide/inject
4、vuex通信
*/
1、父==>子(通过props传值)
父组件
<template>
<div>
<Son msg='小溪流'/>
</div>
</template>
子组件
<script>
export default {
props: {
msg: String,
required: true,
default:"xxl",
},
}
</script>
2、父==>子(通过ref通信)
父组件
<template>
<div>
<Son ref="son"/>
</div>
</template>
<script>
export default {
mounted() {
console.log('在父组件中获取子组件的data', this.$refs.son.sonMsg) //我是son
this.$refs.son.dosomething() //父组件触发了我
},
}
</script>
子组件
<script>
export default {
data() {
sonMsg:"我是son"
},
methods:{
dosomething(){
console.log("父组件触发了我")
}
}
}
</script>
3、父==>子(通过$children通信)
父组件
<template>
<Son ref="son"/>
</div>
</template>
<script>
export default {
mounted() {
//*注意子组件$children不存在组件顺序
console.log('在父组件中获取子组件的data', this.$children[0].sonMsg) //我是son
},
}
</script>
子组件
<script>
export default {
data() {
sonMsg:"我是son"
},
}
</script>
4、子==>父(通过自定义事件this.$emit)
父组件
<template>
<Son @change="tochangeMsg"/>
</div>
</template>
<script>
export default {
data(){
Msg:"我是parent",
},
methods:{
tochangeMsg(val){
this.Msg = val
console.log(this.Msg) //我是parent-update
}
}
}
</script>
子组件
<template>
<div >
<button @click="changeMsg">去改变父组件中的Msg</button>
</div>
</template>
<script>
export default {
methods:{
changeMsg(){
this.$emit("change","我是parent-update")
}
}
}
</script>
5、兄弟==>兄弟(通过$parent)//本质也是利用eventBus
父组件
<template>
<div>
<Son1 />
<Son2 />
</div>
</template>
子组件
<template>
<div class="son_2">
<button @click="toChangeSon_1">点我$parent通信</button>
</div>
</template>
<script>
export default {
methods: {
toChangeSon_1() {
this.$parent.$emit('changeBrother','son_2中的data')
},
},
}
</script>
子组件
<template>
<div class="son_1">
<button @click="toChange">点我改变父组件</button>
</div>
</template>
<script>
export default {
mounted() {
this.$parent.$on('changeBrother', (val) => {
console.log('son_2组件传递的值', val) //son_2中的data
})
},
}
</script>
6、兄弟==>兄弟(通过eventBus事件总线)
新建event-bus.js文件(在src文件夹下)
//也可通过main.js中挂载到prototype上
import Vue from 'vue'
export const EventBus = new Vue()
随机组件son_2(son_2向son_1传值)
<template>
<div class="son_2">
<button @click="toChangeSon_1">点我$parent通信</button>
</div>
</template>
<script>
import { EventBus } from '@/event-bus.js'
export default {
methods: {
toChangeSon_1() {
EventBus.$emit('changeBrother','son_2中的data')
},
},
}
</script>
随机组件son_1
<template>
<div class="son_1">
{{}}
</div>
</template>
<script>
import { EventBus } from '@/event-bus.js'
export default {
data(){
son_1Msg:'我是son_1的data',
},
mounted() {
EventBus.$on('changeBrother', (val) => {
this.son_1Msg = val
console.log('son_2组件传递的值', this.son_1Msg) //son_2中的data
})
},
}
</script>
7、兄弟==>兄弟(通过provide/inject)父=>子=>孙(适用于嵌套了3个以上的组件)
父组件Parent
<template>
<div class="Parent">
<Child />
</div>
</template>
<script>
//在父组件的provide参数,嵌套的组件通过inject注入
export default {
provide() {
return {
val: '我是所有Parent组件中的数据',
}
},
}
</script>
子组件Child
<template>
<div class="Child">
<sonChild/>
</div>
</template>
<script>
export default {
inject: ['val'],
mounted(){
console.log("父组件中的val",this.val)
}
}
</script>
孙组件sonChild
<template>
<div class="sonChild">
{{val}}
</div>
</template>
<script>
export default {
inject: ['val'],
mounted(){
console.log("父组件中的val",this.val)
}
}
</script>
8、兄弟==>兄弟(通过vuex状态管理)
<template>
<div class="vuex">
</div>
</template>
<script>
/*
1、可以用mapState、mapGetters在computed进行简写。
2、可以用mapMutations、mapActions在methods进行简写。
3、this.$store.dispatch触发actions上的方法进行调用后端数据。
4、this.$store.commit触发mutations上的方法修改state上的变量。
*/
import { mapState, mapGetters } from 'vuex'
export default {
data() {
return {
msg: '我是小溪流',
}
},
computed: {
//可以通过mapState,mapGetters方法简写代码,直接通过this去访问
//...mapState('music', ['message']),
//...mapState(['largemsg']),
//...mapGetters(['doneTodos']),
// ...mapGetters({doneCount:'doneTodos'}), //可以命名
},
methods: {
// ...mapMutations('music', ['getMusic']),
// ...mapMutations(['tochangelargemsg']),
// ...mapActions(["settimeouting"]),
tochange() {
let newmessage = '我真的变了'
this.$store.dispatch('settimeouting', newmessage)
this.$store.commit('music/getMusic', newmessage)
this.$store.commit('tochangelargemsg', newmessage)
// this.settimeouting(newmessage)
// this.getMusic(newmessage)
// this.tochangelargemsg(newmessage)
},
},
mounted() {
console.log('vuex状态管理工具', this.$store)
//可以直接访问vuex中的state
console.log('this.$store.state', this.$store.state)
//可以直接访问vuex中的getters
console.log('this.$store.state', this.$store.getters)
}
</script>