Vuex
完整流程
- 从component修改State的值,首先通过dispatch。发布一个Actions。
- 在Actions中执行commit,修改mutations,mutations通过mutate修改State的值
- devtools记录每次改变State的记录,方便进行跟踪。直接通过组件修改state,devtools无法进行跟踪。
- mutations中只进行同步操作,Actions中进行异步操作(网络请求)
使用步骤
- 安装插件
Vue.use(Vuex)
- 创建对象
const store = new Vuex.Store({ })
- 导出
export default store
1.State:单一状态树
const store = new Vuex.Store({
state: {
count: 1000,
},
})
// 获取count
{{$store.state.count}}
2.Getters:可以认为是 store 的计算属性
接受一个参数 state
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
// 使用getters中的doneTodos
store.getters.doneTodos // -> [{ id: 1, text: '...', done: true }]
接受两个参数 state、其他getter
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
doneTodosCount: (state, getters) => {
return getters.doneTodos.length
}
}
通过getter传参:
getters: {
moreAgeStu(state){
return function (age){ // 接收参数age
// 根据传过来的age,过滤出比age大的stu
return state.stu.filter(s => s.age > age)
}
}
}
3.Mutations :mutations中的方法必须是同步的,方便使用devtools进行状态跟踪。
mutation中进行异步操作,会更新结果,但是无法进行状态跟踪
接受一个参数 state
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment (state) { // 接受 state 作为第一个参数
// 变更状态
state.count++
}
}
})
// 点一次,count+1
<button @click="add">+</button>
add(){
this.$store.commit('increment')
}
接受两个参数 state、其他参数
mutations: {
increCount(state,count){ // 接受 state、count两个参数
state.count += count
}
}
// 点一次,count增加传递的参数 -> 5
<button @click="addCount(5)">+5</button>
// 点一次,count增加传递的参数 -> 10
<button @click="addCount(10)">+10</button>
addCount(count){
this.$store.commit('increCount',count)
}
payload --------传递对象作为参数。载荷方式和对象方式进行分发:
addStu(state,payload){
// payload:stu{name:'hhh'},type:'addStu',就是传过来的整个对象
state.stu.push(payload.stu)
}
// 使用
addStu(){
const stu = {name:'hhh'}
this.$store.commit({ // 把整个对象作为参数payload
type:'addStu', //事件类型
stu
})
}
4.Action:Action 提交的是 mutation,而不是直接变更状态。Action 可以包含任意异步操作。
actions: {
increment (context) { // context上下文
context.commit('increment') // 提交一个mutation
},
adChange(context){
setTimeout(()=>{ // 进行异步操作
context.commit('changeStu') // 提交一个mutation
},1000)
}
}
// 使用
this.$store.dispatch('adChange') // 分发一个名为adChange的action
载荷方式和对象方式进行分发:
// action接受参数
adChange(context,payload){ // payload载荷
setTimeout(()=>{
context.commit('changeStu')
console.log(payload.message); // 上面传递过来的 message
payload.success() // 这里会输出success
},1000)
}
this.$store.dispatch('adChange',{
message:'message', // 传递的参数
success(){ // 用于获取action结果的回调函数
console.log('success');
}
})
promise方式进行分发:
// 为了获取action的结果,将action返回一个promise对象。
adChange(context,payload){
return new Promise ((resolve,reject)=>{
setTimeout(()=>{
context.commit('changeStu')
resolve('resolve成功了') // 成功之后,可以调用.then方法
},1000)
})
}
// 使用的时候,在dispatch中传递参数,在then中获取resolve的结果
this.$store
.dispatch('adChange','message') // 此处的dispatch就是promise
.then(res=>{
console.log(res); // resolve成功了
})
5.Modules:Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter。
module中的state使用
const moduleA = {
state:() => ({
moduleAText:'moduleAText'
}),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const store = new Vuex.Store({
modules: {
a: moduleA
}
})
store.state.a // -> moduleA 的状态
<h2>{{$store.state.a.moduleAText}}</h2> // -> 'moduleAText'
module中的getters使用
const moduleA = {
state: {
moduleAText:'moduleAText'
},
getters: {
// 1.直接使用当前moduleA中的state中的moduleAText
getModulesA:(state) => {
return state.moduleAText + '1111111'
},
// 2.直接使用当前moduleA中的getters中的getModulesA
getModulesB:(state,getters) => {
return getters.getModulesA + '2222222222'
},
// 3.直接使用根里面的rootState中的count
getModulesC:(state,getters,rootState) => {
return getters.getModulesB + rootState.count
}
},
}
modules中的mutations使用
const moduleA = {
state: {
moduleAText:'moduleAText'
},
mutations: {
mutationModulesA(state,payload){
state.moduleAText = payload
}
},
}
// 这个是按钮绑定的点击方法
upDateAname(){
// mutationModulesA方法会先在根state里面查找,如果找不到
// 再去modules里面查找这个方法
this.$store.commit('mutationModulesA','lisi')
}
module中的actions使用
const moduleA = {
state: {
moduleAText:'moduleAText'
},
mutations: {
mutationModulesA(state,payload){
state.moduleAText = payload
}
},
actions: {
asyncChangeA(context){
setTimeout(()=>{
// 提交mutations
// 这里会将state中的'moduleAText'修改成'wangwu'
context.commit('mutationModulesA','wangwu')
},1000)
}
},
}
// 这个是按钮绑定的点击事件
asyncUpDateAname(){
this.$store.dispatch('asyncChangeA')
}