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.nconsole.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: {},})