最近又看了vue的文档,借此整理一下知识。用于自我加深理解
vueX是vue官方推出的状态管理机制。
上面一张图是核心
主要为:
State:存储数据
Mutation: 更改数据
Action: 暴露出来的方法,用来调用Mutation
vueX的推出极大方便了项目的维护,特别是大型项目中,数据的管理。VueX不推荐直接改变其数据源
vueX我们可以抽象为一个仓库,用来管理全局的数据,以达到不同实例之间的共同联通。
为什么不直接建立一个js文件来放数据呢?比如:
1 const dataStore = {} 2 3 4 //////////////////////// 5 6 const vm1 = new Vue({ 7 data: dataStore 8 }) 9 10 11 const vm2 = new Vue({ 12 data: dataStore 13 })
看似也行,当改变dataStore中的值,实例中的值也相应发生改变。但是这样会有一个问题,官方的说法是:调试将会变为噩梦。任何时间,我们应用中的任何部分,在任何数据改变后,都不会留下变更过的记录。
这里实现一个简单的vueX实例。
在确保引入vueX,以及在VUE实例上使用这个插件后
// Vue.use(vueX)
const Store = new Vuex.Store({ state: { name: '张三' }, mutations: { CHANGE_NAME(name) { state.name = name } } }) // ***************** // store.commit('CHANGE_NAME(', '李四') console.log(store.state.count) // 李四
当然还是不直接去操作mutations是一个比较好的做法,因为其是为了更好的追踪状态的变化,也便于维护, 所以就有Action是个不错的方式
这里还有两个概念就是modules和getters
modules:当vue的数据量逐渐增加,明显像上面直接使用state的话不太适合管理数据,此时我们可以用modules,将数据源分为一个又一个遍历管理的js文件
如:我有city.js和country.js来作为数据源
1 // city.js 2 const city = { 3 state: { 4 cityName: '' 5 }, 6 // mutations? 讲mutations封装到模块中便于管理,mutataions本身就不应该被直接调用 7 mutations: { 8 'SET_CITY': (state, city) => { 9 state.city = city 10 } 11 } 12 } 13 14 // 不要忘了引出 15 export default city 16 17 // country.js 18 19 const country = { 20 state: { 21 countryName: '' 22 }, 23 mutations: { 24 'SET_COUNTRY': (state, country) => { 25 state.country= country 26 } 27 } 28 } 29 30 export default country 31 32 33 // **************// 34 35 import city from './modules/book' 36 import country from './modules/store' 37 38 import Vue from 'vue' 39 import Vuex from 'vuex' 40 41 // 模块化,需要去vue实例中引入 42 export default new Vuex.Store({ 43 modules: { 44 city , 45 country 46 } 47 })
便于管理的vueX对项目的重构以及维护是很有帮助的,当然在模型(modules)加入actions,和getters也是可以的,主要看设计习惯。
1 store.state.city // 访问city 2 store.state.country // 访问country
getter:可以看做是store的计算属性,很明显state里存储的数据都是一个量而已,当数据需要再处理时,比如需要先筛选再返回给页面,特别是多个页面需要用到这个数据,这时候state就不够用了,就像计算属性一样,getter 的返回值会根据它的依赖被缓存起来,且只有当它的依赖值发生了改变才会被重新计算。
1 // 接着上面的例子 2 export default new Vuex.Store({ 3 modules: { 4 city , 5 country 6 }, 7 getters: { 8 // state是参数 9 realCityName: state => { 10 // 这里举个例子,正常不会筛选这么无聊的东西 11 return state.city.cityName.filter(todo => todo !== '') 12 } 13 } 14 }) 15 16 17 // 可以通过属性访问 18 store.getters.realCityName
getters还可以接收第二个参数getters
1 getters: { 2 // state是参数 3 realCityName: state => { 4 return state.city.cityName.filter(todo => todo !== '') 5 }, 6 cityLength: (state, getters) => { 7 return getter.realCityName.length 8 } 9 }
是否对通过store.state.xxx来获取Vuex中的内容感到繁琐。
Vuex提供了mapGetters和mapActions辅助函数
mapGetters辅助函数仅仅是将 store 中的 getter 映射到局部计算属性
mapActions辅助函数同理,将store中actions映射到组件局部的Methods
1 import { mapGetters, mapActions } from 'vuex' 2 3 export default { 4 computed: { 5 // 使用扩展运算符将getters混入到computed中 6 ...mapGetters([ 7 'fullCityName', 8 'cityNameLength']) 9 }, 10 methods: { 11 // 方法同理 12 XXX为具体方法名 13 ...mapActions(['XXXXX']) 14 } 15 }