vue2全家桶-vuex
1、Vuex是什么?
Vuex是实现组件全局状态(数据)一种管理机制,可以方便的实现组件之间数据的共享
。
2、使用Vuex统一管理状态的好处
- 集中管理共享的数据,易于开发和后期维护
- 高效的时间组件之间的数据共享,提高开发效率
- 存储在vuex中的数据都是响应式的,能够实时保持数据与页面的同步;
3、什么样的数据适合存储到Vuex中
一般情况下,只有组件之间共享的数据,才有必要存储到vuex中,对于组件中的私有数据,依旧存储在组件自身的data中即可
4、Vuex的基本使用
- 安装vuex依赖包 npm i vuex -save
- 导入Vuex包
import Vuex from 'vuex'
Vue.use(Vuex)
- 创建store对象并暴露
export default new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})
- 将创建的store挂载到vue实例中
import store from './store';
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
5、Vuex的核心概念
5.1、State
state提供唯一的公共数据,所有共享的数据都要统一放到Store的State中进行存储。
state: {
count:0
},
5.1.1、访问State中数据的方式
方式1: this.$store.state.count
;
方式2:
1、从vuex中按需导入mapState函数
import {mapState} from "vuex";
通过将导入的mapState函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性
2、将全局数据,映射为当前组件的计算属性
computed: {
...mapState(["count"])
}
5.2、Mutations
Mutation用于变更Store中的数据;
- 只能通过Mutation变更Store中的数据;
不允许组件直接操作Store中的state数据
- 虽然操作起来繁琐,但是可以集中监控所有数据的变化
mutations: {
sub(state) {
//变更状态
state.count--;
},
subN(state, step) {
// 有参
state.count -= step
},
add(state) {
//变更状态
state.count++;
}, addN(state, step) {
// 有参
state.count += step
},
}
5.2.1、触发mutations的方式
commit的作用:调用某个mutations函数
方式1: this.$store.commit('sub')
(无参), this.$store.commit('sub' , 参数)
(有参)
方式2:
1、从vuex中按需导入mapMutations函数
import {mapMutations} from "vuex";
通过将导入的mapMutations函数,将需要的mutations函数,映射为当前组件的methods方法
2、将指定的mutations函数,映射为当前组件的methods方法
methods: {
...mapMutations(["add","addN"])
}
在mutation不要执行异步操作
;
5.3、Action
Action用于处理异步任务。如果通过异步操作变更数据,必须通过Action,而不能使用Mutation,但是在Action中还是要通过触发Mutation的方式间接变更数据。
在Action不能直接修改state里面的数据
,如果需要修改,必须通过commit触发某个mutation函数才行
mutations: {
sub(state) {
//变更状态
state.count--;
},
subN(state, step) {
// 有参
state.count -= step
}
},
actions: {
subAsync(context) {
setTimeout(() => {
context.commit("sub");
}, 1000)
},
subNAsync(context,step) {
setTimeout(() => {
context.commit("subN",step);
}, 1000)
},
addAsync(context) {
setTimeout(() => {
context.commit("add");
}, 1000)
},
addNAsync(context, step) {
setTimeout(() => {
context.commit("addN", step);
}, 1000)
},
},
5.3.1、触发actions的方式
方式1: this.$store.dispatch('subAsync')"
(无参);this.$store.dispatch('subAsync' , 参数)"
(有参)
方式2:
1、从vuex中按需导入mapActions函数
import {mapActions} from "vuex";
通过将导入的mapActions函数,将需要的actions函数,映射为当前组件的methods方法
2、将指定的actions函数,映射为当前组件的methods方法
methods: {
...mapActions(["addAsync","addNAsync"])
}
5.4、Getter
用于对Store中的数据进行加工处理形参新的数据,不会修改Store里面的原数据。
- Getter可以对Store中已有的数据加工处理之后形成新的数据,类似Vue的计算属性。
- Store中数据发生变化,Getter的数据也会跟着变化
state: {
count: 0
},
getters: {
showNum: state => {
return `当前最新的数字是${state.count}`
}
},
5.4.1、触发getters的方式
方式1: this.$store.getters.showNum
方式2:
1、从vuex中按需导入mapGetters函数
import {mapGetters} from "vuex";
通过将导入的mapGetters函数,将当前组件需要的全局数据,映射为当前组件的computed计算属性
2、将全局数据,映射为当前组件的计算属性
computed: {
...mapGetters(["showNum"])
}
5.5、Module
由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,store 对象就有可能变得相当臃肿。
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割。
使用案例:
- 创建一个user.js,拥有自己的 state、mutation、getter等,并将其暴露
const state = {
userName: "张三",
}
const getters = {
getUserName: (state) => {
return state.userName
}
}
const mutations = {
changeName(state, value) {
state.userName = value
}
}
export default {
state,
getters,
mutations
}
- 在index.js文件中引入user.js,并放入modules中使用
import Vue from 'vue'
import Vuex from 'vuex'
import userStore from "@/store/user";
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {userStore},
})
6、vuex严格模式
开启严格模式,仅需在创建 store 的时候传入 strict: true
const store = new Vuex.Store({
// ...
strict: true
在严格模式下,无论何时发生了状态变更且不是由 mutation 函数引起的,将会抛出错误
。这能保证所有的状态变更都能被调试工具跟踪到。
注意:
不要在发布环境下启用严格模式! 严格模式会深度监测状态树来检测不合规的状态变更——请确保在发布环境下关闭严格模式,以避免性能损失。
6、Vuex的运行机制
Vuex提供数据(state),来驱动视图(这里指的是Vue组件),视图通过Dispatch派发Action,在Action中可以进一步做一些异步的操作(例如通过ajax请求后端的接口数据),然后通过Commit提交给Mutations,由Mutations去最终更改state。
那么为什么要经过Mutations呢?这是因为我们要在Vue调试工具(Devtools)中记录数据的变化,这样可以通过插件去进行进一步的调试。所以说Mutations中只能是纯同步的操作,如果是有异步操作,那么就需要在Actions中进行处理。如果说没有异步操作,那么可以直接由组件进行Commit操作Mutations。
7、Vuex页面刷新数据丢失了,怎么解决?
7.1、方法1:结合sessionStorage/localStorage使用
缺点:这种方法需要手动存取
state: {
count: sessionStorage.getItem("count")||0
}
mutations: {
add(state) {
//变更状态
state.count++;
//改变状态的时候将状态存在本地
sessionStorage.setItem("count",state.count);
}
}
7.2、使用vuex-persist插件
- 引入
npm install vuex-persist -S
- 使用
import VuexPersistence from 'vuex-persist'
const vuexLocal = new VuexPersistence({
storage: window.localStorage
//storage: window.sessionStorage
})
export default new Vuex.Store({
state: { ... },
mutations: { ... },
actions: { ... },
plugins: [vuexLocal.plugin]
})