提交 8b93f24d 编写于 作者: fxy060608's avatar fxy060608

feat: init quickapp-light

上级 ad27f7ca
......@@ -23,7 +23,7 @@ const PLATFORMS = {
prefix: 'tt',
title: '头条小程序'
},
'mp-quickapp': {
'quickapp-light': {
prefix: 'qa',
title: '快应用(Light)版'
},
......@@ -64,4 +64,4 @@ module.exports = {
})
],
external: ['vue']
}
}
......@@ -22,8 +22,8 @@
"build:mp-weixin": "cross-env UNI_PLATFORM=mp-weixin rollup -c build/rollup.config.mp.js",
"build:mp-baidu": "cross-env UNI_PLATFORM=mp-baidu rollup -c build/rollup.config.mp.js",
"build:mp-alipay": "cross-env UNI_PLATFORM=mp-alipay rollup -c build/rollup.config.mp.js",
"build:mp-toutiao": "cross-env UNI_PLATFORM=mp-toutiao rollup -c build/rollup.config.mp.js",
"build:mp-quickapp": "cross-env UNI_PLATFORM=mp-quickapp rollup -c build/rollup.config.mp.js",
"build:mp-toutiao": "cross-env UNI_PLATFORM=mp-toutiao rollup -c build/rollup.config.mp.js",
"build:quickapp-light": "cross-env UNI_PLATFORM=quickapp-light rollup -c build/rollup.config.mp.js",
"build:mp-weixin:mp": "npm run lint && cross-env UNI_PLATFORM=mp-weixin UNI_MP=true rollup -c build/rollup.config.mp.js",
"build:mp-weixin:wxs": "rollup -c build/rollup.config.wxs.js",
"build:quickapp": "cross-env NODE_ENV=development node build/build.qa.js && cross-env NODE_ENV=production node build/build.qa.js",
......@@ -111,7 +111,7 @@
"my": true,
"swan": true,
"tt": true,
"qh": true,
"qh": true,
"qa": true,
"HWH5": true,
"weex": true,
......@@ -147,4 +147,4 @@
"main": "index.js",
"description": "",
"author": ""
}
}
......@@ -165,7 +165,8 @@ var serviceContext = (function () {
'startPullDownRefresh',
'stopPullDownRefresh',
'createSelectorQuery',
'createIntersectionObserver'
'createIntersectionObserver',
'getMenuButtonBoundingClientRect'
];
const event = [
......@@ -649,7 +650,7 @@ var serviceContext = (function () {
const ASYNC_API = ['createBLEConnection'];
const CALLBACK_API_RE = /^on/;
const CALLBACK_API_RE = /^on|^off/;
function isContextApi (name) {
return CONTEXT_API_RE.test(name)
......@@ -2970,7 +2971,7 @@ var serviceContext = (function () {
}
function getScreenInfo () {
const { resolutionWidth, resolutionHeight } = plus.screen.getCureentSize();
const { resolutionWidth, resolutionHeight } = plus.screen.getCurrentSize();
return {
screenWidth: Math.round(resolutionWidth),
screenHeight: Math.round(resolutionHeight)
......@@ -5651,14 +5652,21 @@ var serviceContext = (function () {
openLocation: openLocation$1
});
function openLocation$2 (data) {
function openLocation$2 (data, callbackId) {
showPage({
url: '__uniappopenlocation',
data,
style: {
titleNView: {
type: 'transparent'
}
},
popGesture: 'close',
backButtonAutoControl: 'close'
},
onClose () {
invoke$1(callbackId, {
errMsg: 'openLocation:fail cancel'
});
}
});
return {
......@@ -9253,17 +9261,14 @@ var serviceContext = (function () {
const eventNames = [
'load',
'close',
'verify',
'error'
];
const ERROR_CODE_LIST = [-5001, -5002, -5003, -5004, -5005, -5006];
class RewardedVideoAd {
constructor (adpid) {
this._options = {
adpid: adpid
};
constructor (options = {}) {
const _callbacks = this._callbacks = {};
eventNames.forEach(item => {
_callbacks[item] = [];
......@@ -9277,7 +9282,7 @@ var serviceContext = (function () {
this._adError = '';
this._loadPromiseResolve = null;
this._loadPromiseReject = null;
const rewardAd = this._rewardAd = plus.ad.createRewardedVideoAd(this._options);
const rewardAd = this._rewardAd = plus.ad.createRewardedVideoAd(options);
rewardAd.onLoad((e) => {
this._isLoad = true;
this._dispatchEvent('load', {});
......@@ -9290,6 +9295,9 @@ var serviceContext = (function () {
this._loadAd();
this._dispatchEvent('close', { isEnded: e.isEnded });
});
rewardAd.onVerify && rewardAd.onVerify((e) => {
this._dispatchEvent('verify', { isValid: e.isValid });
});
rewardAd.onError((e) => {
const { code, message } = e;
const data = { code: code, errMsg: message };
......@@ -9323,6 +9331,12 @@ var serviceContext = (function () {
}
})
}
getProvider () {
return this._rewardAd.getProvider()
}
destroy () {
this._rewardAd.destroy();
}
_loadAd () {
this._isLoad = false;
this._rewardAd.load();
......@@ -9336,10 +9350,8 @@ var serviceContext = (function () {
}
}
function createRewardedVideoAd ({
adpid = ''
} = {}) {
return new RewardedVideoAd(adpid)
function createRewardedVideoAd (options) {
return new RewardedVideoAd(options)
}
......@@ -10646,8 +10658,9 @@ var serviceContext = (function () {
var cId = canvasEventCallbacks.push(function (data) {
invoke$1(callbackId, data);
});
// fix ...
operateCanvas(canvasId, pageId, 'putImageData', {
data: [...data],
data: Array.prototype.slice.call(data),
x,
y,
width,
......@@ -10729,17 +10742,13 @@ var serviceContext = (function () {
callback.invoke(callbackId, data);
});
const methods = ['getCenterLocation', 'getScale', 'getRegion', 'includePoints', 'translateMarker'];
const methods = ['getCenterLocation', 'moveToLocation', 'getScale', 'getRegion', 'includePoints', 'translateMarker'];
class MapContext {
constructor (id, pageVm) {
this.id = id;
this.pageVm = pageVm;
}
moveToLocation () {
operateMapPlayer$3(this.id, this.pageVm, 'moveToLocation');
}
}
MapContext.prototype.$getAppMap = function () {
......@@ -12146,7 +12155,7 @@ var serviceContext = (function () {
return
}
if (!page.$page.meta.isNVue) {
const target = page.$vm._$vd.elements.find(target => target.tagName === 'web-view' && target.events['message']);
const target = page.$vm._$vd.elements.find(target => target.type === 'web-view' && target.events['message']);
if (!target) {
return
}
......@@ -13191,8 +13200,7 @@ var serviceContext = (function () {
cur = newObj[key];
old = oldObj[key];
if (old !== cur) {
// 全量同步 style (因为 style 可能会动态删除部分样式)
if (key === B_STYLE && isPlainObject(cur) && isPlainObject(old)) {
if (key === B_STYLE && isPlainObject(cur) && isPlainObject(old)) { // 全量同步 style (因为 style 可能会动态删除部分样式)
if (Object.keys(cur).length !== Object.keys(old).length) { // 长度不等
setResult(result || (result = Object.create(null)), B_STYLE, cur);
} else {
......@@ -13203,6 +13211,14 @@ var serviceContext = (function () {
const vFor = diffArray(cur, old);
vFor && setResult(result || (result = Object.create(null)), V_FOR, vFor);
} else {
if (key.indexOf('change:') === 0) { // wxs change:prop
try {
// 先简单的用 stringify 判断
if (JSON.stringify(cur) === JSON.stringify(old)) {
continue
}
} catch (e) {}
}
setResult(result || (result = Object.create(null)), key, cur);
}
}
......
import Vue from 'vue';
const _toString = Object.prototype.toString;
const hasOwnProperty = Object.prototype.hasOwnProperty;
function isFn (fn) {
return typeof fn === 'function'
}
function isStr (str) {
return typeof str === 'string'
}
function isPlainObject (obj) {
return _toString.call(obj) === '[object Object]'
}
function hasOwn (obj, key) {
return hasOwnProperty.call(obj, key)
}
function noop () {}
/**
* Create a cached version of a pure function.
*/
function cached (fn) {
const cache = Object.create(null);
return function cachedFn (str) {
const hit = cache[str];
return hit || (cache[str] = fn(str))
}
}
/**
* Camelize a hyphen-delimited string.
*/
const camelizeRE = /-(\w)/g;
const camelize = cached((str) => {
return str.replace(camelizeRE, (_, c) => c ? c.toUpperCase() : '')
});
const HOOKS = [
'invoke',
'success',
'fail',
'complete',
'returnValue'
];
const globalInterceptors = {};
const scopedInterceptors = {};
function mergeHook (parentVal, childVal) {
const res = childVal
? parentVal
? parentVal.concat(childVal)
: Array.isArray(childVal)
? childVal : [childVal]
: parentVal;
return res
? dedupeHooks(res)
: res
}
function dedupeHooks (hooks) {
const res = [];
for (let i = 0; i < hooks.length; i++) {
if (res.indexOf(hooks[i]) === -1) {
res.push(hooks[i]);
}
}
return res
}
function removeHook (hooks, hook) {
const index = hooks.indexOf(hook);
if (index !== -1) {
hooks.splice(index, 1);
}
}
function mergeInterceptorHook (interceptor, option) {
Object.keys(option).forEach(hook => {
if (HOOKS.indexOf(hook) !== -1 && isFn(option[hook])) {
interceptor[hook] = mergeHook(interceptor[hook], option[hook]);
}
});
}
function removeInterceptorHook (interceptor, option) {
if (!interceptor || !option) {
return
}
Object.keys(option).forEach(hook => {
if (HOOKS.indexOf(hook) !== -1 && isFn(option[hook])) {
removeHook(interceptor[hook], option[hook]);
}
});
}
function addInterceptor (method, option) {
if (typeof method === 'string' && isPlainObject(option)) {
mergeInterceptorHook(scopedInterceptors[method] || (scopedInterceptors[method] = {}), option);
} else if (isPlainObject(method)) {
mergeInterceptorHook(globalInterceptors, method);
}
}
function removeInterceptor (method, option) {
if (typeof method === 'string') {
if (isPlainObject(option)) {
removeInterceptorHook(scopedInterceptors[method], option);
} else {
delete scopedInterceptors[method];
}
} else if (isPlainObject(method)) {
removeInterceptorHook(globalInterceptors, method);
}
}
function wrapperHook (hook) {
return function (data) {
return hook(data) || data
}
}
function isPromise (obj) {
return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function'
}
function queue (hooks, data) {
let promise = false;
for (let i = 0; i < hooks.length; i++) {
const hook = hooks[i];
if (promise) {
promise = Promise.then(wrapperHook(hook));
} else {
const res = hook(data);
if (isPromise(res)) {
promise = Promise.resolve(res);
}
if (res === false) {
return {
then () {}
}
}
}
}
return promise || {
then (callback) {
return callback(data)
}
}
}
function wrapperOptions (interceptor, options = {}) {
['success', 'fail', 'complete'].forEach(name => {
if (Array.isArray(interceptor[name])) {
const oldCallback = options[name];
options[name] = function callbackInterceptor (res) {
queue(interceptor[name], res).then((res) => {
/* eslint-disable no-mixed-operators */
return isFn(oldCallback) && oldCallback(res) || res
});
};
}
});
return options
}
function wrapperReturnValue (method, returnValue) {
const returnValueHooks = [];
if (Array.isArray(globalInterceptors.returnValue)) {
returnValueHooks.push(...globalInterceptors.returnValue);
}
const interceptor = scopedInterceptors[method];
if (interceptor && Array.isArray(interceptor.returnValue)) {
returnValueHooks.push(...interceptor.returnValue);
}
returnValueHooks.forEach(hook => {
returnValue = hook(returnValue) || returnValue;
});
return returnValue
}
function getApiInterceptorHooks (method) {
const interceptor = Object.create(null);
Object.keys(globalInterceptors).forEach(hook => {
if (hook !== 'returnValue') {
interceptor[hook] = globalInterceptors[hook].slice();
}
});
const scopedInterceptor = scopedInterceptors[method];
if (scopedInterceptor) {
Object.keys(scopedInterceptor).forEach(hook => {
if (hook !== 'returnValue') {
interceptor[hook] = (interceptor[hook] || []).concat(scopedInterceptor[hook]);
}
});
}
return interceptor
}
function invokeApi (method, api, options, ...params) {
const interceptor = getApiInterceptorHooks(method);
if (interceptor && Object.keys(interceptor).length) {
if (Array.isArray(interceptor.invoke)) {
const res = queue(interceptor.invoke, options);
return res.then((options) => {
return api(wrapperOptions(interceptor, options), ...params)
})
} else {
return api(wrapperOptions(interceptor, options), ...params)
}
}
return api(options, ...params)
}
const promiseInterceptor = {
returnValue (res) {
if (!isPromise(res)) {
return res
}
return res.then(res => {
return res[1]
}).catch(res => {
return res[0]
})
}
};
const SYNC_API_RE =
/^\$|sendNativeEvent|restoreGlobal|getCurrentSubNVue|getMenuButtonBoundingClientRect|^report|interceptors|Interceptor$|getSubNVueById|requireNativePlugin|upx2px|hideKeyboard|canIUse|^create|Sync$|Manager$|base64ToArrayBuffer|arrayBufferToBase64/;
const CONTEXT_API_RE = /^create|Manager$/;
const ASYNC_API = ['createBLEConnection'];
const CALLBACK_API_RE = /^on|^off/;
function isContextApi (name) {
return CONTEXT_API_RE.test(name)
}
function isSyncApi (name) {
return SYNC_API_RE.test(name) && ASYNC_API.indexOf(name) === -1
}
function isCallbackApi (name) {
return CALLBACK_API_RE.test(name) && name !== 'onPush'
}
function handlePromise (promise) {
return promise.then(data => {
return [null, data]
})
.catch(err => [err])
}
function shouldPromise (name) {
if (
isContextApi(name) ||
isSyncApi(name) ||
isCallbackApi(name)
) {
return false
}
return true
}
/* eslint-disable no-extend-native */
if (!Promise.prototype.finally) {
Promise.prototype.finally = function (callback) {
const promise = this.constructor;
return this.then(
value => promise.resolve(callback()).then(() => value),
reason => promise.resolve(callback()).then(() => {
throw reason
})
)
};
}
function promisify (name, api) {
if (!shouldPromise(name)) {
return api
}
return function promiseApi (options = {}, ...params) {
if (isFn(options.success) || isFn(options.fail) || isFn(options.complete)) {
return wrapperReturnValue(name, invokeApi(name, api, options, ...params))
}
return wrapperReturnValue(name, handlePromise(new Promise((resolve, reject) => {
invokeApi(name, api, Object.assign({}, options, {
success: resolve,
fail: reject
}), ...params);
})))
}
}
const EPS = 1e-4;
const BASE_DEVICE_WIDTH = 750;
let isIOS = false;
let deviceWidth = 0;
let deviceDPR = 0;
function checkDeviceWidth () {
const {
platform,
pixelRatio,
windowWidth
} = qa.getSystemInfoSync(); // uni=>qa runtime 编译目标是 uni 对象,内部不允许直接使用 uni
deviceWidth = windowWidth;
deviceDPR = pixelRatio;
isIOS = platform === 'ios';
}
function upx2px (number, newDeviceWidth) {
if (deviceWidth === 0) {
checkDeviceWidth();
}
number = Number(number);
if (number === 0) {
return 0
}
let result = (number / BASE_DEVICE_WIDTH) * (newDeviceWidth || deviceWidth);
if (result < 0) {
result = -result;
}
result = Math.floor(result + EPS);
if (result === 0) {
if (deviceDPR === 1 || !isIOS) {
return 1
} else {
return 0.5
}
}
return number < 0 ? -result : result
}
const interceptors = {
promiseInterceptor
};
var baseApi = /*#__PURE__*/Object.freeze({
__proto__: null,
upx2px: upx2px,
interceptors: interceptors,
addInterceptor: addInterceptor,
removeInterceptor: removeInterceptor
});
var previewImage = {
args (fromArgs) {
let currentIndex = parseInt(fromArgs.current);
if (isNaN(currentIndex)) {
return
}
const urls = fromArgs.urls;
if (!Array.isArray(urls)) {
return
}
const len = urls.length;
if (!len) {
return
}
if (currentIndex < 0) {
currentIndex = 0;
} else if (currentIndex >= len) {
currentIndex = len - 1;
}
if (currentIndex > 0) {
fromArgs.current = urls[currentIndex];
fromArgs.urls = urls.filter(
(item, index) => index < currentIndex ? item !== urls[currentIndex] : true
);
} else {
fromArgs.current = urls[0];
}
return {
indicator: false,
loop: false
}
}
};
const protocols = {
previewImage
};
const todos = [];
const canIUses = [];
const CALLBACKS = ['success', 'fail', 'cancel', 'complete'];
function processCallback (methodName, method, returnValue) {
return function (res) {
return method(processReturnValue(methodName, res, returnValue))
}
}
function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, keepFromArgs = false) {
if (isPlainObject(fromArgs)) { // 一般 api 的参数解析
const toArgs = keepFromArgs === true ? fromArgs : {}; // returnValue 为 false 时,说明是格式化返回值,直接在返回值对象上修改赋值
if (isFn(argsOption)) {
argsOption = argsOption(fromArgs, toArgs) || {};
}
for (let key in fromArgs) {
if (hasOwn(argsOption, key)) {
let keyOption = argsOption[key];
if (isFn(keyOption)) {
keyOption = keyOption(fromArgs[key], fromArgs, toArgs);
}
if (!keyOption) { // 不支持的参数
console.warn(`快应用(Light)版 ${methodName}暂不支持${key}`);
} else if (isStr(keyOption)) { // 重写参数 key
toArgs[keyOption] = fromArgs[key];
} else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value;
}
} else if (CALLBACKS.indexOf(key) !== -1) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue);
} else {
if (!keepFromArgs) {
toArgs[key] = fromArgs[key];
}
}
}
return toArgs
} else if (isFn(fromArgs)) {
fromArgs = processCallback(methodName, fromArgs, returnValue);
}
return fromArgs
}
function processReturnValue (methodName, res, returnValue, keepReturnValue = false) {
if (isFn(protocols.returnValue)) { // 处理通用 returnValue
res = protocols.returnValue(methodName, res);
}
return processArgs(methodName, res, returnValue, {}, keepReturnValue)
}
function wrapper (methodName, method) {
if (hasOwn(protocols, methodName)) {
const protocol = protocols[methodName];
if (!protocol) { // 暂不支持的 api
return function () {
console.error(`快应用(Light)版 暂不支持${methodName}`);
}
}
return function (arg1, arg2) { // 目前 api 最多两个参数
let options = protocol;
if (isFn(protocol)) {
options = protocol(arg1);
}
arg1 = processArgs(methodName, arg1, options.args, options.returnValue);
const args = [arg1];
if (typeof arg2 !== 'undefined') {
args.push(arg2);
}
const returnValue = qa[options.name || methodName].apply(qa, args);
if (isSyncApi(methodName)) { // 同步 api
return processReturnValue(methodName, returnValue, options.returnValue, isContextApi(methodName))
}
return returnValue
}
}
return method
}
const todoApis = Object.create(null);
const TODOS = [
'onTabBarMidButtonTap',
'subscribePush',
'unsubscribePush',
'onPush',
'offPush',
'share'
];
function createTodoApi (name) {
return function todoApi ({
fail,
complete
}) {
const res = {
errMsg: `${name}:fail:暂不支持 ${name} 方法`
};
isFn(fail) && fail(res);
isFn(complete) && complete(res);
}
}
TODOS.forEach(function (name) {
todoApis[name] = createTodoApi(name);
});
const providers = {
oauth: [],
share: [],
payment: [],
push: []
};
if (qa.canIUse('getAccountProvider')) {
providers.oauth.push(qa.getAccountProvider());
}
if (qa.canIUse('getVendorPaymentProvider')) {
providers.payment.push(qa.getVendorPaymentProvider());
}
function getProvider ({
service,
success,
fail,
complete
}) {
let res = false;
if (providers[service]) {
res = {
errMsg: 'getProvider:ok',
service,
provider: providers[service]
};
isFn(success) && success(res);
} else {
res = {
errMsg: 'getProvider:fail:服务[' + service + ']不存在'
};
isFn(fail) && fail(res);
}
isFn(complete) && complete(res);
}
var extraApi = /*#__PURE__*/Object.freeze({
__proto__: null,
getProvider: getProvider
});
const getEmitter = (function () {
if (typeof getUniEmitter === 'function') {
/* eslint-disable no-undef */
return getUniEmitter
}
let Emitter;
return function getUniEmitter () {
if (!Emitter) {
Emitter = new Vue();
}
return Emitter
}
})();
function apply (ctx, method, args) {
return ctx[method].apply(ctx, args)
}
function $on () {
return apply(getEmitter(), '$on', [...arguments])
}
function $off () {
return apply(getEmitter(), '$off', [...arguments])
}
function $once () {
return apply(getEmitter(), '$once', [...arguments])
}
function $emit () {
return apply(getEmitter(), '$emit', [...arguments])
}
var eventApi = /*#__PURE__*/Object.freeze({
__proto__: null,
$on: $on,
$off: $off,
$once: $once,
$emit: $emit
});
var api = /*#__PURE__*/Object.freeze({
__proto__: null
});
const MPPage = Page;
const MPComponent = Component;
const customizeRE = /:/g;
const customize = cached((str) => {
return camelize(str.replace(customizeRE, '-'))
});
function initTriggerEvent (mpInstance) {
const oldTriggerEvent = mpInstance.triggerEvent;
mpInstance.triggerEvent = function (event, ...args) {
return oldTriggerEvent.apply(mpInstance, [customize(event), ...args])
};
}
function initHook (name, options) {
const oldHook = options[name];
if (!oldHook) {
options[name] = function () {
initTriggerEvent(this);
};
} else {
options[name] = function (...args) {
initTriggerEvent(this);
return oldHook.apply(this, args)
};
}
}
Page = function (options = {}) {
initHook('onLoad', options);
return MPPage(options)
};
Component = function (options = {}) {
initHook('created', options);
return MPComponent(options)
};
const PAGE_EVENT_HOOKS = [
'onPullDownRefresh',
'onReachBottom',
'onShareAppMessage',
'onPageScroll',
'onResize',
'onTabItemTap'
];
function initMocks (vm, mocks) {
const mpInstance = vm.$mp[vm.mpType];
mocks.forEach(mock => {
if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock];
}
});
}
function hasHook (hook, vueOptions) {
if (!vueOptions) {
return true
}
if (Vue.options && Array.isArray(Vue.options[hook])) {
return true
}
vueOptions = vueOptions.default || vueOptions;
if (isFn(vueOptions)) {
if (isFn(vueOptions.extendOptions[hook])) {
return true
}
if (vueOptions.super &&
vueOptions.super.options &&
Array.isArray(vueOptions.super.options[hook])) {
return true
}
return false
}
if (isFn(vueOptions[hook])) {
return true
}
const mixins = vueOptions.mixins;
if (Array.isArray(mixins)) {
return !!mixins.find(mixin => hasHook(hook, mixin))
}
}
function initHooks (mpOptions, hooks, vueOptions) {
hooks.forEach(hook => {
if (hasHook(hook, vueOptions)) {
mpOptions[hook] = function (args) {
return this.$vm && this.$vm.__call_hook(hook, args)
};
}
});
}
function initVueComponent (Vue, vueOptions) {
vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions;
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
return [VueComponent, vueOptions]
}
function initSlots (vm, vueSlots) {
if (Array.isArray(vueSlots) && vueSlots.length) {
const $slots = Object.create(null);
vueSlots.forEach(slotName => {
$slots[slotName] = true;
});
vm.$scopedSlots = vm.$slots = $slots;
}
}
function initVueIds (vueIds, mpInstance) {
vueIds = (vueIds || '').split(',');
const len = vueIds.length;
if (len === 1) {
mpInstance._$vueId = vueIds[0];
} else if (len === 2) {
mpInstance._$vueId = vueIds[0];
mpInstance._$vuePid = vueIds[1];
}
}
function initData (vueOptions, context) {
let data = vueOptions.data || {};
const methods = vueOptions.methods || {};
if (typeof data === 'function') {
try {
data = data.call(context); // 支持 Vue.prototype 上挂的数据
} catch (e) {
if (process.env.VUE_APP_DEBUG) {
console.warn('根据 Vue 的 data 函数初始化小程序 data 失败,请尽量确保 data 函数中不访问 vm 对象,否则可能影响首次数据渲染速度。', data);
}
}
} else {
try {
// 对 data 格式化
data = JSON.parse(JSON.stringify(data));
} catch (e) {}
}
if (!isPlainObject(data)) {
data = {};
}
Object.keys(methods).forEach(methodName => {
if (context.__lifecycle_hooks__.indexOf(methodName) === -1 && !hasOwn(data, methodName)) {
data[methodName] = methods[methodName];
}
});
return data
}
const PROP_TYPES = [String, Number, Boolean, Object, Array, null];
function createObserver (name) {
return function observer (newVal, oldVal) {
if (this.$vm) {
this.$vm[name] = newVal; // 为了触发其他非 render watcher
}
}
}
function initBehaviors (vueOptions, initBehavior) {
const vueBehaviors = vueOptions['behaviors'];
const vueExtends = vueOptions['extends'];
const vueMixins = vueOptions['mixins'];
let vueProps = vueOptions['props'];
if (!vueProps) {
vueOptions['props'] = vueProps = [];
}
const behaviors = [];
if (Array.isArray(vueBehaviors)) {
vueBehaviors.forEach(behavior => {
behaviors.push(behavior.replace('uni://', `${"qa"}://`));
if (behavior === 'uni://form-field') {
if (Array.isArray(vueProps)) {
vueProps.push('name');
vueProps.push('value');
} else {
vueProps['name'] = {
type: String,
default: ''
};
vueProps['value'] = {
type: [String, Number, Boolean, Array, Object, Date],
default: ''
};
}
}
});
}
if (isPlainObject(vueExtends) && vueExtends.props) {
behaviors.push(
initBehavior({
properties: initProperties(vueExtends.props, true)
})
);
}
if (Array.isArray(vueMixins)) {
vueMixins.forEach(vueMixin => {
if (isPlainObject(vueMixin) && vueMixin.props) {
behaviors.push(
initBehavior({
properties: initProperties(vueMixin.props, true)
})
);
}
});
}
return behaviors
}
function parsePropType (key, type, defaultValue, file) {
// [String]=>String
if (Array.isArray(type) && type.length === 1) {
return type[0]
}
return type
}
function initProperties (props, isBehavior = false, file = '') {
const properties = {};
if (!isBehavior) {
properties.vueId = {
type: String,
value: ''
};
properties.vueSlots = { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
type: null,
value: [],
observer: function (newVal, oldVal) {
const $slots = Object.create(null);
newVal.forEach(slotName => {
$slots[slotName] = true;
});
this.setData({
$slots
});
}
};
}
if (Array.isArray(props)) { // ['title']
props.forEach(key => {
properties[key] = {
type: null,
observer: createObserver(key)
};
});
} else if (isPlainObject(props)) { // {title:{type:String,default:''},content:String}
Object.keys(props).forEach(key => {
const opts = props[key];
if (isPlainObject(opts)) { // title:{type:String,default:''}
let value = opts['default'];
if (isFn(value)) {
value = value();
}
opts.type = parsePropType(key, opts.type);
properties[key] = {
type: PROP_TYPES.indexOf(opts.type) !== -1 ? opts.type : null,
value,
observer: createObserver(key)
};
} else { // content:String
const type = parsePropType(key, opts);
properties[key] = {
type: PROP_TYPES.indexOf(type) !== -1 ? type : null,
observer: createObserver(key)
};
}
});
}
return properties
}
function wrapper$1 (event) {
// TODO 又得兼容 mpvue 的 mp 对象
try {
event.mp = JSON.parse(JSON.stringify(event));
} catch (e) {}
event.stopPropagation = noop;
event.preventDefault = noop;
event.target = event.target || {};
if (!hasOwn(event, 'detail')) {
event.detail = {};
}
if (isPlainObject(event.detail)) {
event.target = Object.assign({}, event.target, event.detail);
}
return event
}
function getExtraValue (vm, dataPathsArray) {
let context = vm;
dataPathsArray.forEach(dataPathArray => {
const dataPath = dataPathArray[0];
const value = dataPathArray[2];
if (dataPath || typeof value !== 'undefined') { // ['','',index,'disable']
const propPath = dataPathArray[1];
const valuePath = dataPathArray[3];
const vFor = dataPath ? vm.__get_value(dataPath, context) : context;
if (Number.isInteger(vFor)) {
context = value;
} else if (!propPath) {
context = vFor[value];
} else {
if (Array.isArray(vFor)) {
context = vFor.find(vForItem => {
return vm.__get_value(propPath, vForItem) === value
});
} else if (isPlainObject(vFor)) {
context = Object.keys(vFor).find(vForKey => {
return vm.__get_value(propPath, vFor[vForKey]) === value
});
} else {
console.error('v-for 暂不支持循环数据:', vFor);
}
}
if (valuePath) {
context = vm.__get_value(valuePath, context);
}
}
});
return context
}
function processEventExtra (vm, extra, event) {
const extraObj = {};
if (Array.isArray(extra) && extra.length) {
/**
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*[
* ['data.items', 'data.id', item.data.id],
* ['metas', 'id', meta.id]
*],
*'test'
*/
extra.forEach((dataPath, index) => {
if (typeof dataPath === 'string') {
if (!dataPath) { // model,prop.sync
extraObj['$' + index] = vm;
} else {
if (dataPath === '$event') { // $event
extraObj['$' + index] = event;
} else if (dataPath.indexOf('$event.') === 0) { // $event.target.value
extraObj['$' + index] = vm.__get_value(dataPath.replace('$event.', ''), event);
} else {
extraObj['$' + index] = vm.__get_value(dataPath);
}
}
} else {
extraObj['$' + index] = getExtraValue(vm, dataPath);
}
});
}
return extraObj
}
function getObjByArray (arr) {
const obj = {};
for (let i = 1; i < arr.length; i++) {
const element = arr[i];
obj[element[0]] = element[1];
}
return obj
}
function processEventArgs (vm, event, args = [], extra = [], isCustom, methodName) {
let isCustomMPEvent = false; // wxcomponent 组件,传递原始 event 对象
if (isCustom) { // 自定义事件
isCustomMPEvent = event.currentTarget &&
event.currentTarget.dataset &&
event.currentTarget.dataset.comType === 'wx';
if (!args.length) { // 无参数,直接传入 event 或 detail 数组
if (isCustomMPEvent) {
return [event]
}
return event.detail.__args__ || event.detail
}
}
const extraObj = processEventExtra(vm, extra, event);
const ret = [];
args.forEach(arg => {
if (arg === '$event') {
if (methodName === '__set_model' && !isCustom) { // input v-model value
ret.push(event.target.value);
} else {
if (isCustom && !isCustomMPEvent) {
ret.push(event.detail.__args__[0]);
} else { // wxcomponent 组件或内置组件
ret.push(event);
}
}
} else {
if (Array.isArray(arg) && arg[0] === 'o') {
ret.push(getObjByArray(arg));
} else if (typeof arg === 'string' && hasOwn(extraObj, arg)) {
ret.push(extraObj[arg]);
} else {
ret.push(arg);
}
}
});
return ret
}
const ONCE = '~';
const CUSTOM = '^';
function isMatchEventType (eventType, optType) {
return (eventType === optType) ||
(
optType === 'regionchange' &&
(
eventType === 'begin' ||
eventType === 'end'
)
)
}
function handleEvent (event) {
event = wrapper$1(event);
// [['tap',[['handle',[1,2,a]],['handle1',[1,2,a]]]]]
const dataset = (event.currentTarget || event.target).dataset;
if (!dataset) {
return console.warn(`事件信息不存在`)
}
const eventOpts = dataset.eventOpts || dataset['event-opts']; // 支付宝 web-view 组件 dataset 非驼峰
if (!eventOpts) {
return console.warn(`事件信息不存在`)
}
// [['handle',[1,2,a]],['handle1',[1,2,a]]]
const eventType = event.type;
const ret = [];
eventOpts.forEach(eventOpt => {
let type = eventOpt[0];
const eventsArray = eventOpt[1];
const isCustom = type.charAt(0) === CUSTOM;
type = isCustom ? type.slice(1) : type;
const isOnce = type.charAt(0) === ONCE;
type = isOnce ? type.slice(1) : type;
if (eventsArray && isMatchEventType(eventType, type)) {
eventsArray.forEach(eventArray => {
const methodName = eventArray[0];
if (methodName) {
let handlerCtx = this.$vm;
if (
handlerCtx.$options.generic &&
handlerCtx.$parent &&
handlerCtx.$parent.$parent
) { // mp-weixin,mp-toutiao 抽象节点模拟 scoped slots
handlerCtx = handlerCtx.$parent.$parent;
}
if (methodName === '$emit') {
handlerCtx.$emit.apply(handlerCtx,
processEventArgs(
this.$vm,
event,
eventArray[1],
eventArray[2],
isCustom,
methodName
));
return
}
const handler = handlerCtx[methodName];
if (!isFn(handler)) {
throw new Error(` _vm.${methodName} is not a function`)
}
if (isOnce) {
if (handler.once) {
return
}
handler.once = true;
}
ret.push(handler.apply(handlerCtx, processEventArgs(
this.$vm,
event,
eventArray[1],
eventArray[2],
isCustom,
methodName
)));
}
});
}
});
if (
eventType === 'input' &&
ret.length === 1 &&
typeof ret[0] !== 'undefined'
) {
return ret[0]
}
}
const hooks = [
'onShow',
'onHide',
'onError',
'onPageNotFound'
];
function parseBaseApp (vm, {
mocks,
initRefs
}) {
if (vm.$options.store) {
Vue.prototype.$store = vm.$options.store;
}
Vue.prototype.mpHost = "quickapp-light";
Vue.mixin({
beforeCreate () {
if (!this.$options.mpType) {
return
}
this.mpType = this.$options.mpType;
this.$mp = {
data: {},
[this.mpType]: this.$options.mpInstance
};
this.$scope = this.$options.mpInstance;
delete this.$options.mpType;
delete this.$options.mpInstance;
if (this.mpType !== 'app') {
initRefs(this);
initMocks(this, mocks);
}
}
});
const appOptions = {
onLaunch (args) {
if (this.$vm) { // 已经初始化过了,主要是为了百度,百度 onShow 在 onLaunch 之前
return
}
this.$vm = vm;
this.$vm.$mp = {
app: this
};
this.$vm.$scope = this;
// vm 上也挂载 globalData
this.$vm.globalData = this.globalData;
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted', args);
this.$vm.__call_hook('onLaunch', args);
}
};
// 兼容旧版本 globalData
appOptions.globalData = vm.$options.globalData || {};
// 将 methods 中的方法挂在 getApp() 中
const methods = vm.$options.methods;
if (methods) {
Object.keys(methods).forEach(name => {
appOptions[name] = methods[name];
});
}
initHooks(appOptions, hooks);
return appOptions
}
const mocks = ['nodeId', 'componentName'];
function isPage () {
return !this.ownerId
}
function findVmByVueId (vm, vuePid) {
const $children = vm.$children;
// 优先查找直属(反向查找:https://github.com/dcloudio/uni-app/issues/1200)
for (let i = $children.length - 1; i >= 0; i--) {
const childVm = $children[i];
if (childVm.$scope._$vueId === vuePid) {
return childVm
}
}
// 反向递归查找
let parentVm;
for (let i = $children.length - 1; i >= 0; i--) {
parentVm = findVmByVueId($children[i], vuePid);
if (parentVm) {
return parentVm
}
}
}
function initBehavior (options) {
return Behavior(options)
}
function initRefs (vm) {
const mpInstance = vm.$scope;
Object.defineProperty(vm, '$refs', {
get () {
const $refs = {};
const components = mpInstance.selectAllComponents('.vue-ref');
components.forEach(component => {
const ref = component.dataset.ref;
$refs[ref] = component.$vm || component;
});
const forComponents = mpInstance.selectAllComponents('.vue-ref-in-for');
forComponents.forEach(component => {
const ref = component.dataset.ref;
if (!$refs[ref]) {
$refs[ref] = [];
}
$refs[ref].push(component.$vm || component);
});
return $refs
}
});
}
function handleLink (event) {
const {
vuePid,
vueOptions
} = event.detail || event.value; // detail 是微信,value 是百度(dipatch)
let parentVm;
if (vuePid) {
parentVm = findVmByVueId(this.$vm, vuePid);
}
if (!parentVm) {
parentVm = this.$vm;
}
vueOptions.parent = parentVm;
}
const instances = Object.create(null);
function initRelation ({
vuePid,
mpInstance
}) {
// triggerEvent 后,接收事件时机特别晚,已经到了 ready 之后
const nodeId = mpInstance.nodeId + '';
const webviewId = mpInstance.pageinstance.__pageId__ + '';
instances[webviewId + '_' + nodeId] = mpInstance.$vm;
this.triggerEvent('__l', {
vuePid,
nodeId,
webviewId
});
}
function handleLink$1 ({
detail: {
nodeId,
webviewId
}
}) {
const vm = instances[webviewId + '_' + nodeId];
if (!vm) {
return
}
let parentVm = instances[webviewId + '_' + vm.$scope.ownerId];
if (!parentVm) {
parentVm = this.$vm;
}
vm.$parent = parentVm;
vm.$root = parentVm.$root;
parentVm.$children.push(vm);
const createdVm = function () {
vm.__call_hook('created');
};
const mountedVm = function () {
// 处理当前 vm 子
if (vm._$childVues) {
vm._$childVues.forEach(([createdVm]) => createdVm());
vm._$childVues.forEach(([, mountedVm]) => mountedVm());
delete vm._$childVues;
}
vm.__call_hook('beforeMount');
vm._isMounted = true;
vm.__call_hook('mounted');
vm.__call_hook('onReady');
};
// 当 parentVm 已经 mounted 时,直接触发,否则延迟
if (!parentVm || parentVm._isMounted) {
createdVm();
mountedVm();
} else {
(parentVm._$childVues || (parentVm._$childVues = [])).push([createdVm, mountedVm]);
}
}
function parseApp (vm) {
Vue.prototype._$fallback = true; // 降级(调整原 vue 的部分生命周期,如 created,beforeMount,inject,provide)
Vue.mixin({
created () { // 处理 injections, triggerEvent 是异步,且触发时机很慢,故延迟 relation 设置
if (this.mpType !== 'app') {
initRefs(this);
this.__init_injections(this);
this.__init_provide(this);
}
}
});
return parseBaseApp(vm, {
mocks,
initRefs: function () {} // attached 时,可能查询不到
})
}
function createApp (vm) {
App(parseApp(vm));
return vm
}
function parseBaseComponent (vueComponentOptions, {
isPage,
initRelation
} = {}) {
let [VueComponent, vueOptions] = initVueComponent(Vue, vueComponentOptions);
const options = {
multipleSlots: true,
addGlobalClass: true,
...(vueOptions.options || {})
};
const componentOptions = {
options,
data: initData(vueOptions, Vue.prototype),
behaviors: initBehaviors(vueOptions, initBehavior),
properties: initProperties(vueOptions.props, false, vueOptions.__file),
lifetimes: {
attached () {
const properties = this.properties;
const options = {
mpType: isPage.call(this) ? 'page' : 'component',
mpInstance: this,
propsData: properties
};
initVueIds(properties.vueId, this);
// 处理父子关系
initRelation.call(this, {
vuePid: this._$vuePid,
vueOptions: options
});
// 初始化 vue 实例
this.$vm = new VueComponent(options);
// 处理$slots,$scopedSlots(暂不支持动态变化$slots)
initSlots(this.$vm, properties.vueSlots);
// 触发首次 setData
this.$vm.$mount();
},
ready () {
// 当组件 props 默认值为 true,初始化时传入 false 会导致 created,ready 触发, 但 attached 不触发
// https://developers.weixin.qq.com/community/develop/doc/00066ae2844cc0f8eb883e2a557800
if (this.$vm) {
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
}
},
detached () {
this.$vm && this.$vm.$destroy();
}
},
pageLifetimes: {
show (args) {
this.$vm && this.$vm.__call_hook('onPageShow', args);
},
hide () {
this.$vm && this.$vm.__call_hook('onPageHide');
},
resize (size) {
this.$vm && this.$vm.__call_hook('onPageResize', size);
}
},
methods: {
__l: handleLink,
__e: handleEvent
}
};
if (Array.isArray(vueOptions.wxsCallMethods)) {
vueOptions.wxsCallMethods.forEach(callMethod => {
componentOptions.methods[callMethod] = function (args) {
return this.$vm[callMethod](args)
};
});
}
if (isPage) {
return componentOptions
}
return [componentOptions, VueComponent]
}
function parseComponent (vueOptions) {
const [componentOptions, VueComponent] = parseBaseComponent(vueOptions);
componentOptions.lifetimes.attached = function attached () {
const properties = this.properties;
const options = {
mpType: isPage.call(this) ? 'page' : 'component',
mpInstance: this,
propsData: properties
};
initVueIds(properties.vueId, this);
// 初始化 vue 实例
this.$vm = new VueComponent(options);
// 处理$slots,$scopedSlots(暂不支持动态变化$slots)
initSlots(this.$vm, properties.vueSlots);
// 处理父子关系
initRelation.call(this, {
vuePid: this._$vuePid,
mpInstance: this
});
// 触发首次 setData
this.$vm.$mount();
};
// ready 比 handleLink 还早,初始化逻辑放到 handleLink 中
delete componentOptions.lifetimes.ready;
componentOptions.methods.__l = handleLink$1;
return componentOptions
}
const hooks$1 = [
'onShow',
'onHide',
'onUnload'
];
hooks$1.push(...PAGE_EVENT_HOOKS);
function parseBasePage (vuePageOptions, {
isPage,
initRelation
}) {
const pageOptions = parseComponent(vuePageOptions);
initHooks(pageOptions.methods, hooks$1, vuePageOptions);
pageOptions.methods.onLoad = function (args) {
this.$vm.$mp.query = args; // 兼容 mpvue
this.$vm.__call_hook('onLoad', args);
};
return pageOptions
}
function parsePage (vuePageOptions) {
const pageOptions = parseBasePage(vuePageOptions, {
isPage,
initRelation
});
// 页面需要在 ready 中触发,其他组件是在 handleLink 中触发
pageOptions.lifetimes.ready = function ready () {
if (this.$vm && this.$vm.mpType === 'page') {
this.$vm.__call_hook('created');
this.$vm.__call_hook('beforeMount');
this.$vm._isMounted = true;
this.$vm.__call_hook('mounted');
this.$vm.__call_hook('onReady');
} else {
this.is && console.warn(this.is + ' is not ready');
}
};
pageOptions.lifetimes.detached = function detached () {
this.$vm && this.$vm.$destroy();
// 清理
const pageId = this.pageinstance.__pageId__;
Object.keys(instances).forEach(key => {
if (key.indexOf(pageId + '_') === 0) {
delete instances[key];
}
});
};
return pageOptions
}
function createPage (vuePageOptions) {
{
return Component(parsePage(vuePageOptions))
}
}
function createComponent (vueOptions) {
{
return Component(parseComponent(vueOptions))
}
}
todos.forEach(todoApi => {
protocols[todoApi] = false;
});
canIUses.forEach(canIUseApi => {
const apiName = protocols[canIUseApi] && protocols[canIUseApi].name ? protocols[canIUseApi].name
: canIUseApi;
if (!qa.canIUse(apiName)) {
protocols[canIUseApi] = false;
}
});
let uni = {};
if (typeof Proxy !== 'undefined' && "quickapp-light" !== 'app-plus') {
uni = new Proxy({}, {
get (target, name) {
if (target[name]) {
return target[name]
}
if (baseApi[name]) {
return baseApi[name]
}
if (api[name]) {
return promisify(name, api[name])
}
{
if (extraApi[name]) {
return promisify(name, extraApi[name])
}
if (todoApis[name]) {
return promisify(name, todoApis[name])
}
}
if (eventApi[name]) {
return eventApi[name]
}
if (!hasOwn(qa, name) && !hasOwn(protocols, name)) {
return
}
return promisify(name, wrapper(name, qa[name]))
},
set (target, name, value) {
target[name] = value;
return true
}
});
} else {
Object.keys(baseApi).forEach(name => {
uni[name] = baseApi[name];
});
{
Object.keys(todoApis).forEach(name => {
uni[name] = promisify(name, todoApis[name]);
});
Object.keys(extraApi).forEach(name => {
uni[name] = promisify(name, todoApis[name]);
});
}
Object.keys(eventApi).forEach(name => {
uni[name] = eventApi[name];
});
Object.keys(api).forEach(name => {
uni[name] = promisify(name, api[name]);
});
Object.keys(qa).forEach(name => {
if (hasOwn(qa, name) || hasOwn(protocols, name)) {
uni[name] = promisify(name, wrapper(name, qa[name]));
}
});
}
qa.createApp = createApp;
qa.createPage = createPage;
qa.createComponent = createComponent;
var uni$1 = uni;
export default uni$1;
export { createApp, createComponent, createPage };
{
"compilerOptions": {
"target": "es6",
"module": "commonjs"
}
}
\ No newline at end of file
const compiler = require('@dcloudio/uni-mp-weixin/lib/uni.compiler.js')
module.exports = Object.assign({}, compiler, {
directive: 'qa:'
})
const fs = require('fs')
const path = require('path')
module.exports = {
options: {
cssVars: {
'--status-bar-height': '25px',
'--window-top': '0px',
'--window-bottom': '0px'
},
extnames: {
style: '.css',
template: '.qxml',
filter: '.qjs'
},
filterTag: 'qjs'
},
validate (platformOptions, manifestJson) {
if (!platformOptions.package) {
console.warn('manifest.json->quickapp-light 缺少 package 配置')
}
if (!platformOptions.icon) {
console.error('manifest.json->quickapp-light 缺少 icon 配置')
}
},
copyWebpackOptions (platformOptions, vueOptions) {
const jsConfigPath = path.resolve(process.env.UNI_INPUT_DIR, 'jsconfig.json')
if (fs.existsSync(jsConfigPath)) {
return [jsConfigPath]
}
return [path.resolve(__dirname, 'assets/jsconfig.json')]
},
configureWebpack () {
return {
devtool: process.env.NODE_ENV === 'production' ? false : 'inline-source-map'
}
}
}
{
"name": "@dcloudio/uni-quickapp-light",
"version": "2.0.0-alpha-26420200309002",
"description": "uni-app quickapp-light",
"main": "dist/index.js",
"repository": {
"type": "git",
"url": "git+https://github.com/dcloudio/uni-app.git",
"directory": "packages/uni-quickapp-light"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "fxy060608",
"license": "Apache-2.0",
"uni-app": {
"name": "quickapp-light",
"title": "快应用(Light)版"
},
"gitHead": "84e9cb1ca1898054d161f1514efadd1ab24fd804"
}
const compiler = require('../lib')
function assertCodegen (template, templateCode, renderCode = `with(this){}`, options = {}) {
const res = compiler.compile(template, {
resourcePath: 'test.qxml',
mp: Object.assign({
minified: true,
isTest: true,
platform: 'quickapp-light'
}, options)
})
expect(res.template).toBe(templateCode)
expect(res.render).toBe(renderCode)
}
describe('mp:compiler-quickapp-light', () => {
it('generate v-for directive', () => {
assertCodegen(
'<view><view v-for="(item,index) in items" :key="index"></view></view>',
`<view><block qa:for="{{items}}" qa:for-item="item" qa:for-index="index" qa:key="index"><view></view></block></view>`
)
})
it('generate v-else-if with v-else directive', () => {
assertCodegen(
'<view><view v-if="show">hello</view><view v-else-if="hide">world</view><view v-else>bye</view></view>',
`<view><block qa:if="{{show}}"><view>hello</view></block><block qa:else><block qa:if="{{hide}}"><view>world</view></block><block qa:else><view>bye</view></block></block></view>`
)
})
})
......@@ -4971,10 +4971,10 @@ function initMixin (Vue) {
initEvents(vm);
initRender(vm);
callHook(vm, 'beforeCreate');
vm.mpHost !== 'mp-toutiao' && initInjections(vm); // resolve injections before data/props
!vm._$fallback && initInjections(vm); // resolve injections before data/props
initState(vm);
vm.mpHost !== 'mp-toutiao' && initProvide(vm); // resolve provide after data/props
vm.mpHost !== 'mp-toutiao' && callHook(vm, 'created');
!vm._$fallback && initProvide(vm); // resolve provide after data/props
!vm._$fallback && callHook(vm, 'created');
/* istanbul ignore if */
if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
......@@ -5690,7 +5690,7 @@ function mountComponent$1(
}
}
vm.mpHost !== 'mp-toutiao' && callHook(vm, 'beforeMount');
!vm._$fallback && callHook(vm, 'beforeMount');
var updateComponent = function () {
vm._update(vm._render(), hydrating);
......
/**
* webpack-uni-pages-loader 待重构,需要将平台特有逻辑,收敛到各自包内
* @param {Object} pagesJson
* @param {Object} manifestJson
*/
module.exports = function (pagesJson, manifestJson) {
const {
app
} = require('../mp')(pagesJson, manifestJson)
const baseJson = {
minPlatformVersion: 1053
}
manifestJson.name && (baseJson.name = manifestJson.name)
manifestJson.versionName && (baseJson.versionName = manifestJson.versionName)
manifestJson.versionCode && (baseJson.versionCode = manifestJson.versionCode)
Object.assign(app.content, baseJson, manifestJson['quickapp-light'] || {})
if (!app.content.package) {
app.content.package = manifestJson.name
}
return [app]
}
......@@ -19,6 +19,9 @@ import {
import {
initWebviewApi as initWeixinWebviewApi
} from 'uni-platforms/mp-weixin/runtime/web-view'
import {
initWebviewApi as initQuickappWebviewApi
} from 'uni-platforms/quickapp-light/runtime/web-view'
const UniAppJSBridgeReady = function () {
window.UniAppJSBridge = true
......@@ -35,6 +38,7 @@ const initWebviewApis = [
initAlipayWebviewApi,
initBaiduWebviewApi,
initToutiaoWebviewApi,
initQuickappWebviewApi,
initH5WebviewApi
]
......@@ -61,4 +65,4 @@ if (!api.navigateTo) {
}
api.webView = webViewApi
export default api
export default api
import previewImage from '../../../mp-weixin/helpers/normalize-preview-image'
export const protocols = {
previewImage
}
export const todos = []
export const canIUses = []
const providers = {
oauth: [],
share: [],
payment: [],
push: []
}
if (qa.canIUse('getAccountProvider')) {
providers.oauth.push(qa.getAccountProvider())
}
if (qa.canIUse('getVendorPaymentProvider')) {
providers.payment.push(qa.getVendorPaymentProvider())
}
export default providers
import '../../mp-weixin/runtime/index'
const isQuickapp = window.qa &&
/quickapp/i.test(navigator.userAgent)
export function initWebviewApi (readyCallback) {
if (!isQuickapp) {
return
}
if (window.QaJSBridge && window.QaJSBridge.invoke) {
setTimeout(readyCallback, 0)
} else {
document.addEventListener('QaJSBridgeReady', readyCallback)
}
const {
navigateTo,
navigateBack,
switchTab,
reLaunch,
redirectTo,
postMessage,
getEnv
} = window.qa
return {
navigateTo,
navigateBack,
switchTab,
reLaunch,
redirectTo,
postMessage,
getEnv
}
}
import Vue from 'vue'
import parseBaseApp from '../../../mp-weixin/runtime/wrapper/app-base-parser'
import {
mocks,
initRefs
} from './util'
export default function parseApp (vm) {
Vue.prototype._$fallback = true // 降级(调整原 vue 的部分生命周期,如 created,beforeMount,inject,provide)
Vue.mixin({
created () { // 处理 injections, triggerEvent 是异步,且触发时机很慢,故延迟 relation 设置
if (this.mpType !== 'app') {
initRefs(this)
this.__init_injections(this)
this.__init_provide(this)
}
}
})
return parseBaseApp(vm, {
mocks,
initRefs: function () {} // attached 时,可能查询不到
})
}
import {
isPage,
initRelation,
handleLink
} from './util'
import {
initSlots,
initVueIds
} from 'uni-wrapper/util'
import parseBaseComponent from '../../../mp-weixin/runtime/wrapper/component-base-parser'
export default function parseComponent (vueOptions) {
const [componentOptions, VueComponent] = parseBaseComponent(vueOptions)
componentOptions.lifetimes.attached = function attached () {
const properties = this.properties
const options = {
mpType: isPage.call(this) ? 'page' : 'component',
mpInstance: this,
propsData: properties
}
initVueIds(properties.vueId, this)
// 初始化 vue 实例
this.$vm = new VueComponent(options)
// 处理$slots,$scopedSlots(暂不支持动态变化$slots)
initSlots(this.$vm, properties.vueSlots)
// 处理父子关系
initRelation.call(this, {
vuePid: this._$vuePid,
mpInstance: this
})
// 触发首次 setData
this.$vm.$mount()
}
// ready 比 handleLink 还早,初始化逻辑放到 handleLink 中
delete componentOptions.lifetimes.ready
componentOptions.methods.__l = handleLink
return componentOptions
}
import {
isPage,
instances,
initRelation
} from './util'
import parseBasePage from '../../../mp-weixin/runtime/wrapper/page-base-parser'
export default function parsePage (vuePageOptions) {
const pageOptions = parseBasePage(vuePageOptions, {
isPage,
initRelation
})
// 页面需要在 ready 中触发,其他组件是在 handleLink 中触发
pageOptions.lifetimes.ready = function ready () {
if (this.$vm && this.$vm.mpType === 'page') {
this.$vm.__call_hook('created')
this.$vm.__call_hook('beforeMount')
this.$vm._isMounted = true
this.$vm.__call_hook('mounted')
this.$vm.__call_hook('onReady')
} else {
this.is && console.warn(this.is + ' is not ready')
}
}
pageOptions.lifetimes.detached = function detached () {
this.$vm && this.$vm.$destroy()
// 清理
const pageId = this.pageinstance.__pageId__
Object.keys(instances).forEach(key => {
if (key.indexOf(pageId + '_') === 0) {
delete instances[key]
}
})
}
return pageOptions
}
export {
mocks,
isPage
}
from '../../../mp-baidu/runtime/wrapper/util'
export {
initRefs
}
from '../../../mp-weixin/runtime/wrapper/util'
export const instances = Object.create(null)
export function initRelation ({
vuePid,
mpInstance
}) {
// triggerEvent 后,接收事件时机特别晚,已经到了 ready 之后
const nodeId = mpInstance.nodeId + ''
const webviewId = mpInstance.pageinstance.__pageId__ + ''
instances[webviewId + '_' + nodeId] = mpInstance.$vm
this.triggerEvent('__l', {
vuePid,
nodeId,
webviewId
})
}
export function handleLink ({
detail: {
nodeId,
webviewId
}
}) {
const vm = instances[webviewId + '_' + nodeId]
if (!vm) {
return
}
let parentVm = instances[webviewId + '_' + vm.$scope.ownerId]
if (!parentVm) {
parentVm = this.$vm
}
vm.$parent = parentVm
vm.$root = parentVm.$root
parentVm.$children.push(vm)
const createdVm = function () {
vm.__call_hook('created')
}
const mountedVm = function () {
// 处理当前 vm 子
if (vm._$childVues) {
vm._$childVues.forEach(([createdVm]) => createdVm())
vm._$childVues.forEach(([, mountedVm]) => mountedVm())
delete vm._$childVues
}
vm.__call_hook('beforeMount')
vm._isMounted = true
vm.__call_hook('mounted')
vm.__call_hook('onReady')
}
// 当 parentVm 已经 mounted 时,直接触发,否则延迟
if (!parentVm || parentVm._isMounted) {
createdVm()
mountedVm()
} else {
(parentVm._$childVues || (parentVm._$childVues = [])).push([createdVm, mountedVm])
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册