深入理解Vuex的作用
什么是Vuex?
Vuex 是一个专门为 Vue.js 设计的状态管理库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
在一个典型的 Vue 应用中,组件之间的通信是通过 props 和事件进行的,这样简单的场景并没有问题,但是在大型的应用中,状态的管理会变得非常复杂。每一个子组件都需要用 props 来传递状态,或者用事件来触发状态的改变,这样既是极为繁琐且容易出错,也不容易维护和扩展。而使用 Vuex 可以高效地解决这个问题。
Vuex 是受到了 Flux 和 Redux 的启发,主要包含以下四个大的概念:
- state: 提供唯一的公共数据源,所有共享状态放置于此。
- mutations: 可以修改 state 的方法,但是是同步执行的,是Vuex中唯一的修改状态的方式。
- actions: 异步执行的操作,是可以包含任意异步操作的方法体,但是它不能直接修改 state。必须通过提交 mutations 来调用 mutations 中的某个方法来修改状态。
- getters: 可以直接获取 state 中的数据的方法。
Vuex的几个重要概念
state
state 包含了应用中每个组件都需要的共享状态。通过定义 store 对象中的 state 属性。如下所示:
const store = new Vuex.Store({
state: {
count: 0
}
})
mutations
mutations 是唯一可以修改 state 数据的地方。Vuex 中的 mutations 和事件很像,每个 mutation 都有一个字符串的 事件类型 (type) 和 一个 回调函数 (handler)。
定义 mutations:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
// 变更状态都要通过提交 mutation
state.count++
}
}
})
提交 mutations:
store.commit('increment');
actions
actions 定义处理状态提交的异步操作。actions 函数接收一个 context 参数,这个参数提供了与 store 实例具有相同方法和属性的对象,比如 commit 方法、dispatch 方法、state 实例等等。
定义 actions:
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
},
decrement (state) {
state.count--
}
},
actions: {
incrementAsync ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
提交 actions:
store.dispatch('incrementAsync');
getters
getters 可以看作 store 的计算属性。它们会根据 store 中的 state 计算出新的值,并返回这些值。可以通过 getters 访问到 state。
定义 getters:
const store = new Vuex.Store({
state: {
todos: [
{ id: 1, text: '...', done: true },
{ id: 2, text: '...', done: false }
]
},
getters: {
doneTodos: state => {
return state.todos.filter(todo => todo.done)
}
}
})
使用 getters:
store.getters.doneTodos;
两个应用场景示例
场景一: 实现购物车功能
在购物车中,有很多的商品,每个商品都可以加入到购物车中,而且每个商品的数量都可以修改,我们使用Vuex来实现:
首先,定义状态:
const store= new Vuex.Store({
state:{
goods:[
{id:1, name:'item1', price:100, qty:10},
{id:2, name:'item2', price:200, qty:20},
{id:3, name:'item3', price:300, qty:30},
{id:4, name:'item4', price:400, qty:40},
]
},
mutations:{
incrementQty(state, index){
state.goods[index].qty++;
},
decrementQty(state, index){
state.goods[index].qty--;
},
clearGoods(state){
state.goods = [];
}
}
})
然后,在组件中,可以通过 computed 计算属性来获取 Vuex 中的状态或者通过 methods 方法来调用 mutations 中的函数,比如下面这个例子:
<template>
<div>
<table>
<thead>
<tr>
<th>商品名称</th>
<th>商品单价</th>
<th>商品数量</th>
</tr>
</thead>
<tbody>
<tr v-for="(good, index) in goods" :key="good.id">
<td>{{ good.name }}</td>
<td>{{ good.price }}</td>
<td>
<button @click="incrementQty(index)">+</button>
{{ good.qty }}
<button @click="decrementQty(index)">-</button>
</td>
</tr>
</tbody>
</table>
<button @click="clearGoods">清空购物车</button>
</div>
</template>
<script>
export default {
computed: {
goods() {
return this.$store.state.goods;
}
},
methods: {
incrementQty(index) {
this.$store.commit('incrementQty', index);
},
decrementQty(index) {
this.$store.commit('decrementQty', index);
},
clearGoods(){
this.$store.commit('clearGoods');
}
}
}
</script>
场景二: 利用Vuex传递登录状态信息
在网站中,登录状态是需要全局共享的,如果使用全局变量或者 sessionStorage,虽然能够完成数据共享,但是不易管理。而Vuex则在这种情况下显得非常高效,我们可以通过 Vuex 传递登录状态信息。示例如下:
定义状态:
const store = new Vuex.Store({
state: {
isLoggedIn: false
},
mutations: {
login (state) {
state.isLoggedIn = true
},
logout (state) {
state.isLoggedIn = false
}
}
})
使用状态:
我们可以在组件的生命周期中读取状态值,如果状态值为 true,则代表用户已经登录:
export default {
mounted() {
if(this.$store.state.isLoggedIn){
// 用户已登录,执行相关操作
}else{
// 用户未登录,执行相关操作
}
}
}
同时,在登录和退出时,我们需要调用 mutations 改变状态,如下:
methods: {
login() {
// 登录操作
this.$store.commit('login');
},
logout(){
// 退出登录操作
this.$store.commit('logout');
}
}
总结
以上就是Vuex的基本使用方法和两个应用场景,其中包括状态、mutations、actions 以及 getters 的定义方式和使用方式。熟练使用Vuex能够大大简化组件间的通信,在管理大型应用的时候也非常有用。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:深入理解Vuex的作用 - Python技术站