This commit is contained in:
王鹏
2025-08-14 14:52:01 +08:00
commit 0c2edb6036
1551 changed files with 41152 additions and 0 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,178 @@
import { Hooks, nativeHooks, getDiyHooks } from './hooks.js';
import { getVal, getStore } from './utils.js';
/**
* @Author 鹅鹅鹅
* @DateTime 2023-12-01
* @description 自定义钩子
*/
export default class customHook {
constructor({ instance, options, pageHooks, instanceType, initHookName }) {
// 页面实例、原生钩子对象
this.instance = instance;
// 实例类型 app,page,component
this.instanceType = instanceType;
// 进行实例化的钩子名称
this.initHookName = initHookName;
// 是否是组件
this.isComponent = instanceType === 'component';
// 页面内需要处理的所有钩子构成和函数执行状态
this.customHooks = {};
// 页面内需要处理的所有钩子数组
this.customHookArr = [];
// 所有钩子对象注册的所有钩子的hookEntity类集合
this.hook = {};
// url里的参数
this.options = options || {};
// 钩子对象
this.pageHooks = pageHooks;
// 自定义的属性监听钩子
this.diyHooks = getDiyHooks();
this.init();
//检测是否有需要立即触发的钩子
this.triggerHook();
}
init() {
// 提出需要注入的自定义钩子
let hook = Hooks(this, this.initHookName);
// 当前实例支持的所有钩子
this.presetHooksName = Object.keys(hook);
this.hook = hook;
let pageHooks = this.pageHooks;
// 钩子对象在自身还是原型链
let oneself = pageHooks.hasOwnProperty('beforeCreate') || pageHooks.hasOwnProperty('onReady');
pageHooks = oneself ? pageHooks : pageHooks['__proto__'];
if (this.isComponent) {
// 把lifetimes和pageLifetimes合并过来一起处理
Object.assign(pageHooks, pageHooks.lifetimes, pageHooks.pageLifetimes);
}
// 过滤钩子对象、分析钩子构成
let { customHookArr, hookInscape } = this.filterHooks(pageHooks);
// 单独处理每个钩子
customHookArr.forEach((e) => {
this.customHooks[e] = {
// 此钩子实体函数
callback: pageHooks[e].bind(this.instance),
// 此钩子构成
inscape: hookInscape[e],
// 此钩子是否已执行
execute: false,
// 决定执行顺序的累加权重值,小的在前先执行
weightValue: hookInscape[e].reduce((total, hookKey) => {
return (total += this.hook[hookKey]?.weightValue || 0);
}, 0),
};
});
// 按weightValue进行排序
this.customHookArr = customHookArr.sort((a, b) => {
return this.customHooks[a].weightValue - this.customHooks[b].weightValue;
});
// await Promise.resolve();
Object.keys(this.hook).forEach((e) => this.hook[e].init());
}
/**
* 过滤出钩子对象
* @params Object<key,function> 页面所有钩子对象列表
* return {
* customHookArr Array<string> 自定义钩子数组
* hookInscape Object<key,Array<string>> 自定义钩子构成
* }
*/
filterHooks(option) {
// 各钩子和包含的所有已注册单独钩子构成
let hookInscape = {};
// 筛选出来用到的hook实例
const filterHook = {};
const customHookArr = Object.keys(option).filter((e) => {
// 不符合规则的钩子不予处理
let hookArr = this.getHookArr(e);
if (hookArr.length) {
//过滤掉未注册的钩子
hookInscape[e] = hookArr.filter((h) => {
if (this.hook[h]) {
filterHook[h] = this.hook[h];
return true;
}
console.warn(
`[custom-hook 错误声明警告] "${h}"钩子未注册,意味着"${e}"可能永远不会执行请先注册此钩子再使用文档https://github.com/1977474741/spa-custom-hooks#-diyhooks对象说明`
);
return false;
});
//格式 + 是否注册的效验
return e == 'on' + hookArr.join('') && hookInscape[e].length == hookArr.length;
}
return false;
});
// 只保留用到的hook实例
this.hook = filterHook;
return {
customHookArr,
hookInscape,
};
}
/**
* 检测是否有需要触发的钩子
* @params <string> 本次变化的钩子key
*/
triggerHook(hitKey) {
this.customHookArr.forEach((name) => {
let customHook = this.customHooks[name];
let meet = customHook.inscape.every((e) => this.hook[e] && this.checkHookHit(this.hook[e]));
if (meet && !customHook.execute) {
customHook.execute = true;
this.customHooks[name]['callback'](this.options);
}
});
}
/**
* 清除关于本次destroy钩子的所有包含此钩子的执行状态
* @params <string> 要清除的钩子名称
*/
resetExecute(destroyHookName) {
this.customHookArr.forEach((pageHookName) => {
let customHook = this.customHooks[pageHookName];
if (customHook.inscape.find((hookName) => destroyHookName === this.hook[hookName]?.destroy)) {
customHook.execute = false;
}
});
}
/**
* 检验此钩子是否满足命中条件
* @param hookEntity实例
* return <boolean> 是否满足
*/
checkHookHit(hookEntity) {
if (hookEntity.watchKey) {
//注意instance对象必须从传进来的实体里拿不能this.instance
let val = getVal(getStore(hookEntity.__customhook.instance).state, hookEntity.watchKey);
return hookEntity.onUpdate ? hookEntity.onUpdate(val) : val;
} else {
return hookEntity.hit;
}
}
/**
* 获取组合钩子包含的所有钩子(包含多于一个钩子 || 单个自定义属性钩子)、是的话返回钩子构成
* @param <string> 钩子名称
* return Array<string> 钩子构成
*/
getHookArr(name) {
if (name.indexOf('on') == -1) return [];
const hookArr = this.splitHook(name),
diyHooks = this.diyHooks;
return hookArr.length > 1 || diyHooks.indexOf(hookArr[0]) != -1 ? hookArr : [];
}
/**
* 分析组合钩子构成
* @param <string> 组合钩子名称
* return Array<string> 钩子构成数组
*/
splitHook(name) {
name = name.replace('on', '');
// 将钩子数组按照长度进行降序排序,以确保匹配最长的字符串优先
this.presetHooksName.sort((a, b) => b.length - a.length);
// 使用正则表达式将钩子数组中的每个元素都转换为对应的捕获组然后通过join函数连接起来
let regex = new RegExp('(' + this.presetHooksName.join('|') + ')', 'g');
// 使用split函数根据正则表达式对组合钩子进行分割并过滤掉无效的部分
return name.split(regex).filter((e) => this.hook[e]);
}
}

View File

@@ -0,0 +1,64 @@
/**
* @Author 鹅鹅鹅
* @description 单个hook处理工厂
*/
import { getStore, getVal } from './utils.js';
export default class hookEntity {
constructor({ customhook, name, destroy, hit = false, watchKey, onUpdate, type, weightValue }) {
// 钩子名
this.name = name;
// 相反钩子名
this.destroy = destroy;
// 钩子类型 app、page、component
this.type = type;
// hit是在是生命周期钩子的情况下才有用属性监听钩子是检测时triggerHook实时判断的没有用hit属性
this.hit = hit;
// 需要监听的key
this.watchKey = watchKey;
// 权重值,决定了和其他钩子同时满足条件时执行先后顺序
this.weightValue = weightValue;
// 是否已经初始化
this.initFlag = false;
// 属性监听回调
this.onUpdate = onUpdate;
this.__customhook = customhook;
}
init() {
if (this.initFlag) return;
if (this.watchKey) {
this.unwatchFn = this.watchAttr((success) => {
this[success ? 'cycleStart' : 'cycleEnd']();
});
}
this.initFlag = true;
}
cycleStart() {
if (this.hit) return;
this.hit = true;
this.__customhook && this.__customhook.triggerHook(this.name);
}
cycleEnd() {
if (!this.hit) return;
this.hit = false;
this.__customhook && this.destroy && this.__customhook.resetExecute(this.destroy);
}
watchAttr(cb) {
try {
const that = this;
const store = getStore(this.__customhook.instance);
const unwatchFn = store.watch(
(state) => {
return getVal(state, that.watchKey);
},
(val, oldval) => {
cb(that.onUpdate ? that.onUpdate(val, oldval) : val);
},
{
//兼容mini-polyfill
watchKey: that.watchKey,
}
);
return unwatchFn;
} catch (err) {}
}
}

View File

@@ -0,0 +1,232 @@
import hookEntity from './hook-entity.js';
// 注册的自定义钩子
let diyHooks = {};
// 需要mixin的原生钩子
const nativeHooks = [
// vue
'beforeCreate',
'created',
'onPageShow',
'beforeMount',
'mounted',
'activated',
'onPageHide',
'deactivated',
'beforeDestroy',
'destroyed',
// app和page
'onLaunch',
'onLoad',
'onShow',
'onReady',
'onHide',
'onUnload',
];
// 原生组件钩子
const componentHooks = ['onInit', 'created', 'attached', 'ready', 'didMount', 'detached', 'didUnmount'];
const lifetimesHooks = ['created', 'attached', 'ready', 'detached'];
const pageLifetimesHooks = ['show', 'hide', 'routeDone'];
// 原生所有钩子
const nativeAllHooks = [...new Set([...nativeHooks, ...componentHooks])];
/**
* 输入hooks配置项所有hook经过hookEntity处理输出hookEntity对象列表
* @param1 <customhook>实例化对象
* @param2 <string> 初始化的钩子名
* return Object<key,hookEntity> 所有注册的hook对应的hookEntity对象列表
*/
const Hooks = (customhook, initHookName) =>
Object.keys(diyHooks).reduce(
(hooks, key) => {
const diyHook = diyHooks[key];
diyHook.customhook = customhook;
return (hooks[key] = new hookEntity(diyHook)) && hooks;
},
{
// vue钩子
BeforeCreate: new hookEntity({
customhook,
name: 'BeforeCreate',
destroy: 'destroyed',
hit: true,
weightValue: 2,
}),
BeforeMount: new hookEntity({
customhook,
name: 'beforeMount',
destroy: 'destroyed',
weightValue: 4,
}),
PageShow: new hookEntity({
customhook,
name: 'onPageShow',
destroy: 'onPageHide',
weightValue: 4.1,
}),
Mounted: new hookEntity({
customhook,
name: 'mounted',
destroy: 'destroyed',
weightValue: 5,
}),
Activated: new hookEntity({
customhook,
name: 'activated',
destroy: 'deactivated',
weightValue: 6,
}),
PageHide: new hookEntity({
customhook,
name: 'onPageHide',
destroy: 'onPageShow',
weightValue: 6.1,
}),
Deactivated: new hookEntity({
customhook,
name: 'deactivated',
destroy: 'activated',
weightValue: 7,
}),
// 兼容页面的钩子和组件的钩子名相似的情况比如各种小程序的页面是onShow组件却是show但他们的key在这里都是Show为了防止key冲突故而加判断分开注册保证key的唯一性也统一了页面和组件钩子的声明方式
...(!customhook.isComponent
? {
Launch: new hookEntity({
customhook,
name: 'onLaunch',
destroy: 'onUnload',
hit: true,
weightValue: 3,
}),
Created: new hookEntity({
customhook,
name: 'created',
destroy: 'destroyed',
hit: initHookName === 'created',
weightValue: 3,
}),
Load: new hookEntity({
customhook,
name: 'onLoad',
destroy: 'onUnload',
hit: initHookName === 'onLoad',
weightValue: 4,
}),
Ready: new hookEntity({
customhook,
name: 'onReady',
destroy: 'onUnload',
weightValue: 5,
}),
Show: new hookEntity({
customhook,
name: 'onShow',
destroy: 'onHide',
weightValue: 6,
}),
Hide: new hookEntity({
customhook,
name: 'onHide',
destroy: 'onShow',
weightValue: 7,
}),
}
: {
// 原生小程序组件 包含的钩子
Init: new hookEntity({
customhook,
name: 'onInit',
destroy: 'didUnmount',
hit: initHookName === 'onInit',
weightValue: 2,
}),
Created: new hookEntity({
customhook,
name: 'created',
destroy: 'detached',
hit: initHookName === 'created',
weightValue: 3,
}),
Attached: new hookEntity({
customhook,
name: 'attached',
destroy: 'detached',
weightValue: 4,
}),
Show: new hookEntity({
customhook,
name: 'show',
destroy: 'hide',
weightValue: 5,
}),
DidMount: new hookEntity({
customhook,
name: 'didMount',
destroy: 'didUnmount',
hit: initHookName === 'didMount',
weightValue: 6,
}),
Ready: new hookEntity({
customhook,
name: 'ready',
destroy: 'detached',
weightValue: 7,
}),
// 微信小程序组件所在页面的生命周期
RouteDone: new hookEntity({
customhook,
name: 'routeDone',
destroy: 'detached',
weightValue: 8,
}),
Hide: new hookEntity({
customhook,
name: 'hide',
destroy: 'show',
weightValue: 9,
}),
Detached: new hookEntity({
customhook,
name: 'detached',
destroy: 'attached',
weightValue: 10,
}),
}),
}
);
const init = (hooks) => (diyHooks = hooks);
/**
* 获取所有自定义钩子
* return Array<string> diy钩子数组
*/
const getDiyHooks = () => Object.keys(diyHooks);
/**
* 手动命中某属性钩子-待开发
* @param1 <string> 单个钩子名
* @param2 <string> 要改变的状态
*/
const setHit = (name, state) => {
Hooks()[name][state ? 'cycleStart' : 'cycleEnd']();
};
/**
* 使用js监听属性钩子-待开发
* @param1 <string> 钩子名、这里只允许属性监听钩子
* @param2 <function> 回调函数
*/
const on = (name, cb) => { };
export {
Hooks,
getDiyHooks,
nativeAllHooks,
lifetimesHooks,
pageLifetimesHooks,
nativeHooks,
componentHooks,
init,
setHit,
on,
};

View File

@@ -0,0 +1,16 @@
import * as init from './init.js';
import { setHit } from './hooks.js';
import * as polyfill from './mini-polyfill.js';
const install = function () {
if (arguments.length < 3) {
// 小程序架构,使用垫片
init.install(polyfill.vue, arguments[0], polyfill.store, arguments[1] || 'globalData');
} else {
// vue架构
init.install(...arguments);
}
};
export default {
install,
setHit,
};

View File

@@ -0,0 +1,158 @@
import customHook from './custom-hook.js';
import * as hooks from './hooks.js';
import { getVal, setStore } from './utils.js';
const userAgentKeys = {
'vue-h5': {
// 组件的hook对象
hooksKey: '$options',
// 用来初始化的hook
initHook: 'beforeCreate',
// 是否支持组件、暂废弃
supportComponent: true,
isPage(pageHooks) {
return pageHooks._compiled && this.supportComponent;
},
},
'vue-miniprogram': {
hooksKey: '$options',
initHook: 'beforeCreate',
supportComponent: true,
isPage() {
return this.supportComponent;
},
},
miniprogram: {
name: 'miniprogram',
hooksKey: '',
initHook: 'onLoad',
initHookApp: 'onLaunch',
initHookComponentAlipay: 'didMount',
initHookComponentAlipayInit: 'onInit',
initHookComponentWx: 'created',
initHookComponentLifetimes: 'created',
supportComponent: true,
isPage() {
return this.supportComponent;
},
},
};
let BASE = userAgentKeys['vue-miniprogram'];
const install = (vue, params, store, storeKey) => {
//基于mpvue框架特殊处理避免created的bug
if (vue.mpvueVersion) {
BASE.initHook = 'onLoad';
} else if (vue.userAgentKey) {
// 垫片里指定userAgentKey,根据参数来判断vue架构||原生小程序
BASE = userAgentKeys[vue.userAgentKey];
}
setStore(store);
hooks.init(params);
vue.mixin({
// 监听所有原生钩子,改变对应状态
...hooksMutation(hooks.nativeAllHooks),
// vue初始化钩子beforeCreate
[BASE.initHook](options) {
hookInit.call(this, options, 'page', undefined, BASE.initHook);
},
...(BASE.name === 'miniprogram'
? {
// 所有小程序App初始化钩子onLaunch
[BASE.initHookApp](options) {
hookInit.call(this, options, 'app', undefined, BASE.initHookApp);
},
//微信小程序组件初始化钩子created
[BASE.initHookComponentWx](optionProperties, options) {
hookInit.call(this, options, 'component', optionProperties, BASE.initHookComponentWx);
},
//支付宝小程序组件初始化钩子onInit
[BASE.initHookComponentAlipayInit](optionProperties, options) {
hookInit.call(this, options, 'component', optionProperties, BASE.initHookComponentAlipayInit);
},
//支付宝小程序组件初始化钩子didMount
//兼容支付宝小程序普通和component2模式init、created、didMount都有可能做初始化
[BASE.initHookComponentAlipay](optionProperties, options) {
componentHookTriggered.call(this, optionProperties, options, BASE.initHookComponentAlipay);
},
// 小程序原生组件api混入
lifetimes: {
...hooksMutation(hooks.lifetimesHooks),
//支付宝小程序组件初始化钩子created、在lifetimes为true并且未开启component2时作为初始化
[BASE.initHookComponentLifetimes](optionProperties, options) {
componentHookTriggered.call(this, optionProperties, options, BASE.initHookComponentLifetimes);
},
},
pageLifetimes: {
...hooksMutation(hooks.pageLifetimesHooks),
},
}
: {}),
});
// 钩子执行后,初始化 || 改钩子状态
function componentHookTriggered(optionProperties, options, hookName) {
// 已经初始化的修改内部钩子状态,否则走初始化逻辑
if (this.customHook) {
updateHookState.call(this, options, hookName);
return;
}
hookInit.call(this, options, 'component', optionProperties, hookName);
}
// 初始化实例化custom-hook-spa
function hookInit(options, instanceType, optionProperties, initHookName) {
if (this.customHook) return;
// 入口文件特殊处理
let pageHooks = getVal(this, BASE['hooksKey']);
// 过滤掉非业务组件
if (BASE.isPage(pageHooks)) {
// 兼容非vuex环境
if (!store.state && storeKey) {
store.state = this[storeKey] || storeKey;
}
const isComponent = instanceType === 'component';
Object.defineProperty(this, 'customHook', {
value: new customHook({
instance: this,
options,
pageHooks: isComponent ? optionProperties : pageHooks,
instanceType,
initHookName: initHookName,
}),
configurable: true,
enumerable: false,
});
}
}
// 监听所有钩子并修改状态
function hooksMutation(hookNames) {
return hookNames.reduce(
(hooks, hookName) =>
(hooks[hookName] = function (options) {
updateHookState.call(this, options, hookName);
}) && hooks,
{}
);
}
// 更新已经存在的实例化custom-hook-spa对应钩子状态
function updateHookState(options, hookName) {
//没有创建customHook不作处理
if (typeof this.customHook != 'object' && typeof this.customHook != null) return;
//customHook里没有自定义钩子不作处理
if (!this.customHook.customHookArr.length) return;
if (options && Object.keys(options).length > 0) {
this.customHook.options = options;
}
const hooks = this.customHook.hook;
const isDestroy = ['beforeDestroy', 'destroyed', 'onUnload', 'didUnmount', 'detached'].includes(hookName);
for (let k in hooks) {
const hook = hooks[k];
if (hook.name == hookName) {
hook.cycleStart();
} else if (hook.destroy == hookName) {
hook.cycleEnd();
}
isDestroy && hook.unwatchFn?.();
}
isDestroy && delete this.customHook;
}
};
export { install, BASE };

View File

@@ -0,0 +1,180 @@
import { getStore, getVal } from './utils.js';
const vue = {
mixin(mixin) {
let app = App,
page = Page,
component = Component;
// 通过重写构造器实现mixin的生命周期部分
App = (options) => {
this.mergeHook(mixin, options);
app(options);
};
Page = (options) => {
this.mergeHook(mixin, options);
page(options);
};
Component = (options) => {
this.mergeComponentHook(mixin, options);
const newOptions = this.mixinLifetimes(mixin, options);
component(newOptions);
};
},
// mixin实现
mergeHook(mixin, options) {
for (let [key, value] of Object.entries(mixin)) {
const originFunc = options[key];
options[key] = function (...args) {
originFunc && originFunc.call(this, ...args);
value.call(this, ...args);
};
}
},
//由于小程序组件钩子的特殊性this上没有挂钩子引用所以需要特殊处理
mergeComponentHook(mixin, options) {
const hooksObjectKeys = ['lifetimes', 'pageLifetimes'];
for (let [key, value] of Object.entries(mixin).filter((e) => !hooksObjectKeys.includes(e[0]))) {
const originFunc = options[key];
options[key] = function (...args) {
originFunc && originFunc.call(this, ...args);
value.call(this, options, ...args);
};
}
},
// 使用小程序自带api混入pageLifetimes和lifetimes
mixinLifetimes(mixin, options) {
if (typeof Behavior === 'function') {
const orightMixin = options.behaviors || [];
// 由于lifetimes内的created优先级最高则在这里做组件的初始化传入构造参数用来替代组件的pageHooks对象
const originFunc = mixin.lifetimes.created;
mixin.lifetimes.created = function (...args) {
originFunc && originFunc.call(this, options, ...args);
};
orightMixin.push(
Behavior({
lifetimes: mixin.lifetimes,
pageLifetimes: mixin.pageLifetimes,
})
);
options.behaviors = orightMixin;
return options;
} else {
const orightMixin = options.mixins || [];
if (options.options && options.options.lifetimes) {
const originFunc = mixin.lifetimes.created;
mixin.lifetimes.created = function (...args) {
originFunc && originFunc.call(this, options, ...args);
};
}
orightMixin.push(
Mixin({
lifetimes: mixin.lifetimes,
pageLifetimes: mixin.pageLifetimes,
options: {
// 允许基础库识别 lifetimes 字段以支持 lifetimes 功能
lifetimes: true,
},
})
);
options.mixins = orightMixin;
return options;
}
},
userAgentKey: 'miniprogram',
};
const subscribers = {};
const store = {
// 基于es5实现不支持监听没有定义的属性
watch(keyFun, cb, options) {
// 获取数据仓库一般为globalData对象
const baseState = getStore().state;
// 具体要监听的属性
const watchKey = options.watchKey;
const base = getVal(baseState, watchKey, true);
let subscriber = {
callback: cb,
// 是否是卸载监听
unwatch: false,
};
if (subscribers[watchKey]) {
subscribers[watchKey].push(subscriber);
} else {
subscribers[watchKey] = [subscriber];
}
const unMonitorArrayFn = [];
deep(base.obj, base.key);
function deep(obj, key) {
// 监听基本数据类型
let name = obj[key];
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
set: function (v) {
name = v;
subscribers[watchKey].map((subscriber) => subscriber.callback(base.obj[base.key]));
},
get: function () {
return name;
},
});
// 额外添加对数组长度的监听
if (Array.isArray(obj[key])) {
// 监听数组长度
unMonitorArrayFn.push(
monitorArray(obj[key], () => {
cb(base.obj[base.key]);
})
);
}
// 递归监听引用数据类型
if (typeof obj[key] === 'object' && obj[key] != null) {
for (let [key_, value_] of Object.entries(obj[key])) {
deep(obj[key], key_);
}
}
}
return () => {
// 取消基本数据类型监听
subscriber.unwatch = true;
const unwatchIndex = subscribers[watchKey].findIndex((e) => e.unwatch);
subscribers[watchKey].splice(unwatchIndex, 1);
if (!subscribers[watchKey].length) {
delete subscribers[watchKey];
}
// 取消数组长度监听
unMonitorArrayFn.map((f) => f());
};
},
};
// 监听数组长度
function monitorArray(array, callback) {
// 获取Array原型
const arrayMethods = Object.create(array);
const unwatchFn = ['push', 'pop', 'shift', 'unshift', 'splice', 'sort', 'reverse'].map((method) => {
// 原生Array的原型方法
let original = arrayMethods[method];
define(array, method, function () {
original.apply(this, arguments);
// 调用对应的原生方法并返回结果(新数组长度)
return callback.apply(this, arguments);
});
return () => {
define(array, method, original);
};
});
return () => {
unwatchFn.map((f) => f());
};
}
// 定义不可枚举的属性
function define(obj, key, val, enumerable) {
Object.defineProperty(obj, key, {
value: val,
enumerable: !!enumerable,
writable: true,
configurable: true,
});
}
export { vue, store };

View File

@@ -0,0 +1,64 @@
let store;
/**
* 根据动态字符串key获取属性相当于eval
* @param1 <object> 在此对象上查找
* @param2 <string> | Array<string> 要找的对象key支持字符串调用链
* @param3 <boolean> 是否保留最后一层
* return <any> 获取到的属性
*/
const getVal = (obj, keys, LastFloor) => {
try {
if (keys) {
let keyArr = keys;
if (typeof keys === 'string') {
keyArr = keys.split('.');
}
// 是否保留最后一层,用于做数据监听
const length = LastFloor ? keyArr.length - 1 : keyArr.length;
//兼容1.1.1以及之前的版本,结束
for (let i = 0; i < length; i++) {
obj = obj[keyArr[i]];
}
return LastFloor
? {
key: keyArr[length],
obj,
}
: obj;
} else {
return obj;
}
} catch (err) {
return;
}
};
/**
* 暂存store对象
* @param <object> 传入的store对象
* return <object> 传入的store对象
*/
const setStore = (_store) => {
store = _store;
return store;
};
/**
* 获取store对象
* @param <App> | <Page> | <Component> 组件实例
* return <object> store对象
*/
const getStore = (page) => {
//有显式传入的store
if (store && store.state) {
return store;
}
// 否则使用组件里的store
else if (page) {
return page.$store || {};
} else {
return {};
}
};
export { getVal, setStore, getStore };