Vuex 终极秘籍总结
一、什么是Vuex
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
你可以理解 Vuex 为全局变量,与 data 不同的是,Vuex 的值刷新不会改变、所有页面均可使用、调用 Vuex 的方法和属性
二、Vuex 核心属性
- state 相当于data
- mutations 相当于 methods (只能写同步)
- action 相当于 methods中的异步方法 (只能写异步)
- getters 相当于 computed 计算属性
- modules 模块化思想**(后边着重讲)**
三、项目中使用 Vuex
1. Vuex 代码
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules' // 模块化部分,暂时忽略,后期在讲
import getters from './getters' // 模块化部分,暂时忽略,后期在讲
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0
},
// 此函数下不可写异步代码
mutations: {
// 相当于methods方法
add (state) {
// mutations方法中可以接收两个参数 state 和 val
// state 用来承接上下文,调用方法可不传,默认第一个参数为 state
// val 即修改 state 中的值
state.count++
},
addX (state, x) {
state.count += x
},
sub (state) {
state.count--
},
addStore (state, step) {
state.count -= step
},
addMoreSync (state, step) {
state.count += step
}
},
// 此函数下写异步方法
actions: {
addAsync (content) {
// actions 类似于 mutations,都可以接收两个参数
// content 承接上下文, val 用来接收实参
// actions 中的方法需要使用 commit 调用 mutations 中的方法来修改 state 中的值
setTimeout(() => {
content.commit('add')
}, 1000)
},
addMoreAsync (content, step) {
setTimeout(() => {
content.commit('addMoreSync', step)
}, 1000)
}
},
// 为方便大家在非模块化时更容易理解 getters 所以这里定义了两个 getters 函数
getters:{
getterCount (state) {
return state.count + 'Vuex'
},
},
// 模块化部分,暂时忽略,后期在讲
getters, // 不会修改state的值,类似于计算属性对其包装
modules
})
2. Vuex 中 state 的使用
// 直接获取并赋值
this.$store.state.count = 1
// 使用 mapState 函数
import { mapState } from 'vuex'
computed: {
...mapState(['count']),
},
// 直接使用 this 即可
console.log(this.count)
3.Vuex 中 mutations 的使用
// 直接使用 commit 调用 mutations 中定义的函数
this.$store.commit('add')
// 使用 mapMutations 辅助函数
import { mapMutations } from 'vuex'
methods:{
...mapMutations(['addX'),
changeCount(){
// 在方法中直接使用 this. 调用 mutations 中的方法即可
// 可传参数,使用 commit 同样
this.addX(10)
},
}
4 .Vuex 中 actions 的使用
// 直接使用 dispatch 调用 actions 中定义的函数
this.$store.dispatch('addAsync')
// 使用 mapActions 辅助函数
import { mapActions } from 'vuex'
methods:{
...mapActions(['addAsync']),
PromiseChangeVal(){
// 使用方法与 mapMutations 类似
this.addMoreAsync(6)
}
}
5 . Vuex 中 getters 的使用
// 直接使用
this.$store.getters.getterCount
// 使用 mapGetters 辅助函数
import { mapGetters } from 'vuex'
computed: {
...mapGetters(['getterCount'])
},
// 使用 this. 即可
this.getterCount
四、Vuex modules
因为我并不喜欢给 Vuex namespaced,有需要的可以自行百度
模块化重点,也更加简便
-
modules 导出不添加 namespaced ,使用更方便
-
需要使用到的 state 通过 getters 包装后导出
1. 先看下 Store 文件夹结构
|----|store // vuex 目录
|-------- |modules // 所有模块都在此目录中定义
|-------- | --------- |index.js // 所有模块导出后都在此文件导入并导出
|-------- | --------- |todoList.js // 模块化文件
|-------- |getters.js // 计算属性文件
|-------- |index.js // vuex导出最终文件
我们从内往外一步步实现模块化
- 在 store 目录下新建 modules 目录
- 在 modules 目录下新建模块化文件,如 todoList.js
- 在 modules 目录下新建 index.js,把所有模块化 js 文件全部引入并导出
- 在 store 目录下新建 getters.js 文件,包装后导出所有需要用到的state属性
- 在 store 目录下的 index.js 引入 modules 目录下的index.js 和 getters.js
2. modules 中的 模块化 js 文件这样写
以 todoList.js 为例
// 引入 axios 是为了请求接口,如在实际项目中使用直接引入封装好的 api 即可
import axios from 'axios'
// state mutations actions getters 均使用 const 定义
const state = {
list: [],
inputVal: ''
}
const mutations = {
// 设置 list 的值
setList (state, data) {
state.list = data
},
// 修改 inputVal 的值
changeInputVal (state, val) {
state.inputVal = val
},
}
const actions = {
getList (content) {
// actions 异步方法,在此使用 axios 请求获取数据
axios.get('/list.json').then(res => {
// 数据获取成功后使用 commit 调用 mutations 的方法给 list 赋值
content.commit('setList', res.data)
})
}
}
const getters = {
// getters 的意义 就是如果在页面直接使用模块化中 state 的属性会报错 undefined
getterCount (state) {
// 计算属性,不在此导出的话也可以统一在 getters.js 文件中封装
// 但是一定要把值 return 出去
return state.list.filter(item => !item.done).length
}
}
// 这里一定要导出
export default {
state,
mutations,
actions,
getters
}
3. modules 中的 index.js 这样写
import todoList from './todoList'
// 如果有多个模块,只需参考这种形式引入即可
export default {
// 导出亦是如此
todoList
}
4. store 下的 getters.js 这样写
// 如果在模块化中使用 getters 函数包装了就不需要在这里再写一遍
export default {
inputVal: state => state.todoList.inputVal,
list: state => state.todoList.list
}
5. store 下的 index.js 这样写
import Vue from 'vue'
import Vuex from 'vuex'
import modules from './modules' // 引入 modules 文件夹下的 index.js 也就是引入了全部的模块
import getters from './getters' // 引入 getters 计算属性文件
Vue.use(Vuex)
// 导出 new Vuex.Store 即可使用
export default new Vuex.Store({
getters,
modules
})
五、Vuex 持久化数据
为什么要持久化 Vuex
-------- 页面刷新会丢失 Vuex 中的值
Vuex 持久化方法
// 使用 vuex-persistedstate 插件
npm install vuex-persistedstate
// store 目录下 index.js 使用
import createPersistedState from 'vuex-persistedstate';
export default new Vuex.Store({
getters,
modules,
// 在此配置
plugins:[
createPersistedState({
// 默认存储在 localStorage 中
// 也可配置成 sessionStorage cookie
storage:window.sessionStorage // 注意
})
],
})