vuex vue 专用 状态管理模式 采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生改变。
1,状态 :本质上就是一个变量,赋予不同的值就是不同的状态,管理状态实际上就是管理一堆变量。
2,响应式 ,vuex 跟全局变量不同,修改了vuex 的某个状态,依赖这个状态的试图都会发生改变。
(二)vuex 的五个核心概念
1,state 定义状态(变量),辅导函数mapState
2, Getter 获取状态(变量的值),同时可以对状态进行处理,辅助函数mapGetters.
3, Mutation 修改状态 (修改变量的值)
4,action 触发 mutation函数 ,从而修改状态,支持异步
5,module 当状态很多时,把状态分开管理。
安装 vuex
1,npm i vuex
vuex 配置
在根目录新建 /store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex);
const config = {
// 定义状态
state: {
isLogin: false
},
// getters
getters: {
// isLogin:(state) =>{
// return state.isLogin;
// },
// 等同上面的写法
isLogin: state => state.isLogin
},
// 修改state里面的变量
mutations: {
// state指向上面的state,payload是调用muation时传过来的参数
updateLogin(state, payload) {
state.isLogin = payload;
}
},
// action行为
actions: {
},
// module
modules: {
}
}
export default new Vuex.Store(config);
在main.js 导入 并挂载到Vue 实例上
import Vue from 'vue'
import App from './App.vue'
import store from './store/index'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App),
}).$mount('#app')
四,获取在vuex 定义的状态
1,通过this.$store.state.XXX 来取,具体使用
created() {
console.log(this.$store.state.isLogin);
console.log(this.$store.state.firstName);
}
// 通常我们会定义计算属性来取值,比如
computed: {
// 自定义计算属性
isLogin() {
// 获取vuex的isLogin的值
return this.$store.state.isLogin
}
}
2,通过辅助函数 mapState 来获取
data() {
return {
addr: '广西'
};
},
computed: mapState({
// 取state里count的值
count: 'count',
// 取state里count的值,用countAlias变量接收
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
fullName(state) {
return this.addr + state.firstName + state.lastName;
}
})
// 如果需要定义其它的计算属性,就按照下面的写法
computed: {
// 其他的计算属性
total() {
return 500
},
...mapState({
// 取state里count的值
count: 'count',
// 取state里count的值,用countAlias变量接收
countAlias: 'count',
// 为了能够使用 `this` 获取局部状态,必须使用常规函数
fullName(state) {
return this.addr + state.firstName + state.lastName;
}
})
}
3,通过 getters 和mapGetters 来取
// 定义一个用来获取fullName的getter
getters: {
fullName(state) {
return state.firstName + state.lastName;
}
},
// 通过mapGetters
import {mapGetters} from 'vuex';
computed: {
fullName() {
return this.$store.getters.fullName;
}
}
5,修改state 中的状态
1,定义 state 和 mutation
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
name: "没名字",
count: 1
},
getters: {
},
// 修改state里的值必须通过mutation来修改
mutations: {
/**
* 定义一个修改name的mutation
* state是上面的定义的state
* payload是新的数据
*/
updateName(state, payload) {
state.name = payload;
}
}
})
2,在需要的时候调用mutation 进行修改state里的name状态。
```
// 第一个参数是mutation的名字,第二参数是要修改成的数据
this.$store.commit('updateName','老胡');
```
综合例子:通过Vuex实现加减
1,vuex 里配置state 和 mutation
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
addOne(state, payload) {
state.count = state.count + 1;
},
minusOne(state, payload) {
if (state.count > 0) {
state.count = state.count - 1;
}
}
}
})
index.vue的配置
<template>
<div>
<button@click="minus">-</button>
<span>{{count}}</span>
<button@click="add">+</button>
</div>
</template>
<script>
import { mapState } from "vuex";
export default {
computed: mapState({
count: "count"
}),
methods: {
add() {
this.$store.commit("addOne");
},
minus() {
this.$store.commit("minusOne");
}
}
};
</script>
6,vuex本地持久化
当刷新页面,项目重新加载,vuex会重置,所有状态回到初始状态,使用vuex-persistedstate 可以避免这种情况。
1,安装 vuex-persistedstate
npm i vuex-persistedstate
2,在vuex中,添加plugins
import createPersistedState from 'vuex-persistedstate'
plugins: [createPersistedState()],
具体例子
import Vue from 'vue';
import Vuex from 'vuex';
import createPersistedState from 'vuex-persistedstate'
// 导入模块
import login from './module/login'
import my from './module/my'
Vue.use(Vuex);
export default new Vuex({
plugins: [createPersistedState()],
// 模块
modules: {
login,
my
},
state: {
isLogin: false,
username: '',
token: ''
},
getters: {
isLogin: state => state.isLogin,
token: state => state.token,
username: state => state.username
},
mutations: {
updateLogin(state, payload) {
state.isLogin = payload;
},
updateToken(state, payload) {
state.token = payload;
},
updateUsername(state, payload) {
state.username = payload;
}
},
actions: {
LoginAction({commit}, payload) {
commit('updateLogin',payload)
},
TokenAction({commit}, payload) {
commit('updateToken',payload)
},
UsernameAction({commit}, payload) {
commit('updateUsername',payload)
},
}
})
7,modules的使用
1,配置模块的vuex
export default {
state: {
cartNum: 10
},
getters: {
},
mutations: {
updateCartNum(state, payload) {
state.cartNum = payload;
}
},
actions: {
}
}
2,获取状态
<template>
<div>{{cartNum}}</div>
</template>
<script>
import { mapState } from "vuex";
export default {
computed: mapState({
cartNum(state) {
return state.cart.cartNum;
}
})
};
</script>
3,修改状态
this.$store.commit("updateCartNum",200);
八) acion
Action 类似于 mutation,都是用来修改vuex的状态, 不同在于:
Action 提交的是 mutation,而不是直接变更状态。
Action 可以包含任意异步操作。
1,配置action
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
num: 10
},
mutations: {
updateNum(state, payload) {
state.num = payload;
}
},
actions: {
/**
* 修改num的action
* @param {*} ctx 可以拿到一个类似store的实例
* @param {*} payload 修改的数据
*/
updateNum(ctx, payload) {
setTimeout(() => {
ctx.commit('updateNum', payload);
}, 3000)
}
}
})
2,派发action,在需要的地方,调用以下方法
this.$store.dispatch("updateNum",500);