1.Vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。Vuex 也集成到 Vue 的官方调试工具 devtools extension ,提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
VueX
是适用于在Vue
项目开发时使用的状态管理工具。试想一下,如果在一个项目开发中频繁的使用组件传参的方式来同步data
中的值,一旦项目变得很庞大,管理和维护这些值将是相当棘手的工作。为此,Vue
为这些被多个组件频繁使用的值提供了一个统一管理的工具——VueX
。在具有VueX
的Vue项目中,我们只需要把这些值定义在VueX中,即可在整个Vue项目的组件中使用。
什么是状态模式?
这个状态自管理应用包含以下几个部分:
- state,驱动应用的数据源;
- view,以声明方式将 state 映射到视图;
- actions,响应在 view 上的用户输入导致的状态变化。
// 如果在模块化构建系统中,请确保在开头调用了 Vue.use(Vuex)
const store = new Vuex.Store({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
}
})
为什么要使用vueX
VueX是实现组件全局状态管理的一种机制,可以方便的实现组件之间数据的共享。一般情况下,只有组件之间共享的数据,才有必要存储在vuex中;对于组件的私有数据,已久存储在组件自身的data中即可。
使用vuex统一管理状态的好处
(1)能够在vuex中集中管理共享的数据,易于开发和后期维护
(2)能够高效地实现组件之间的数据共享,提交开发效率
(3)存储在vuex中的数据都是响应式的,能够实时保持数据页面的同步
2.起步
由于VueX
是在创建VueCli
后进行的,所以在下文出现的项目的目录请参照VueCli 2.x
构建的目录。以下步骤的前提是你已经完成了Vue项目构建,并且已转至该项目的文件目录下。
- npm安装Vuex
npm i vuex -s
- 文件夹结构
3.使用
- 初始化store文件夹下的index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
//挂载Vuex
Vue.use(Vuex)
//创建VueX对象
const store = new Vuex({
state:{
//存放的键值对就是所要管理的状态
name:'helloVueX'
}
})
export default store
-
将store挂载到当前项目的Vue实例当中去
打开main.js
import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
store, //store:store 和router一样,将我们创建的Vuex实例挂载到这个vue实例中
render: h => h(App)
})
- 在组件中使用vuex
例如在App.vue中,我们要将state中定义的count进行运算
<template>
<div>
<!--此处的this可以省略-->
<h1>{{this.$store.state.count}}</h1>
<button @click="addNum">+1</button>
</div>
</template>
-
在store文件夹下的index.js文件
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
count:0
},
mutations: {
},
actions: {
},
modules: {
}
})
运行得到
安装Vue开发工具VueDevtools
在Vue项目开发中,需要监控项目中得各种值,为了提高效率,Vue提供了一款浏览器扩展——VueDevtools。
在学习VueX时,更为需要使用该插件。关于该插件的具体使用可以移步官网。
4.vueX的主要内容
在VueX对象中,其实不止有state
,还有用来操作state
中数据的方法集,以及当我们需要对state
中的数据需要加工的方法集等等成员。
成员列表:
- state 存放状态
- mutations state成员操作
- getters 加工state成员给外界
- actions 异步操作
- modules 模块化状态管理
VueX的工作流程
首先,Vue
组件如果调用某个VueX
的方法过程中需要向后端请求时或者说出现异步操作时,需要dispatch
VueX中actions
的方法,以保证数据的同步。可以说,action
的存在就是为了让mutations
中的方法能在异步操作中起作用。
如果没有异步操作,那么我们就可以直接在组件内提交状态中的Mutations
中自己编写的方法来达成对state
成员的操作。注意,不建议在组件中直接对state
中的成员进行操作,这是因为直接修改(例如:this.$store.state.name = 'hello'
)的话不能被VueDevtools
所监控到。
最后被修改后的state成员会被渲染到组件的原位置当中去。
Mutations
mutations
是操作state
数据的方法的集合,比如对该数据的修改、增加、删除等等。简单说就是操作state中的数据的。
Mutations使用方法
(1)方法一
this.$store.commit("方法名",参数)是触发mutations的第一种方式.
mutations
方法都有默认的形参:
([state] [,payload])
state
是当前VueX
对象中的state
payload
是该方法在被调用时传递参数使用的
在index.js中定义:
mutations: {
//点击按钮进行+1操作
addNumFun(state){
state.count++
}
},
在App.vue中进行调用:
methods:{
// 点击按钮进行+1操作
addNum(){
// commit的作用就是调用某个mutation函数
this.$store.commit("addNumFun")
}
}
运行结果:
(2)方法二
在vue中进行按需导入
// 从Vuex中按需导入mapMutations函数
import {mapMutations} from "vuex"
在vue的methods中:
// 将指定的mutation函数,映射到当前组件的Methods函数
...mapMutations(["addNumFun"]),
addNum(){
this.addNumFun()
}
运行得到同样的结果。
Getters
可以对state中的成员加工后传递给外界
Getters中的方法有两个默认参数
- state 当前VueX对象中的状态对象
- getters 当前getters对象,用于将getters下的其他getter拿来用
- Getter用于对Store中的数据进行加工处理后形成新的数据,类似于Vue的计算属性
Store中数据发生变化,Getter的数据也会发生变化
index.js
getters:{
showNum(state) {
return '当前最新的数量是:[' + state.count + ']'
}
}
App.vue
//按需导入
import { mapGetters } from "vuex";
computed:{
// 将全局数据映射为当前组件的计算属性
...mapGetters(["showNum"])
}
运行得到:
Actions
由于直接在mutation
方法中进行异步操作,将会引起数据失效。所以提供了Actions来专门进行异步操作,最终提交mutation
方法。
Actions
中的方法有两个默认参数
context
上下文(相当于箭头函数中的this)对象payload
挂载参数
注意:mutations中不能使用异步函数,actions中可以用来建立异步函数。
index.js
// 可以用来存储异步函数
actions: {
addAsync(context) {
setTimeout(() => {
// 在actions中,不能直接修改state中的数据
// 必须通过 context.commit()进行触发某个mumation才行
context.commit('addNumFun')
}, 1000)
}
},
(1)第一种调用方式
App.vue
// 异步地让count自增+1
btnAddNumAuto(){
// 这里的dispatch函数,专门用来触发action
this.$store.dispatch("addAsync");
}
运行结果:
(2)第二种调用方式
// 从vuex中按需导入mapActions函数
import {mapActions} from "vuex"
...mapActions(["subAsync"]),
运行结果:
规范目录结构
如果把整个store
都放在index.js
中是不合理的,所以需要拆分。比较合适的目录格式如下:
store:.
│ actions.js
│ getters.js
│ index.js
│ mutations.js
│ mutations_type.js ##该项为存放mutaions方法常量的文件,按需要可加入
│
└─modules
Astore.js
对应的内容存放在对应的文件中,和以前一样,在index.js
中存放并导出store
。state
中的数据尽量放在index.js
中。而modules
中的Astore
局部模块状态如果多的话也可以进行细分。