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>
通過以上幾種方式基本可以解決多數情況下組件傳值的問題。