vue組件傳值方式,包含父向子、子向父、兄弟之間以及Vuex傳值的代碼實現

vue組件間傳值的方式

1.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>
  1. 在子組件中定義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 子組件向父組件傳值

  1. 在子組件中定義一個單擊事件,使用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>
  1. 在父組件中通過定義方法接收子組件傳遞的值
<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 非父子組件傳值

  1. 創建一個bus.js,在bus.js中創建一個Vue實例
import Vue from "vue";
export default new Vue();
  1. 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>
  1. 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庫)消息訂閱與發佈的方式傳值

  1. 安裝PubSubJS

    npm install --save pubsub-js
    
  2. 在需要發佈消息的組件中發佈消息

    <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>
    
  3. 在需要接收消息的組件中訂閱消息

    <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 應用程序開發的狀態管理模式。它採用集中式存儲管理應用的所有組件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。

  1. 安裝vuex

    npm install vuex --save
    
  2. 創建一個count,提供一個初始 stategetters 對象和一些 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);
        }
      }
    };
    
  3. 創建一個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
      }
    });
    
    
  4. main.js中引入vuex並掛載storeVue實例

    import store from '@/store/store'
    
    new Vue({
      el: "#app",
      router,
      store,
      components: { App },
      template: "<App/>"
    });
    
    
  5. 在組件中獲取狀態

    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>
    

通過以上幾種方式基本可以解決多數情況下組件傳值的問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章