Vuex概述
Vuex 是一个专为 Vue.js 应用程序开发的状态管理库。它采用集中式存储管理应用的所有组件的状态,并以一种可预测的方式来保证状态以一种可预测的方式发生变化。
state状态
把公用的数据放到store里的state就行了,上面是vue2的代码,下面是vue3
import { createStore } from 'vuex'
export default createStore({
state: {
counter:0,
title:'标题'
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
},
})
访问state里的数据
有两种方法,
1.通过store直接访问
2.通过辅助函数
通过store直接访问
注意,在模板,组件,js模块中的写法是不一样的
这里又可以分成两种方法,二者效果一样
直接用$store.state
<template>
<nav>
<p>counter:{{$store.state.counter}}</p>
<p>{{$store.state.title}}</p>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view/>
</template>
<script>
export default {
created() {
console.log(this.$store)
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
写个计算属性
补充computed知识点
在
computed
属性中定义的storeCount
方法被视为一个计算属性,Vue 会自动追踪其依赖。当this.$store.state.count
的值变化时,storeCount
也会随之更新,从而实现响应式更新。这使得你能够在模板中直接使用storeCount
,而不需要手动管理状态的变化。简而言之,这种方式利用了 Vue 的响应式特性,确保了数据的同步和更新。
<template>
<nav>
<p>counter:{{counter}}</p>
<p>{{$store.state.title}}</p>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view/>
</template>
<script>
export default {
computed:{
counter(){
return this.$store.state.counter
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
通过辅助函数mapState访问
可以看到上面的方法其实有点麻烦,因为如果要多次访问的话,代码量大,看起来也不整洁。
用法:
详细解释
导入
mapState
:javascriptCopy Code
import { mapState } from 'vuex';
通过导入
mapState
,你可以在组件中使用这个函数。使用
mapState
:javascriptCopy Code
computed: { ...mapState(['count']) // 直接映射 state 中的 count }
mapState
接受一个字符串数组作为参数,这些字符串是 Vuex store 中 state 的属性名。- 这里的
['count']
表示你要将 Vuex store 中的count
状态映射到当前组件的计算属性中。展开运算符
...
:
...
是 ES6 的扩展运算符,它会将mapState
返回的对象中的属性展开到computed
中。- 这意味着
mapState(['count'])
会返回一个对象,例如{ count() { return this.$store.state.count; } }
,而展开运算符会将这个对象中的count
方法直接添加到computed
中。结果:
- 最终,组件中就可以通过
{{ count }}
来直接使用 Vuex store 中的count
状态了。由于计算属性的响应式特性,当 Vuex 中的count
发生变化时,组件会自动重新渲染。
试一下
<template>
<nav>
<p>{{ counter }}</p>
<p>{{ title }}</p>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</nav>
<router-view/>
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['counter','title'])
},
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
修改store里的数据
Mutations介绍
通过mutations可以提供修改数据的方法
注意!mutation的第一个参数都是state。而且最多只能有两个参数,如果想实现多个参数,那第二个参数就要包装成对象
在store中定义 Mutation
import { createStore } from 'vuex'
export default createStore({
state: {
count:0,
title:'标题'
},
getters: {
},
mutations: {
add(state,n){
state.count+=n
}
},
actions: {
},
modules: {
},
})
要调用 mutation
,需要使用 store.commit
方法
<template>
<nav>
<p>{{ count }}</p>
<p>{{ title }}</p>
<button @click="add">增加</button>
</nav>
<!-- <router-view/>-->
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['count','title'])
},
methods:{
add(){
this.$store.commit('add',3)
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
第二个参数要包装成对象的用法
add(state,obj){
state.count+=obj.n
console.log(obj.msg)
}
import { createStore } from 'vuex'
export default createStore({
state: {
count:0,
title:'标题'
},
getters: {
},
mutations: {
add(state,obj){
state.count+=obj.n
console.log(obj.msg)
}
},
actions: {
},
modules: {
},
})
add(){
this.$store.commit('add',{
n:3,msg:'哈哈'
})
}
<template>
<nav>
<p>{{ count }}</p>
<p>{{ title }}</p>
<button @click="add">增加</button>
</nav>
<!-- <router-view/>-->
</template>
<script>
import { mapState } from 'vuex';
export default {
computed: {
...mapState(['count','title'])
},
methods:{
add(){
this.$store.commit('add',{
n:3,msg:'哈哈'
})
}
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
练习
不能使用v-model双向绑定的方法。任何要修改仓库(store)里的数据,都要用mutation进行提交。
mapMutations介绍
mapMutations
是 Vuex 提供的一个辅助函数,用于简化组件中调用 mutations 的过程。它可以将 store 中的 mutation 映射为组件的方法,使得调用更简洁。
使用方法
导入
mapMutations
:import { mapMutations } from 'vuex';
在组件中使用:
在组件的
methods
中使用mapMutations
来映射 mutations。例如:export default { methods: { ...mapMutations(['increment', 'decrement']), // 你也可以指定方法名称 ...mapMutations({ add: 'increment', // 将 store 中的 increment 映射为组件的方法 add }) } }
<template>
<nav>
<p>{{ count }}</p>
<p>{{ title }}</p>
<button @click="add({n:2,msg:'增加'})">增加</button>
</nav>
<!-- <router-view/>-->
</template>
<script>
import { mapState,mapMutations } from 'vuex';
export default {
computed: {
...mapState(['count','title'])
},
methods:{
...mapMutations(['add'])
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
mapActions
这边就主要介绍辅助函数mapAction了
<template>
<nav>
<p>{{ count }}</p>
<p>{{ title }}</p>
<button @click="add(5)">增加</button>
<button @click="change">延迟增加</button>
</nav>
<!-- <router-view/>-->
</template>
<script>
import { mapState,mapMutations,mapActions } from 'vuex';
export default {
computed: {
...mapState(['count','title'])
},
methods:{
...mapMutations(['add']),
...mapActions(['change'])
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
import { createStore } from 'vuex'
export default createStore({
state: {
count:0,
title:'标题'
},
getters: {
},
mutations: {
add(state,n){
state.count+=n
}
},
actions: {
change(context,num){
setTimeout(()=>{
context.state.count+=10
},1000)
}
},
modules: {
},
})
mapGetter
注意!
1.getters函数的第一个参数是state
2.必须要有返回值
<template>
<nav>
<p>{{ count }}</p>
<p>{{ title }}</p>
<button @click="add(5)">增加</button>
<button @click="change">延迟增加</button>
<div>
<p>mapGetter函数:</p>
{{filterList}}
</div>
</nav>
<!-- <router-view/>-->
</template>
<script>
import { mapState,mapMutations,mapActions,mapGetters } from 'vuex';
export default {
computed: {
...mapState(['count','title']),
...mapGetters(['filterList'])
},
methods:{
...mapMutations(['add']),
...mapActions(['change'])
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
</style>
import { createStore } from 'vuex'
export default createStore({
state: {
count:0,
title:'标题',
list:[1,2,3,4,5,6,7,8]
},
getters: {
filterList(state){
return state.list.filter(i=>i>4)
}
},
mutations: {
add(state,n){
state.count+=n
}
},
actions: {
change(context,num){
setTimeout(()=>{
context.state.count+=10
},1000)
}
},
modules: {
},
})