2021-3-26 前端达人
正如Redux一样,当你不知道是否需要Vuex那就是不需要。不要因为想用Vuex而使用它。
用过Vue的人都知道,Vuex是Vue的一个全局状态管理模块,它的作用是多个组件共享状态及数据,当某个组件将全局状态修改时,在绑定了该状态的另一个组件也将响应。实际上可以将Vue理解为一个function,在Vue的作用域中有一个数据代理,在每个Vue的实例中都能对其读和写
我们都知道Vue的数据驱动原理是用Object.defineProperty()进行数据代理,在setter中对数据绑定的view进行异步响应(vue3.0则是使用proxy)
通过查看Vuex源码可知Vuex的核心原理就是在Vue的beforeCreate钩子前混入(mixin)Vuex,并在init中将$store属性注册到Vue中
为了使案例更具体,我这还是简单使用脚手架搭了个项目(可参考另一篇文章),虽然只有两个组件,但是能清晰的理解其用法,我的src目录如下,除了最基础的App.vue和main.js外只有两个组件和一个store
先说明一下两个组件的作用,第一个组件是输入框,在里面输入字符,在二个组件div中显示,就是这么简单
首先我们使用常规方式(EventBus)实现一下,这里只需要在mainjs中创建一个vue实例,然后注册在vue中就可以通过事件emit和on来进行组件通信
main.js
import Vue
from 'vue'
import App
from './App'
Vue.prototype.$eventBus = new Vue()
new Vue({
el: '#app',
components: {App},
template: '<App/>'
})
<template>
<div>
{{
val
}}
</div>
</template>
<script>
export default {
name: "divComp",
data () {
return {
val: ''
}
},
mounted () {
this.$eventBus.$on('changeVal', (e) => {//监听输入事件通过eventBus传递信息
this.val = e
})
}
}
</script>
<style
scoped>
</style>
如果到这一步,你仍然感觉难度不大,那么恭喜你,Vuex的使用已经掌握了一大半了
下面,我们来说说actions,在说actions之前,我们先回顾一下mutations,mutations中注册了一些事件,在组件中通过emit对事件进行触发,达到处理异步且解耦的效果,然而官方并不推荐我们直接对store进行操作
官方对actions的说明是:Action 类似于 mutation,不同在于1.Action 提交的是 mutation,而不是直接变更状态。2.Action 可以包含任意异步操作。
也就是说,我们要把组件中的emit操作放到actions中,而在组件中通过某些方式来触发actions中的函数间接调用emit,此时,为了让action更直观,我们添加一个清除输入框字符的方法,当点击清除按钮时清除state.val
在输入框组件中将value绑定到state上
<template>
<input type="text" @input="inputHandler" :value="this.$store.state.val" />
</template>
<script>
export default {
name: "inputComp",
methods: {
inputHandler(e) {
this.$store.dispatch("actionVal", e.target.value);
},
},
};
</script>
<style
scoped>
</style>
在另一个显示数据的组件中新增删除按钮并绑定删除事件,通过dispatch告知store并通过emit操作state
<template>
<div>
<button @click="clickHandler">清除</button>
<span>{{ this.$store.state.val + this.$store.getters.getValueLength }}</span>
</div>
</template>
<script>
export default {
name: "divComp",
methods: {
clickHandler(){
this.$store.dispatch('actionClearVal')
}
},
};
</script>
<style
scoped>
</style>
最后在store中新建删除的actions和mutations
import Vue
from "vue";
import Vuex
from "vuex";
Vue.use(Vuex);
const state = {
val: ''
}
const mutations = {
changeVal(state, _val) {
state.val = _val
},
clearVal(state, _val) {
state.val = ''
}
}
const actions = {
actionVal(state, _val) {
state.commit('changeVal', _val)
},
actionClearVal(state) {
state.commit('clearVal')
}
}
const getters = {
getValueLength(state) {
return `长度:${state.val.length}`
}
}
export default new Vuex.Store({
state,
mutations,
actions,
getters
})
最终效果如下:
到这里为止,Vuex的基本用法就介绍完毕了。
然而除此之外,Vuex官方还提供了辅助函数(mapState,mapMutations,mapGetters,mapActions)和Modules(store的子模块,当有许多全局状态时,我们为了避免代码臃肿,就可以将各个store分割成模块)方便我们书写
下面我们用辅助函数重新实现一下上述功能
输入框:
<template>
<input type="text" @input="inputHandler" :value="value" />
</template>
<script>
import { mapState, mapMutations } from "vuex";
export default {
name: "inputComp",
computed: {
...mapState({ value: "val" }),
},
methods: {
...mapMutations({ sendParams: "changeVal" }), // sendParams用来传递参数,先把sendParams注册到mutations上,输入时触发sendParams
inputHandler(e) {
this.sendParams(e.target.value);
},
},
};
</script>
<style
scoped>
</style>
显示框:
<template>
<div>
<button @click="clickHandler">清除</button>
<span>{{ value + valueLength }}</span>
</div>
</template>
<script>
import { mapState, mapGetters, mapActions } from "vuex";
export default {
name: "divComp",
computed: {
...mapState({ value: "val" }),
...mapGetters({ valueLength: "getValueLength" }),
},
methods: {
...mapActions({ clickHandler: "actionClearVal" }),
},
};
</script>
<style
scoped>
</style>
蓝蓝设计( www.lanlanwork.com )是一家专注而深入的界面设计公司,为期望卓越的国内外企业提供卓越的UI界面设计、BS界面设计 、 cs界面设计 、 ipad界面设计 、 包装设计 、 图标定制 、 用户体验 、交互设计、 网站建设 、平面设计服务