vue组件通信
Posted 测试zhzh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue组件通信相关的知识,希望对你有一定的参考价值。
父子组件通信
父组件向子组件传值通过props属性,子组件向父组件传值通过$emit来触发事件。
子组件代码:
<template>
<div>
<h4 @click="showMsg">{{msg}}</h4>
<div class="item" v-for="(v,i) in list" :key="i">
我是{{v.name}}
<button @click="sendInfo(v)">点击发送</button>
</div>
</div>
</template>
<script>
export default {
props: ["msg", "list"],
mounted() {},
methods: {
showMsg() {
this.$emit("getMessage", "这是父组件");
},
sendInfo(v) {
this.$emit("showInfo", v);
}
}
};
</script>
<style scoped>
.item {
margin-top: 10px;
}
</style>
props中的msg和list都是父组件传过来的,
父组件代码:
<template>
<div class="home">
<h1>爷爷:孙子们,来说话</h1>
<h4 v-if="isShow">我是{{info.name}},我今年{{info.age}}岁</h4>
<Child :msg="msg" :list="list" @getMessage="showMsg" @showInfo="showInfo"></Child>
</div>
</template>
<script>
import Child from "@/components/child.vue";
export default {
name: "home",
components: {
Child
},
data() {
return {
child2Msg: 'Hello World',
message: "",
msg: "child组件",
list: [
{
name: '孙子1',
age: 10
},
{
name: '孙子2',
age: 15
},
{
name: '孙子3',
age: 18
},
{
name: '孙子4',
age: 15
}
],
info: {
},
isShow: false,
};
},
methods: {
showMsg(title) {
this.message = title;
},
showInfo(prop) {
this.isShow = true;
this.info = prop;
}
}
};
</script>
父组件通过props把msg和list两个参数传给子组件,渲染子组件,父传子。
在父组件中的child子组件上注册事件@getMessage和@showInfo两个事件,在子组件中的按钮上注册点击事件通过this.$emit("getMessage", "这是父组件");以及this.$emit("showInfo", v);来触发事件实现将第二个参数传给父组件,父组件接收到后进行操作,这是子传父。
2.非父子组件通信 ($emit/$on)
这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。
在根组件上注册上bus,
main.js代码:
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store,
render: h => h(App),
data: {
Bus: new Vue()
}
}).$mount('#app')
child组件代码如下:
<template>
<div>
<h4 @click="showMsg">{{msg}}</h4>
<div class="item" v-for="(v,i) in list" :key="i">
我是{{v.name}}
<button @click="sendInfo(v)">点击发送</button>
</div>
</div>
</template>
<script>
export default {
props: ["msg", "list"],
mounted() {},
methods: {
showMsg() {
this.$emit("getMessage", "这是父组件");
},
sendInfo(v) {
this.$emit("showInfo", v);
this.$root.Bus.$emit('sendName', v);
}
}
};
</script>
<style scoped>
.item {
margin-top: 10px;
}
</style>
child2组件代码如下:
<template>
<div>
<h1>{{name}}</h1>
{{child2}}
</div>
</template>
<script>
export default {
props: ["child2"],
data() {
return {
name: ""
};
},
created() {
this.$root.Bus.$on("sendName", value => {
this.print(value);
});
},
methods: {
print(v) {
this.name = v.name;
}
},
beforeDestroy() {
this.$root.Bus.$off("sendName");
}
};
</script>
<style scoped>
</style>
home组件代码:
<template>
<div class="home">
<h1>爷爷:孙子们,来说话</h1>
<h4 v-if="isShow">我是{{info.name}},我今年{{info.age}}岁</h4>
<Child :msg="msg" :list="list" @getMessage="showMsg" @showInfo="showInfo"></Child>
<Child2 :child2="child2Msg"></Child2>
</div>
</template>
<script>
import Child from "@/components/child.vue";
import Child2 from "@/components/child2.vue";
export default {
name: "home",
components: {
Child,
Child2
},
data() {
return {
child2Msg: 'Hello World',
message: "",
msg: "child组件",
list: [
{
name: '孙子1',
age: 10
},
{
name: '孙子2',
age: 15
},
{
name: '孙子3',
age: 18
},
{
name: '孙子4',
age: 15
}
],
info: {
},
isShow: false,
};
},
methods: {
showMsg(title) {
this.message = title;
},
showInfo(prop) {
this.isShow = true;
this.info = prop;
}
}
};
</script>
在home组件中我们可以看到child和child2是非父子组件
在child2中通过
this.$root.Bus.$on("sendName", value => {
this.print(value);
});
去注册一个自定义事件,value是接收到的参数,sendName是事件名,print是具体的执行函数,在child组件中通过
this.$root.Bus.$emit('sendName', v);去触发sendName函数,传递参数v,
child2组件能接收到v进行具体的操作数据。
如果有多个组件组件需要通信,不需要的根组件上多建几个 Bus,只要保证事件名 (sendName)不一样就行了。
3.vuex
Vuex实现了一个单向数据流,在全局拥有一个State存放数据,当组件要更改State中的数据时,必须通过Mutation进行,Mutation同时提供了订阅者模式供外部插件调用获取State数据的更新。而当所有异步操作(常见于调用后端接口异步获取更新数据)或批量的同步操作需要走Action,但Action也是无法直接修改State的,还是需要通过Mutation来修改State的数据。最后,根据State的变化,渲染到视图上。
新建store/test.js文件:
const test = {
namespaced: true,
state: {
count: 3
},
mutations: {
increment(state, payload) {
state.count += payload;
},
reduce(state, payload) {
state.count -= payload;
}
},
actions: {
getCountRet(context) {
context.commit('increment', 10);
},
getCountRet2(context) {
context.commit('reduce', 10);
}
}
}
export default test;
store/index.js代码:
import Vue from 'vue'
import Vuex from 'vuex'
import Test from './test';
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
},
modules: {
Test
}
})
child2代码:
<template>
<div>
<h1>{{name}}</h1>
{{child2}}----
{{count}}
<button @click="getCount">增加</button>
<button @click="reduce">减少</button>
</div>
</template>
<script>
import { mapActions, mapMutations, mapState } from "vuex";
export default {
props: ["child2"],
data() {
return {
name: ""
};
},
created() {
this.$root.Bus.$on("sendName", value => {
this.print(value);
});
this.getCountRet();
},
computed: {
// ...mapState(模块名,[属性名]);
...mapState("Test", ["count"])
},
methods: {
// 要使用哪个模块的什么方法
...mapActions("Test", ["getCountRet", "getCountRet2"]),
getCount() {
this.getCountRet();
},
reduce() {
this.getCountRet2();
},
print(v) {
this.name = v.name;
}
},
beforeDestroy() {
this.$root.Bus.$off("sendName");
}
};
</script>
<style scoped>
</style>
child代码:
<template>
<div>
<h4 @click="showMsg">{{msg}}--------{{count}}</h4>
<div class="item" v-for="(v,i) in list" :key="i">
我是{{v.name}}
<button @click="sendInfo(v)">点击发送</button>
</div>
</div>
</template>
<script>
import { mapActions, mapMutations, mapState } from "vuex";
export default {
props: ["msg", "list"],
mounted() {},
computed: {
...mapState("Test", ["count"])
},
methods: {
...mapActions("Test", ["getCountRet"]),
showMsg() {
this.$emit("getMessage", "这是父组件");
},
sendInfo(v) {
this.$emit("showInfo", v);
this.$root.Bus.$emit("sendName", v);
}
}
};
</script>
<style scoped>
.item {
margin-top: 10px;
}
</style>
在test.js的muations中有两个方法,在actions中提交。
在child2组件中通过
...mapState("Test", ["count"])监测属性count
...mapActions("Test", ["getCountRet", "getCountRet2"]),使用getCountRet和getCountRet2方法去改变vuex中的值。
在child组件中监测{{count}}的变化。
在child2组件中通过按钮分别调用getCountRet和getCountRet2事件来控制count值的增减,child组件会随之发生变化。
以上是关于vue组件通信的主要内容,如果未能解决你的问题,请参考以下文章