1、Vuex是什么?
Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。
简而言之,Vuex采用类似全局对象的形式来管理所有组件的公用数据,如果想修改这个全局对象的数据,得按照Vuex提供的方式来修改(不能自己随意用自己的方式来修改)。
Vuex状态管理跟使用传统全局变量的不同之处:
1、Vuex的状态存储是响应式的:就是当你的组件使用到了这个Vuex的状态,一旦它改变了,所有关联的组件都会自动更新相对应的数据。
2、不能直接修改Vuex的状态:如果是传统全局对象变量,要修改很容易,但是在Vuex中不能这样做,想修改就得使用Vuex提供的唯一途径:提交(commint)mutations来实现修改
Vue有五个核心概念,state, getters, mutations, actions, modules。接下来将对这个五个核心概念进行梳理。
State:State 意为“状态”,是 vuex 状态管理的数据源。类似于vue中的data
Getter:类似于computed,对state里的数据进行一些过滤,改造等等
Mutation:Mutaion 是 vuex 中改变 State 的唯一途径(严格模式下),并且只能是同步操作。
Action:一些对 State 的异步操作可以放在 Action 中,并通过在 Action 提交 Mutaion 变更状态。
Module:可以将 store 分割成模块(module)。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块——从上至下进行同样方式的分割
Vuex的工作流程:
总的来说,我们可以在组件中触发 Action,Action 则会提交 Mutation,Mutaion 会对 State 进行修改,组件再根据 State 、Getter 渲染页面。
2、应用场景
vuex 一般用于中大型 web 单页应用中对应用的状态进行管理,对于一些组件间关系较为简单的小型应用,使用 vuex 的必要性不是很大,因为完全可以用组件 prop 属性或者事件来完成父子组件之间的通信,vuex 更多地用于解决跨组件通信以及作为数据中心集中式存储数据。
使用 vuex 解决跨组件通信问题
跨组件通信一般指非父子组件间的通信,父子组件的通信一般可以通过以下方式:
1、通过 prop 属性实现父组件向子组件传递数据
2、通过在子组件中触发事件实现向父组件传递数据
非父子组件之间的通信一般通过一个空的 Vue 实例作为 中转站,也可以称之为 事件中心、event bus。
3、怎么用
3.1、安装
NPM
npm install vuex --save
Yarn
yarn add vuex
3.2、使用(五个核心概念)
基本工作:在项目的src目录下新增一个store文件夹,在该文件夹内创建一个js文件:
index.js
初始化store下index.js中的内容
import Vue from 'vue'
import Vuex from 'vuex'
//挂载Vuex
Vue.use(Vuex)
//创建VueX对象(store仓库)利用这个仓库对我们的代码进行管理
const store = new Vuex.Store({
state:{
}
})
export default store
将store挂载到当前项目的Vue实例当中去main.js
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue.config.productionTip = false
new Vue({
router,
store, //store:store 和router一样,将我们创建的Vuex实例挂载到这个vue实例中
render: h => h(App)
}).$mount('#app')
1、state
假设有一个全局状态count为10,那么我们就可以将其定义为state对象中的key和value作为全局状态供我们使用:
const store = new Vuex.Store({
state:{
//存放的键值对就是所要管理的状态
count:10
}
})
或在组件方法中使用
methods:{
print(){
console.log(this.$store.state.count)
}
}
2、Getters
可以认为,getters 是store的计算属性,类似于computed,对state里的数据进行一些过滤,改造等等
假设我们要在state.count的基础上获得一个新的值newCount,就适合使用getters对其进行改造。
index.js
const store = new Vuex.Store({
state:{
//存放的键值对就是所要管理的状态
count:10
},
getters:{
newCount:state => state.count * 5
}
})
在HelloWorld.vue中获取{{newCount}}:
computed:{
newCount(){
return this.$store.getters.newCount
}
}
3、Mutations
Vuex给我们提供修改仓库
store中的状态的唯一办法就是通过提交mutation,且必须是同步函数
在mutation中定义一个叫increase的函数,函数体就是我们要修改状态的一些操作。接受两个参数:要修改的数据(state)、自定义参数。
index.js
//创建VueX对象
const store = new Vuex.Store({
state:{
//存放的键值对就是所要管理的状态
count:10
},
mutations:{
//es6语法,等同edit:funcion(){...}
increase(state,value){
state.count += value
}
}
})
在HelloWorld.vue组件中提交时,字符串参数increase,就在index.js文件里对应的mutation中的increase,在组件中一般通过钩子或方法触发。
methods:{
getNewCount(){
this.$store.commit("increase",3)
}
}
在组件中获取count的方式:
<h1>{{ $store.state.count }}</h1>
<button @click="getNewCount">点击按钮改变count的值</button>
4、Action
1、用于提交 mutation,而不是直接变更状态,可以包含任意异步操作。
2、只有通过action=>mutations=>states,这个流程进行操作,具体步骤如下:
const store = new Vuex.Store({
state:{
//存放的键值对就是所要管理的状态
obj:{}
},
mutations:{
getParam(state,object) {
// 修改state中的数据
state.obj = object
}
},
actions:{
//处理异步操作
getParamSync(context,Object) {
setTimeout(()=>{
// 通过commit提交一个名为getParam的mutation
// action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation
context.commit('getParam',Object)
},3000)
}
}
})
在组件中使用
getObj() {
let name= 'john';
let age= '21';
let sex= 'man';
// 通过dispatch将方法getParamSync和多个参数{name,age,sex}传递给actions
this.$store.dispatch('getParamSync',{name,age,sex})
}
5. Modules
随着项目的复杂度增大,为了方便管理vuex,一般会将其按功能分割成不同的模块(Module),方便日后管理。每个模块拥有自己的 state、mutation、action、getter、甚至是嵌套子模块
结构:
store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import state from './state'
import mutations from './mutations'
import actions from './actions'
import getters from './getters'
import user from './module/user' // 模块A
Vue.use(Vuex)
export default new Vuex.Store({
actions,
getters,
state,
mutations,
modules: {
user
}
})
state.js
const state = {
//存放的键值对就是所要管理的状态
count:10,
obj:{}
}
export default state
getters.js
const getters = {
newCount:state => state.count * 5
}
export default getters
mutation.js
const mutations = {
//es6语法,等同edit:funcion(){...}
increase(state,value){
state.count += value
},
getParam(state,object) {
// 修改state中的数据
state.obj = object
}
}
export default mutations
actions.js
const actions = {
//处理异步操作
getParamSync(context,Object) {
setTimeout(()=>{
//通过commit提交一个名为getParam的mutation
//action 函数接受一个与 store 实例具有相同方法和属性的 context 对象,因此你可以调用 context.commit 提交一个 mutation
context.commit('getParam',Object)
},3000)
}
}
export default actions
感谢这位@猫老板的豆 大佬的文章让我受益匪浅。