vue-moo
Version:
moo
170 lines (148 loc) • 5.17 kB
JavaScript
import Vuex, { Store, mapGetters, mapActions } from 'vuex';
import util from '../../util';
const storeGetters = {};
const storeActions = {};
const storeMutations = {};
const storeStates = {};
const stateNamespaces = [];
// create的构造函数
export const create = function create(Vue, process) {
const store = {
state: {},
getters: {},
actions: {},
mutations: {},
};
const state = function(processName = '') {
let namespace = processName;
storeGetters[namespace] = [];
storeActions[namespace] = [];
storeMutations[namespace] = [];
storeStates[namespace] = [];
this.setStoreScope = function setStoreScope(name) {
namespace = namespace === '' ? name : namespace;
};
this.namespace = function setNamespace(name) {
return `${namespace}${util.String.firstUppercase(name)}`;
};
this.mealActionName = function mealActionName(name) {
return `set${util.String.firstUppercase(namespace)}${util.String.firstUppercase(name)}`;
};
this.getState = function getState(state, name) {
return state[this.namespace(name)];
};
this.meal = function setMeal(name, params) {
const storeName = this.namespace(name);
const actionName = `set${util.String.firstUppercase(storeName)}`;
store.state[storeName] = params;
store.actions[actionName] = ({ state }, params) => {
state[storeName] = params;
state[namespace][name] = params;
};
store.mutations[storeName] = (state, payload) => {
state[storeName] = payload;
state[namespace][name] = payload;
};
store.getters[storeName] = state => state[storeName];
storeStates[namespace].push(storeName);
storeActions[namespace].push(actionName);
storeMutations[namespace].push(storeName);
storeGetters[namespace].push(storeName);
};
this.mutation = function setMutation(name, callback) {
const storeName = this.namespace(name);
store.mutations[storeName] = callback;
storeMutations[namespace].push(storeName);
};
this.getter = function setGetter(name, callback = null) {
const storeName = this.namespace(name);
store.getters[storeName] = callback !== null ? callback : state => state[storeName];
storeGetters[namespace].push(storeName);
};
this.action = function setAction(name, cb) {
const ns = this.namespace;
const storeName = ns(name);
store.actions[storeName] = function (item, params) {
const conf = {
...item,
doth: (name, params) => {
item.dispatch(ns(name), params);
},
push: (name, val) => {
item.commit(ns(name), val);
},
publish: (nameList) => {
Object.entries(nameList).map((kv) => {
const [name, val] = kv;
item.commit(ns(name), val);
return kv;
});
},
};
return cb(conf, params);
};
storeActions[namespace].push(storeName);
};
this.state = function setState(maps) {
if (stateNamespaces.indexOf(namespace) < 0) {
stateNamespaces.push(namespace);
store.state[namespace] = {};
store.getters[namespace] = state => state[namespace];
}
Object.entries(maps).map((kv) => {
const [name, params] = kv;
const stateSpace = store.state[namespace];
const storeName = this.namespace(name);
this.meal(name, params);
stateSpace[name] = params;
store.state[storeName] = params;
store.getters[storeName] = state => state[storeName];
store.mutations[storeName] = (state, payload) => {
state[storeName] = payload;
stateSpace[name] = payload;
};
storeMutations[namespace].push(storeName);
storeStates[namespace].push(storeName);
storeGetters[namespace].push(storeName);
return kv;
});
};
};
state.use = function use(key, target) {
state.prototype[key] = target;
}
if (typeof process === 'function') process(state);
Vue.use(Vuex);
return new Store(store);
};
const maps = function(namespace, nameList, category) {
return nameList !== null ? nameList.map((name) => {
return `${namespace}${util.String.firstUppercase(name)}`;
}) : category[namespace];
}
export const getters = function getters(namespace, nameList = null) {
if (!storeGetters[namespace]) return {};
return mapGetters(maps(namespace, nameList, storeGetters));
}
export const getterNS = function getterNS(namespace) {
if (stateNamespaces.indexOf(namespace) < 0) return {};
return mapGetters(stateNamespaces);
}
export const getterAll = function getterAll(namespace, nameList = null) {
if (stateNamespaces.indexOf(namespace) < 0 && !storeGetters[namespace]) return {};
const a = maps(namespace, nameList, storeGetters);
const b = stateNamespaces;
const c = [];
return mapGetters(c.concat(a).concat(b));
}
export const actions = function actions(namespace, nameList = null) {
if (!storeActions[namespace]) return {};
return mapActions(maps(namespace, nameList, storeActions));
}
export default {
create,
getterAll,
getterNS,
getters,
actions,
};