vuex个人的理解是全局状态管理更合适;简单的理解就是你在state中定义了一个数据之后,你可以在所在项目中的任何一个组件里进行获取、进行修改,并且你的修改可以得到全局的响应变更。
1,先分析Vuex的组成:(官方文档比较详细)
- Store
表示对Vuex对象的全局引用。组件通过Store来访问Vuex对象中的State(下面讲到) - State
Vuex对象的状态,即其所拥有的数据 - Getter
相当于Store的计算属性。因为就像计算属性一样,Getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。下面会说到具体的使用场景 - Mutation
定义了对State中数据的修改操作。组件使用State中的数据的时候并不能直接对数据进行修改操作,需要调用Mutation定义的操作来实现对数据的修改。这也是Vuex定义中所说的用相应的规则来让数据发生变化的具体实现 - Action
Mutation中定义的操作只能执行同步操作,Vuex中的异步操作在Action中进行,Action最终通过调用Mutation的操作来更新数据 - Module
Store和State之间的一层,便于大型项目管理,Store包含多个Module,Module包含State、Mutation和Action
接下来我们开始
第一步安装:
使用:npm install vuex --save
第二步:在src目录下新建一个store文件夹再在该文件下创建一个 store.js 文件(引入Vuex)
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 全局调用
const store = new Vuex.Store((
))
export default store
第三步:在 main.js里面引入store.js,然后再全局注入一下,这样一来就可以在任何一个组件里面使用this.$store了
import store from './store/store' // 引入store
new Vue({
···
store,//使用store
···
})
基本工作就做得差不多了,现在就来编写store.js 文件,在开始的时候对vuex 的文件格式进行了一个简单分析:我们先声明一个state变量,并赋值一个空对象给它,里面随便定义两个初始属性值;然后再在实例化的Vuex.Store里面传入一个空对象,并把刚声明的变量state放里面
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 全局变量
const state = { // 设置全局访问的state对象
show: true,
changableNum: 0
}
// 全局调用
const store = new Vuex.Store((
state
))
export default store
做完上面的三个步骤后,我们就可以用this.store.state.show或this.store.state.changebleNum在任何一个组件里面获取show和changebleNum定义的值了,但这不是理想的获取方式;vuex官方API提供了一个getters,和vue计算属性computed一样,来实时监听state值的变化(最新状态),并把它也仍进Vuex.Store里面
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 全局变量
const state = { // 设置全局访问的state对象
show: true,
changableNum: 0
}
// 监听全局变量的改变
const getters = { // 实时监听state值的变化(最新状态)
isShows (state) { // 方法名随意,主要是来承载变化的show的值
return state.show
},
getchangableNum () { // 方法名随意用来承载变化的changableNum的值
return state.changableNum
}
}
// 全局调用
const store = new Vuex.Store((
state,
getters
))
export default store
定义了对State中数据的修改操作。组件使用State中的数据的时候并不能直接对数据进行修改操作,需要调用Mutation定义的操作来实现对数据的修改。这也是Vuex定义中所说的用相应的规则来让数据发生变化的具体实现,具体的用法就是给里面的方法传入参数state或额外的参数,然后利用vue的双向数据驱动进行值的改变,同样的定义好之后也把这个mutations扔进Vuex.Store里面,如下:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 全局变量
const state = { // 设置全局访问的state对象
show: true,
changableNum: 0
}
// 监听全局变量的改变
const getters = { // 实时监听state值的变化(最新状态)
isShows (state) { // 方法名随意,主要是来承载变化的show的值
return state.show
},
getchangableNum () { // 方法名随意用来承载变化的changableNum的值
return state.changableNum
}
}
// 修改state中的参数方法
const mutations = {
show (state) { // 自定义改变state初始值的方法,这里面的参数除了state之外还可以再传额外的参数(变量或对象);
state.show = true
},
hide (state) { // 同上
state.show = false
},
newNum (state, sum) { // 这里面的参数除了state之外还传了需要增加的值sum
state.changableNum += sum
}
}
// 全局调用
const store = new Vuex.Store((
state,
getters,
mutations
))
export default store
Mutation中定义的操作只能执行同步操作这肯定不是我们想要的结果,Vuex中的异步操作在Action中进行,Action最终通过调用Mutation的操作来更新数据,actions里面自定义的函数接收一个context参数和要变化的形参,context与store实例具有相同的方法和属性,所以它可以执行context.commit(’ ')
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
// 全局变量
const state = { // 设置全局访问的state对象
show: true,
changableNum: 0
}
// 监听全局变量的改变
const getters = { // 实时监听state值的变化(最新状态)
isShows (state) { // 方法名随意,主要是来承载变化的show的值
return state.show
},
getchangableNum () { // 方法名随意用来承载变化的changableNum的值
return state.changableNum
}
}
// 修改state中的参数方法
const mutations = {
show (state) { // 自定义改变state初始值的方法,这里面的参数除了state之外还可以再传额外的参数(变量或对象);
state.show = true
},
hide (state) { // 同上
state.show = false
},
newNum (state, sum) { // 这里面的参数除了state之外还传了需要增加的值sum
state.changableNum += sum
}
}
// 实现异步调用修改参数值方法
const actions = {
hide (context) {
context.commit('hide')
},
show (context) {
context.commit('show')
},
getNewNum (context, num) {
context.commit('newNum', num)
}
}
// 全局调用
const store = new Vuex.Store((
state,
getters,
mutations,
actions
))
export default store
而在外部组件里进行全局执行actions里面方法的时候,你只需要用执行
this.$store.dispatch(‘hide’)
或this.$store.dispatch(‘show’)
以及this.$store.dispatch(‘getNewNum’,6) //6要变化的实参
这样就可以全局改变改变show或changebleNum的值了,如下面的组件中,需求是跳转组件页面后,根据当前所在的路由页面进行隐藏或显示页面底部的tabs选项卡
<template>
<div class="login-warp">
<title_bar1></title_bar1>
<input1 v-if="isShow"></input1>
</div>
</template>
<script>
export default {
name: 'login',
components: {
title_bar1: () => import('@/components/plugin/title'),
input1: () => import('@/components/plugin/input')
},
data () {
return {
}
},
computed: {
isShow: function () {
return this.$store.getters.isShows
}
},
watch: {
$route (to, from) { // 跳转组件页面后,监听路由参数中对应的当前页面以及上一个页面
if (// 根据你的需求来控制) {
this.$store.dispatch('show')
} else {
this.$store.dispatch('show')
}
}
}
}
</script>
到这里就可以做到全局响应状态的改变了!
还剩下一个Module 模块化,未完待续。。。。。