Vue组件间通信的几种方式:
在还没有接触到vuex之前,关于vue组件之间的通信,还停留在事件总线上,现在关于组件间的最常用的几种通信方式做一个简单的使用说明。
一、父子组件间通信
(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,vuex的核心就是store,创建方式如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: { //存放状态
flag: 2
},
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的进阶使用版,债见!