Vuex 是一个专为 Vue.js 应用程序设计的状态管理模式和库,它集中管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。以下是关于 Vuex 的详细介绍:
State(状态)
它是 Vuex 中存储状态的地方,类似于普通 Vue 组件的 data
选项。所有组件的状态都存储在 Vuex 的 state
中,组件通过 mapState
或直接从 Vuex 中读取状态。
const store = new Vuex.Store({
state: {
count: 0
}
});
Getter(获取器)
类似于 Vue 组件中的计算属性,用于从 state
中派生出一些状态。Getter 接收 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);
}
}
});
Mutation(变异)
是修改 Vuex 中状态的唯一方法。Mutation 是同步函数,接收 state
作为第一个参数,接收额外的参数作为第二个参数。
例如:
const store = new Vuex.Store({
state: {
count: 1
},
mutations: {
increment(state) {
state.count++;
}
}
});
Action(动作)
类似于 Mutation,但它可以包含异步操作。Action 提交的是 Mutation,而不是直接修改状态。Action 接收一个上下文对象(包含 state
、commit
等方法)作为第一个参数。
例如:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++;
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment');
}, 1000);
}
}
});
Module(模块)
Vuex 允许将状态分割成模块(Module)。每个模块拥有自己的 state
、mutation
、action
和 getter
,使得代码更加模块化。
const moduleA = {
state: { ... },
mutations: { ... },
actions: { ... },
getters: { ... }
};
const moduleB = {
state: { ... },
mutations: { ... },
actions: { ... }
};
const store = new Vuex.Store({
modules: {
a: moduleA,
b: moduleB
}
});
Vuex 的核心是 store
,它是一个全局的存储对象,用于存储应用的状态。
组件通过 this.$store.state
或 mapState
辅助函数来读取状态。
当需要修改状态时,组件通过 this.$store.commit
提交一个 Mutation,Mutation 通过同步方式修改状态。
如果需要执行异步操作,组件通过 this.$store.dispatch
触发一个 Action,Action 内部再提交 Mutation 来修改状态。
Vuex 的状态更新是响应式的,当状态发生变化时,Vue 组件会自动更新
Vuex 主要用于管理全局状态,例如用户登录状态、主题切换、购物车数据等。
当应用的状态变得复杂,多个组件需要共享状态时,使用 Vuex 可以更好地管理状态。
集中管理状态:Vuex 将状态集中管理,避免了组件之间复杂的通信方式。
状态可预测:通过 Mutation 和 Action 的规则,确保状态的变化是可预测的。
方便调试:Vuex 提供了开发者工具,可以方便地查看状态的变化历史。
下面是一个完整的示例,展示如何将 Vuex 的逻辑写在一个单独的 JavaScript 文件中,并在 Vue 组件中使用它来修改姓名。
首先,创建一个名为 store.js
的文件,用于定义 Vuex 的逻辑。
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
// 使用 Vuex 插件
Vue.use(Vuex);
// 定义状态
const state = {
name: '张三' // 初始姓名
};
// 定义 Mutation
const mutations = {
// 修改姓名的 Mutation
setName(state, newName) {
state.name = newName;
}
};
// 创建 Vuex Store
export default new Vuex.Store({
state,
mutations
});
在主文件(如 main.js
或 app.js
)中引入 store.js
,并将其挂载到 Vue 实例中。
// main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store'; // 引入 Vuex Store
new Vue({
store, // 将 Vuex Store 挂载到 Vue 实例中
render: h => h(App)
}).$mount('#app');
在 Vue 组件中,通过 this.$store
来访问 Vuex 的状态和提交 Mutation。
当前姓名:{{ name }}
页面上显示当前姓名(初始为“张三”)。
用户可以在输入框中输入新的姓名,并点击“修改姓名”按钮。
点击按钮后,姓名会更新为输入框中的值,并且输入框清空。
状态存储:姓名存储在 Vuex 的 state
中。
修改状态:通过提交 Mutation(setName
)来修改状态。
组件交互:组件通过 this.$store.state
获取状态,通过 this.$store.commit
提交 Mutation。
mapState
是 Vuex 中的一个非常有用的辅助函数,它可以帮助我们更方便地在组件中生成与 Vuex 状态相关的计算属性,从而避免手动编写冗长的代码。使用 mapState
,可以从 Vuex 的 state
中直接提取出状态,并将其映射为组件的计算属性。
mapState
的作用mapState
的主要作用是简化从 Vuex 的 state
中提取状态的过程。它会根据传入的参数自动生成计算属性,并确保这些计算属性能够响应式地更新。
mapState
生成多个计算属性的示例假设我们有一个 Vuex Store,其中存储了用户的名字和年龄。我们希望在组件中使用 mapState
来生成对应的计算属性,并提供修改名字和年龄的功能。
在 store.js
文件中定义 Vuex 的状态、Mutation 和 Action。
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
name: '张三', // 初始名字
age: 20 // 初始年龄
};
const mutations = {
setName(state, newName) {
state.name = newName;
},
setAge(state, newAge) {
state.age = newAge;
}
};
export default new Vuex.Store({
state,
mutations
});
mapState
在 Vue 组件中,通过 mapState
生成计算属性,并提供修改名字和年龄的方法。
首先,需要从 vuex
中导入 mapState
:
import { mapState } from 'vuex';
然后,在组件中使用 mapState
来生成计算属性:
用户信息
名字:{{ name }}
年龄:{{ age }}
mapState
的不同用法mapState
可以接受多种参数形式,来生成不同的计算属性:
如果你只需要将 Vuex 的 state
中的状态直接映射为组件的计算属性,可以直接传递一个数组:
computed: {
...mapState(['name', 'age'])
}
这会生成两个计算属性 name
和 age
,它们的内容分别等于 Vuex 的 state.name
和 state.age
。
如果你需要对生成的计算属性进行重命名或进行一些额外的处理,可以通过对象映射的方式使用 mapState
:
computed: {
...mapState({
userName: state => state.name, // 将 Vuex 的 state.name 映射为计算属性 userName
userAge: state => state.age // 将 Vuex 的 state.age 映射为计算属性 userAge
})
}
在模板中,你可以直接使用 userName
和 userAge
,而不是 name
和 age
。
以下是完整的项目代码:
store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
name: '张三',
age: 20
};
const mutations = {
setName(state, newName) {
state.name = newName;
},
setAge(state, newAge) {
state.age = newAge;
}
};
export default new Vuex.Store({
state,
mutations
});
main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store';
new Vue({
store,
render: h => h(App)
}).$mount('#app');
组件(App.vue
)
用户信息
名字:{{ name }}
年龄:{{ age }}
mapState
是一个非常便捷的工具,可以简化从 Vuex 状态到组件计算属性的映射过程。
它可以接受数组或对象作为参数,满足不同的使用需求。
使用 mapState
可以让组件的代码更加简洁,也更容易维护。
mapMutations
是 Vuex 提供的一个辅助函数,用于简化在组件中提交 Mutation 的操作。它允许你直接在组件的方法中调用 Mutation,而无需手动使用 this.$store.commit
。这使得代码更加简洁,也更容易维护。
mapMutations
的作用mapMutations
的主要作用是将 Vuex 的 Mutation 映射为组件方法。它接受一个数组或对象作为参数,根据参数的类型生成对应的组件方法。
mapMutations
的示例假设我们有一个 Vuex Store,其中定义了修改名字和年龄的 Mutation。我们希望在组件中使用 mapMutations
来简化提交这些 Mutation 的操作。
store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
name: '张三',
age: 20
};
const mutations = {
setName(state, newName) {
state.name = newName;
},
setAge(state, newAge) {
state.age = newAge;
}
};
export default new Vuex.Store({
state,
mutations
});
main.js
import Vue from 'vue';
import App from './App.vue';
import store from './store';
new Vue({
store,
render: h => h(App)
}).$mount('#app');
组件(App.vue
)
用户信息
名字:{{ name }}
年龄:{{ age }}
mapMutations
是一个非常便捷的工具,可以简化在组件中提交 Mutation 的操作。
它可以接受数组或对象作为参数,满足不同的使用需求。
使用 mapMutations
可以让组件的代码更加简洁,也更容易维护。
mapActions
是 Vuex 提供的一个辅助函数,用于简化在组件中触发 Action 的操作。它允许你直接在组件的方法中调用 Action,而无需手动使用 this.$store.dispatch
。这使得代码更加简洁,也更容易维护。
mapActions
的作用mapActions
的主要作用是将 Vuex 的 Action 映射为组件方法。它接受一个数组或对象作为参数,根据参数的类型生成对应的组件方法。
mapActions
的示例假设我们有一个 Vuex Store,其中定义了修改名字和年龄的 Action。我们希望在组件中使用 mapActions
来简化触发这些 Action 的操作。
在 store.js
文件中定义 Vuex 的状态、Mutation 和 Action。
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
name: '张三', // 初始名字
age: 20 // 初始年龄
};
const mutations = {
setName(state, newName) {
state.name = newName;
},
setAge(state, newAge) {
state.age = newAge;
}
};
const actions = {
updateName({ commit }, newName) {
commit('setName', newName);
},
updateAge({ commit }, newAge) {
commit('setAge', newAge);
}
};
export default new Vuex.Store({
state,
mutations,
actions
});
mapActions
在 Vue 组件中,通过 mapActions
生成组件方法,并调用这些方法来触发 Action。
首先,需要从 vuex
中导入 mapActions
:
import { mapState, mapActions } from 'vuex';
然后,在组件中使用 mapActions
来生成方法:
用户信息
名字:{{ name }}
年龄:{{ age }}
mapActions
的不同用法mapActions
可以接受多种参数形式,来生成不同的组件方法:
如果你只需要将 Vuex 的 Action 直接映射为组件方法,可以直接传递一个数组:
methods: {
...mapActions(['updateName', 'updateAge'])
}
这会生成两个组件方法 updateName
和 updateAge
,它们的内容分别等于 this.$store.dispatch('updateName', ...)
和 this.$store.dispatch('updateAge', ...)
。
如果你需要对生成的组件方法进行重命名或进行一些额外的处理,可以通过对象映射的方式使用 mapActions
:
methods: {
...mapActions({
changeName: 'updateName', // 将 Vuex 的 updateName 映射为组件方法 changeName
changeAge: 'updateAge' // 将 Vuex 的 updateAge 映射为组件方法 changeAge
})
}
在模板中,你可以直接使用 changeName
和 changeAge
,而不是 updateName
和 updateAge
。
mapActions
是一个非常便捷的工具,可以简化在组件中触发 Action 的操作。
它可以接受数组或对象作为参数,满足不同的使用需求。
使用 mapActions
可以让组件的代码更加简洁,也更容易维护。
9.dispatch
方法 dispatch
是 Vuex 中用于触发 Action 的方法。它允许你在组件或其他地方调用 Vuex 的 Action,从而执行异步操作或一系列的 Mutation。dispatch
是 Vuex 中处理异步逻辑的核心方法,它提供了灵活的方式来管理复杂的状态更新。
dispatch
的作用dispatch
的主要作用是触发 Vuex 的 Action。Action 可以包含异步操作,如 API 请求、延时操作等。通过 dispatch
,你可以在组件中调用这些 Action,从而间接地修改 Vuex 的状态。
dispatch
的基本用法dispatch
的基本语法如下:
this.$store.dispatch('actionName', payload);
actionName
:要触发的 Action 的名称。
payload
:传递给 Action 的参数,可以是任何类型(字符串、数字、对象等)。
假设我们有一个 Vuex Store,其中定义了一个 Action 用于更新用户信息。我们将在组件中使用 dispatch
来触发这个 Action。
在 store.js
文件中定义 Vuex 的状态、Mutation 和 Action。
// store.js
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
const state = {
user: {
name: '张三',
age: 20
}
};
const mutations = {
updateUser(state, userData) {
state.user.name = userData.name;
state.user.age = userData.age;
}
};
const actions = {
updateUser({ commit }, userData) {
// 模拟异步操作
setTimeout(() => {
commit('updateUser', userData);
}, 1000);
}
};
export default new Vuex.Store({
state,
mutations,
actions
});
dispatch
在 Vue 组件中,通过 this.$store.dispatch
调用 Action。
用户信息
名字:{{ user.name }}
年龄:{{ user.age }}
dispatch
的高级用法dispatch
也可以返回一个 Promise,这使得你可以处理 Action 的异步结果。例如,你可以在 Action 中执行异步操作,并在组件中等待这些操作完成。
让 Action 返回一个 Promise:
const actions = {
updateUser({ commit }, userData) {
return new Promise((resolve, reject) => {
// 模拟异步操作
setTimeout(() => {
commit('updateUser', userData);
resolve();
}, 1000);
});
}
};
在组件中等待 Action 完成:
用户信息
名字:{{ user.name }}
年龄:{{ user.age }}
dispatch
是 Vuex 中用于触发 Action 的方法,允许你在组件或其他地方调用 Action。
基本用法:this.$store.dispatch('actionName', payload)
。
高级用法:dispatch
可以返回一个 Promise,使得你可以处理 Action 的异步结果。
灵活性:dispatch
是一个通用方法,可以在任何地方调用,适用于复杂的调用场景。