diff --git a/build/rollup.config.js b/build/rollup.config.js
index 94e782a9fcffef928385b485c8cdd1971b224f35..f261bbc7c2560b53675382387cf8703df9cac3c4 100644
--- a/build/rollup.config.js
+++ b/build/rollup.config.js
@@ -41,6 +41,7 @@ module.exports = {
replace({
__GLOBAL__: platform.prefix,
__PLATFORM_TITLE__: platform.title,
+ __PLATFORM_PREFIX__: JSON.stringify(platform.prefix),
__PLATFORM__: JSON.stringify(process.env.UNI_PLATFORM)
})
],
diff --git a/package.json b/package.json
index 0e017e0ff76bc1a3ffb359e0e795924e42f03869..9ab868b0b30c6c48338886e9570cbdb83615e79d 100644
--- a/package.json
+++ b/package.json
@@ -76,7 +76,8 @@
"__PLATFORM__": true,
"__VERSION__": true,
"__GLOBAL__": true,
- "__PLATFORM_TITLE__": true
+ "__PLATFORM_TITLE__": true,
+ "__PLATFORM_PREFIX__":true
},
"rules": {
"no-tabs": 0,
diff --git a/packages/uni-app-plus/dist/index.js b/packages/uni-app-plus/dist/index.js
index 672330eed81d0cb362a7e40063385c9b21b3616f..1fe07d7a8f173e33b479fb557695fc1c56dc4e88 100644
--- a/packages/uni-app-plus/dist/index.js
+++ b/packages/uni-app-plus/dist/index.js
@@ -173,7 +173,7 @@ function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, k
} else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value;
}
- } else if (CALLBACKS.includes(key)) {
+ } else if (CALLBACKS.indexOf(key) !== -1) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue);
} else {
if (!keepFromArgs) {
@@ -309,11 +309,43 @@ Component = function (options = {}) {
return MPComponent(options)
};
-const MOCKS = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__', '__webviewId__'];
+const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'];
-function initMocks (vm) {
+function triggerLink (mpInstance, vueOptions) {
+ mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, {
+ bubbles: true,
+ composed: true
+ });
+}
+
+function handleLink (event) {
+ if (event.detail.$mp) { // vm
+ if (!event.detail.$parent) {
+ event.detail.$parent = this.$vm;
+ event.detail.$parent.$children.push(event.detail);
+
+ event.detail.$root = this.$vm.$root;
+ }
+ } else { // vueOptions
+ if (!event.detail.parent) {
+ event.detail.parent = this.$vm;
+ }
+ }
+}
+
+function initPage$1 (pageOptions) {
+ initComponent$1(pageOptions);
+}
+
+function initComponent$1 (componentOptions) {
+ componentOptions.methods.$getAppWebview = function () {
+ return plus.webview.getWebviewById(`${this.__wxWebviewId__}`)
+ };
+}
+
+function initMocks (vm, mocks) {
const mpInstance = vm.$mp[vm.mpType];
- MOCKS.forEach(mock => {
+ mocks.forEach(mock => {
if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock];
}
@@ -347,6 +379,10 @@ function getData (vueOptions, context) {
} 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];
@@ -366,9 +402,65 @@ function createObserver (name) {
}
}
-function getProperties (props) {
- const properties = {
- vueSlots: { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
+function getBehaviors (vueOptions) {
+ 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://', `${"wx"}://`));
+ if (behavior === 'uni://form-field') {
+ if (Array.isArray(vueProps)) {
+ vueProps.push('name');
+ vueProps.push('value');
+ } else {
+ vueProps['name'] = String;
+ vueProps['value'] = null;
+ }
+ }
+ });
+ }
+ if (isPlainObject(vueExtends) && vueExtends.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(vueExtends.props, true)
+ })
+ );
+ }
+ if (Array.isArray(vueMixins)) {
+ vueMixins.forEach(vueMixin => {
+ if (isPlainObject(vueMixin) && vueMixin.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(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 getProperties (props, isBehavior = false, file = '') {
+ const properties = {};
+ if (!isBehavior) {
+ properties.vueSlots = { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
type: null,
value: [],
observer: function (newVal, oldVal) {
@@ -380,8 +472,8 @@ function getProperties (props) {
$slots
});
}
- }
- };
+ };
+ }
if (Array.isArray(props)) { // ['title']
props.forEach(key => {
properties[key] = {
@@ -397,14 +489,18 @@ function getProperties (props) {
if (isFn(value)) {
value = value();
}
+
+ opts.type = parsePropType(key, opts.type, value, file);
+
properties[key] = {
- type: PROP_TYPES.includes(opts.type) ? opts.type : null,
+ type: PROP_TYPES.indexOf(opts.type) !== -1 ? opts.type : null,
value,
observer: createObserver(key)
};
} else { // content:String
+ const type = parsePropType(key, opts, null, file);
properties[key] = {
- type: PROP_TYPES.includes(opts) ? opts : null,
+ type: PROP_TYPES.indexOf(type) !== -1 ? type : null,
observer: createObserver(key)
};
}
@@ -414,6 +510,11 @@ function getProperties (props) {
}
function wrapper$1 (event) {
+ // TODO 又得兼容 mpvue 的 mp 对象
+ try {
+ event.mp = JSON.parse(JSON.stringify(event));
+ } catch (e) {}
+
event.stopPropagation = noop;
event.preventDefault = noop;
@@ -423,9 +524,6 @@ function wrapper$1 (event) {
event.detail = {};
}
- // TODO 又得兼容 mpvue 的 mp 对象
- event.mp = event;
-
if (isPlainObject(event.detail)) {
event.target = Object.assign({}, event.target, event.detail);
}
@@ -470,7 +568,7 @@ function getExtraValue (vm, dataPathsArray) {
return context
}
-function processEventExtra (vm, extra) {
+function processEventExtra (vm, extra, event) {
const extraObj = {};
if (Array.isArray(extra) && extra.length) {
@@ -490,7 +588,13 @@ function processEventExtra (vm, extra) {
if (!dataPath) { // model,prop.sync
extraObj['$' + index] = vm;
} else {
- extraObj['$' + index] = vm.__get_value(dataPath);
+ 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);
@@ -501,6 +605,15 @@ function processEventExtra (vm, extra) {
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) { // 自定义事件
@@ -515,7 +628,7 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
- const extraObj = processEventExtra(vm, extra);
+ const extraObj = processEventExtra(vm, extra, event);
const ret = [];
args.forEach(arg => {
@@ -530,7 +643,9 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
} else {
- if (typeof arg === 'string' && hasOwn(extraObj, arg)) {
+ 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);
@@ -653,7 +768,7 @@ function createApp (vm) {
{ // 头条的 selectComponent 竟然是异步的
initRefs(this);
}
- initMocks(this);
+ initMocks(this, mocks);
}
},
created () { // 处理 injections
@@ -688,38 +803,6 @@ function createApp (vm) {
return vm
}
-function triggerLink (mpInstance, vueOptions) {
- mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, {
- bubbles: true,
- composed: true
- });
-}
-
-function handleLink (event) {
- if (event.detail.$mp) { // vm
- if (!event.detail.$parent) {
- event.detail.$parent = this.$vm;
- event.detail.$parent.$children.push(event.detail);
-
- event.detail.$root = this.$vm.$root;
- }
- } else { // vueOptions
- if (!event.detail.parent) {
- event.detail.parent = this.$vm;
- }
- }
-}
-
-function initPage$1 (pageOptions) {
- initComponent$1(pageOptions);
-}
-
-function initComponent$1 (componentOptions) {
- componentOptions.methods.$getAppWebview = function () {
- return plus.webview.getWebviewById(`${this.__wxWebviewId__}`)
- };
-}
-
const hooks$1 = [
'onShow',
'onHide',
@@ -830,7 +913,9 @@ function initVm$2 (VueComponent) {
function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
- const properties = getProperties(vueOptions.props);
+ const behaviors = getBehaviors(vueOptions);
+
+ const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
@@ -840,6 +925,7 @@ function createComponent (vueOptions) {
addGlobalClass: true
},
data: getData(vueOptions, Vue.prototype),
+ behaviors,
properties,
lifetimes: {
attached () {
diff --git a/packages/uni-app-plus/package.json b/packages/uni-app-plus/package.json
index 95c0094a403287b0c1cdf7915943ba7891756b21..50ba1b2b20f0864a2d7e400d35509dbbf2ea0180 100644
--- a/packages/uni-app-plus/package.json
+++ b/packages/uni-app-plus/package.json
@@ -1,6 +1,6 @@
{
"name": "@dcloudio/uni-app-plus",
- "version": "0.0.218",
+ "version": "0.0.228",
"description": "uni-app app-plus",
"main": "dist/index.js",
"scripts": {
diff --git a/packages/uni-mp-baidu/dist/index.js b/packages/uni-mp-baidu/dist/index.js
index b71e33d938f5a0b310829d750e0c0e62b79de28a..a981de4e9d253950ae3fec8d7ead67f7d0e16fb8 100644
--- a/packages/uni-mp-baidu/dist/index.js
+++ b/packages/uni-mp-baidu/dist/index.js
@@ -270,7 +270,7 @@ function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, k
} else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value;
}
- } else if (CALLBACKS.includes(key)) {
+ } else if (CALLBACKS.indexOf(key) !== -1) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue);
} else {
if (!keepFromArgs) {
@@ -444,11 +444,41 @@ Component = function (options = {}) {
return MPComponent(options)
};
-const MOCKS = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__', '__webviewId__'];
+const mocks = ['nodeId'];
-function initMocks (vm) {
+function initPage (pageOptions) {
+ initComponent(pageOptions);
+}
+
+function initComponent (componentOptions) {
+ componentOptions.messages = {
+ '__l': handleLink
+ };
+}
+
+function triggerLink (mpInstance, vueOptions) {
+ mpInstance.dispatch('__l', mpInstance.$vm || vueOptions);
+}
+
+function handleLink (event) {
+ const target = event.value;
+ if (target.$mp) {
+ if (!target.$parent) {
+ target.$parent = this.$vm;
+ target.$parent.$children.push(target);
+
+ target.$root = this.$vm.$root;
+ }
+ } else {
+ if (!target.parent) {
+ target.parent = this.$vm;
+ }
+ }
+}
+
+function initMocks (vm, mocks) {
const mpInstance = vm.$mp[vm.mpType];
- MOCKS.forEach(mock => {
+ mocks.forEach(mock => {
if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock];
}
@@ -482,6 +512,10 @@ function getData (vueOptions, context) {
} 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];
@@ -501,9 +535,81 @@ function createObserver (name) {
}
}
-function getProperties (props) {
- const properties = {
- vueSlots: { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
+function getBehaviors (vueOptions) {
+ 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://', `${"swan"}://`));
+ if (behavior === 'uni://form-field') {
+ if (Array.isArray(vueProps)) {
+ vueProps.push('name');
+ vueProps.push('value');
+ } else {
+ vueProps['name'] = String;
+ vueProps['value'] = null;
+ }
+ }
+ });
+ }
+ if (isPlainObject(vueExtends) && vueExtends.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(vueExtends.props, true)
+ })
+ );
+ }
+ if (Array.isArray(vueMixins)) {
+ vueMixins.forEach(vueMixin => {
+ if (isPlainObject(vueMixin) && vueMixin.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(vueMixin.props, true)
+ })
+ );
+ }
+ });
+ }
+ return behaviors
+}
+
+function parsePropType (key, type, defaultValue, file) {
+ // [String]=>String
+ if (Array.isArray(type) && type.length === 1) {
+ return type[0]
+ }
+ {
+ if (
+ defaultValue === false &&
+ Array.isArray(type) &&
+ type.length === 2 &&
+ type.indexOf(String) !== -1 &&
+ type.indexOf(Boolean) !== -1
+ ) { // [String,Boolean]=>Boolean
+ if (file) {
+ console.warn(
+ `props.${key}.type should use Boolean instead of [String,Boolean] at ${file}`
+ );
+ }
+ return Boolean
+ }
+ }
+ return type
+}
+
+function getProperties (props, isBehavior = false, file = '') {
+ const properties = {};
+ if (!isBehavior) {
+ properties.vueSlots = { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
type: null,
value: [],
observer: function (newVal, oldVal) {
@@ -515,8 +621,8 @@ function getProperties (props) {
$slots
});
}
- }
- };
+ };
+ }
if (Array.isArray(props)) { // ['title']
props.forEach(key => {
properties[key] = {
@@ -532,14 +638,18 @@ function getProperties (props) {
if (isFn(value)) {
value = value();
}
+
+ opts.type = parsePropType(key, opts.type, value, file);
+
properties[key] = {
- type: PROP_TYPES.includes(opts.type) ? opts.type : null,
+ type: PROP_TYPES.indexOf(opts.type) !== -1 ? opts.type : null,
value,
observer: createObserver(key)
};
} else { // content:String
+ const type = parsePropType(key, opts, null, file);
properties[key] = {
- type: PROP_TYPES.includes(opts) ? opts : null,
+ type: PROP_TYPES.indexOf(type) !== -1 ? type : null,
observer: createObserver(key)
};
}
@@ -549,6 +659,11 @@ function getProperties (props) {
}
function wrapper$1 (event) {
+ // TODO 又得兼容 mpvue 的 mp 对象
+ try {
+ event.mp = JSON.parse(JSON.stringify(event));
+ } catch (e) {}
+
event.stopPropagation = noop;
event.preventDefault = noop;
@@ -568,9 +683,6 @@ function wrapper$1 (event) {
}
}
- // TODO 又得兼容 mpvue 的 mp 对象
- event.mp = event;
-
if (isPlainObject(event.detail)) {
event.target = Object.assign({}, event.target, event.detail);
}
@@ -615,7 +727,7 @@ function getExtraValue (vm, dataPathsArray) {
return context
}
-function processEventExtra (vm, extra) {
+function processEventExtra (vm, extra, event) {
const extraObj = {};
if (Array.isArray(extra) && extra.length) {
@@ -635,7 +747,13 @@ function processEventExtra (vm, extra) {
if (!dataPath) { // model,prop.sync
extraObj['$' + index] = vm;
} else {
- extraObj['$' + index] = vm.__get_value(dataPath);
+ 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);
@@ -646,6 +764,15 @@ function processEventExtra (vm, extra) {
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) { // 自定义事件
@@ -660,7 +787,7 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
- const extraObj = processEventExtra(vm, extra);
+ const extraObj = processEventExtra(vm, extra, event);
const ret = [];
args.forEach(arg => {
@@ -675,7 +802,9 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
} else {
- if (typeof arg === 'string' && hasOwn(extraObj, arg)) {
+ 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);
@@ -812,7 +941,7 @@ function createApp (vm) {
{ // 头条的 selectComponent 竟然是异步的
initRefs(this);
}
- initMocks(this);
+ initMocks(this, mocks);
}
},
created () { // 处理 injections
@@ -847,36 +976,6 @@ function createApp (vm) {
return vm
}
-function initPage (pageOptions) {
- initComponent(pageOptions);
-}
-
-function initComponent (componentOptions) {
- componentOptions.messages = {
- '__l': handleLink
- };
-}
-
-function triggerLink (mpInstance, vueOptions) {
- mpInstance.dispatch('__l', mpInstance.$vm || vueOptions);
-}
-
-function handleLink (event) {
- const target = event.value;
- if (target.$mp) {
- if (!target.$parent) {
- target.$parent = this.$vm;
- target.$parent.$children.push(target);
-
- target.$root = this.$vm.$root;
- }
- } else {
- if (!target.parent) {
- target.parent = this.$vm;
- }
- }
-}
-
const hooks$1 = [
'onShow',
'onHide',
@@ -997,7 +1096,9 @@ function initVm$2 (VueComponent) {
function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
- const properties = getProperties(vueOptions.props);
+ const behaviors = getBehaviors(vueOptions);
+
+ const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
@@ -1007,6 +1108,7 @@ function createComponent (vueOptions) {
addGlobalClass: true
},
data: getData(vueOptions, Vue.prototype),
+ behaviors,
properties,
lifetimes: {
attached () {
diff --git a/packages/uni-mp-baidu/package.json b/packages/uni-mp-baidu/package.json
index a06a2a6e6873b935c7b2e822326dfcd9fad944fb..fd9ce10f1a3eeedf0c945321f2e1de4e7a721309 100644
--- a/packages/uni-mp-baidu/package.json
+++ b/packages/uni-mp-baidu/package.json
@@ -1,6 +1,6 @@
{
"name": "@dcloudio/uni-mp-baidu",
- "version": "0.0.813",
+ "version": "0.0.825",
"description": "uni-app mp-baidu",
"main": "dist/index.js",
"scripts": {
diff --git a/packages/uni-mp-toutiao/dist/index.js b/packages/uni-mp-toutiao/dist/index.js
index 59006669eb61530b50918540b8bebe5937da8693..7db66e24c8825882952e10ff52ef8dfeeb27ddc1 100644
--- a/packages/uni-mp-toutiao/dist/index.js
+++ b/packages/uni-mp-toutiao/dist/index.js
@@ -331,7 +331,7 @@ function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, k
} else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value;
}
- } else if (CALLBACKS.includes(key)) {
+ } else if (CALLBACKS.indexOf(key) !== -1) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue);
} else {
if (!keepFromArgs) {
@@ -489,11 +489,80 @@ Component = function (options = {}) {
return MPComponent(options)
};
-const MOCKS = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__', '__webviewId__'];
+const instances = Object.create(null);
+
+const mocks = ['__route__', '__webviewId__', '__nodeid__'];
+
+function initPage (pageOptions) {
+ initComponent(pageOptions);
+}
+
+function initComponent (componentOptions) {
+ if (componentOptions.properties) { // ref
+ componentOptions.properties.vueRef = {
+ type: String,
+ value: ''
+ };
+ }
+ const oldAttached = componentOptions.lifetimes.attached;
+ componentOptions.lifetimes.attached = function () {
+ oldAttached.call(this);
+ // TODO 需要处理动态变化后的 refs
+ initRefs.call(this);
+ };
+}
+
+function initRefs () {
+ this.selectAllComponents('.vue-ref', (components) => {
+ components.forEach(component => {
+ const ref = component.data.vueRef; // 头条的组件 dataset 竟然是空的
+ this.$vm.$refs[ref] = component.$vm || component;
+ });
+ });
+ this.selectAllComponents('.vue-ref-in-for', (forComponents) => {
+ forComponents.forEach(component => {
+ const ref = component.data.vueRef;
+ if (!this.$vm.$refs[ref]) {
+ this.$vm.$refs[ref] = [];
+ }
+ this.$vm.$refs[ref].push(component.$vm || component);
+ });
+ });
+}
+
+function triggerLink (mpInstance) {
+ const nodeId = mpInstance.__nodeid__ + '';
+ const webviewId = mpInstance.__webviewId__ + '';
+
+ instances[webviewId + '_' + nodeId] = mpInstance.$vm;
-function initMocks (vm) {
+ mpInstance.triggerEvent('__l', {
+ nodeId,
+ webviewId
+ }, {
+ bubbles: true,
+ composed: true
+ });
+}
+// TODO 目前有 bug,composed 不生效
+function handleLink (event) {
+ const nodeId = event.detail.nodeId;
+ const webviewId = event.detail.webviewId;
+
+ const childVm = instances[webviewId + '_' + nodeId];
+
+ if (childVm) {
+ childVm.$parent = this.$vm;
+ childVm.$parent.$children.push(event.detail);
+
+ childVm.$root = this.$vm.$root;
+ delete instances[webviewId + '_' + nodeId];
+ }
+}
+
+function initMocks (vm, mocks) {
const mpInstance = vm.$mp[vm.mpType];
- MOCKS.forEach(mock => {
+ mocks.forEach(mock => {
if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock];
}
@@ -527,6 +596,10 @@ function getData (vueOptions, context) {
} 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];
@@ -546,9 +619,65 @@ function createObserver (name) {
}
}
-function getProperties (props) {
- const properties = {
- vueSlots: { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
+function getBehaviors (vueOptions) {
+ 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://', `${"tt"}://`));
+ if (behavior === 'uni://form-field') {
+ if (Array.isArray(vueProps)) {
+ vueProps.push('name');
+ vueProps.push('value');
+ } else {
+ vueProps['name'] = String;
+ vueProps['value'] = null;
+ }
+ }
+ });
+ }
+ if (isPlainObject(vueExtends) && vueExtends.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(vueExtends.props, true)
+ })
+ );
+ }
+ if (Array.isArray(vueMixins)) {
+ vueMixins.forEach(vueMixin => {
+ if (isPlainObject(vueMixin) && vueMixin.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(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 getProperties (props, isBehavior = false, file = '') {
+ const properties = {};
+ if (!isBehavior) {
+ properties.vueSlots = { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
type: null,
value: [],
observer: function (newVal, oldVal) {
@@ -560,8 +689,8 @@ function getProperties (props) {
$slots
});
}
- }
- };
+ };
+ }
if (Array.isArray(props)) { // ['title']
props.forEach(key => {
properties[key] = {
@@ -577,14 +706,18 @@ function getProperties (props) {
if (isFn(value)) {
value = value();
}
+
+ opts.type = parsePropType(key, opts.type, value, file);
+
properties[key] = {
- type: PROP_TYPES.includes(opts.type) ? opts.type : null,
+ type: PROP_TYPES.indexOf(opts.type) !== -1 ? opts.type : null,
value,
observer: createObserver(key)
};
} else { // content:String
+ const type = parsePropType(key, opts, null, file);
properties[key] = {
- type: PROP_TYPES.includes(opts) ? opts : null,
+ type: PROP_TYPES.indexOf(type) !== -1 ? type : null,
observer: createObserver(key)
};
}
@@ -594,6 +727,11 @@ function getProperties (props) {
}
function wrapper$1 (event) {
+ // TODO 又得兼容 mpvue 的 mp 对象
+ try {
+ event.mp = JSON.parse(JSON.stringify(event));
+ } catch (e) {}
+
event.stopPropagation = noop;
event.preventDefault = noop;
@@ -603,9 +741,6 @@ function wrapper$1 (event) {
event.detail = {};
}
- // TODO 又得兼容 mpvue 的 mp 对象
- event.mp = event;
-
if (isPlainObject(event.detail)) {
event.target = Object.assign({}, event.target, event.detail);
}
@@ -650,7 +785,7 @@ function getExtraValue (vm, dataPathsArray) {
return context
}
-function processEventExtra (vm, extra) {
+function processEventExtra (vm, extra, event) {
const extraObj = {};
if (Array.isArray(extra) && extra.length) {
@@ -670,7 +805,13 @@ function processEventExtra (vm, extra) {
if (!dataPath) { // model,prop.sync
extraObj['$' + index] = vm;
} else {
- extraObj['$' + index] = vm.__get_value(dataPath);
+ 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);
@@ -681,6 +822,15 @@ function processEventExtra (vm, extra) {
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) { // 自定义事件
@@ -695,7 +845,7 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
- const extraObj = processEventExtra(vm, extra);
+ const extraObj = processEventExtra(vm, extra, event);
const ret = [];
args.forEach(arg => {
@@ -710,7 +860,9 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
} else {
- if (typeof arg === 'string' && hasOwn(extraObj, arg)) {
+ 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);
@@ -807,7 +959,7 @@ function createApp (vm) {
delete this.$options.mpInstance;
if (this.mpType !== 'app') {
- initMocks(this);
+ initMocks(this, mocks);
}
},
created () { // 处理 injections
@@ -842,75 +994,6 @@ function createApp (vm) {
return vm
}
-const instances = Object.create(null);
-
-function initPage (pageOptions) {
- initComponent(pageOptions);
-}
-
-function initComponent (componentOptions) {
- if (componentOptions.properties) { // ref
- componentOptions.properties.vueRef = {
- type: String,
- value: ''
- };
- }
- const oldAttached = componentOptions.lifetimes.attached;
- componentOptions.lifetimes.attached = function () {
- oldAttached.call(this);
- // TODO 需要处理动态变化后的 refs
- initRefs$1.call(this);
- };
-}
-
-function initRefs$1 () {
- this.selectAllComponents('.vue-ref', (components) => {
- components.forEach(component => {
- const ref = component.data.vueRef; // 头条的组件 dataset 竟然是空的
- this.$vm.$refs[ref] = component.$vm || component;
- });
- });
- this.selectAllComponents('.vue-ref-in-for', (forComponents) => {
- forComponents.forEach(component => {
- const ref = component.data.vueRef;
- if (!this.$vm.$refs[ref]) {
- this.$vm.$refs[ref] = [];
- }
- this.$vm.$refs[ref].push(component.$vm || component);
- });
- });
-}
-
-function triggerLink (mpInstance) {
- const nodeId = mpInstance.__nodeid__ + '';
- const webviewId = mpInstance.__webviewId__ + '';
-
- instances[webviewId + '_' + nodeId] = mpInstance.$vm;
-
- mpInstance.triggerEvent('__l', {
- nodeId,
- webviewId
- }, {
- bubbles: true,
- composed: true
- });
-}
-// TODO 目前有 bug,composed 不生效
-function handleLink (event) {
- const nodeId = event.detail.nodeId;
- const webviewId = event.detail.webviewId;
-
- const childVm = instances[webviewId + '_' + nodeId];
-
- if (childVm) {
- childVm.$parent = this.$vm;
- childVm.$parent.$children.push(event.detail);
-
- childVm.$root = this.$vm.$root;
- delete instances[webviewId + '_' + nodeId];
- }
-}
-
const hooks$1 = [
'onShow',
'onHide',
@@ -1021,7 +1104,9 @@ function initVm$2 (VueComponent) {
function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
- const properties = getProperties(vueOptions.props);
+ const behaviors = getBehaviors(vueOptions);
+
+ const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
@@ -1031,6 +1116,7 @@ function createComponent (vueOptions) {
addGlobalClass: true
},
data: getData(vueOptions, Vue.prototype),
+ behaviors,
properties,
lifetimes: {
attached () {
diff --git a/packages/uni-mp-toutiao/package.json b/packages/uni-mp-toutiao/package.json
index 6f595d5667ddb606ee1ee8b7a20bbaf7d3037582..b9a406ffff794e6ea1eca24d3b0356db3323ecff 100644
--- a/packages/uni-mp-toutiao/package.json
+++ b/packages/uni-mp-toutiao/package.json
@@ -1,6 +1,6 @@
{
"name": "@dcloudio/uni-mp-toutiao",
- "version": "0.0.313",
+ "version": "0.0.323",
"description": "uni-app mp-toutiao",
"main": "dist/index.js",
"scripts": {
diff --git a/packages/uni-mp-weixin/dist/index.js b/packages/uni-mp-weixin/dist/index.js
index 42e8692d579100c6ced1ca040b25bf871b0edae9..cc49efb8b2919fb56893e2e36cbd94650f50e398 100644
--- a/packages/uni-mp-weixin/dist/index.js
+++ b/packages/uni-mp-weixin/dist/index.js
@@ -173,7 +173,7 @@ function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, k
} else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value;
}
- } else if (CALLBACKS.includes(key)) {
+ } else if (CALLBACKS.indexOf(key) !== -1) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue);
} else {
if (!keepFromArgs) {
@@ -336,11 +336,33 @@ Component = function (options = {}) {
return MPComponent(options)
};
-const MOCKS = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__', '__webviewId__'];
+const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'];
-function initMocks (vm) {
+function triggerLink (mpInstance, vueOptions) {
+ mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, {
+ bubbles: true,
+ composed: true
+ });
+}
+
+function handleLink (event) {
+ if (event.detail.$mp) { // vm
+ if (!event.detail.$parent) {
+ event.detail.$parent = this.$vm;
+ event.detail.$parent.$children.push(event.detail);
+
+ event.detail.$root = this.$vm.$root;
+ }
+ } else { // vueOptions
+ if (!event.detail.parent) {
+ event.detail.parent = this.$vm;
+ }
+ }
+}
+
+function initMocks (vm, mocks) {
const mpInstance = vm.$mp[vm.mpType];
- MOCKS.forEach(mock => {
+ mocks.forEach(mock => {
if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock];
}
@@ -374,6 +396,10 @@ function getData (vueOptions, context) {
} 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];
@@ -393,9 +419,65 @@ function createObserver (name) {
}
}
-function getProperties (props) {
- const properties = {
- vueSlots: { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
+function getBehaviors (vueOptions) {
+ 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://', `${"wx"}://`));
+ if (behavior === 'uni://form-field') {
+ if (Array.isArray(vueProps)) {
+ vueProps.push('name');
+ vueProps.push('value');
+ } else {
+ vueProps['name'] = String;
+ vueProps['value'] = null;
+ }
+ }
+ });
+ }
+ if (isPlainObject(vueExtends) && vueExtends.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(vueExtends.props, true)
+ })
+ );
+ }
+ if (Array.isArray(vueMixins)) {
+ vueMixins.forEach(vueMixin => {
+ if (isPlainObject(vueMixin) && vueMixin.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(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 getProperties (props, isBehavior = false, file = '') {
+ const properties = {};
+ if (!isBehavior) {
+ properties.vueSlots = { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
type: null,
value: [],
observer: function (newVal, oldVal) {
@@ -407,8 +489,8 @@ function getProperties (props) {
$slots
});
}
- }
- };
+ };
+ }
if (Array.isArray(props)) { // ['title']
props.forEach(key => {
properties[key] = {
@@ -424,14 +506,18 @@ function getProperties (props) {
if (isFn(value)) {
value = value();
}
+
+ opts.type = parsePropType(key, opts.type, value, file);
+
properties[key] = {
- type: PROP_TYPES.includes(opts.type) ? opts.type : null,
+ type: PROP_TYPES.indexOf(opts.type) !== -1 ? opts.type : null,
value,
observer: createObserver(key)
};
} else { // content:String
+ const type = parsePropType(key, opts, null, file);
properties[key] = {
- type: PROP_TYPES.includes(opts) ? opts : null,
+ type: PROP_TYPES.indexOf(type) !== -1 ? type : null,
observer: createObserver(key)
};
}
@@ -441,6 +527,11 @@ function getProperties (props) {
}
function wrapper$1 (event) {
+ // TODO 又得兼容 mpvue 的 mp 对象
+ try {
+ event.mp = JSON.parse(JSON.stringify(event));
+ } catch (e) {}
+
event.stopPropagation = noop;
event.preventDefault = noop;
@@ -450,9 +541,6 @@ function wrapper$1 (event) {
event.detail = {};
}
- // TODO 又得兼容 mpvue 的 mp 对象
- event.mp = event;
-
if (isPlainObject(event.detail)) {
event.target = Object.assign({}, event.target, event.detail);
}
@@ -497,7 +585,7 @@ function getExtraValue (vm, dataPathsArray) {
return context
}
-function processEventExtra (vm, extra) {
+function processEventExtra (vm, extra, event) {
const extraObj = {};
if (Array.isArray(extra) && extra.length) {
@@ -517,7 +605,13 @@ function processEventExtra (vm, extra) {
if (!dataPath) { // model,prop.sync
extraObj['$' + index] = vm;
} else {
- extraObj['$' + index] = vm.__get_value(dataPath);
+ 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);
@@ -528,6 +622,15 @@ function processEventExtra (vm, extra) {
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) { // 自定义事件
@@ -542,7 +645,7 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
- const extraObj = processEventExtra(vm, extra);
+ const extraObj = processEventExtra(vm, extra, event);
const ret = [];
args.forEach(arg => {
@@ -557,7 +660,9 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
} else {
- if (typeof arg === 'string' && hasOwn(extraObj, arg)) {
+ 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);
@@ -685,7 +790,7 @@ function createApp (vm) {
{ // 头条的 selectComponent 竟然是异步的
initRefs(this);
}
- initMocks(this);
+ initMocks(this, mocks);
}
},
created () { // 处理 injections
@@ -720,28 +825,6 @@ function createApp (vm) {
return vm
}
-function triggerLink (mpInstance, vueOptions) {
- mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, {
- bubbles: true,
- composed: true
- });
-}
-
-function handleLink (event) {
- if (event.detail.$mp) { // vm
- if (!event.detail.$parent) {
- event.detail.$parent = this.$vm;
- event.detail.$parent.$children.push(event.detail);
-
- event.detail.$root = this.$vm.$root;
- }
- } else { // vueOptions
- if (!event.detail.parent) {
- event.detail.parent = this.$vm;
- }
- }
-}
-
const hooks$1 = [
'onShow',
'onHide',
@@ -850,7 +933,9 @@ function initVm$2 (VueComponent) {
function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions;
- const properties = getProperties(vueOptions.props);
+ const behaviors = getBehaviors(vueOptions);
+
+ const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
@@ -860,6 +945,7 @@ function createComponent (vueOptions) {
addGlobalClass: true
},
data: getData(vueOptions, Vue.prototype),
+ behaviors,
properties,
lifetimes: {
attached () {
diff --git a/packages/uni-mp-weixin/package.json b/packages/uni-mp-weixin/package.json
index a96c2835da36f73ec571eff3ed4c591a92c3b4e2..4f2cdbc02063224bc661043e94556b56e3114339 100644
--- a/packages/uni-mp-weixin/package.json
+++ b/packages/uni-mp-weixin/package.json
@@ -1,6 +1,6 @@
{
"name": "@dcloudio/uni-mp-weixin",
- "version": "0.0.937",
+ "version": "0.0.947",
"description": "uni-app mp-weixin",
"main": "dist/index.js",
"scripts": {
diff --git a/src/core/helpers/hidpi.js b/src/core/helpers/hidpi.js
new file mode 100644
index 0000000000000000000000000000000000000000..e3bb8e856570b17b411ec315a74c4f2dd8bbd464
--- /dev/null
+++ b/src/core/helpers/hidpi.js
@@ -0,0 +1,168 @@
+const pixelRatio = (function () {
+ const canvas = document.createElement('canvas')
+ const context = canvas.getContext('2d')
+ const backingStore = context.backingStorePixelRatio ||
+ context.webkitBackingStorePixelRatio ||
+ context.mozBackingStorePixelRatio ||
+ context.msBackingStorePixelRatio ||
+ context.oBackingStorePixelRatio ||
+ context.backingStorePixelRatio || 1
+ return (window.devicePixelRatio || 1) / backingStore
+})()
+
+const forEach = function (obj, func) {
+ for (let key in obj) {
+ if (obj.hasOwnProperty(key)) {
+ func(obj[key], key)
+ }
+ }
+}
+const ratioArgs = {
+ 'fillRect': 'all',
+ 'clearRect': 'all',
+ 'strokeRect': 'all',
+ 'moveTo': 'all',
+ 'lineTo': 'all',
+ 'arc': [0, 1, 2],
+ 'arcTo': 'all',
+ 'bezierCurveTo': 'all',
+ 'isPointinPath': 'all',
+ 'isPointinStroke': 'all',
+ 'quadraticCurveTo': 'all',
+ 'rect': 'all',
+ 'translate': 'all',
+ 'createRadialGradient': 'all',
+ 'createLinearGradient': 'all',
+ 'setTransform': [4, 5]
+}
+if (pixelRatio !== 1) {
+ const proto = CanvasRenderingContext2D.prototype
+
+ forEach(ratioArgs, function (value, key) {
+ proto[key] = (function (_super) {
+ return function () {
+ if (this.__ignore__) {
+ return _super.apply(this, arguments)
+ }
+
+ let args = Array.prototype.slice.call(arguments)
+
+ if (value === 'all') {
+ args = args.map(function (a) {
+ return a * pixelRatio
+ })
+ } else if (Array.isArray(value)) {
+ for (let i = 0; i < value.length; i++) {
+ args[value[i]] *= pixelRatio
+ }
+ }
+ return _super.apply(this, args)
+ }
+ })(proto[key])
+ })
+
+ proto.stroke = (function (_super) {
+ return function () {
+ if (this.__ignore__) {
+ return _super.apply(this, arguments)
+ }
+ this.lineWidth *= pixelRatio
+ _super.apply(this, arguments)
+ this.lineWidth /= pixelRatio
+ }
+ })(proto.stroke)
+
+ proto.fillText = (function (_super) {
+ return function () {
+ if (this.__ignore__) {
+ return _super.apply(this, arguments)
+ }
+ const args = Array.prototype.slice.call(arguments)
+
+ args[1] *= pixelRatio
+ args[2] *= pixelRatio
+
+ this.font = this.font.replace(
+ /(\d+)(px|em|rem|pt)/g,
+ function (w, m, u) {
+ return (m * pixelRatio) + u
+ }
+ )
+
+ _super.apply(this, args)
+
+ this.font = this.font.replace(
+ /(\d+)(px|em|rem|pt)/g,
+ function (w, m, u) {
+ return (m / pixelRatio) + u
+ }
+ )
+ }
+ })(proto.fillText)
+
+ proto.strokeText = (function (_super) {
+ return function () {
+ if (this.__ignore__) {
+ return _super.apply(this, arguments)
+ }
+ var args = Array.prototype.slice.call(arguments)
+
+ args[1] *= pixelRatio // x
+ args[2] *= pixelRatio // y
+
+ this.font = this.font.replace(
+ /(\d+)(px|em|rem|pt)/g,
+ function (w, m, u) {
+ return (m * pixelRatio) + u
+ }
+ )
+
+ _super.apply(this, args)
+
+ this.font = this.font.replace(
+ /(\d+)(px|em|rem|pt)/g,
+ function (w, m, u) {
+ return (m / pixelRatio) + u
+ }
+ )
+ }
+ })(proto.strokeText)
+
+ proto.drawImageByCanvas = (function (_super) {
+ return function (canvas, srcx, srcy, srcw, srch, desx, desy, desw, desh, isScale) {
+ if (this.__ignore__) {
+ return _super.apply(this, arguments)
+ }
+ srcx *= pixelRatio
+ srcy *= pixelRatio
+ srcw *= pixelRatio
+ srch *= pixelRatio
+ desx *= pixelRatio
+ desy *= pixelRatio
+ desw = isScale ? desw * pixelRatio : desw
+ desh = isScale ? desh * pixelRatio : desh
+ _super.call(this, canvas, srcx, srcy, srcw, srch, desx, desy, desw, desh)
+ }
+ })(proto.drawImage)
+
+ proto.drawImage = (function (_super) {
+ return function () {
+ if (this.__ignore__) {
+ return _super.apply(this, arguments)
+ }
+ this.scale(pixelRatio, pixelRatio)
+ _super.apply(this, arguments)
+ this.scale(1 / pixelRatio, 1 / pixelRatio)
+ }
+ })(proto.drawImage)
+}
+
+export function wrapper (canvas) {
+ canvas.style.height = canvas.height + 'px'
+ canvas.style.width = canvas.width + 'px'
+ canvas.width *= pixelRatio
+ canvas.height *= pixelRatio
+
+ console.log(canvas.width)
+ console.log(canvas.height)
+}
diff --git a/src/core/runtime/wrapper.js b/src/core/runtime/wrapper.js
index 8b33a4be53d48943dac58e9257c56aa13c7e48cc..f6a3e7e214fbccadaf75e147c9c625b5c80374b5 100644
--- a/src/core/runtime/wrapper.js
+++ b/src/core/runtime/wrapper.js
@@ -39,7 +39,7 @@ function processArgs (methodName, fromArgs, argsOption = {}, returnValue = {}, k
} else if (isPlainObject(keyOption)) { // {name:newName,value:value}可重新指定参数 key:value
toArgs[keyOption.name ? keyOption.name : key] = keyOption.value
}
- } else if (CALLBACKS.includes(key)) {
+ } else if (CALLBACKS.indexOf(key) !== -1) {
toArgs[key] = processCallback(methodName, fromArgs[key], returnValue)
} else {
if (!keepFromArgs) {
diff --git a/src/core/runtime/wrapper/create-app.js b/src/core/runtime/wrapper/create-app.js
index f95b39ac12337033d35ed67dc021a2090c86b919..667b70863d8ed3df6f276222390056055028e4fc 100644
--- a/src/core/runtime/wrapper/create-app.js
+++ b/src/core/runtime/wrapper/create-app.js
@@ -1,6 +1,10 @@
import 'uni-platform/runtime/index'
import Vue from 'vue'
+
+import {
+ mocks
+} from 'uni-platform/runtime/wrapper/index'
import {
initRefs,
@@ -51,7 +55,7 @@ export function createApp (vm) {
if (__PLATFORM__ !== 'mp-toutiao') { // 头条的 selectComponent 竟然是异步的
initRefs(this)
}
- initMocks(this)
+ initMocks(this, mocks)
}
},
created () { // 处理 injections
diff --git a/src/core/runtime/wrapper/create-component.js b/src/core/runtime/wrapper/create-component.js
index e7ff868e6a4b709d1fac0875733ab699f72ace07..f987c017784c4fe2ad652bb8e7c98e179246415b 100644
--- a/src/core/runtime/wrapper/create-component.js
+++ b/src/core/runtime/wrapper/create-component.js
@@ -9,6 +9,7 @@ import {
import {
getData,
handleEvent,
+ getBehaviors,
getProperties
} from './util'
@@ -42,7 +43,9 @@ function initVm (VueComponent) {
export function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions
- const properties = getProperties(vueOptions.props)
+ const behaviors = getBehaviors(vueOptions)
+
+ const properties = getProperties(vueOptions.props, false, vueOptions.__file)
const VueComponent = Vue.extend(vueOptions)
@@ -52,6 +55,7 @@ export function createComponent (vueOptions) {
addGlobalClass: true
},
data: getData(vueOptions, Vue.prototype),
+ behaviors,
properties,
lifetimes: {
attached () {
diff --git a/src/core/runtime/wrapper/util.js b/src/core/runtime/wrapper/util.js
index 8034a59224e10326c23d2c11a0c566b908a6bc7b..e08c4cf68cf3fd3c8d40bf4e1abc000ae1ce5444 100644
--- a/src/core/runtime/wrapper/util.js
+++ b/src/core/runtime/wrapper/util.js
@@ -5,11 +5,9 @@ import {
isPlainObject
} from 'uni-shared'
-const MOCKS = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__', '__webviewId__']
-
-export function initMocks (vm) {
+export function initMocks (vm, mocks) {
const mpInstance = vm.$mp[vm.mpType]
- MOCKS.forEach(mock => {
+ mocks.forEach(mock => {
if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock]
}
@@ -43,6 +41,10 @@ export function getData (vueOptions, context) {
} 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]
@@ -62,9 +64,81 @@ function createObserver (name) {
}
}
-export function getProperties (props) {
- const properties = {
- vueSlots: { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
+export function getBehaviors (vueOptions) {
+ 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://', `${__PLATFORM_PREFIX__}://`))
+ if (behavior === 'uni://form-field') {
+ if (Array.isArray(vueProps)) {
+ vueProps.push('name')
+ vueProps.push('value')
+ } else {
+ vueProps['name'] = String
+ vueProps['value'] = null
+ }
+ }
+ })
+ }
+ if (isPlainObject(vueExtends) && vueExtends.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(vueExtends.props, true)
+ })
+ )
+ }
+ if (Array.isArray(vueMixins)) {
+ vueMixins.forEach(vueMixin => {
+ if (isPlainObject(vueMixin) && vueMixin.props) {
+ behaviors.push(
+ Behavior({
+ properties: getProperties(vueMixin.props, true)
+ })
+ )
+ }
+ })
+ }
+ return behaviors
+}
+
+function parsePropType (key, type, defaultValue, file) {
+ // [String]=>String
+ if (Array.isArray(type) && type.length === 1) {
+ return type[0]
+ }
+ if (__PLATFORM__ === 'mp-baidu') {
+ if (
+ defaultValue === false &&
+ Array.isArray(type) &&
+ type.length === 2 &&
+ type.indexOf(String) !== -1 &&
+ type.indexOf(Boolean) !== -1
+ ) { // [String,Boolean]=>Boolean
+ if (file) {
+ console.warn(
+ `props.${key}.type should use Boolean instead of [String,Boolean] at ${file}`
+ )
+ }
+ return Boolean
+ }
+ }
+ return type
+}
+
+export function getProperties (props, isBehavior = false, file = '') {
+ const properties = {}
+ if (!isBehavior) {
+ properties.vueSlots = { // 小程序不能直接定义 $slots 的 props,所以通过 vueSlots 转换到 $slots
type: null,
value: [],
observer: function (newVal, oldVal) {
@@ -93,14 +167,18 @@ export function getProperties (props) {
if (isFn(value)) {
value = value()
}
+
+ opts.type = parsePropType(key, opts.type, value, file)
+
properties[key] = {
- type: PROP_TYPES.includes(opts.type) ? opts.type : null,
+ type: PROP_TYPES.indexOf(opts.type) !== -1 ? opts.type : null,
value,
observer: createObserver(key)
}
} else { // content:String
+ const type = parsePropType(key, opts, null, file)
properties[key] = {
- type: PROP_TYPES.includes(opts) ? opts : null,
+ type: PROP_TYPES.indexOf(type) !== -1 ? type : null,
observer: createObserver(key)
}
}
@@ -110,6 +188,11 @@ export function getProperties (props) {
}
function wrapper (event) {
+ // TODO 又得兼容 mpvue 的 mp 对象
+ try {
+ event.mp = JSON.parse(JSON.stringify(event))
+ } catch (e) {}
+
event.stopPropagation = noop
event.preventDefault = noop
@@ -129,9 +212,6 @@ function wrapper (event) {
}
}
- // TODO 又得兼容 mpvue 的 mp 对象
- event.mp = event
-
if (isPlainObject(event.detail)) {
event.target = Object.assign({}, event.target, event.detail)
}
@@ -176,7 +256,7 @@ function getExtraValue (vm, dataPathsArray) {
return context
}
-function processEventExtra (vm, extra) {
+function processEventExtra (vm, extra, event) {
const extraObj = {}
if (Array.isArray(extra) && extra.length) {
@@ -196,7 +276,13 @@ function processEventExtra (vm, extra) {
if (!dataPath) { // model,prop.sync
extraObj['$' + index] = vm
} else {
- extraObj['$' + index] = vm.__get_value(dataPath)
+ 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)
@@ -207,6 +293,15 @@ function processEventExtra (vm, extra) {
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) { // 自定义事件
@@ -221,7 +316,7 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
- const extraObj = processEventExtra(vm, extra)
+ const extraObj = processEventExtra(vm, extra, event)
const ret = []
args.forEach(arg => {
@@ -236,7 +331,9 @@ function processEventArgs (vm, event, args = [], extra = [], isCustom, methodNam
}
}
} else {
- if (typeof arg === 'string' && hasOwn(extraObj, arg)) {
+ 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)
diff --git a/src/core/service/api/context/canvas.js b/src/core/service/api/context/canvas.js
index c3ea0826a03ffe55ef053788e6e1aeb9b8aec7df..3aeb1da19f73b0f5890dbf5e66d2fba80b03cdff 100644
--- a/src/core/service/api/context/canvas.js
+++ b/src/core/service/api/context/canvas.js
@@ -1,4 +1,5 @@
import createCallbacks from 'uni-helpers/callbacks'
+import { wrapper } from 'uni-helpers/hidpi'
const canvasEventCallbacks = createCallbacks('canvasEvent')
@@ -257,6 +258,7 @@ var tempCanvas
function getTempCanvas () {
if (!tempCanvas) {
tempCanvas = document.createElement('canvas')
+ wrapper(tempCanvas)
}
return tempCanvas
}
@@ -816,7 +818,7 @@ export function canvasToTempFilePath ({
pageId = app.$route.params.__id__
} else {
invoke(callbackId, {
- errMsg: 'canvasPutImageData:fail'
+ errMsg: 'canvasToTempFilePath:fail'
})
return
}
@@ -840,20 +842,24 @@ export function canvasToTempFilePath ({
canvas.width = data.width
canvas.height = data.height
var c2d = canvas.getContext('2d')
- c2d.putImageData(imgData, 0, 0)
- var base64 = canvas.toDataURL('image/png')
- var img = new Image()
- img.onload = function () {
- canvas.width = destWidth || imgData.width
- canvas.height = destHeight || imgData.height
- c2d.drawImage(img, 0, 0)
- base64 = canvas.toDataURL(`image/${fileType.toLowerCase()}`, qualit)
- invoke(callbackId, {
- errMsg: 'canvasToTempFilePath:ok',
- tempFilePath: base64
- })
- }
- img.src = base64
+ c2d.putImageData(imgData, 0, 0, 0, 0, destWidth || imgData.width, destHeight || imgData.height)
+ var base64 = canvas.toDataURL(`image/${fileType.toLowerCase()}`, qualit)
+ invoke(callbackId, {
+ errMsg: 'canvasToTempFilePath:ok',
+ tempFilePath: base64
+ })
+ // var img = new Image()
+ // img.onload = function () {
+ // canvas.width = destWidth || imgData.width
+ // canvas.height = destHeight || imgData.height
+ // c2d.drawImage(img, 0, 0)
+ // base64 = canvas.toDataURL(`image/${fileType.toLowerCase()}`, qualit)
+ // invoke(callbackId, {
+ // errMsg: 'canvasToTempFilePath:ok',
+ // tempFilePath: base64
+ // })
+ // }
+ // img.src = base64
})
operateCanvas(canvasId, pageId, 'getImageData', {
x,
diff --git a/src/core/service/plugins/app/router-guard.js b/src/core/service/plugins/app/router-guard.js
index a0e36bee15774d7dd1e7730f6153a0f9a8d4fc41..9eb4223600dd3a7acd2c2ba541416c81bd2e9751 100644
--- a/src/core/service/plugins/app/router-guard.js
+++ b/src/core/service/plugins/app/router-guard.js
@@ -15,7 +15,28 @@ function removeKeepAliveInclude (componentName) {
}
}
-function switchTab (routes) {
+let positionStore = Object.create(null)
+
+export function getTabBarScrollPosition (id) {
+ return positionStore[id]
+}
+
+function saveTabBarScrollPosition (id) {
+ positionStore[id] = {
+ x: window.pageXOffset,
+ y: window.pageYOffset
+ }
+}
+
+function switchTab (routes, to, from) {
+ if (
+ to &&
+ from &&
+ to.meta.isTabBar &&
+ from.meta.isTabBar
+ ) { // tabbar 跳 tabbar
+ saveTabBarScrollPosition(from.params.__id__)
+ }
// 关闭非 tabBar 页面
const pages = getCurrentPages()
for (let i = pages.length - 1; i >= 0; i--) {
@@ -33,11 +54,13 @@ function reLaunch (toName) {
// 关闭所有页面
const pages = getCurrentPages(true)
for (let i = pages.length - 1; i >= 0; i--) {
- callPageHook(pages[i], 'onUnload')
- // 重新reLaunch至首页可能会被keepAlive,先手动强制destroy
+ callPageHook(pages[i], 'onUnload')
+ // 重新reLaunch至首页可能会被keepAlive,先手动强制destroy
pages[i].$destroy()
}
- this.keepAliveInclude = []
+ this.keepAliveInclude = []
+ // 清空 positionStore
+ positionStore = Object.create(null)
}
let currentPages = []
@@ -65,7 +88,7 @@ function beforeEach (to, from, next, routes) {
removeKeepAliveInclude.call(this, fromName)
if (from.meta) {
if (from.meta.isQuit) { // 如果 redirectTo 的前一个页面是 quit 类型,则新打开的页面也是 quit
- to.meta.isQuit = true
+ to.meta.isQuit = true
to.meta.isEntry = !!from.meta.isEntry
}
if (from.meta.isTabBar) { // 如果是 tabBar,需要更新系统组件 tabBar 内的 list 数据
@@ -78,7 +101,7 @@ function beforeEach (to, from, next, routes) {
break
case 'switchTab':
- switchTab.call(this, routes)
+ switchTab.call(this, routes, to, from)
break
case 'reLaunch':
reLaunch.call(this, toName)
diff --git a/src/core/service/plugins/index.js b/src/core/service/plugins/index.js
index 1f2c8262ad5791c2ddd13d42bd8793a6497277f2..b961a5587fa1107a07323cb6c995bc8a3dd50e88 100644
--- a/src/core/service/plugins/index.js
+++ b/src/core/service/plugins/index.js
@@ -16,6 +16,10 @@ import {
createPageMixin
} from './page'
+import {
+ getTabBarScrollPosition
+} from './app/router-guard'
+
function getMinId (routes) {
let minId = 0
routes.forEach(route => {
@@ -62,6 +66,17 @@ export default {
if (savedPosition) {
return savedPosition
} else {
+ if (
+ to &&
+ from &&
+ to.meta.isTabBar &&
+ from.meta.isTabBar
+ ) { // tabbar 跳 tabbar
+ const position = getTabBarScrollPosition(to.params.__id__)
+ if (position) {
+ return position
+ }
+ }
return {
x: 0,
y: 0
@@ -101,7 +116,9 @@ export default {
const appMixin = createAppMixin(routes, entryRoute)
// mixin app hooks
Object.keys(appMixin).forEach(hook => {
- options[hook] = options[hook] ? [].concat(appMixin[hook], options[hook]) : [appMixin[hook]]
+ options[hook] = options[hook] ? [].concat(appMixin[hook], options[hook]) : [
+ appMixin[hook]
+ ]
})
// router
@@ -117,7 +134,9 @@ export default {
const pageMixin = createPageMixin()
// mixin page hooks
Object.keys(pageMixin).forEach(hook => {
- options[hook] = options[hook] ? [].concat(pageMixin[hook], options[hook]) : [pageMixin[hook]]
+ options[hook] = options[hook] ? [].concat(pageMixin[hook], options[hook]) : [
+ pageMixin[hook]
+ ]
})
} else {
if (this.$parent && this.$parent.__page__) {
diff --git a/src/core/view/components/canvas/index.vue b/src/core/view/components/canvas/index.vue
index ec7db333be67b91d02488182481e7a92e0e840eb..11abd6f33162d051788e499563de169bcf9e1c67 100644
--- a/src/core/view/components/canvas/index.vue
+++ b/src/core/view/components/canvas/index.vue
@@ -1,450 +1,462 @@
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
diff --git a/src/core/view/components/scroll-view/index.vue b/src/core/view/components/scroll-view/index.vue
index 632321f584686a883955d9200688a7c80f4f82e5..b60017cde6d584cca96c2b41beee5c7147dc751e 100644
--- a/src/core/view/components/scroll-view/index.vue
+++ b/src/core/view/components/scroll-view/index.vue
@@ -166,6 +166,11 @@ export default {
passive: false
} : false)
},
+ activated () {
+ // 还原 scroll-view 滚动位置
+ this.scrollY && (this.$refs.main.scrollTop = this.lastScrollTop)
+ this.scrollX && (this.$refs.main.scrollLeft = this.lastScrollLeft)
+ },
beforeDestroy () {
this.$refs.main.removeEventListener('touchstart', this.__handleTouchStart, passiveOptions)
this.$refs.main.removeEventListener('touchmove', this.__handleTouchMove, passiveOptions)
diff --git a/src/core/view/plugins/behaviors/form-field.js b/src/core/view/plugins/behaviors/form-field.js
new file mode 100644
index 0000000000000000000000000000000000000000..56548ab864dcddaaf2930fd2ea7a77e6ce198112
--- /dev/null
+++ b/src/core/view/plugins/behaviors/form-field.js
@@ -0,0 +1,103 @@
+/**
+ * uni://form-field
+ */
+import {
+ hasOwn
+} from 'uni-shared'
+
+import {
+ emitter
+} from 'uni-mixins'
+
+function created () {
+ this.$dispatch('Form', 'uni-form-group-update', {
+ type: 'add',
+ vm: this
+ })
+}
+
+function beforeDestroy () {
+ this.$dispatch('Form', 'uni-form-group-update', {
+ type: 'remove',
+ vm: this
+ })
+}
+
+export default {
+ name: 'uni://form-field',
+ init (options, vm) {
+ if (
+ !vm.constructor.options.props.name ||
+ !vm.constructor.options.props.value
+ ) { // 未初始化 props
+ if (!vm.constructor.options.props.name) {
+ vm.constructor.options.props.name = options.props.name = {
+ type: String
+ }
+ }
+ if (!vm.constructor.options.props.value) {
+ vm.constructor.options.props.value = options.props.value = {
+ type: null
+ }
+ }
+ }
+
+ if (!options.propsData) {
+ options.propsData = {}
+ }
+
+ const $vnode = vm.$vnode
+ if ($vnode && $vnode.data && $vnode.data.attrs) {
+ if (hasOwn($vnode.data.attrs, 'name')) {
+ options.propsData.name = $vnode.data.attrs.name
+ }
+ if (hasOwn($vnode.data.attrs, 'value')) {
+ options.propsData.value = $vnode.data.attrs.value
+ }
+ }
+
+ if (
+ !vm.constructor.options.methods ||
+ !vm.constructor.options.methods._getFormData
+ ) { // 未初始化 methods
+ if (!vm.constructor.options.methods) {
+ vm.constructor.options.methods = {}
+ }
+
+ if (!options.methods) {
+ options.methods = {}
+ }
+
+ const formMethods = {
+ _getFormData () {
+ return this.name ? {
+ key: this.name,
+ value: this.value
+ } : {}
+ },
+ _resetFormData () {
+ this.value = ''
+ }
+ }
+
+ Object.assign(vm.constructor.options.methods, formMethods)
+ Object.assign(options.methods, formMethods)
+
+ // add $dispatch
+ Object.assign(vm.constructor.options.methods, emitter.methods)
+ Object.assign(options.methods, emitter.methods)
+
+ const createdHooks = options['created']
+ vm.constructor.options['created'] = options['created'] =
+ createdHooks ? [].concat(created, createdHooks) : [
+ created
+ ]
+
+ const beforeDestroyHooks = options['beforeDestroy']
+ vm.constructor.options['beforeDestroy'] = options['beforeDestroy'] =
+ beforeDestroyHooks ? [].concat(beforeDestroy, beforeDestroyHooks) : [
+ beforeDestroy
+ ]
+ }
+ }
+}
diff --git a/src/core/view/plugins/behaviors/index.js b/src/core/view/plugins/behaviors/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..fa1a4265f3747b059e02cda71b161607b7886117
--- /dev/null
+++ b/src/core/view/plugins/behaviors/index.js
@@ -0,0 +1,12 @@
+import formField from './form-field'
+
+const behaviors = {
+ [formField.name]: formField
+}
+
+export default function initBehaviors (options, vm) {
+ options.behaviors.forEach(name => {
+ const behavior = behaviors[name]
+ behavior && behavior.init(options, vm)
+ })
+}
diff --git a/src/core/view/plugins/index.js b/src/core/view/plugins/index.js
index 643d1f08d4fe8455f1dcb19fc1a8a0795ef3f0c6..f0e0dccf0c210be9d3fe109fc77a880181ecbb25 100644
--- a/src/core/view/plugins/index.js
+++ b/src/core/view/plugins/index.js
@@ -7,6 +7,8 @@ import {
processEvent
} from './events'
+import initBehaviors from './behaviors'
+
function pageMounted () {
// 通知 Service,View 层已 ready
UniViewJSBridge.publishHandler('onPageReady', {}, this.$page.id)
@@ -34,13 +36,18 @@ export default {
}
}
$event = processEvent.call(this, $event.type, $event, {}, target || $event.target, $event.currentTarget)
- }
+ }
return $event
}
Vue.mixin({
beforeCreate () {
const options = this.$options
+
+ if (options.behaviors && options.behaviors.length) {
+ initBehaviors(options, this)
+ }
+
if (isPage(this)) {
options.mounted = options.mounted ? [].concat(pageMounted, options.mounted) : [pageMounted]
}
diff --git a/src/platforms/app-plus/runtime/wrapper/index.js b/src/platforms/app-plus/runtime/wrapper/index.js
index d5dceb800d3c45a9e56e321a4761d98557b19c33..2628b2b95222c1eed2e626f8a6561e5ec6d292da 100644
--- a/src/platforms/app-plus/runtime/wrapper/index.js
+++ b/src/platforms/app-plus/runtime/wrapper/index.js
@@ -1,4 +1,5 @@
export {
+ mocks,
handleLink,
triggerLink
}
diff --git a/src/platforms/h5/components/app/popup/modal.vue b/src/platforms/h5/components/app/popup/modal.vue
index bbed8644ea84b86e71eb779bbe066a21a4705f1f..2404da5b9f88dd55e76fdd5716f90f3db66870b6 100644
--- a/src/platforms/h5/components/app/popup/modal.vue
+++ b/src/platforms/h5/components/app/popup/modal.vue
@@ -3,9 +3,7 @@
-
+