# uView简化Vuex写法的基本原理

vuex传统写法简单,但是也很繁琐:

  1. 我们需要在vuex中定义statemutations
  2. 我们需要在每个用到vuex变量的地方,都引入mapState,同时还要解构到computed中去
  3. 修改vuex变量的时候,还需要通过commit提交
  4. 由于vuex变量是保存在运行内存中的,刷新浏览器vuex变量会消失,还需要通过其他手段实现变量的存续
  • 针对上面的第1点,我们写了一个统一的mutations,用于更新所有的state变量,这样可以免去每个变量都要写一个对应的mutations步骤,同时在 这个统一的mutations中,根据配置判断是否在变量更新的时候,把它存进本地Local Storage,这样H5刷新或者APP下次启动,就会自动把这些变量赋值给 state

具体实现如下(当然,这可能不是最优的写法)

// 根目录的/store/index.js

$uStore(state, payload) {
	// 判断是否多层级调用,state中为对象存在的情况,诸如user.info.score = 1
	let nameArr = payload.name.split('.');
	let saveKey = '';
	let len = nameArr.length;
	if(nameArr.length >= 2) {
		let obj = state[nameArr[0]];
		for(let i = 1; i < len - 1; i ++) {
			obj = obj[nameArr[i]];
		}
		obj[nameArr[len - 1]] = payload.value;
		saveKey = nameArr[0];
	} else {
		// 单层级变量,在state就是一个普通变量的情况
		state[payload.name] = payload.value;
		saveKey = payload.name;
	}
	saveLifeData(saveKey, state[saveKey])
}
  • 针对上面第二点,我们通过Vue.mixin全局混入的形式,可以很好的解决。mixin会把内容注入到每一个页面,所以我们在其中写了mapStatecomputed, 每个页面自然地就获得了从vuexstate中注入的全局变量,这里我们需要在uni-app目根目录新建一个store文件夹(如果没有的话), 在其中新建一个$u.mixin.js文件,这个文件无需您手动引入和Vue.mixin处理,uView会自动处理,只为让您少写两行代码。
// $u.mixin.js的部分实现

import { mapState } from 'vuex'
import store from "@/store"

// 尝试将用户在根目录中的store/index.js的vuex的state变量,全部加载到全局变量中
let $uStoreKey = [];
try{
	$uStoreKey = store.state ? Object.keys(store.state) : [];
}catch(e){}

module.exports = {
	computed: {
		// 将vuex的state中的所有变量,解构到全局混入的mixin中
		...mapState($uStoreKey)
	}
}
  • 针对上面的第3点,因为我们通过统一的mutations的去更新state,自然就需要一个统一方法去触发mutations,用以替代原来的commit方法, 具体是将此方法顺带写入到$u.mixin.js,并挂载到this.$u中,命名为vuex,见如下:
module.exports = {
	created() {
		// 将vuex方法挂在到$u中
		// 使用方法为:如果要修改vuex的state中的user.name变量为"史诗" => this.$u.vuex('user.name', '史诗')
		// 如果要修改vuex的state的version变量为1.0.1 => this.$u.vuex('version', '1.0.1')
		this.$u.vuex = (name, value) => {
			this.$store.commit('$uStore', {
				name,value
			})
		}
	}
}

当我们要修改某一个state值的时候,就用this.$u.vuex('name', value)的形式,通过其他办法,也可以实现this.name = value的简写,但是这种方式 不支持对象的修改,同时也会造成其他的问题,这里不做过多讨论。

  • 针对第4点,其实已经在第1点中解决了。

上面的做法,只是抛砖引玉的做了一个思路的解析,如果您有更好的思路,也可以和我们分享。

说明:确保您是新项目的情况下,或者您对这个实现方法很清楚,才使用这个方法。