目录
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。 (官网介绍)
解读概念:
专门在Vue中实现集中式状态(数据)管理的一个Vue插件,对vue应用中多个组件的共享状态进行集中式的管理(读/写),也是一种组件间通信的方式,且适用于任意组件间通信。
让我们从一个简单的 Vue 计数应用开始:
- const Counter = {
- // 状态
- data () {
- return {
- count: 0
- }
- },
- // 视图
- template: `
- {{ count }}
- `,
- // 操作
- methods: {
- increment () {
- this.count++
- }
- }
- }
-
- createApp(Counter).mount('#app')
这个状态自管理应用包含以下几个部分:
以下是一个表示“单向数据流”理念的简单示意:
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。这就是 Vuex 背后的基本思想.
当你无法很好进行数据管理的时候,多个组件需要共享数据时,你更需要用Vuex,即:
1.多个组件依赖于同一状态
2.来自不同组件的行为需要变更为同一状态
通过全局事件总线多组件数据共享来看vuex:
如果组件过多且需要数据共享,那么全局事件总线实现数据共享就太过麻烦,此时如果使用vuex便可以更好的进行数据管理。
使用总结:Vuex 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果您不打算开发大型单页应用,使用 Vuex 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
一个例子让你理解工作原理:把store表示饭店,把Vue components比作去餐厅吃饭的客人,Actions比作服务员,Mutations比作后厨团队,State比作吃到嘴里的菜。store.dispath(‘jia’,2)比作点餐,点多少份;store.commit则为服务员手里的点餐宝或者点餐软件把你需要的餐告诉后厨团队。
注意,异步操作被封装在了Actions中,Actions中jia:function的function函数中调用commit('jia',2)。
Actions里面执行异步操作,Mutations执行同步操作。看似Action很多余,其实不然,那么Action到底有什么用呢?
Actions的作用在于当你进行一个动作,但是这个动作所对应的值需要发送ajax请求才能获取的时候,此时就需要在Actions中发送ajax请求给Backend API。就像下面的dispath('chu')只有动作没有值,需要Actions发送ajax请求获取值。 只有Actions能够处理逻辑操作。
但其实vue允许跳过Action,在组件中直接调用commit与Mutations对话,只是在图中没有体现出来。(例子中如果客人足够熟悉菜单,当然可以直接跟后厨对话点餐)
npm install vuex@版本
Vue.use(Vuex)
store
vc==>store
- Vue2项目安装:
- npm install vuex@3
-
- Vue3项目安装:
- npm install vuex@4
1.创建文件:src/store/index.js
- //引入Vue核心库
- import Vue from 'vue'
- //引入Vuex
- import Vuex from 'vuex'
- //应用Vuex插件
- Vue.use(Vuex)
-
- //准备actions对象——响应组件中用户的动作
- const actions = {}
- //准备mutations对象——修改state中的数据
- const mutations = {}
- //准备state对象——保存具体的数据
- const state = {}
-
- //创建并暴露store
- export default new Vuex.Store({
- actions,
- mutations,
- state
- })
2.在main.js
中创建vm时传入store
配置项
- ......
- //引入store
- import store from './store'
- ......
-
- //创建vm
- new Vue({
- el:'#app',
- render: h => h(App),
- store
- })
以后,文件夹看见store就相当于看到了vuex
1.初始化数据、配置
actions
、配置mutations
,操作文件store.js
- //引入Vue核心库
- import Vue from 'vue'
- //引入Vuex
- import Vuex from 'vuex'
- //引用Vuex
- Vue.use(Vuex)
-
- const actions = {
- //响应组件中加的动作
- jia(context,value){
- // console.log('actions中的jia被调用了',miniStore,value)
- context.commit('JIA',value)
- },
- }
-
- const mutations = {
- //执行加
- JIA(state,value){
- // console.log('mutations中的JIA被调用了',state,value)
- state.sum += value
- }
- }
-
- //初始化数据
- const state = {
- sum:0
- }
-
- //创建并暴露store
- export default new Vuex.Store({
- actions,
- mutations,
- state,
- })
2.组件中读取vuex中的数据:
$store.state.sum
3.组件中修改vuex中的数据:
$store.dispatch('action中的方法名',数据)
或$store.commit('mutations中的方法名',数据)
备注:若没有网络请求或其他业务逻辑,组件中也可以越过actions,即不写
dispatch
,直接编写commit
src/store/index.js
- //该文件用于创建Vuex中最为核心的store
-
- import Vue from 'vue'
- //引入Vuex
- import Vuex from 'vuex'
- //应用Vuex插件
- Vue.use(Vuex)
-
- //准备actions——用于响应组件中的动作
- const actions = {
-
- }
- }
- //准备mutations——用于操作数据(state)
- const mutations = {
-
- }
- //准备state——用于存储数据
- const state = {
-
- }
-
- //创建并暴露store
- export default new Vuex.Store({
- actions,
- mutations,
- state,
- })
src/main.js
- //引入Vue
- import Vue from 'vue'
- //引入App
- import App from './App.vue'
- //引入插件
- import vueResource from 'vue-resource'
- //引入store
- import store from './store'
-
- //关闭Vue的生产提示
- Vue.config.productionTip = false
- //使用插件
- Vue.use(vueResource)
-
- //创建vm
- new Vue({
- el:'#app',
- render: h => h(App),
- store,
- beforeCreate() {
- Vue.prototype.$bus = this
- }
- })
vuex中一共有五个状态 State Getter Mutation Action Module 下面进行详细讲解
提供唯一的公共数据源,所有共享的数据统一放到store的state进行储存,相似与data
在vuex中state中定义数据,可以在任何组件中进行调用
- import Vue from 'vue'
- import Vuex from 'vuex'
-
- Vue.use(Vuex)
-
- export default new Vuex.Store({
- //数据,相当于data
- state: {
- name:"张三",
- age:12,
- count:0
- },
- })
调用:
方法一:
在标签中直接使用
方法二:
this.$store.state.全局数据名称
方法三:
从vuex中按需导入mapstate函数
import { mapState } from "vuex";
注意:当前组件需要的全局数据,映射为当前组件computed属性
更改 Vuex 的 store 中的状态的唯一方法是提交 mutation。Vuex 中的 mutation 非常类似于事件:每个 mutation 都有一个字符串的事件类型 (type)和一个回调函数 (handler)。这个回调函数就是我们实际进行状态更改的地方,并且它会接受 state 作为第一个参数:
在vuex中定义:
其中参数state参数是必须的,也可以自己传递一个参数,如下代码,进行计数器的加减操作,加法操作时可以根据所传递参数大小进行相加,减法操作没有传参每次减一
在组件中使用:
定义两个按钮进行加减操作
方法一:
注意:使用commit触发Mutation操作
- methods:{
- //加法
- btn(){
- this.$store.commit("addcount",10) //每次加十
- }
- //减法
- btn1(){
- this.$store.commit("reduce")
- }
- }
方法二:
使用辅助函数进行操作,具体方法同上
Action和Mutation相似,Mutation 不能进行异步操作,若要进行异步操作,就得使用Action
在vuex中定义:
将上面的减法操作改为异步操作
在组件中使用:
方法一:
直接使用 dispatch触发Action函数
this.$store.dispatch("reduce")
方法二:
使用辅助函数
类似于vue中的computed,进行缓存,对于Store中的数据进行加工处理形成新的数据
具体操作类似于前几种,这里不做具体说明
当遇见大型项目时,数据量大,store就会显得很臃肿
为了解决以上问题,Vuex 允许我们将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割: