Vuex的使用
一、Vuex的理解
每一个 Vuex 应用的核心就是 store(仓库)。“store”基本上就是一个容器,它包含着你的应用中大部分的状态 (state)。Vuex 和单纯的全局对象有以下两点不同:
-
Vuex 的状态存储是响应式的。当 Vue 组件从 store 中读取状态的时候,若 store 中的状态发生变化,那么相应的组件也会相应地得到高效更新。
-
你不能直接改变 store 中的状态。改变 store 中的状态的唯一途径就是显式地提交 (commit) mutation。这样使得我们可以方便地跟踪每一个状态的变化,从而让我们能够实现一些工具帮助我们更好地了解我们的应用。
二、使用场景
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
三、如何使用
1、state
state中数据的定义:
state.js
//state的存放方式
const state = {
items: []
}
export default state;
state中数据的读取:
Shop.vue
2、getters(计算属性)
getters计算属性的定义
getters.js
//返回state中items的内容
export const items = function (state) {
return state.items
}
//state.items的长度
export const sum = function (state) {
return state.items.length
}
getters计算属性的使用
Shop.vue
3、mutations
mutations方法的定义
小技巧:可以创建mutation-types.js来定义mutations中的方法名
/*mutation-types.js*/
export const FUN1 = 'FUN1'
export const FUN2 = 'FUN2'
/*mutations.js*/
import * as types from './mutation-types'
const mutations = {
//新增
[types.FUN1](state, arg) {
state.items.push({
id: arg.id,
title: arg.title,
price: arg.price,
num: 1,
})
},
//如果重复,只增加数量
[types.FUN2](state, arg) {
const cartItem = state.items.find(item => item.id === arg.id);
cartItem.num++;
}
}
export default mutations;
mutations方法的使用(在method中使用)
Shop.vue
<template>
<div>
<ul>
<li v-for="item in list" :key="item.id">
<h3>{{ item.title }}</h3>
<button @click="fun1(item)">添加到购物车</button>
</li>
</ul>
<h2>state中items:{{ $store.getters.items }}</h2>
<h2>state中items的长度:{{ sum }}</h2>
</div>
</template>
<script>
import { mapGetters, mapMutations } from "vuex";
export default {
data() {
return {
list: [
{
id: 1,
title: "物品1",
},
],
};
},
computed: {
...mapGetters(["sum", "items"]),
},
methods: {
add(item) {
this.$store.commit("FUN1", item);
},
...mapMutations({
fun1: "FUN1",
}),
},
};
</script>
<style>
li {
list-style: none;
}
</style>
4、actions
actions定义
/*actions.js*/
import * as types from './mutation-types'
export const addToCart = function ({ commit, state }, arg) {
const cartItem = state.items.find(item => item.id === arg.id);
if (!cartItem) {
commit(types.FUN1, { id: arg.id, title: arg.title })
} else {
commit(types.FUN2, cartItem)
}
}
actions的使用(在method中使用)
<!--Shop.vue-->
<template>
<div>
<ul>
<li v-for="item in list" :key="item.id">
<h3>{{ item.title }}</h3>
<button @click="fun1(item)">添加到购物车</button>
</li>
</ul>
<h2>state中items:{{ $store.getters.items }}</h2>
<h2>state中items的长度:{{ sum }}</h2>
</div>
</template>
<script>
import { mapGetters, mapActions } from "vuex";
export default {
data() {
return {
list: [
{
id: 1,
title: "物品1",
},
{
id: 2,
title: "物品2",
},
],
};
},
computed: {
...mapGetters(["sum", "items"]),
},
methods: {
add(item) {
this.$store.commit("FUN1", item);
},
// ...mapMutations({
// fun1: "FUN1",
// }),
...mapActions({
fun1: "addToCart",
}),
},
};
</script>
<style>
li {
list-style: none;
}
</style>