作用
1.Vuex是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享
2. 多个组件依赖于同一状态3. 来自不同组件的行为需要变更同一状态
安装
//在引入Vuex时 警告 "export 'inject' was not found in 'vue'。同时控制台报错。vue/cli 版本 //4.5.13。
//创建项目时没有下载vuex 后期自己下载的,看了一下下载的vuex版本时4.x.x 页面报错
//解决办法:
//1、看一下自己的vuex版本是不是4.x.x ,如果是,先卸载vuex
npm uninstall vuex
//2、重新下载vuex
npm install vuex@3.1.0 --save
//如果你的vue版本是 2.X ,将vuex升到 3.X.X 就能够解决
npm install --save vuex@3.6.2
//如果你的vue版本是 3.X ,将vuex升到 4.X.X 就能够解决
npm install --save vue@3.0.2
npm install --save vuex@4.0.0
引入
//main.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app')
-------------------------------------------------
//store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
// 只有 mutations 中定义的函数,才有权利修改 state 中的数据
mutations: {
add(state) {
// 不要在 mutations 函数中,执行异步操作
// setTimeout(() => {
// state.count++
// }, 1000)
state.count++
},
addN(state, step) {
state.count += step
},
sub(state) {
state.count--
},
subN(state, step) {
state.count -= step
}
},
actions: {
addAsync(context) {
setTimeout(() => {
// 在 actions 中,不能直接修改 state 中的数据;
// 必须通过 context.commit() 触发某个 mutation 才行
context.commit('add')
}, 1000)
},
addNAsync(context, step) {
setTimeout(() => {
context.commit('addN', step)
}, 1000)
},
subAsync(context) {
setTimeout(() => {
context.commit('sub')
}, 1000)
},
subNAsync(context, step) {
setTimeout(() => {
context.commit('subN', step)
}, 1000)
}
},
getters: {
showNum(state) {
return '当前最新的数量是【' + state.count + '】'
}
}
})
State,在组件中访问State的方式
1. State提供唯一的公共数据源,所有共享的数据都要统一放到Store中的State中存储
//声明
//-------------------------------------------------
state: {
count: 0
}
//--------------------------------------------------
//使用,两种方式
//1).this.$store.state.全局数据名称 如:this.$store.state.count,代码如下:
<!-- <h3>当前最新的count值为:{{$store.state.count}}</h3> -->
------------------------------------------------------------------------------------------
//2).先按需导入mapState函数: import { mapState } from 'vuex', 然后数据映射为计算属性: //computed:{ ...mapState(['全局数据名称']) },代码如下:
computed:{
...mapState(['count'])
}
//<!-- <h3>当前最新的count值为:{{count}}</h3> -->
Mutation,用于修改变更$store中的数据(只能写同步的代码)
1.//第一个形参永远都是state也就是$state对象
2.//第二个形参是调用add时传递的参数
声明
1.打开store.js文件,在mutations中添加代码如下
mutations: {
add(state,step){
//第一个形参永远都是state也就是$state对象
//第二个形参是调用add时传递的参数
state.count+=step;
}
}
--------------------------------------------
使用
1.方式一,在Addition.vue中给按钮添加事件代码如下:
<button @click="Add">+1</button>
methods:{
Add(){
//使用commit函数调用mutations中的对应函数,
//第一个参数就是我们要调用的mutations中的函数名
//第二个参数就是传递给add函数的参数
this.$store.commit('add',10)
}
}
----------------------------------------------
2.使用mutations的第二种方式:
import { mapMutations } from 'vuex'
methods:{
...mapMutations(['add'])
}
-----------------------------------------------
代码如下:
import { mapState,mapMutations } from 'vuex'
export default {
data() {
return {}
},
methods:{
//获得mapMutations映射的sub函数
...mapMutations(['sub']),
//当点击按钮时触发Sub函数
Sub(){
//调用sub函数完成对数据的操作
this.sub(10);
}
},
computed:{
...mapState(['count'])
}
}
Action,在vuex中我们可以使用Action来执行异步操作
1.只能执行Mutation中的方法
2.只能通过context.commit()执行Mutation中的方法
1.打开store.js文件,修改Action,如下:
```
声明
---------------------------------------------
actions: {
addAsync(context,step){
setTimeout(()=>{
context.commit('add',step);
},2000)
}
}
----------------------------------------------
触发
1.第一种方式
然后在Addition.vue中给按钮添加事件代码如下:
```
<button @click="AddAsync">...+1</button>
methods:{
AddAsync(){
this.$store.dispatch('addAsync',5)
}
}
------------------------------------------------
2.第二种方式
import { mapActions } from 'vuex'
methods:{
...mapMutations(['subAsync'])
}
--------------------------------------------------
代码如下:
```
------------------------------------------------------
import { mapState,mapMutations,mapActions } from 'vuex'
export default {
data() {
return {}
},
methods:{
//获得mapMutations映射的sub函数
...mapMutations(['sub']),
//当点击按钮时触发Sub函数
Sub(){
//调用sub函数完成对数据的操作
this.sub(10);
},
//获得mapActions映射的addAsync函数
...mapActions(['subAsync']),
asyncSub(){
this.subAsync(5);
}
},
computed:{
...mapState(['count'])
}
}
注意
context的话就相当于state的父亲,上一级,包含着state中的所有属性
context:{
state, 等同于store.$state,若在模块中则为局部状态 rootState, 等同于store.$state,只存在模块中 commit, 等同于store.$commit dispatch, 等同于store.$dispatch getters 等同于store.$getters
}
所以这种写法
getUserInfo({ commit, dispatch, getters, state }, token = '') { return new Promise((resolve, reject) => { token && uni.setStorageSync('token', token); http('user.info').then(res => { if (res.code === 1) { let lastLoginStatus = getters.isLogin; commit('userInfo', res.data); commit('isLogin', true); dispatch('showAuthModal', ''); !lastLoginStatus && share.setShareInfo(); // 存在分享信息 添加分享记录 let spm = uni.getStorageSync('spm'); if (spm) { http('common.shareAdd', { spm: spm }); uni.removeStorageSync('spm'); } resolve(res.data) } }).then(() => { // 只有在登录的时候请求购物车信息,订单信息,获取登录信息之后。 token && dispatch('getCartList'); token && dispatch('getUserData'); }) .catch(e => { reject(e) }) }) }
Getter,Getter用于对Store中的数据进行加工处理形成新的数据
它只会包装Store中保存的数据,并不会修改Store中保存的数据,当Store中的数据发生变化时,Getter生成的内容也会随之变化
声明
打开store.js文件,添加getters,如下:
```
export default new Vuex.Store({
.......
getters:{
//添加了一个showNum的属性
showNum : state =>{
return '最新的count值为:'+state.count;
}
}
})
```
---------------------------------------------
使用
1.方式一
然后打开Addition.vue中,添加插值表达式使用getters
<h3>{{$store.getters.showNum}}</h3>
-----------------------------------------------
2.方式二
在Addition.vue中,导入mapGetters,并将之映射为计算属性
import { mapGetters } from 'vuex'
computed:{
...mapGetters(['showNum'])
}
调试