Vuex模块化应用实践示例

Vuex作为Vue全家桶的成员之一,重要性肯定不用多说,正在做Vue项目的同学,随着项目需求、功能逐渐增加,用到Vuex也是早晚的事儿,作为一个前端,只能面对现实:学不动也得学!

这篇文章主要介绍Vuex在大型项目中的模块化及持久化应用实践,下面正文开始

Vuex的应用场景

多个组件视图共享同一状态时(如登录状态等)

多个组件需要改变同一个状态时

多个组件需要互相传递参数且关系较为复杂,正常传参方式变得难以维护时

持久化存储某些数据

所以我们把组件共享的状态抽离出来,不管组件间的关系如何,都通过Vuex来处理

组织store目录

我们先按模块化的方式组织store目录,并在Vue根实例中注册store,Vuex 通过 store 选项,提供了一种机制将状态从根组件“注入”到每一个子组件中

src ├── ... ├── main.js ├── App.vue └── store ├── index.js # 我们组装模块并导出 store 的地方 └── modules ├── product.js # 产品模块 ├── windowInfo.js # 窗口信息模块 └── user.js # 登录模块

src/store/index.js

import Vue from 'vue' import Vuex from 'vuex' import user from './modules/user' import product from './modules/product' import windowInfo from './modules/windowInfo' Vue.use(Vuex) export default new Vuex.Store({ modules: { // 注册modules中的模块 user, product, windowInfo } })

src/main.js

import ... import store from './store' // 添加这行 new Vue({ el: '#app', router, store, // 注入到根实例 template: '<App/>', components: { App } })

store的属性

state(状态对象)
state中存放多页面共享的状态字段

getters
相当于当前模块state的计算属性

mutations
如果想更新state中的字段,提交mutations中定义的事件是唯一的方式(key为事件名,value是一个函数),但是这个事件函数必须是同步执行的

actions
可以定义异步函数,并在回调中提交mutation,就相当于异步更新了state中的字段

Vuex模块化应用实践示例

vuex数据传递规则

使用方法

把窗口的高度和宽度存到Vuex中,并且每当窗口被resize,state中的高度和宽度自动更新

src/store/modules/windowInfo.js

import { MU_WIN_RESIZE } from '../../common/constants' const windowInfo = { state: { // 初始化 winHeight: 0, winWidth: 0 }, mutations: { // 这里把事件名统一抽离到constants.js统一管理,方便维护,避免重复。 // 当然,你也可以不这么写。。 // mutation事件接受的第一个参数是当前模块的state对象 // 第二个参数是提交事件时传递的附加参数 [MU_WIN_RESIZE] (state, payload) { const { winWidth, winHeight } = payload state.winWidth = winWidth state.winHeight = winHeight } }, actions: {}, getters: {} } export default windowInfo

src/common/constants.js

export const MU_WIN_RESIZE = 'MU_WIN_RESIZE' // 更新窗口尺寸

下面打开项目的根组件添加监听resize事件和提交mutation事件逻辑

src/App.vue

<!--上面的template我就不往这儿放了--> <script> import { _on, _off, getClientWidth, getClientHeight } from './common/dom' import { MU_WIN_RESIZE } from './common/constants' import { mapMutations } from 'vuex' export default { name: 'app', data () { return {} }, mounted () { this.handleResize() // 这里对addEventListener方法做了IE兼容处理,就不贴出来了,反正事件监听你们都会 _on(window, 'resize', this.handleResize) }, beforeDestroy () { _off(window, 'resize', this.handleResize) }, methods: { // 对象展开运算符,不熟悉的同学该学学ES6了 ...mapMutations({ // 映射 this.winResize 为 this.$store.commit(MU_WIN_RESIZE) winResize: MU_WIN_RESIZE }), handleResize () { const winWidth = getClientWidth() const winHeight = getClientHeight() this.winResize({ winWidth, winHeight }) } } } </script>

到这一步,在拖动窗口触发‘resize'事件的时候,就会触发‘MU_WIN_RESIZE'这个mutation事件并把窗口宽高写入vuex,下面我们随便找个页面看能不能获取到我们写入的值

<template> <div>窗口高:{{winHeight}} 窗口宽:{{winWidth}}</div> </template> <script> import { mapState } from 'vuex' export default { name: 'test', data () { return {} }, computed: { // 把state写入计算属性 // 如果使用mapGetters也是写入计算属性 ...mapState({ winHeight: state => state.windowInfo.winHeight, winWidth: state => state.windowInfo.winWidth }) }, } </script>

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

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