Vuex使用详解
Vuex介绍
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
为什么要用vuex
如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
使用说明
由于Vuex 使用单一状态树,每个应用将仅仅包含一个 store 实例,因此在组件中使用vuex时一般创建一个store文件夹来存放store实例。
state基本使用
//store/index.js文件
import { createStore } from "vuex"
//创建一个store实例
const store=createStore({
state:()=>({
count:2
})
})
//将store实例暴露
export default store;
<!-- 组件app.vue文件 -->
<template>
<div class="app">
<!-- 直接使用state拿数据 -->
<h2>当前计数:{{ $store.state.count}}</h2>
<!-- 利用toRefs解构之后拿数据 -->
<h2>setup计数count:{{ count}}</h2>
</div>
</template>
<!-- options写法 -->
<!-- <script>
export default{
computed:{
storeCounter(){
return this.$store.state.counter
}
}
}
</script> -->
<!-- Composition方式 -->
<script setup>
import { useStore } from 'vuex';
import { toRefs } from "vue";
const store=useStore()
//在Composition API中使用直接解构
const { count}=toRefs(store.state)
</script>
//使用的时候一定不要忘了在main.js中使用use()方法使用store
createApp(App).use(store).mount('#app')
mapState辅助函数
// 在计算属性里面使用mapState辅助函数,映射我们需要映射的属性,这样使用的时候直接写属性名就好不用再通过$store.state.属性来获取state对象的属性
<script>
import { mapState } from 'vuex';
export default{
computed:{
...mapState(["age"])
}
}
</script>
<!--使用:直接利用属性名访问属性-->
<h2>options计数age:{{age}}</h2>
<h2>setup计数count:{{ count}}</h2>
getters基本使用
//getters中是支持进行属性的运算的,也可以在一个getters函数中使用其他的getter ,同时也支持在getters函数中返回函数
import { createStore } from "vuex"
const store=createStore({
state:()=>({
count:2,
age:20,
name:"bobe",
counts:0,
number:10,
users: [
{ id: 111, name: "hw", age: 20 },
{ id: 112, name: "ew", age: 34 },
{ id: 113, name: "as", age: 23 },
]
}),
getters:{
//实现count*2
doubleCount(state){
return state.count*2
},
//在getother中使用doubleCount
getOther(state,getters){
//返回state对象的name和doubleCount
return `name:${state.name}-${getters.doubleCount}`
},
//在backFun()中返回一个函数
backFun(state){
return function(id){
//利用users的id返回users数据
const users=state.users.find((item)=> item.id===id)
return users;
}
}
}
})
export default store;
<!-- 使用:$store.getters.xxx -->
<h2>doublecount:{{$store.getters.doubleCount}}</h2>
<h2>在getters中使用其他的getters:{{ $store.getters.getOther}}</h2>
<h2>在getters中返回函数:{{ $store.getters.backFun(111)}}</h2>
mapGetters辅助函数
<!-- 获取doubleCount -->
import { mapGetters } from 'vuex';
export default {
computed:{
...mapGetters(["doubleCount"])
}
}
</script>
//使用:直接利用getters函数访问即可
<h2>doublecount:{{doubleCount}}</h2>
mutations基本使用
//用于修改用户的状态
mutations:{
increment(state){
return state.count++
},
//修改state.name
changeName(state){
return state.name="kitty"
},
upDown(state,payload){
payload+=state.count
state.counts=payload
console.log( state.counts)
console.log(payload)
},
upNumber(state){
state.number++
}
}```
```javascript
<template>
<div class="app">
<h2>name:{{ $store.state.name}}</h2>
<button @click="changeName">修改name </button>
<h2>counts:{{ $store.state.counts}}</h2>
<button @click="upDown">测试函数参数</button>
</div>
</template>
<script>
export default {
computed:{
},
methods:{
//使用mutations
changeName(){
//使用:$store.commit("mutations函数名")
this.$store.commit("changeName")
},
upDown(){
this.$store.commit("upDown",1)
}
}
}
</script>
mapMutations辅助函数
<script>
import { mapMutations } from 'vuex';
export default {
computed:{
},
methods:{
...mapMutations(["changeName","upDown"])
},
}
</script>
actions基本使用
基本思路
由于Action 提交的是 mutation,而不是直接变更状态,
所以我们在使用actions时要先定义mutations,然后在actions中利用context.commit()将mutations,最后在组件中利用$store.dispatch()来改变状态
mutations:{
upNumber(state){
state.number++
}
},
actions:{
upNumber(context){
context.commit('upNumber')
}
}
<template>
<div class="app">
<h2>number:{{ $store.state.number}}</h2>
<button @click="upNumber">测试函数参数</button>
</div>
</template>
<script>
export default {
computed:{
},
methods:{
upNumber(){
this.$store.dispatch("upNumber")
}
},
}
</script>
<div class="app">
<h2>number:{{ $store.state.number}}</h2>
<button @click="upNumber">测试函数参数</button>
</div>
</template>
<script>
import { mapActions } from 'vuex';
export default {
computed:{
},
methods:{
...mapActions(["upNumber"])
}
}
</script>
Module基本使用
const counter = {
state: () => ({ counter:9 }),
mutations: { ... },
actions: { ... },
getters: { ... }
}
const moduleB = {
state: () => ({ ... }),
mutations: { ... },
actions: { ... }
}
const store = createStore({
modules: {
a: counter,
b: moduleB
}
})
//使用
<!-- 1,使用store时,需要state.moduleName.xxx -->
<h2>count模块的count:{{ $store.state.a.counter}}</h2>
<!-- 2,使用getters时,直接使用getters.xxx拿到store -->
<h2>count模块的doubleCounter:{{ $store.getters.doubleCount}}</h2>
说明
默认情况下,模块内部的 action 和 mutation 仍然是注册在全局命名空间的——这样使得多个模块能够对同一个 action 或 mutation 作出响应。
如果希望模块具有更高的封装度和复用性,你可以通过添加 namespaced: true属性 的方式使其成为带命名空间的模块。当模块被注册后,它的所有 getter、action 及 mutation 都会自动根据模块注册的路径调整命名。