VueX
VueX
是一个专为 Vue.js 应用程序开发的状态管理模式。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化。VueX
也集成到 Vue 的官方调试工具 devtools extension (opens new window),提供了诸如零配置的 time-travel 调试、状态快照导入导出等高级调试功能。
VueX 是vue的状态管理工具
使用Vuex统一管理状态的好处:
- 能够在Vuex中集中管理共享的数据,易于开发和后期维护
- 能够高效的实现组件之间的数据共享,提高开发效率
- 存储在Vuex中的数据都是响应式的,能够实时保证数据与页面的同步
这个状态自管理应用包含以下几个部分:
state
,驱动应用的数据源;view
,以声明方式将 state 映射到视图;actions
,响应在 view 上的用户输入导致的状态变化。
以下是一个表示“单向数据流”理念的简单示意:
但是,当我们的应用遇到多个组件共享状态时,单向数据流的简洁性很容易被破坏:
- 多个视图依赖于同一状态。
- 来自不同视图的行为需要变更同一状态。
对于问题一,传参的方法对于多层嵌套的组件将会非常繁琐,并且对于兄弟组件间的状态传递无能为力。对于问题二,我们经常会采用父子组件直接引用或者通过事件来变更和同步状态的多份拷贝。以上的这些模式非常脆弱,通常会导致无法维护的代码。
因此,我们为什么不把组件的共享状态抽取出来,以一个全局单例模式管理呢?在这种模式下,我们的组件树构成了一个巨大的“视图”,不管在树的哪个位置,任何组件都能获取状态或者触发行为!
通过定义和隔离状态管理中的各种概念并通过强制规则维持视图和状态间的独立性,我们的代码将会变得更结构化且易维护。
VueX 可以帮助我们管理共享状态,并附带了更多的概念和框架。这需要对短期和长期效益进行权衡。
如果不打算开发大型单页应用,使用 VueX 可能是繁琐冗余的。确实是如此——如果您的应用够简单,您最好不要使用 Vuex。一个简单的 store 模式就足够您所需了。但是,如果您需要构建一个中大型单页应用,您很可能会考虑如何更好地在组件外部管理状态,Vuex 将会成为自然而然的选择。
Vue集成Vuex
下载Vuex
npm i vuex -S
使用
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
配置示例
import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({
//state中存放的就是全局共享的数据
state:{ name:mahe666 }
})
export default store
导出配置的store,然后在 main.js
的vue示例中导入并注册
import store from '@/store'
new Vue({
store,
render: h => h(App),
}).$mount('#app')
核心概念
Vuex的主要核心功能如下
State
提供唯一公共数据源,所有共享的数据都要放到Store的State中进行存储
Mutation
用于变更Store中的数据
- Vue中,只能通过 Mutation 变更Store数据,不可以直接操作Store中的数据
- 通过这种方式虽然操作起来稍微繁琐一些,但是可以集中监控所有数据的变化
Action
用于异步地调用Mutation方法
Getter
Getter 用于对 Store 中的数据进行加工处理形成新的数据(Getter不会修改原有的数据)
- Getter对Store中原有的数据进行加工处理后形成的新数据,类似于Vue的计算属性
- Store 中数据发生变化,Getter的数据也会跟着变化
State
访问State中数据的第一种方式
this.$store.state.属性名
访问State中数据的第二种方式:
从Vuex中按需导入 mapState 函数
import {mapState} from 'vuex'
通过刚才导入的 mapState 函数,将当前组件需要的全局数据,映射为当前组件的 computed 计算属性:
computed:{
...mapState(['username']);
}
注意:在Vue中,不允许组件修改全局数据
Mutation
定义mutations的时候,在与state平级的位置定义
const store = new Vuex.store({
state:{
count:0
},
mutations:{
//事件处理函数
add(state){
//变更状态
state.count++
}
}
})
使用方式
第一种方式,在组件中调用mutations函数:
this.$store.commit('函数名')
第二种方式,按需导入 mapMutations
函数
通过刚才导入的 mapMutations
函数,将需要的 mutations
函数,映射为当前组件的methods方法
import { mapMutations } from 'vuex'
methods:{
...mapMutations(['add','addN'])
add(){
this.add();
this.addN(3);
}
}
注意:mutations中的方法不能是异步的
触发mutations时传递参数
const store = new Vuex.store({
state:{
count:0
},
mutations:{
//事件处理函数
addN(state,step){
//变更状态
state.count += step
}
}
})
传递参数
this.$store.commit('函数名','实参')
Action
异步调用mutations方法
在store对象中按如下方式定义
const store = new Vuex.store({
state:{
count:0
},
mutations:{
//事件处理函数
add(state){
//变更状态
state.count++
}
},
actions:{
addAsync(context){
setTimeout(()=>{
//调用的是mutation中的方法
context.commit('add')
},1000)
}
}
})
触发Action的两种方式
methods:{
handle(){
this.$store.dispatch('addAsync')
}
}
//按需导入mapActions
import { mapActions } from 'vuex'
methods:{
...mapActions(['addAsync']),
addAsync(){
this.addAsync()
}
}
调用时如果需要携带参数,则需要将上述代码改动成下面的样子
const store = new Vuex.store({
state:{
count:0
},
mutations:{
//事件处理函数
add(state){
//变更状态
state.count++
}
},
actions:{
addAsync(context,step){
setTimeout(()=>{
//调用的是mutation中的方法
context.commit('add',step)
},1000)
}
}
})
methods:{
handle(){
this.$store.dispatch('addAsync',3)
}
}
import { mapActions } from 'vuex'
methods:{
...mapActions(['addAsync']),
addAsync(){
this.addAsync(3)
}
}
Getter
在与state平级的位置定义
getters:{
showUsername(state){
return '当前的用户为'+ state.username
}
}
this.$store.getters.名称
//导入
import { mapGetter } from 'vuex'
//在computed里面获取
computed:{
...mapGetter(['showUsername'])
}
在template中直接渲染就好
{{showUsername}}
Vuex数据持久化
相关博客: