Vuex模块化应用实践示例(2)

有的时候我们会从后端获取一些下拉框选项的静态常量,而且很多页面都能用到,这个时候用Vuex是比较好的选择,涉及到后端获取,就要用到可以使用异步的actions了

src/store/modules/product.js

import {MU_PRODUCT_UPDATE_CONSTANTS} from '../../common/constants' const product = { state: { productConstants: [] }, mutations: { [MU_PRODUCT_UPDATE_CONSTANTS] (state, payload) { state.productConstants = payload } }, actions: { // action函数第一个参数接受一个与 store 实例具有相同方法和属性的 context 对象, // 因此你可以调用 context.commit 提交一个 mutation, // 或者通过 context.state 和 context.getters 来获取 state 和 getters // 这里虽然能获取到state,但是不建议直接修改state中的字段 async getProductConstants ({ commit }, payload) { try { // 请求接口,如果需要参数可以通过payload传递 const res = await this.$api.product.getConstants() commit(MU_PRODUCT_UPDATE_CONSTANTS, res) } catch (e) { console.error(e) } } }, getters: {} } export default product

下面触发这个getProductConstants事件,触发这个action事件的位置需要注意一下,假设你有5个组件需要使用这个state,那就应该在这5个组件共同的父组件中调用一次action(找不到就在根实例中调用),然后在各个子组件中通过mapState或mapGetters获取state,千万不要每个组件使用前都调用一次action方法!

src/App.vue

<!--为了更直观的展示action,把之前的代码删掉了--> <script> import { mapActions } from 'vuex' // 注意是mapActions export default { name: 'app', data () { return {} }, created () { // 触发请求 this.getProductConstants() } methods: { ...mapActions([ // 映射 this.getProductConstants 为 this.$store.dispatch('getProductConstants') 'getProductConstants' ]) } } </script>

mapGetters, mapMutations, mapActions,这几个函数可以接受对象也可以接受数组作为参数,如果你需要在组件中以别的名字调用该事件(像上面的mapMutations)就可以传入对象,key为新命名,value是store中定义的名字;否则的话传数组就好了。

那么问题来了,既然是异步操作,我想在操作结束后干点儿别的怎么做呢?
很简单,调用action中的异步函数(this.$store.dispatch)返回的是一个Promise,如果你跟我一样用的是async await:

<!--为了更直观的展示action,把之前的代码删掉了--> <script> import { mapActions } from 'vuex' // 注意是mapActions export default { name: 'app', data () { return {} }, async created () { // 触发请求 await this.getProductConstants() // 接下来执行的操作会等待上面函数完成才会执行 } methods: { ...mapActions([ // 映射 this.getProductConstants 为 this.$store.dispatch('getProductConstants') 'getProductConstants' ]) } } </script>

如果你用的不是async await那就麻烦一点,在actions中定义事件的时候return一个new Promise,官方文档中有一个例子

表单处理

当你把从state中获取的字段填在v-model中时,如果用户修改表单数据,v-model会尝试直接修改store中的数据,这样做会有两个问题:

破坏了vuex的数据传递规则,如果想修改state中的数据只能通过提交一个mutation

控制台报错:计算属性没有setter

官方提供了两种解决方法,我更倾向于下面这种,给计算属性添加setter,并在setter中提交mutation修改state:

<template> <input v-model="message"> </template> <script> export default { name: 'app', data () { return {} }, computed: { message: { get () { return this.$store.state.test.message }, set (value) { this.$store.commit('updateMessage', value) } } } methods: {} } </script>

Vuex持久化

推荐插件vuex-persist

安装插件:

npm install --save vuex-persist

引入、配置、加载插件:
src/store/persist.js

import VuexPersistence from 'vuex-persist' const persist = new VuexPersistence({ // 其他参数看文档 storage: window.sessionStorage }) export default persist.plugin

src/store/index.js

import ... import persist from './persist' Vue.use(Vuex) export default new Vuex.Store({ modules: { user, product, windowInfo }, plugins: [persist] })

现在刷新浏览器数据也不会重置了!

总结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/2e57c9e2f97ac98efce6af8dbe1809e6.html