Vue组件间通信的几种方式

256 阅读2分钟

Vue组件间通信的几种方式:

在还没有接触到vuex之前,关于vue组件之间的通信,还停留在事件总线上,现在关于组件间的最常用的几种通信方式做一个简单的使用说明。

一、父子组件间通信

image.png

(1)父组件-->子组件:

//App.vue父组件
<template>
  <div id="app">
    <users v-bind:users="users"></users>//前者自定义名称便于子组件调用,后者要传递数据名
  </div>
</template>

<script>
import Users from "./components/Users"
export default {
  name: 'App',
  data(){
    return{
      users:["Henry","Bucky","Emily"]
    }
  },
  components:{
    "users":Users
  }
}
</script>
//users子组件
<template>
  <div class="hello">
    <ul>
      <li v-for="user in users">{{user}}</li>//遍历传递过来的值,然后呈现到页面
    </ul>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props:{
    users:{           //这个就是父组件中子标签自定义名字
      type:Array,
      required:true
    }
  }
}
</script>

注:建议props以对象的格式进行传递,后期子组件是无法直接对props绑定的数据进行修改的,但是封装成对象之后,就完美解决了;

(2)子组件-->父组件

methods: {
      send() {
        Event.$emit('事件名', 数据);
      }
   }
<users @事件名="处理函数"></users>

二、事件总线通信

这种方法通过一个空的Vue实例作为中央事件总线(事件中心),用它来触发事件和监听事件,巧妙而轻量地实现了任何组件间的通信,包括父子、兄弟、跨级。当我们的项目比较大时,可以选择更好的状态管理解决方案vuex。

(1)首先在main.js中注册一个空的Vue实例

Vue.prototype.$bus = new Vue()

(2)其次就可以通过该实例触发事件

this.$bus.$emit('事件名',数据)

(3)其他的组件也就可以通过对该事件进行监听

this.$bus.$on('事件名',(data)=>{处理函数})

(4)最后在组件注销时,记得终止对该事件的监听

destroyed(){this.$bus.$off(事件名)}

三、Vuex通信

vuex.png 终于到了终极神器vuex,vuex的核心就是store,创建方式如下:

import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)

export default new Vuex.Store({
  state: { //存放状态
    flag2
  },
  mutations: {
    setFlag(state, val){
      state.flag = val
    }
  },
  actions: {},
  modules: {}
})

此时,可以通过引入store即可访问其中的变量,但是多次引入不如在main中直接引入,引入之后可以通过this.$store进行访问。

new Vue({
  el: '#app',
  store: store
})

Vuex中主要分为state,getters,mutations,actions以及modules五个属性。

state:

state就是状态容器,一般通过computed属性引入vue中(视作data),后期可以配合watch来进行监听并处理。如果本地数据名与state中的数据名一致,也可以通过mapState进行简化;

(记得使用之前要引入:import {mapState} from 'vuex';并且当前vue实例上挂载了store)

computed: {flag() {return this.$store.state.flag}}
computed: ...mapState(['flag'])

getters:

getters很像computed,接受state作为第一个参数,并对state中的内容进行修改之后return回去,在vue组件中可以通过this.$store.getters.getFlag()访问,也可以通过mapGetters进行访问

getters: { getFlag: state => { return state.flag += 1 }}
computed: getFlag(){return this.$store.getters.getFlag()}
computed: ...mapGetters(['getFlag'])

mutations:

值得注意的是在对state中的参数进行修改时,如果直接进行修改,就不会被监测到变化,而通过commit提交mutations中的方法进行修改则可以被监测到,具体方法如下:

mutations: setFlag(state, val){state.flag=val}
methods:{setFlag(val){this.$store.commit('setFlag',val})
methods: ...mapMutations(['setFlag'])

actions:

actions类似于mutations,但是他是通过提交mutations来修改state,并且mutations支持同步修改,而像axios等异步操作则需要actions来完成,并且在actions中的方法,默认也是异步的;

//context可以理解为它是整个Store的对象.类似于this.$store,
actions: { addFlag(context,val) {context.commit('setFlag',val)}}
methods: {addFlag(val){this.$store.dispatch('addFlag',val)}}
methods: ...mapActions(['addFlag'])

以上基本就可以应付日常组件间的通信,后面会更新一期vuex的进阶使用版,债见!

再见.gif