状态管理Vuex
掌握Vuex实现全局状态管理的方式 目录:
- 问题
- Vuex 工作流程
- 下载
- 创建 Store
- state
- getters
- mutations
- actions
- module
问题
在不使用全局状态管理库时 应用状态组件管理 当多个组件需要共享使用同一个应用状态时 通过props 自定义事件在组件之间进行传递 在组件和组件之间的关系比较疏远时 使得应用的维护变的困难 在使用了全局状态管理库后 需要共享的应用状态被单独保存在一个独立组件的Store对象中 所有组件可以直接从这个对象中获取状态 省去了繁琐的组件状态传递过程 而且当 Store 中的状态发生变化后 组件会自动更新
Vuex 工作流程
- State:用保存应用状态(store.state)
- Action:用执行异步操作 不能在此处直接修改状态(dispatch)
- Mutation:用执行同步操作 修改state中的存储的应用状态(commit)
- Getter:vuex中的计算属性(store.getters)
- Module:模块 用对状态进行拆分
在组件开发者可以通过 dispatch 调用 Action 类型的方法执行异步操作 当异步操作执行完成后 在Action 方法中可以通过 commit 调用 mutation 类型的方法修改状态 当状态被修改后 视图更新
下载
Vuex 目前有两个版本 一个是3.6.2 另一个是 4.0.4 3.X的版本是供Vue2使用的 4.X 版本是供 Vue3使用的
创建 Store
在 src 下的 store 创建一个 index.js 文件
import {createStore} from "vuex"
export default createStore({})
在 src 下的 main.js 文件
import store from "./store"
const app = createApp(App)
app.use(store)
state
在应用状态对象中存储 username 状态
import {createStore} from "vuex"
export default createStore({
state: {
username: "张三"
}
})
在组件获取 username 状态
<template>
{{$store.state.username}}
</template>
<script>
import {useStore} from "vuex"
export default {
setup () {
const store = userStore()
console.log(store.state.username)
}
}
</script>
getters
是vuex 中的计算属性 基于现有状态计算出新的状态
import {createStore} from "vuex"
export default createStore({
getters: {
newUsername(state) {
return state.username + "小明"
}
}
})
<template>
{{$store.getters.newUsername}}
</template>
<script>
export default () {
setup () {
console.log(store.getters.newUsername)
}
}
</script>
mutations
是vuex 中用修改状态的方法
import {createStore} from "vuex"
export default createStore({
mutations: {
updateUsername(state, username) {
state.username = username
}
}
})
<template>
<button @click="$store.commit("updateUsername", "李四")">
change username
</button>
</template>
actions
在vuex 中 执行异步操作 当异步操作执行完成以后 可以通过commit 调用 mutation 方法来修改应用状态
import {createStore} from "vuex"
export default createStore({
actions: {
updateName(ctx) {
setTimeout(() => {
ctx.commit("updateName", "李四")
}, 1000)
}
}
})
<template>
<button @click="onClickHandler">button</button>
</template>
<script>
export default {
setup () {
const onClickHandler = () => {
store.dispatch("updateName")
}
return {onClickHandler}
}
}
</script>
module
描述: Vuex 允许开发者通过模块对状态进行拆分 允许开发者把不同状态代码拆分到不同的模块中 命名空间模块需要在模块对象中添加 namespaced:true选择
import {createStore} from "vuex"
const moduleA = {
namespaced: true,
state() {
return {name: "模块A"}
}
}
const modlueB = {
namespaced: true,
state () {
return {name: "模块B"}
}
}
export default createStore ({
modules: {
a: moduleA,
b: moduleB
}
})
<template>
{{$store.state['a'].name}}
{{$store.state['b'].name}}
</template>
import { createStore } from 'vuex'
const moduleA = {
namespaced: true,
getters: {
newName (state) {
return state.name + '😀'
}
}
}
const moduleB = {
namespaced: true,
getters: {
newName (state) {
return state.name + '😀'
}
}
}
export default createStore({
modules: {
a: moduleA,
b: moduleB
}
})
<template>
{{$store.getters['a/newName']}}
{{$store.getters['b/newName']}}
</template>
import { createStore } from 'vuex'
const moduleA = {
namespaced: true,
mutations: {
updateName (state) {
state.name = '我是模块A'
}
}
}
const moduleB = {
namespaced: true,
mutations: {
updateName (state) {
state.name = '我是模块B'
}
}
}
export default createStore({
modules: {
a: moduleA,
b: moduleB
}
})
<template>
{{$store.getters['a/newName']}}
{{$store.getters['b/newName']}}
<button @click="$store.commit('a/updateName')">update moduleA</button>
<button @click="$store.commit('b/updateName')">update moduleb</button>
</template>
|