vuex.vue
format:
import { resolve } from "dns";
import { reject } from "q";
const test = {
// 共享数据源 data
state: {
userinfo: {},
userList: [],
departmentInfo: {},
departmentList: [],
sum: 0,
substract: 0,
multiply: 0,
divide: 0,
countPartA: 0,
countPartB: 0
},
// 方法 methods
mutations: {
setUserInfo: (state, info) => {
state.userinfo = Object.assign(info);
},
setDepartmentInfo: (state, info) => {
state.departmentInfo = Object.assign(info);
},
setCountPartA: (state, info) => {
state.countPartA = Number(info);
},
setCountPartB: (state, info) => {
state.countPartB = Number(info);
}
},
// 计算属性 类似computed
getters: {
getSum: state => {
return state.countPartA + state.countPartB;
},
getSubtract: state => {
return state.countPartA - state.countPartB;
},
getMultiply: state => {
return state.countPartA * state.countPartB;
},
getDivide: state => {
return state.countPartA / state.countPartB;
},
// getter方法作为filter使用
getAdultUser: state => {
// 筛选年龄大于18岁的用户
return state.userList.filter(userinfo => Number(userinfo.age) > 18);
},
// filter 实际是有三个参数的 => value, index, list
getBabyUser: state => {
return state.userList.filter((userinfo, index, list) => {
Number(userinfo.age) < 2 &&
Number(userinfo.age) > 0 &&
index >= 0 &&
list.length !== 0;
});
},
// 接受getters作为第二参数,可以调用其他getter
getOlderUser: (state, getters) => {
return getters.getAdultUser.filter(userinfo => Number(userinfo.age) > 65);
},
// 接受外部传参
getAdultBySex: (state, getters) => sex => {
return getters.getAdultUser.filter(userinfo => userinfo.sex === sex);
}
},
actions: {
// 利用 context 本地资源对象
asyncSetpartA: (context, info) => {
setTimeout(() => {
context.commit("setCountPartA", info);
}, 1000);
},
// 接受多个参数
asyncSetPartB: (context, { info, time }) => {
setTimeout(() => {
context.commit("setCountPartB", info);
}, time);
},
/**
* context中包含的属性
* commit 调用mutation
* state
* dispatch 调用其他action
*/
asyncSetChange: ({ dispatch }) => {
dispatch("asyncSetpartA").then(() => {
dispatch("asyncSetPartB");
});
},
asyncSetChange2: ({ dispatch, state }) => {
return new Promise((resolve, reject) => {
dispatch("asyncSetPartB").then(() => {
dispatch("asyncSetpartA").then(() => {
if (state.sum !== 0) {
resolve("done");
} else {
reject("no change");
}
});
});
});
}
}
};
/**
* vuex 若非必要,不建议使用
* 1. 状态存储是响应式的,从 store 实例中读取状态最简单的方法就是在计算属性中返回某个状态
* 2. store 中的状态改变的时候不能被vue中的data监听到
* 3. Vuex中store数据改变的唯一方法就是mutation
* 4. Action可以异步,Action 提交的是 mutation,而不是直接变更状态。
*
*
*
* state 可以使用 mapState 在任意组件的computed中声明需要使用的数据
* ...mapState([ // 数组
* "userinfo", // 如果使用同名引用,必须保证在state中此名字唯一
* "userList"
* ])
* 或者
* ...mapStae({ // 对象
* depList: state => { // 允许自定义名字,指向具体某个模块下的共享值
* return state.test.departmentList
* }
* })
* this.$store.state.userinfo // 单独引用
*
*
*
* // mutations的调用方式唯一, 没有指定type的默认就是方法名
* // 第二个参数为方法所需参数, 如果需要多个参数,commit第二个参数就位一个对象,存放所有参数
* this.$store.commit("setCountPartB", info);
* 作为对象提交
* this.$store.commit({
* type: "setCountPartB",
* info: info
* })
* // 使用 mapMutations 快速集成方法,一般在 methods 中声明使用
* ...mapMutations([
* "setUserInfo",
* "setDepartmentInfo"
* ])
* 或者
* ...mapMutations({
* setA: "setCountPartA",
* setB: "setCountPartB"
* })
*
*
*
* getters 可以使用 mapGetters 在任意组件的computed中声明使用
* ...mapGetters({
* getAdult: "getAdultUser" // 这是对象
* })
* 或者
* ...mapGetters([
* "getOlderUser" // 这是数组
* ])
* this.$store.getters.getBabyUser // 单独调用getter时不会创建缓存
* this.$store.getters.getAdultBySex("man") // 获取所有男性成年用户
*/
export default test;
example: vue + vuex
<template>
<div>
<span>用户信息:</span>
<span>{{userInfo}}</span><br>
<span>用户地址:</span>
<span>{{address}}</span><br>
<span>用户部门:</span>
<span>{{department}}</span>
<hr>
<span>{{userDetails}}</span>
<hr>
<div style="display:flex;flex-direction:column;justify-content:center;align-items:center;">
<input type="button" value="one year pass by!" @click="gettingOlder">
<hr>
<div>
<input type="text" placeholder="entry your new name !" v-model="name">
<input type="button" value="change name !" @click="changeUserName(name)">
</div>
<hr>
<div>
<input type="text" placeholder="entry a new street name !" v-model="str">
<input type="button" value="change name !" @click="localFunChangeStrName(str)">
</div>
<hr>
<input type="button" value="action" @click="localActionChangeData">
</div>
</div>
</template>
<script>
import { mapState, mapGetters, mapMutations } from 'vuex'
export default {
data () {
return {
name: '',
str: ''
}
},
methods: {
...mapMutations([
'gettingOlder',
'changeUserName'
]),
// 使用传统的commit使用方法
localFunChangeStrName (streetName) {
this.$store.commit('changeStreet', streetName)
},
// 调用action
localActionChangeData () {
this.$store.dispatch('changeData').then(res => {
console.log(res)
})
}
},
// state不能跨module注册,action , mutation , getter 可以被映射到根节点直接访问
computed: {
...mapState({
userInfo: (state) => { return state.localState.userInfo },
address: (state) => { return state.localState.address },
department: (state) => { return state.localState.department }
}),
...mapGetters({
userDetails: 'getUserInfo'
})
}
}
</script>
<style lang="less" scoped>
.test {
justify-content: center;
align-items: center;
}
</style>
state.js
const localState = {
state: {
address: {
street: '江岸区五福路',
city: '武汉市',
country: '中国'
},
userInfo: {
userName: '肖大洋',
userAge: 31
},
department: [
'development',
'salor',
'changeMan'
]
},
// vuex的同步methods,异步操作需要在action中完成
mutations: {
// 没有载荷的mutation
gettingOlder (state) {
console.log('gettingOlder')
state.userInfo.userAge = state.userInfo.userAge + 1
},
// 拥有载荷的mutation
changeUserName (state, payload) {
console.log('changeUserName')
state.userInfo.userName = payload
},
// 使用type版本的mutation方法在尝试中没有调用成功
changeStreet (state, payload) {
console.log('changeStreet')
state.address.street = payload
}
},
// vuex的计算属性computed => getters
getters: {
// 将getUserDepartment作为vuex的过滤器
getUserDepartment: (state) => {
state.department.forEach(item => {
if (item === 'development') {
return item
}
})
return '没有'
},
getUserInfo: (state, getters) => {
let userInfo = state.userInfo
let address = state.address
let department = getters.getUserDepartment
let obj = { ...userInfo, ...address, department }
return obj
}
},
// 异步处理动作
// 实测vue中无法将异步操作的结果通过resolve回传给调用方法的.then()
actions: {
// 异步操作
async changeData ({commit, state}, payload) {
// 等待数据更新完毕后弹窗
await new Promise(function (resolve, reject) {
setTimeout(function () {
commit('gettingOlder')
commit('changeUserName', '毛大和')
commit('changeStreet', '湖北省武汉市')
}, 3000)
})
}
}
}
export default localState
index.js
import Vue from 'vue'
import Vuex from 'vuex'
import count from './modules/count.js'
import localState from './modules/state.js'
Vue.use(Vuex)
const store = new Vuex.Store({
state: {},
mutations: {},
actions: {},
modules: {
count,
localState
}
})
export default store