Vuex 是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
这是官网对 vuex 的一个简单介绍,看到这段介绍大家可能有点懵,没有关系,接下来我会为大家讲解一下 vuex 的一些基本概念,咱也不会什么底层原理,但更多的还是教大家在实际工作中该怎么样使用
Vuex 状态管理核心
要想学会使用 Vuex 我们先来简单了解一下 vuex 中的几个核心概念
State
Vuex就是一个仓库,仓库里面放了很多对象。其中state就是数据源存放地,对应于一般Vue对象里面的data
data() {
return {
a: 'b',
b: 'a'
}
}
state里面存放的数据是响应式的,Vue组件从store中读取数据,若是store中的数据发生改变,依赖这个数据的组件也会发生更新
你可以把status看作成登录后的状态,这几个页面都依赖于这个状态显示相应的信息,但是有一个页面做了退出的操作,其他几个页面也会受到影响
Getter
1、getters 可以对 State进行计算操作,他就是 Store的计算属性
2、虽然在组件内也可以做计算属性,但是getters可以在多组件内复用
Mutation && Action
action 类似于 mutation
不同在于:Action 提交的是 Mutaion,而不是直接变更状态,mutation 是改变 store中状态的执行者,Action可以包含任意异步操作,而 mutation 只能是同步操作
什么情况下应该使用 Vuex?
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式 就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
很常见应用场景如:
- 购物城功能
- 登录状态
...
使用 Vuex 的优势
- 多层嵌套的组件、兄弟组件间的状态会更好管理维护
- 缓存一些当前要使用请求远程或本地的数据集(刷新后会自己销毁)
- 有了第二条,就可以减少向服务器的请求,节省资源。如果你的用户足够多,那么每多出一个请求,对公司来说,都是一大笔钱
- 对开发者来说,如果你的项目足够复杂,团队的规模也不仅是一个人,数据集中处理更利于程序的稳定和维护
不多逼逼让我们在实践中学习 Vuex
Vuex 的案例
首先我们先通过 Vue Cli 脚手架生成一个vue 项目
$ vue create vuex-test
选择 Vuex 如果不选择我们后边需要单独安装,为了省事还是勾上吧
创建好项目后在你的项目根目录 src
下会有一个 store.js
文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
},
actions: {
}
})
我们看到这个 store.js
文件内容结构是这个样子,这是 vue-cli 帮我们生成项目的时候自动生成的,接下来我们就要基于这个模板来一步步完成我们的小案例
我们来撸 store.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count: 0
},
mutations: {
INCREMENT (state, num) {
state.count = state.count + num
},
DECREMENT (state, num) {
state.count = state.count - num
}
},
actions: {
increment: ({ commit }) => commit('INCREMENT', 1),
decrement: ({ commit }) => commit('DECREMENT', 1)
}
})
在这个文件中我们首先声明了一个状态 count
, 接着我们在 mutations
里写了两个方法来改变 count
的状态,之后我们又在 actions
里写了两个方法去调用 mutations
里的方法, 一个非常简单的逻辑
为了省事,我们直接在Vue CLI 创建的 模板中进行操作
App.vue
<template>
<div id="app">
<span>App组件: {{count}}</span>
<br>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<Home />
<About />
</div>
</template>
<script>
import { mapActions, mapState } from 'vuex'
import Home from './views/Home';
import About from './views/About';
export default {
components: {
Home,
About
},
computed: {
...mapState({
count: 'count'
// count: 'count', // 第一种写法
// count: (state) => state.count, // 第二种写法
})
},
methods: {
...mapActions({
increment: 'increment',
decrement: 'decrement'
})
}
}
</script>
<style>
#app {
width: 200px;
height: 200px;
margin: 200px auto;
}
</style>
上面我们简单的画了下页面,并引入了其他两个组件,在上面我们看到 mapStat
和 mapActions
这是什么鬼操作啊??
表面意思: mapState
是 state
的辅助函数,相应的 mapActions
就是 actions
的辅助函数
mapState
映射 this.count 为 store.state.countmapMutations
其实跟mapState 的作用是类似的,将组件中的 methods 映射为 store.commit 调用mapActions
将组件的 methods 映射为 store.dispatch 调用mapGetter
仅仅是将 store 中的 getter 映射到局部计算属性
这个页面的逻辑也很简单就是点击按钮对数据 +1 -1 的操作,当我们点击按钮的时候分别触发了 actions
里的 increment
和 decrement
方法。因为我们使用了mapActions
所以可以直接像普通方法一样去写 如果你不使用 mapActions
, 那么你的写法就必须是这样 this.$store.dispatch('xxxxx')
借用官网的图: 通过过mapActions 触发mutation 从而commit ,改变state的值
Home.vue
<template>
<div class="home">
Home组件: {{count}}
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
count: 'count'
})
},
}
</script>
在这个组件里我们打印出了 count 这个状态的值
About.vue
<template>
<div class="about">
About组件: {{count}}
</div>
</template>
<script>
import { mapState } from 'vuex'
export default {
computed: {
...mapState({
count: 'count'
})
},
}
</script>
在这个组件里我们打印出了 count 这个状态的值