npm install vuex@next --save
创建src/store/index.js
main.js中全局注册
// 引入创建的store/index.js
import store from './store'
// store注入到vue根实例
createApp(App).use(store)
import {createStore} from 'vuex'
export default createStore({
// 1、共享的状态(数据),相似于data
state: () => ({
user: {
name: 'kimi',
age: 18,
honor: [
'1-三好学生',
'1-优秀班干部',
'2-优秀班干部'
]
}
}),
// 2、有时候我们需要从 state 中派生出一些状态,如果有多个组件需要用到此属性,我们要么复制这个函数,或者抽取到一个共享函数然后在多处导入它,无论哪种方式都不是很理想
// 只能读取state中的状态
getters: {
/**
* 使用state - 获取个人荣誉的数量
*
* @param state 上面的state
* @returns
*/
getUserHonorNum(state) {
return state.user.honor.length
},
/**
* 使用getters
*
* @param state
* @param getters
* @returns
*/
getUserAvgHonorNum(state, getters) {
return getters.getUserHonorNum / 3
},
/**
* 传入自定义参数
*
* @param state
* @param getters
* @returns
*/
getUserAvgHonorNumber: (state, getters) => (year) => {
return getters.getUserHonorNum / year
}
},
// 3、更改 Vuex 的 store 中的状态(数据)的唯一方法是提交 mutation
// mutation中必须是同步函数
mutations: {
/**
* 使用state - 年龄+1
*
* @param state
*/
setAgeIncrement(state) {
state.user.age++
},
/**
* 传入自定义参数 - 单个
*
* @param state
* @param age
*/
setAge(state, age) {
state.user.age = age
},
/**
* 传入自定义参数 - 多个(需使用对象)
*
* @param state
* @param user
*/
setUser(state, user) {
state.user = user
}
},
// 4、actions类似于mutation都是修改state中的状态,但是actions提交的是mutation,而不是直接变更state中的状态
// actions可以包含任意异步操作
actions: {
/**
* 年龄+1,异步操作,2秒之后再执行
*
* @param context 与store实例具有相同方法和属性的对象(context.getters、context.commit、context.dispatch),但并不是store实例本身
*/
setAgeIncrement(context) {
setTimeout(() => {
context.commit('setAgeIncrement')
}, 2000)
},
/**
* 传入自定义参数 - 单个
*
* @param context
* @param age
*/
setAge(context, age) {
context.commit('setAge', age)
},
/**
* 传入自定义参数 - 多个(需使用对象)
*
* @param context
* @param user
*/
setUser(context, user) {
context.commit('setUser', user)
},
/**
* actions中的函数也可以调用actions中的其他函数
*
* @param context
*/
setAgeAdd(context) {
context.dispatch('setAgeIncrement').then(() => {
context.commit('setAgeIncrement')
})
}
},
// 5、由于使用单一状态树,应用的所有状态会集中到一个比较大的对象(store/index.js会变得很大),store对象就会变的很臃肿,为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)
modules: {
}
})
<script setup>
import {useStore} from 'vuex'
const store = useStore()
//1、访问state
store.state.user
//2、访问getters
store.getters.getUserHonorNum
store.getters.getUserAvgHonorNumber(6) //传入自定义参数
//3、修改state中的状态,调用mutations中的函数
store.commit('setAgeIncrement')
store.commit({type: 'setAgeIncrement'})//对象风格的提交方式
store.commit('setAge', 30)//传入自定义参数 - 单个
store.commit('setUser', {name: 'sally', age: 20})//传入自定义参数 - 多个
//4、修改state中的状态,调用actions中的函数(分发Action,Action通过store.dispatch方法触发,异步操作所以是回调方法)
store.dispatch('setAgeAdd').then(() => {
})
//对象风格的提交方式
store.dispatch({type: 'setAgeIncrement'}).then(() => {
})
//传入自定义参数 - 单个
store.dispatch('setAge', 20).then(() => {
})
//传入自定义参数 - 多个
store.dispatch('setUser', {name: 'sally', age: 20}).then(() => {
})
</script>
const user = {
state: () => ({
user: {
name: 'kimi',
age: 18,
honor: [
'1-三好学生',
'1-优秀班干部',
'2-优秀班干部'
]
}
}),
getters: {
/**
* @param state 该模块中的state
* @param getters 该模块中的getters
* @param rootState 所有模块的state
* @returns
*/
getUserHonorNum(state, getters, rootState) {
return state.user.honor.length
}
},
mutations: {
/**
* @param state 该模块中的state
*/
setAgeIncrement(state) {
state.user.age++
}
},
actions: {
/**
* @param context 与store实例具有相同方法和属性的对象(如下),但并不是store实例本身
* context.state
* context.getters
* context.commit
* context.dispatch
* context.rootState:所有模块的state
*/
setAgeIncrement(context) {
setTimeout(() => {
context.commit('setAgeIncrement')
}, 2000)
}
}
}
export default user
import {createStore} from 'vuex'
//引入user模块
import user from '@/store/modules/user'
export default createStore({
modules: {
user
}
})
<script setup>
import {useStore} from 'vuex'
const store = useStore()
//1、访问state(模块名.共享数据)
store.state.user.user
//2、不带命名空间时,模块内部的getter、mutation、action仍然是注册在全局命名空间的,所以访问这3个中的函数没有变化
store.getters.getUserHonorNum
const user = {
// 带命名空间
namespaced: true,
state: () => ({
user: {
name: 'kimi',
age: 18,
honor: [
'1-三好学生',
'1-优秀班干部',
'2-优秀班干部'
]
}
}),
getters: {
/**
* @param state 该模块中的state
* @param getters 该模块中的getters
* @param rootState 所有模块的state
* @param rootGetters 所有模块的getters
* @returns
*/
getUserHonorNum(state, getters, rootState, rootGetters) {
return state.user.honor.length
}
},
mutations: {
/**
* @param state 该模块中的state
*/
setAgeIncrement(state) {
state.user.age++
}
},
actions: {
/**
* @param context 与store实例具有相同方法和属性的对象(如下),但并不是store实例本身
* context.state
* context.getters
* context.commit
* context.dispatch
* context.rootState:所有模块的state
* context.rootGetters 所有模块的getters
*/
setAgeIncrement(context) {
setTimeout(() => {
context.commit('setAgeIncrement')
}, 1000)
}
}
}
export default user
import {createStore} from 'vuex'
//引入user模块
import user from '@/store/modules/user'
export default createStore({
modules: {
user
}
})
<script setup>
import {useStore} from 'vuex'
const store = useStore()
//1、访问state(模块名.共享数据)
store.state.user.user
//2、访问模块中的getters(模块名/函数名)
store.getters['user/getAge']
//3、访问模块中的mutations(模块名/函数名)
store.commit('user/setAgeIncrement')
//4、访问模块中的actions(模块名/函数名)
store.dispatch('user/setAgeIncrement').then(() => {
})