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>
    

通过以上几种方式基本可以解决多数情况下组件传值的问题。

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