/**
* uni-app框架工具集,与uni-app框架耦合的内容在此处实现
* @module uniAppKit
*/
import Vue from 'vue';
/**
* 注册全局this属性
* @param {Object|string} lib|name
* @param {Object|*} propMap|value
@example
//通过键值对的方式一次注册一个属性
registerToThis('$navigateTo', wx.navigateTo);
registerToThis('$redirectTo', wx.redirectTo);
//则所有页面&组件可以以 this.$navigateTo 的形式调用 wx.navigateTo
//通过 库-映射表 的方式一次注册多个属性
registerToThis(wx, {
'$navigateTo': 'navigateTo',
'$redirectTo': 'redirectTo'
});
//则所有页面&组件可以以 this.$navigateTo 的形式调用 wx.navigateTo
*/
export function registerToThis(lib, propMap) {
if (typeof lib === "string") {
let [name, value] = [lib, propMap];
lib = {
[name]: value
};
propMap = {
[name]: name
};
}
if (!((typeof lib==="object"||typeof lib==="function") && typeof propMap==="object")) {
console.error('[registerToThis failed] bad params:', arguments);
return;
}
for (let prop in propMap)
Vue.prototype[prop] = propMap[prop]==='*this' ? lib : lib[propMap[prop]];
}
/**
* 注册全局页面钩子
* @param {string} hook 页面生命周期钩子名称
* @param {Function} handler 处理函数
*/
export function registerPageHook(hook, handler) {
if (typeof handler !== "function") {
console.error('[registerPageHook] bad params:', hook, handler);
return;
}
Vue.mixin({
[hook]: function (...args) {
if (this.mpType !== 'page') //非页面顶级组件,不作处理
return;
handler.apply(this, args);
}
});
}
/**
* 获取当前页面对应的uni-app框架实例
* @return uniPage
*/
export function getCurUniPage() {
let curPages = getCurrentPages();
let curPage = curPages[curPages.length-1];
return curPage && curPage.$vm;
}
/**
* 页面数据恢复函数,用于
* 1. [无关]wepy实例覆盖问题,存在两级同路由页面时,前者数据会被后者覆盖,返回时需予以恢复,详见bug:[两级页面为同一路由时,后者数据覆盖前者](https://github.com/Tencent/wepy/issues/322)
* 2. 无限层级路由策略中,层级过深时,新开页面会替换前一页面,导致前一页面数据丢失,返回时需予以恢复
*
* @param {History~Route} route 页面路由对象
* @param {string} context 数据丢失场景: tainted - 实例覆盖问题导致的数据丢失 | unloaded - 层级问题导致的数据丢失
* @return {{succeeded: boolean}} 处理结果,格式形如:{succeeded: true}
*/
export function pageRestoreHandler({route, context}) {
if (context === 'tainted') //uni-app框架不存在实例覆盖问题,无需处理
return {succeeded: true};
//恢复页面数据
restoreVmTree({
targetVm: getCurUniPage(),
sourceVm: route.wxPage.$vm,
});
return {succeeded: true};
}
/**
* 恢复组件树中各组件的数据
* @ignore
* @param {VueComponent} targetVm 待恢复的组件树根实例
* @param {VueComponent} sourceVm 作为数据源的组件树根实例
*/
function restoreVmTree({targetVm, sourceVm}){
//恢复根实例自身数据
Object.assign(targetVm, sourceVm.$data || sourceVm._data);
//恢复各子组件及其后代组件的数据
for (let i=0; i<targetVm.$children.length; ++i)
restoreVmTree({targetVm: targetVm.$children[i], sourceVm: sourceVm.$children[i]});
}