vue
组件间传值的方式
1.1 父组件向子组件传值
- 在
parent.vue
中引入子组件之后,在子组件的标签上添加传值方式:msg="msgToChild"
,然后在子组件中定义msg
属性接收父组件传递过来的值。
// 父组件
<template>
<div>
<h1>Parent</h1>
// 这里表示父组件向子组件传递msgToChild字符串,属性值为msg
<m-child :msg="msgToChild"></m-child>
</div>
</template>
<script>
import MChild from "./Child";
export default {
data() {
return {
msgToChild: "from parent msg to child o",
};
},
components: {
MChild
}
};
</script>
- 在子组件中定义
props
接收父组件传来的值,具体如下:
// 子组件
<template>
<div>
<h2>child</h2>
// 显示父组件传来的值
<h5>{{ msg }}</h5>
</div>
</template>
<script>
export default {
props: {
// 定义msg属性,接收父组件传过来的值
msg: {
type: String,
default: ""
}
}
};
</script>
父组件还可以通过
this.$children[0].childmsg
或者this.$refs.child.childmsg
来获取子组件中的属性,传值类型也可以为Function。
1.2 子组件向父组件传值
- 在子组件中定义一个单击事件,使用this.$emit定义一个触发事件的名称和触发事件传递的值,到父组件中监听并接收。
// 子组件
<template>
<div>
<h2>child</h2>
<h5>{{ msg }}</h5>
<h6>{{ childmsg }}</h6>
<button @click="passMsg">子组件向父组件传值通过事件触发</button>
</div>
</template>
<script>
import bus from "../utils/bus";
export default {
methods: {
passMsg() {
// 在子组件中定义一个触发事件名称和值,到父组件中监听并接收
this.$emit("showMsg", "i am msg from child");
}
}
};
</script>
- 在父组件中通过定义方法接收子组件传递的值
<template>
<div>
<h1>Parent</h1>
<h3>{{ msg }}</h3>
<m-child @showMsg="showMsg"></m-child>
</div>
</template>
<script>
import MChild from "./Child";
export default {
data() {
return {
msg: ""
};
},
components: {
MChild
},
methods: {
// msgfromchild即为子组件中触发事件中传递的值
showMsg(msgfromchild) {
// 接收子组件传递的值并赋值
this.msg = msgfromchild;
}
}
};
</script>
1.3 非父子组件传值
- 创建一个
bus.js
,在bus.js
中创建一个Vue
实例
import Vue from "vue";
export default new Vue();
- 在
App
中需要传值到Child
,首先在App
中引入bus
,并给bus
定义触发事件
// App组件
<template>
<button @click="passMsg">非父子组件传值</button>
</div>
</template>
<script>
// 引入父组件
import MParent from "./views/Parent";
// 非父子组件传值
import bus from "./utils/bus";
export default {
name: "App",
components: {
MParent
},
methods: {
passMsg() {
// 在bus上定义触发事件
bus.$emit("msg", "I am from app");
}
}
};
</script>
- 在
child
组件中接收
<template>
<div>
<h2>child</h2>
<h5>{{ msg }}</h5>
<h6>{{ childmsg }}</h6>
<button @click="passMsg">子组件向父组件传值通过事件触发</button>
</div>
</template>
<script>
import bus from "../utils/bus";
export default {
data() {
return {
childmsg: "可以尝试通过this.$children来获取我"
};
},
mounted() {
// 子组件中接收并使用箭头函数赋值
bus.$on("msg", msgfromapp => {
this.childmsg = msgfromapp;
});
}
};
</script>
1.4 (PubSubJS
库)消息订阅与发布的方式传值
-
安装
PubSubJS
npm install --save pubsub-js
-
在需要发布消息的组件中发布消息
<template> <div> <button @click="pubsubmsg">通过PubSub发布消息</button> </div> </template> <script> <!-- 1. 引入PubSub --> import PubSub from 'pubsub-js' export default { data() { return { // 消息需要传递的值,这里可以是任何类型包括对象函数等 msgfromPubpublish: "msgfromPubpublish" }; }, methods: { // 发布消息 pubsubmsg() { // publishmsg为发布的消息名称,接收时需要对应选择,this.msgfromPubpublish为传递的值 PubSub.publish("publishmsg", this.msgfromPubpublish); } } }; </script>
-
在需要接收消息的组件中订阅消息
<template> <div> <h6>{{ childmsg }}</h6> </div> </template> <script> import PubSub from "pubsub-js"; import Diff from "./Diff"; export default { data() { return { childmsg: "初始msg" }; }, mounted() { // 订阅消息,publishmsg为发布消息时定义的名称,msgfromPubpublish为传递的值,如果有多个值的话请封装成对象即可,通过箭头函数获取到this // 这样就完成了接收消息并获取到传递的值,该方法不限定组件父子关系,类似bus总线方式 PubSub.subscribe("publishmsg", (msg, msgfromPubpublish) => { console.log(msgfromPubpublish); this.childmsg = msgfromPubpublish; }); } }; </script>
1.5 通过vuex
进行组件中传值
Vuex
是一个专为 Vue.js
应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
-
安装
vuex
npm install vuex --save
-
创建一个
count
,提供一个初始state
,getters
对象和一些mutation
,actions
:export default { state: { count: 0 }, getters: { doubleCount(state) { return state.count * 2; } }, mutations: { // 类似method,通过commit进行调用 add(state) { state.count++; }, decrese(state) { state.count--; } }, actions: { delayadd(context) { setTimeout(() => { // 通过context commit触发mutations中的事件 context.commit("decrese"); console.log("decrese double"); }, 1000); } } };
-
创建一个
store
,直接获取count
并模块化命名import Vue from "vue"; import Vuex from "vuex"; import count from "@/store/count"; Vue.use(Vuex); export default new Vuex.Store({ modules: { count } });
-
在
main.js
中引入vuex
并挂载store
到Vue
实例import store from '@/store/store' new Vue({ el: "#app", router, store, components: { App }, template: "<App/>" });
-
在组件中获取状态
import { mapState, mapGetters } from "vuex"; export default { computed: { ...mapState({ // count: "count" // 模块拆分时 count: state => state.count.count }), ...mapGetters(["doubleCount"]) // doubelCount() { // return this.$store.getters.doubleCount; // } }, // computed: mapState({ // count: "count" // }), data() { return { msgToChild: "from parent msg to child o", msg: "", msgfromPubpublish: "msgfromPubpublish" }; }, methods: { showMsg(msgfromchild) { this.msg = msgfromchild; }, // 这里也可以通过...mutations解构 add() { // 通过commit触发mutations this.$store.commit("add"); // 通过dispatch触发actions // this.$store.dispatch("delayadd"); } } }; </script>
通过以上几种方式基本可以解决多数情况下组件传值的问题。