VueX详解
如果项目中存在大量组件及公用数据,此时就可以考虑使用同一的数据管理工具—VueX。
VueX 是一个专为 Vue.js 应用程序开发的状态管理模式,VueX是实现组件全局状态(数据)管理的一种机制,可以方便的实现组件之间的数据共享。如果您不打算开发
大型单页应用
,使用 Vuex 可能是繁琐冗余的。如果您的应用够简单,最好不要使用VueX。使用Vuex管理数据
优势
:1.能够在vuex中集中管理共享的数据,便于开发和后期进行维护
2.能够高效的实现组件之间的数据共享,提高开发效率
3.存储在vuex中的数据是响应式的,当数据发生改变时,页面中的视图也会同步更新
4.vuex中的数据操作可以在开发阶段通过开发调试工具来进行追踪,便于开发
安装
npm i -S vuex@3 //这里的版本一定要与Vue-Cli的版本相对应 这里兼容的是Vue2.6以下
引入文件
//app.js
import Vue from 'vue'
import App from './App.vue'
import store from './store'
Vue.config.productionTip = false
new Vue({
store,
render: h => h(App)
}).$mount('#app')
配置文件
//一般在src/store/index.js
//index.js就是vuex的仓库
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
// 存放状态(全局状态数据) 必填项
num: 100,
newslist:[],
news:[],
},
mutations: {
// 对于state成员进行同步修改操作
/*
mutation 必须是同步函数, 每一条 mutation 被记录,devtools 都需要捕捉到前一状态和后一状 态的快照
*/
// payload 负荷,调用此方法时,你传入过来的数据 任意类型
addNum(state, payload = 1) {
state.num += payload
}
},
actions: {
// 进行异步操作,异步得到结果后通知mutation修改state成员
async actionNum({ commit }, payload) {
// 进行阻塞式异步网络请求
let ret = await get('你的后端请求地址')
// 在action中得到数据,交给mutation来完成对于state数据的更改
commit('addNum', ret.data.num)
}
},
getters: {
// 获取state中的数据,类似于组件中的计算属性 只要依赖项不发生改变就读缓存
getNum(state) {
return state.num > 103 ? state.num + '--保密@' : state.num
}
},
modules: {
// 模块化状态管理,多状态文件管理时使用 开发项目时多为多模块项目
dataA:modules1
dataB:modules2
}
// 当不同模块之间的方法命名一样的情况下,会造成方法同时调用的问题
// 在多模块vuex中会有配置 namespaced:true 开启命名空间
namespaced:true
})
如何获取VueX中的数据
在组件中可以通过 this.$store 得到 vuex 中的 state 数据。
<template>
<div>
<h3>我是state中的变量 {{ $store.state.num }} </h3>
<h3>我是直接调用getters中方法 {{$store.getters.getNum }} </h3>
<h3>我是通过组件的计算属性调用getters方法 {{ num }} </h3>
<hr />
<button @click="clickNum">点击同步操作num数据 让num+10</button>
<hr />
<button @click="clickAsyncNum">异步操作num数据</button>
<h3>没有开启命名空间的模块化 {{}} </h3>
</div>
</template>
<script>
// 模块化 没有开启命名空间 使用辅助函数方式(固定的这几种方法)来读取和操作vuex中的数据和方法
import { mapState, mapGetters, mapMutations, mapActions } from 'vuex'
// 统一指定命名空间名称
// 使用这个 可以直接访问指定模块 dataA 中的方法
//const{mapState,mapGetters,mapMutations,mapActions} =createNamespacedHelpers('dataA')
/**
...mapState('dataA',['newslist']) 变成=> ...mapState(['newslist'])
**/
export default {
// 可以利用计算属性来完成对于在vuex中获取state数据的简写
computed: {
num() {
return this.$store.getters.getNum
},
// 没有开启命名空间的模块化调用方法
// 数组中的元素,如果有模块化,则为modules中的key的名称,
...mapState(['news']),
// 如果没有模块化,则为state中的key名称
...mapState({
// key为自定义在当前组件中定义的名称(在当前组件使用),value就是在state方法中的变量
news: state => state.newslist
}),
// mapGetters中的元素它就是getters对象方法的名称
...mapGetters(['getNum']),
// key为自定义在当前组件中定义的名称(在当前组件使用),value就是在getters配置中的方法名称
...mapGetters({
news: 'getNum'
}),
//开启命名空间的模块化调用方法
// 参数1:就是moudles中的key的名称
// 参数2:对象或数组
...mapState('dataA',['newslist']),
...mapState('dataA', {
// 在这个组件中要用的变量: 默认回调 => 目标模块dataA中state方法的newslist变量
newslist: state => state.newslist
}),
// mapGetters中的元素它就是getters对象方法的名称
...mapGetters('news', ['lists']),
...mapGetters('news',{
lists: 'lists'
})
},
methods: {
clickNum() {
// 在组件中让vuex中的mutations方法来操作 通知它 同步
// commit 为执行mutations中函数的方法
// 参数1:mutations中的定义的方法名
// 参数2:payload数据 可选
this.$store.commit('addNum', 10)
// 开启命名空间模块化后
this.$store.commit('modules中声明的模块化文件名称/addNum', 10)
},
clickAsyncNum() {
// 参数1:actions配置中的方法名
// 参数2:可选项,传递的数据
this.$store.dispatch('actionNum', 1)
// 开启命名空间模块化后
this.$store.dispatch('modules中声明的模块化文件名称/actionNum', 1)
}
}
}
</script>
<style lang="scss" scoped></style>