提交 39f98c73 编写于 作者: fxy060608's avatar fxy060608

build uni runtime(mp-alipay usingComponents)

上级 ac4bd265
...@@ -282,8 +282,7 @@ function initTriggerEvent (mpInstance) { ...@@ -282,8 +282,7 @@ function initTriggerEvent (mpInstance) {
}; };
} }
Page = function (options = {}) { function initHook (name, options) {
const name = 'onLoad';
const oldHook = options[name]; const oldHook = options[name];
if (!oldHook) { if (!oldHook) {
options[name] = function () { options[name] = function () {
...@@ -295,22 +294,45 @@ Page = function (options = {}) { ...@@ -295,22 +294,45 @@ Page = function (options = {}) {
return oldHook.apply(this, args) return oldHook.apply(this, args)
}; };
} }
}
Page = function (options = {}) {
initHook('onLoad', options);
return MPPage(options) return MPPage(options)
}; };
const behavior = Behavior({
created () {
initTriggerEvent(this);
}
});
Component = function (options = {}) { Component = function (options = {}) {
(options.behaviors || (options.behaviors = [])).unshift(behavior); initHook('created', options);
return MPComponent(options) return MPComponent(options)
}; };
const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__']; const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'];
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 triggerLink (mpInstance, vueOptions) { function triggerLink (mpInstance, vueOptions) {
mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, { mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, {
bubbles: true, bubbles: true,
...@@ -334,18 +356,19 @@ function handleLink (event) { ...@@ -334,18 +356,19 @@ function handleLink (event) {
} }
function initPage$1 (pageOptions) { function initPage$1 (pageOptions) {
initComponent$1(pageOptions); return initComponent$1(pageOptions)
} }
function initComponent$1 (componentOptions) { function initComponent$1 (componentOptions) {
componentOptions.methods.$getAppWebview = function () { componentOptions.methods.$getAppWebview = function () {
return plus.webview.getWebviewById(`${this.__wxWebviewId__}`) return plus.webview.getWebviewById(`${this.__wxWebviewId__}`)
}; };
return Component(componentOptions)
} }
function initMocks (vm, mocks) { function initMocks (vm, mocks$$1) {
const mpInstance = vm.$mp[vm.mpType]; const mpInstance = vm.$mp[vm.mpType];
mocks.forEach(mock => { mocks$$1.forEach(mock => {
if (hasOwn(mpInstance, mock)) { if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock]; vm[mock] = mpInstance[mock];
} }
...@@ -402,7 +425,7 @@ function createObserver (name) { ...@@ -402,7 +425,7 @@ function createObserver (name) {
} }
} }
function getBehaviors (vueOptions) { function getBehaviors (vueOptions) {
const vueBehaviors = vueOptions['behaviors']; const vueBehaviors = vueOptions['behaviors'];
const vueExtends = vueOptions['extends']; const vueExtends = vueOptions['extends'];
const vueMixins = vueOptions['mixins']; const vueMixins = vueOptions['mixins'];
...@@ -430,7 +453,7 @@ function getBehaviors (vueOptions) { ...@@ -430,7 +453,7 @@ function getBehaviors (vueOptions) {
} }
if (isPlainObject(vueExtends) && vueExtends.props) { if (isPlainObject(vueExtends) && vueExtends.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueExtends.props, true) properties: getProperties(vueExtends.props, true)
}) })
); );
...@@ -439,7 +462,7 @@ function getBehaviors (vueOptions) { ...@@ -439,7 +462,7 @@ function getBehaviors (vueOptions) {
vueMixins.forEach(vueMixin => { vueMixins.forEach(vueMixin => {
if (isPlainObject(vueMixin) && vueMixin.props) { if (isPlainObject(vueMixin) && vueMixin.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueMixin.props, true) properties: getProperties(vueMixin.props, true)
}) })
); );
...@@ -705,29 +728,6 @@ function handleEvent (event) { ...@@ -705,29 +728,6 @@ function handleEvent (event) {
}); });
} }
}); });
}
function initRefs (vm) {
const mpInstance = vm.$mp[vm.mpType];
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
}
});
} }
const hooks = [ const hooks = [
...@@ -750,24 +750,27 @@ function initVm (vm) { ...@@ -750,24 +750,27 @@ function initVm (vm) {
} }
function createApp (vm) { function createApp (vm) {
// 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin
Vue.mixin({ Vue.mixin({
beforeCreate () { beforeCreate () {
if (!this.$options.mpType) { if (!this.$options.mpType) {
return return
} }
this.mpType = this.$options.mpType; this.mpType = this.$options.mpType;
this.$mp = { this.$mp = {
data: {}, data: {},
[this.mpType]: this.$options.mpInstance [this.mpType]: this.$options.mpInstance
}; };
this.$scope = this.$options.mpInstance;
delete this.$options.mpType; delete this.$options.mpType;
delete this.$options.mpInstance; delete this.$options.mpInstance;
if (this.mpType !== 'app') { if (this.mpType !== 'app') {
{ // 头条的 selectComponent 竟然是异步的 initRefs(this);
initRefs(this);
}
initMocks(this, mocks); initMocks(this, mocks);
} }
}, },
...@@ -878,9 +881,7 @@ function createPage (vueOptions) { ...@@ -878,9 +881,7 @@ function createPage (vueOptions) {
initHooks(pageOptions.methods, hooks$1); initHooks(pageOptions.methods, hooks$1);
initPage$1(pageOptions); return initPage$1(pageOptions, vueOptions)
return Component(pageOptions)
} }
function initVm$2 (VueComponent) { function initVm$2 (VueComponent) {
...@@ -888,16 +889,18 @@ function initVm$2 (VueComponent) { ...@@ -888,16 +889,18 @@ function initVm$2 (VueComponent) {
return return
} }
const properties = this.properties;
const options = { const options = {
mpType: 'component', mpType: 'component',
mpInstance: this, mpInstance: this,
propsData: this.properties propsData: properties
}; };
// 初始化 vue 实例 // 初始化 vue 实例
this.$vm = new VueComponent(options); this.$vm = new VueComponent(options);
// 处理$slots,$scopedSlots(暂不支持动态变化$slots) // 处理$slots,$scopedSlots(暂不支持动态变化$slots)
const vueSlots = this.properties.vueSlots; const vueSlots = properties.vueSlots;
if (Array.isArray(vueSlots) && vueSlots.length) { if (Array.isArray(vueSlots) && vueSlots.length) {
const $slots = Object.create(null); const $slots = Object.create(null);
vueSlots.forEach(slotName => { vueSlots.forEach(slotName => {
...@@ -907,18 +910,24 @@ function initVm$2 (VueComponent) { ...@@ -907,18 +910,24 @@ function initVm$2 (VueComponent) {
} }
// 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并 // 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并
// 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性 // 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性
this.$vm.$mount(); this.$vm.$mount();
} }
function createComponent (vueOptions) { function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions; vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions; // TODO form-field props.name,props.value
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
const behaviors = getBehaviors(vueOptions); const behaviors = getBehaviors(vueOptions);
const properties = getProperties(vueOptions.props, false, vueOptions.__file); const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
const componentOptions = { const componentOptions = {
options: { options: {
multipleSlots: true, multipleSlots: true,
...@@ -963,9 +972,7 @@ function createComponent (vueOptions) { ...@@ -963,9 +972,7 @@ function createComponent (vueOptions) {
} }
}; };
initComponent$1(componentOptions); return initComponent$1(componentOptions, vueOptions)
return Component(componentOptions)
} }
let uni = {}; let uni = {};
......
{ {
"name": "@dcloudio/uni-app-plus", "name": "@dcloudio/uni-app-plus",
"version": "0.0.229", "version": "0.0.230",
"description": "uni-app app-plus", "description": "uni-app app-plus",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
{ {
"name": "@dcloudio/uni-mp-alipay", "name": "@dcloudio/uni-mp-alipay",
"version": "0.0.8", "version": "0.0.801",
"description": "uni-app mp-alipay", "description": "uni-app mp-alipay",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
...@@ -417,8 +417,7 @@ function initTriggerEvent (mpInstance) { ...@@ -417,8 +417,7 @@ function initTriggerEvent (mpInstance) {
}; };
} }
Page = function (options = {}) { function initHook (name, options) {
const name = 'onLoad';
const oldHook = options[name]; const oldHook = options[name];
if (!oldHook) { if (!oldHook) {
options[name] = function () { options[name] = function () {
...@@ -430,37 +429,62 @@ Page = function (options = {}) { ...@@ -430,37 +429,62 @@ Page = function (options = {}) {
return oldHook.apply(this, args) return oldHook.apply(this, args)
}; };
} }
}
Page = function (options = {}) {
initHook('onLoad', options);
return MPPage(options) return MPPage(options)
}; };
const behavior = Behavior({
created () {
initTriggerEvent(this);
}
});
Component = function (options = {}) { Component = function (options = {}) {
(options.behaviors || (options.behaviors = [])).unshift(behavior); initHook('created', options);
return MPComponent(options) return MPComponent(options)
}; };
const mocks = ['nodeId']; 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
}
});
}
const mocks$1 = ['nodeId'];
function initPage (pageOptions) { function initPage$1 (pageOptions) {
initComponent(pageOptions); return initComponent$1(pageOptions)
} }
function initComponent (componentOptions) { function initComponent$1 (componentOptions) {
componentOptions.messages = { componentOptions.messages = {
'__l': handleLink '__l': handleLink$1
}; };
return Component(componentOptions)
} }
function triggerLink (mpInstance, vueOptions) { function triggerLink$1 (mpInstance, vueOptions) {
mpInstance.dispatch('__l', mpInstance.$vm || vueOptions); mpInstance.dispatch('__l', mpInstance.$vm || vueOptions);
} }
function handleLink (event) { function handleLink$1 (event) {
const target = event.value; const target = event.value;
if (target.$mp) { if (target.$mp) {
if (!target.$parent) { if (!target.$parent) {
...@@ -535,7 +559,7 @@ function createObserver (name) { ...@@ -535,7 +559,7 @@ function createObserver (name) {
} }
} }
function getBehaviors (vueOptions) { function getBehaviors (vueOptions) {
const vueBehaviors = vueOptions['behaviors']; const vueBehaviors = vueOptions['behaviors'];
const vueExtends = vueOptions['extends']; const vueExtends = vueOptions['extends'];
const vueMixins = vueOptions['mixins']; const vueMixins = vueOptions['mixins'];
...@@ -563,7 +587,7 @@ function getBehaviors (vueOptions) { ...@@ -563,7 +587,7 @@ function getBehaviors (vueOptions) {
} }
if (isPlainObject(vueExtends) && vueExtends.props) { if (isPlainObject(vueExtends) && vueExtends.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueExtends.props, true) properties: getProperties(vueExtends.props, true)
}) })
); );
...@@ -572,7 +596,7 @@ function getBehaviors (vueOptions) { ...@@ -572,7 +596,7 @@ function getBehaviors (vueOptions) {
vueMixins.forEach(vueMixin => { vueMixins.forEach(vueMixin => {
if (isPlainObject(vueMixin) && vueMixin.props) { if (isPlainObject(vueMixin) && vueMixin.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueMixin.props, true) properties: getProperties(vueMixin.props, true)
}) })
); );
...@@ -866,29 +890,6 @@ function handleEvent (event) { ...@@ -866,29 +890,6 @@ function handleEvent (event) {
}); });
} }
function initRefs (vm) {
const mpInstance = vm.$mp[vm.mpType];
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 baiduComponentDestroy ($vm) { function baiduComponentDestroy ($vm) {
$vm.$children.forEach(childVm => { $vm.$children.forEach(childVm => {
childVm.$mp.component.detached(); childVm.$mp.component.detached();
...@@ -923,25 +924,28 @@ function initVm (vm) { ...@@ -923,25 +924,28 @@ function initVm (vm) {
} }
function createApp (vm) { function createApp (vm) {
// 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin
Vue.mixin({ Vue.mixin({
beforeCreate () { beforeCreate () {
if (!this.$options.mpType) { if (!this.$options.mpType) {
return return
} }
this.mpType = this.$options.mpType; this.mpType = this.$options.mpType;
this.$mp = { this.$mp = {
data: {}, data: {},
[this.mpType]: this.$options.mpInstance [this.mpType]: this.$options.mpInstance
}; };
this.$scope = this.$options.mpInstance;
delete this.$options.mpType; delete this.$options.mpType;
delete this.$options.mpInstance; delete this.$options.mpInstance;
if (this.mpType !== 'app') { if (this.mpType !== 'app') {
{ // 头条的 selectComponent 竟然是异步的 initRefs(this);
initRefs(this); initMocks(this, mocks$1);
}
initMocks(this, mocks);
} }
}, },
created () { // 处理 injections created () { // 处理 injections
...@@ -1055,15 +1059,13 @@ function createPage (vueOptions) { ...@@ -1055,15 +1059,13 @@ function createPage (vueOptions) {
} }
}, },
__e: handleEvent, __e: handleEvent,
__l: handleLink __l: handleLink$1
} }
}; };
initHooks(pageOptions.methods, hooks$1); initHooks(pageOptions.methods, hooks$1);
initPage(pageOptions); return initPage$1(pageOptions, vueOptions)
return Component(pageOptions)
} }
function initVm$2 (VueComponent) { function initVm$2 (VueComponent) {
...@@ -1071,16 +1073,18 @@ function initVm$2 (VueComponent) { ...@@ -1071,16 +1073,18 @@ function initVm$2 (VueComponent) {
return return
} }
const properties = this.properties;
const options = { const options = {
mpType: 'component', mpType: 'component',
mpInstance: this, mpInstance: this,
propsData: this.properties propsData: properties
}; };
// 初始化 vue 实例 // 初始化 vue 实例
this.$vm = new VueComponent(options); this.$vm = new VueComponent(options);
// 处理$slots,$scopedSlots(暂不支持动态变化$slots) // 处理$slots,$scopedSlots(暂不支持动态变化$slots)
const vueSlots = this.properties.vueSlots; const vueSlots = properties.vueSlots;
if (Array.isArray(vueSlots) && vueSlots.length) { if (Array.isArray(vueSlots) && vueSlots.length) {
const $slots = Object.create(null); const $slots = Object.create(null);
vueSlots.forEach(slotName => { vueSlots.forEach(slotName => {
...@@ -1090,18 +1094,24 @@ function initVm$2 (VueComponent) { ...@@ -1090,18 +1094,24 @@ function initVm$2 (VueComponent) {
} }
// 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并 // 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并
// 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性 // 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性
this.$vm.$mount(); this.$vm.$mount();
} }
function createComponent (vueOptions) { function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions; vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions; // TODO form-field props.name,props.value
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
const behaviors = getBehaviors(vueOptions); const behaviors = getBehaviors(vueOptions);
const properties = getProperties(vueOptions.props, false, vueOptions.__file); const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
const componentOptions = { const componentOptions = {
options: { options: {
multipleSlots: true, multipleSlots: true,
...@@ -1116,7 +1126,7 @@ function createComponent (vueOptions) { ...@@ -1116,7 +1126,7 @@ function createComponent (vueOptions) {
}, },
ready () { ready () {
initVm$2.call(this, VueComponent); // 目前发现部分情况小程序 attached 不触发 initVm$2.call(this, VueComponent); // 目前发现部分情况小程序 attached 不触发
triggerLink(this); // 处理 parent,children triggerLink$1(this); // 处理 parent,children
// 补充生命周期 // 补充生命周期
this.$vm.__call_hook('created'); this.$vm.__call_hook('created');
...@@ -1142,13 +1152,11 @@ function createComponent (vueOptions) { ...@@ -1142,13 +1152,11 @@ function createComponent (vueOptions) {
}, },
methods: { methods: {
__e: handleEvent, __e: handleEvent,
__l: handleLink __l: handleLink$1
} }
}; };
initComponent(componentOptions); return initComponent$1(componentOptions, vueOptions)
return Component(componentOptions)
} }
let uni = {}; let uni = {};
......
{ {
"name": "@dcloudio/uni-mp-baidu", "name": "@dcloudio/uni-mp-baidu",
"version": "0.0.826", "version": "0.0.827",
"description": "uni-app mp-baidu", "description": "uni-app mp-baidu",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
...@@ -462,8 +462,7 @@ function initTriggerEvent (mpInstance) { ...@@ -462,8 +462,7 @@ function initTriggerEvent (mpInstance) {
}; };
} }
Page = function (options = {}) { function initHook (name, options) {
const name = 'onLoad';
const oldHook = options[name]; const oldHook = options[name];
if (!oldHook) { if (!oldHook) {
options[name] = function () { options[name] = function () {
...@@ -475,62 +474,60 @@ Page = function (options = {}) { ...@@ -475,62 +474,60 @@ Page = function (options = {}) {
return oldHook.apply(this, args) return oldHook.apply(this, args)
}; };
} }
}
Page = function (options = {}) {
initHook('onLoad', options);
return MPPage(options) return MPPage(options)
}; };
const behavior = Behavior({
created () {
initTriggerEvent(this);
}
});
Component = function (options = {}) { Component = function (options = {}) {
(options.behaviors || (options.behaviors = [])).unshift(behavior); initHook('created', options);
return MPComponent(options) return MPComponent(options)
}; };
function initBehavior (options) {
return Behavior(options)
}
const instances = Object.create(null); const instances = Object.create(null);
const mocks = ['__route__', '__webviewId__', '__nodeid__']; const mocks$1 = ['__route__', '__webviewId__', '__nodeid__'];
function initPage (pageOptions) { function initPage$1 (pageOptions) {
initComponent(pageOptions); return initComponent$1(pageOptions)
} }
function initComponent (componentOptions) { function initComponent$1 (componentOptions) {
if (componentOptions.properties) { // ref if (componentOptions.properties) { // ref
componentOptions.properties.vueRef = { componentOptions.properties.vueRef = {
type: String, type: String,
value: '' value: ''
}; };
} }
const oldAttached = componentOptions.lifetimes.attached; return Component(componentOptions)
componentOptions.lifetimes.attached = function () {
oldAttached.call(this);
// TODO 需要处理动态变化后的 refs
initRefs.call(this);
};
} }
function initRefs () { function initRefs$1 (vm) {
this.selectAllComponents('.vue-ref', (components) => { const mpInstance = vm.$scope;
mpInstance.selectAllComponents('.vue-ref', (components) => {
components.forEach(component => { components.forEach(component => {
const ref = component.data.vueRef; // 头条的组件 dataset 竟然是空的 const ref = component.data.vueRef; // 头条的组件 dataset 竟然是空的
this.$vm.$refs[ref] = component.$vm || component; vm.$refs[ref] = component.$vm || component;
}); });
}); });
this.selectAllComponents('.vue-ref-in-for', (forComponents) => { mpInstance.selectAllComponents('.vue-ref-in-for', (forComponents) => {
forComponents.forEach(component => { forComponents.forEach(component => {
const ref = component.data.vueRef; const ref = component.data.vueRef;
if (!this.$vm.$refs[ref]) { if (!vm.$refs[ref]) {
this.$vm.$refs[ref] = []; vm.$refs[ref] = [];
} }
this.$vm.$refs[ref].push(component.$vm || component); vm.$refs[ref].push(component.$vm || component);
}); });
}); });
} }
function triggerLink (mpInstance) { function triggerLink$1 (mpInstance) {
const nodeId = mpInstance.__nodeid__ + ''; const nodeId = mpInstance.__nodeid__ + '';
const webviewId = mpInstance.__webviewId__ + ''; const webviewId = mpInstance.__webviewId__ + '';
...@@ -545,7 +542,7 @@ function triggerLink (mpInstance) { ...@@ -545,7 +542,7 @@ function triggerLink (mpInstance) {
}); });
} }
// TODO 目前有 bug,composed 不生效 // TODO 目前有 bug,composed 不生效
function handleLink (event) { function handleLink$1 (event) {
const nodeId = event.detail.nodeId; const nodeId = event.detail.nodeId;
const webviewId = event.detail.webviewId; const webviewId = event.detail.webviewId;
...@@ -619,7 +616,7 @@ function createObserver (name) { ...@@ -619,7 +616,7 @@ function createObserver (name) {
} }
} }
function getBehaviors (vueOptions) { function getBehaviors (vueOptions) {
const vueBehaviors = vueOptions['behaviors']; const vueBehaviors = vueOptions['behaviors'];
const vueExtends = vueOptions['extends']; const vueExtends = vueOptions['extends'];
const vueMixins = vueOptions['mixins']; const vueMixins = vueOptions['mixins'];
...@@ -647,7 +644,7 @@ function getBehaviors (vueOptions) { ...@@ -647,7 +644,7 @@ function getBehaviors (vueOptions) {
} }
if (isPlainObject(vueExtends) && vueExtends.props) { if (isPlainObject(vueExtends) && vueExtends.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueExtends.props, true) properties: getProperties(vueExtends.props, true)
}) })
); );
...@@ -656,7 +653,7 @@ function getBehaviors (vueOptions) { ...@@ -656,7 +653,7 @@ function getBehaviors (vueOptions) {
vueMixins.forEach(vueMixin => { vueMixins.forEach(vueMixin => {
if (isPlainObject(vueMixin) && vueMixin.props) { if (isPlainObject(vueMixin) && vueMixin.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueMixin.props, true) properties: getProperties(vueMixin.props, true)
}) })
); );
...@@ -944,22 +941,28 @@ function initVm (vm) { ...@@ -944,22 +941,28 @@ function initVm (vm) {
} }
function createApp (vm) { function createApp (vm) {
// 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin
Vue.mixin({ Vue.mixin({
beforeCreate () { beforeCreate () {
if (!this.$options.mpType) { if (!this.$options.mpType) {
return return
} }
this.mpType = this.$options.mpType; this.mpType = this.$options.mpType;
this.$mp = { this.$mp = {
data: {}, data: {},
[this.mpType]: this.$options.mpInstance [this.mpType]: this.$options.mpInstance
}; };
this.$scope = this.$options.mpInstance;
delete this.$options.mpType; delete this.$options.mpType;
delete this.$options.mpInstance; delete this.$options.mpInstance;
if (this.mpType !== 'app') { if (this.mpType !== 'app') {
initMocks(this, mocks); initRefs$1(this);
initMocks(this, mocks$1);
} }
}, },
created () { // 处理 injections created () { // 处理 injections
...@@ -1063,15 +1066,13 @@ function createPage (vueOptions) { ...@@ -1063,15 +1066,13 @@ function createPage (vueOptions) {
this.$vm.__call_hook('onUnload'); this.$vm.__call_hook('onUnload');
}, },
__e: handleEvent, __e: handleEvent,
__l: handleLink __l: handleLink$1
} }
}; };
initHooks(pageOptions.methods, hooks$1); initHooks(pageOptions.methods, hooks$1);
initPage(pageOptions); return initPage$1(pageOptions, vueOptions)
return Component(pageOptions)
} }
function initVm$2 (VueComponent) { function initVm$2 (VueComponent) {
...@@ -1079,16 +1080,18 @@ function initVm$2 (VueComponent) { ...@@ -1079,16 +1080,18 @@ function initVm$2 (VueComponent) {
return return
} }
const properties = this.properties;
const options = { const options = {
mpType: 'component', mpType: 'component',
mpInstance: this, mpInstance: this,
propsData: this.properties propsData: properties
}; };
// 初始化 vue 实例 // 初始化 vue 实例
this.$vm = new VueComponent(options); this.$vm = new VueComponent(options);
// 处理$slots,$scopedSlots(暂不支持动态变化$slots) // 处理$slots,$scopedSlots(暂不支持动态变化$slots)
const vueSlots = this.properties.vueSlots; const vueSlots = properties.vueSlots;
if (Array.isArray(vueSlots) && vueSlots.length) { if (Array.isArray(vueSlots) && vueSlots.length) {
const $slots = Object.create(null); const $slots = Object.create(null);
vueSlots.forEach(slotName => { vueSlots.forEach(slotName => {
...@@ -1098,18 +1101,24 @@ function initVm$2 (VueComponent) { ...@@ -1098,18 +1101,24 @@ function initVm$2 (VueComponent) {
} }
// 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并 // 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并
// 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性 // 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性
this.$vm.$mount(); this.$vm.$mount();
} }
function createComponent (vueOptions) { function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions; vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions; // TODO form-field props.name,props.value
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
const behaviors = getBehaviors(vueOptions); const behaviors = getBehaviors(vueOptions);
const properties = getProperties(vueOptions.props, false, vueOptions.__file); const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
const componentOptions = { const componentOptions = {
options: { options: {
multipleSlots: true, multipleSlots: true,
...@@ -1124,7 +1133,7 @@ function createComponent (vueOptions) { ...@@ -1124,7 +1133,7 @@ function createComponent (vueOptions) {
}, },
ready () { ready () {
initVm$2.call(this, VueComponent); // 目前发现部分情况小程序 attached 不触发 initVm$2.call(this, VueComponent); // 目前发现部分情况小程序 attached 不触发
triggerLink(this); // 处理 parent,children triggerLink$1(this); // 处理 parent,children
// 补充生命周期 // 补充生命周期
this.$vm.__call_hook('created'); this.$vm.__call_hook('created');
...@@ -1150,13 +1159,11 @@ function createComponent (vueOptions) { ...@@ -1150,13 +1159,11 @@ function createComponent (vueOptions) {
}, },
methods: { methods: {
__e: handleEvent, __e: handleEvent,
__l: handleLink __l: handleLink$1
} }
}; };
initComponent(componentOptions); return initComponent$1(componentOptions, vueOptions)
return Component(componentOptions)
} }
let uni = {}; let uni = {};
......
{ {
"name": "@dcloudio/uni-mp-toutiao", "name": "@dcloudio/uni-mp-toutiao",
"version": "0.0.324", "version": "0.0.325",
"description": "uni-app mp-toutiao", "description": "uni-app mp-toutiao",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
...@@ -309,8 +309,7 @@ function initTriggerEvent (mpInstance) { ...@@ -309,8 +309,7 @@ function initTriggerEvent (mpInstance) {
}; };
} }
Page = function (options = {}) { function initHook (name, options) {
const name = 'onLoad';
const oldHook = options[name]; const oldHook = options[name];
if (!oldHook) { if (!oldHook) {
options[name] = function () { options[name] = function () {
...@@ -322,22 +321,53 @@ Page = function (options = {}) { ...@@ -322,22 +321,53 @@ Page = function (options = {}) {
return oldHook.apply(this, args) return oldHook.apply(this, args)
}; };
} }
}
Page = function (options = {}) {
initHook('onLoad', options);
return MPPage(options) return MPPage(options)
}; };
const behavior = Behavior({
created () {
initTriggerEvent(this);
}
});
Component = function (options = {}) { Component = function (options = {}) {
(options.behaviors || (options.behaviors = [])).unshift(behavior); initHook('created', options);
return MPComponent(options) return MPComponent(options)
}; };
const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__']; const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'];
function initPage (pageOptions) {
return initComponent(pageOptions)
}
function initComponent (componentOptions) {
return Component(componentOptions)
}
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 triggerLink (mpInstance, vueOptions) { function triggerLink (mpInstance, vueOptions) {
mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, { mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, {
bubbles: true, bubbles: true,
...@@ -360,9 +390,9 @@ function handleLink (event) { ...@@ -360,9 +390,9 @@ function handleLink (event) {
} }
} }
function initMocks (vm, mocks) { function initMocks (vm, mocks$$1) {
const mpInstance = vm.$mp[vm.mpType]; const mpInstance = vm.$mp[vm.mpType];
mocks.forEach(mock => { mocks$$1.forEach(mock => {
if (hasOwn(mpInstance, mock)) { if (hasOwn(mpInstance, mock)) {
vm[mock] = mpInstance[mock]; vm[mock] = mpInstance[mock];
} }
...@@ -419,7 +449,7 @@ function createObserver (name) { ...@@ -419,7 +449,7 @@ function createObserver (name) {
} }
} }
function getBehaviors (vueOptions) { function getBehaviors (vueOptions) {
const vueBehaviors = vueOptions['behaviors']; const vueBehaviors = vueOptions['behaviors'];
const vueExtends = vueOptions['extends']; const vueExtends = vueOptions['extends'];
const vueMixins = vueOptions['mixins']; const vueMixins = vueOptions['mixins'];
...@@ -447,7 +477,7 @@ function getBehaviors (vueOptions) { ...@@ -447,7 +477,7 @@ function getBehaviors (vueOptions) {
} }
if (isPlainObject(vueExtends) && vueExtends.props) { if (isPlainObject(vueExtends) && vueExtends.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueExtends.props, true) properties: getProperties(vueExtends.props, true)
}) })
); );
...@@ -456,7 +486,7 @@ function getBehaviors (vueOptions) { ...@@ -456,7 +486,7 @@ function getBehaviors (vueOptions) {
vueMixins.forEach(vueMixin => { vueMixins.forEach(vueMixin => {
if (isPlainObject(vueMixin) && vueMixin.props) { if (isPlainObject(vueMixin) && vueMixin.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueMixin.props, true) properties: getProperties(vueMixin.props, true)
}) })
); );
...@@ -722,29 +752,6 @@ function handleEvent (event) { ...@@ -722,29 +752,6 @@ function handleEvent (event) {
}); });
} }
}); });
}
function initRefs (vm) {
const mpInstance = vm.$mp[vm.mpType];
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
}
});
} }
const hooks = [ const hooks = [
...@@ -772,24 +779,27 @@ function initVm (vm) { ...@@ -772,24 +779,27 @@ function initVm (vm) {
} }
function createApp (vm) { function createApp (vm) {
// 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin
Vue.mixin({ Vue.mixin({
beforeCreate () { beforeCreate () {
if (!this.$options.mpType) { if (!this.$options.mpType) {
return return
} }
this.mpType = this.$options.mpType; this.mpType = this.$options.mpType;
this.$mp = { this.$mp = {
data: {}, data: {},
[this.mpType]: this.$options.mpInstance [this.mpType]: this.$options.mpInstance
}; };
this.$scope = this.$options.mpInstance;
delete this.$options.mpType; delete this.$options.mpType;
delete this.$options.mpInstance; delete this.$options.mpInstance;
if (this.mpType !== 'app') { if (this.mpType !== 'app') {
{ // 头条的 selectComponent 竟然是异步的 initRefs(this);
initRefs(this);
}
initMocks(this, mocks); initMocks(this, mocks);
} }
}, },
...@@ -900,7 +910,7 @@ function createPage (vueOptions) { ...@@ -900,7 +910,7 @@ function createPage (vueOptions) {
initHooks(pageOptions.methods, hooks$1); initHooks(pageOptions.methods, hooks$1);
return Component(pageOptions) return initPage(pageOptions, vueOptions)
} }
function initVm$2 (VueComponent) { function initVm$2 (VueComponent) {
...@@ -908,16 +918,18 @@ function initVm$2 (VueComponent) { ...@@ -908,16 +918,18 @@ function initVm$2 (VueComponent) {
return return
} }
const properties = this.properties;
const options = { const options = {
mpType: 'component', mpType: 'component',
mpInstance: this, mpInstance: this,
propsData: this.properties propsData: properties
}; };
// 初始化 vue 实例 // 初始化 vue 实例
this.$vm = new VueComponent(options); this.$vm = new VueComponent(options);
// 处理$slots,$scopedSlots(暂不支持动态变化$slots) // 处理$slots,$scopedSlots(暂不支持动态变化$slots)
const vueSlots = this.properties.vueSlots; const vueSlots = properties.vueSlots;
if (Array.isArray(vueSlots) && vueSlots.length) { if (Array.isArray(vueSlots) && vueSlots.length) {
const $slots = Object.create(null); const $slots = Object.create(null);
vueSlots.forEach(slotName => { vueSlots.forEach(slotName => {
...@@ -927,18 +939,24 @@ function initVm$2 (VueComponent) { ...@@ -927,18 +939,24 @@ function initVm$2 (VueComponent) {
} }
// 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并 // 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并
// 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性 // 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性
this.$vm.$mount(); this.$vm.$mount();
} }
function createComponent (vueOptions) { function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions; vueOptions = vueOptions.default || vueOptions;
let VueComponent;
if (isFn(vueOptions)) {
VueComponent = vueOptions; // TODO form-field props.name,props.value
vueOptions = VueComponent.extendOptions;
} else {
VueComponent = Vue.extend(vueOptions);
}
const behaviors = getBehaviors(vueOptions); const behaviors = getBehaviors(vueOptions);
const properties = getProperties(vueOptions.props, false, vueOptions.__file); const properties = getProperties(vueOptions.props, false, vueOptions.__file);
const VueComponent = Vue.extend(vueOptions);
const componentOptions = { const componentOptions = {
options: { options: {
multipleSlots: true, multipleSlots: true,
...@@ -983,7 +1001,7 @@ function createComponent (vueOptions) { ...@@ -983,7 +1001,7 @@ function createComponent (vueOptions) {
} }
}; };
return Component(componentOptions) return initComponent(componentOptions, vueOptions)
} }
let uni = {}; let uni = {};
......
{ {
"name": "@dcloudio/uni-mp-weixin", "name": "@dcloudio/uni-mp-weixin",
"version": "0.0.948", "version": "0.0.949",
"description": "uni-app mp-weixin", "description": "uni-app mp-weixin",
"main": "dist/index.js", "main": "dist/index.js",
"scripts": { "scripts": {
......
import 'uni-platform/runtime/index' import 'uni-platform/runtime/index'
import Vue from 'vue' import Vue from 'vue'
import {
mocks
} from 'uni-platform/runtime/wrapper/index'
import { import {
initRefs, mocks,
initRefs
} from 'uni-platform/runtime/wrapper/index'
import {
initHooks, initHooks,
initMocks initMocks
} from './util' } from './util'
...@@ -38,23 +38,45 @@ function initVm (vm) { ...@@ -38,23 +38,45 @@ function initVm (vm) {
export function createApp (vm) { export function createApp (vm) {
// 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin // 外部初始化时 Vue 还未初始化,放到 createApp 内部初始化 mixin
if (__PLATFORM__ === 'mp-alipay') {
Object.defineProperty(Vue.prototype, '$slots', {
get () {
return this.$scope && this.$scope.props.$slots
},
set () {
}
})
Object.defineProperty(Vue.prototype, '$scopedSlots', {
get () {
return this.$scope && this.$scope.props.$scopedSlots
},
set () {
}
})
}
Vue.mixin({ Vue.mixin({
beforeCreate () { beforeCreate () {
if (!this.$options.mpType) { if (!this.$options.mpType) {
return return
} }
this.mpType = this.$options.mpType this.mpType = this.$options.mpType
this.$mp = { this.$mp = {
data: {}, data: {},
[this.mpType]: this.$options.mpInstance [this.mpType]: this.$options.mpInstance
} }
this.$scope = this.$options.mpInstance
delete this.$options.mpType delete this.$options.mpType
delete this.$options.mpInstance delete this.$options.mpInstance
if (this.mpType !== 'app') { if (this.mpType !== 'app') {
if (__PLATFORM__ !== 'mp-toutiao') { // 头条的 selectComponent 竟然是异步的 initRefs(this)
initRefs(this)
}
initMocks(this, mocks) initMocks(this, mocks)
} }
}, },
......
import Vue from 'vue' import Vue from 'vue'
import {
isFn
} from 'uni-shared'
import { import {
handleLink, handleLink,
triggerLink, triggerLink,
...@@ -18,16 +22,20 @@ function initVm (VueComponent) { ...@@ -18,16 +22,20 @@ function initVm (VueComponent) {
return return
} }
const properties = __PLATFORM__ === 'mp-alipay'
? this.props
: this.properties
const options = { const options = {
mpType: 'component', mpType: 'component',
mpInstance: this, mpInstance: this,
propsData: this.properties propsData: properties
} }
// 初始化 vue 实例 // 初始化 vue 实例
this.$vm = new VueComponent(options) this.$vm = new VueComponent(options)
// 处理$slots,$scopedSlots(暂不支持动态变化$slots) // 处理$slots,$scopedSlots(暂不支持动态变化$slots)
const vueSlots = this.properties.vueSlots const vueSlots = properties.vueSlots
if (Array.isArray(vueSlots) && vueSlots.length) { if (Array.isArray(vueSlots) && vueSlots.length) {
const $slots = Object.create(null) const $slots = Object.create(null)
vueSlots.forEach(slotName => { vueSlots.forEach(slotName => {
...@@ -37,18 +45,24 @@ function initVm (VueComponent) { ...@@ -37,18 +45,24 @@ function initVm (VueComponent) {
} }
// 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并 // 性能优先,mount 提前到 attached 中,保证组件首次渲染数据被合并
// 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性 // 导致与标准 Vue 的差异,data 和 computed 中不能使用$parent,provide等组件属性
this.$vm.$mount() this.$vm.$mount()
} }
export function createComponent (vueOptions) { export function createComponent (vueOptions) {
vueOptions = vueOptions.default || vueOptions vueOptions = vueOptions.default || vueOptions
let VueComponent
if (isFn(vueOptions)) {
VueComponent = vueOptions // TODO form-field props.name,props.value
vueOptions = VueComponent.extendOptions
} else {
VueComponent = Vue.extend(vueOptions)
}
const behaviors = getBehaviors(vueOptions) const behaviors = getBehaviors(vueOptions)
const properties = getProperties(vueOptions.props, false, vueOptions.__file) const properties = getProperties(vueOptions.props, false, vueOptions.__file)
const VueComponent = Vue.extend(vueOptions)
const componentOptions = { const componentOptions = {
options: { options: {
multipleSlots: true, multipleSlots: true,
...@@ -93,7 +107,5 @@ export function createComponent (vueOptions) { ...@@ -93,7 +107,5 @@ export function createComponent (vueOptions) {
} }
} }
initComponent(componentOptions) return initComponent(componentOptions, vueOptions)
return Component(componentOptions)
} }
...@@ -101,7 +101,5 @@ export function createPage (vueOptions) { ...@@ -101,7 +101,5 @@ export function createPage (vueOptions) {
initHooks(pageOptions.methods, hooks) initHooks(pageOptions.methods, hooks)
initPage(pageOptions) return initPage(pageOptions, vueOptions)
return Component(pageOptions)
} }
...@@ -5,6 +5,10 @@ import { ...@@ -5,6 +5,10 @@ import {
isPlainObject isPlainObject
} from 'uni-shared' } from 'uni-shared'
import {
initBehavior
} from 'uni-platform/runtime/wrapper/index'
export function initMocks (vm, mocks) { export function initMocks (vm, mocks) {
const mpInstance = vm.$mp[vm.mpType] const mpInstance = vm.$mp[vm.mpType]
mocks.forEach(mock => { mocks.forEach(mock => {
...@@ -64,7 +68,7 @@ function createObserver (name) { ...@@ -64,7 +68,7 @@ function createObserver (name) {
} }
} }
export function getBehaviors (vueOptions) { export function getBehaviors (vueOptions) {
const vueBehaviors = vueOptions['behaviors'] const vueBehaviors = vueOptions['behaviors']
const vueExtends = vueOptions['extends'] const vueExtends = vueOptions['extends']
const vueMixins = vueOptions['mixins'] const vueMixins = vueOptions['mixins']
...@@ -92,7 +96,7 @@ export function getBehaviors (vueOptions) { ...@@ -92,7 +96,7 @@ export function getBehaviors (vueOptions) {
} }
if (isPlainObject(vueExtends) && vueExtends.props) { if (isPlainObject(vueExtends) && vueExtends.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueExtends.props, true) properties: getProperties(vueExtends.props, true)
}) })
) )
...@@ -101,7 +105,7 @@ export function getBehaviors (vueOptions) { ...@@ -101,7 +105,7 @@ export function getBehaviors (vueOptions) {
vueMixins.forEach(vueMixin => { vueMixins.forEach(vueMixin => {
if (isPlainObject(vueMixin) && vueMixin.props) { if (isPlainObject(vueMixin) && vueMixin.props) {
behaviors.push( behaviors.push(
Behavior({ initBehavior({
properties: getProperties(vueMixin.props, true) properties: getProperties(vueMixin.props, true)
}) })
) )
...@@ -395,29 +399,6 @@ export function handleEvent (event) { ...@@ -395,29 +399,6 @@ export function handleEvent (event) {
}) })
} }
export function initRefs (vm) {
const mpInstance = vm.$mp[vm.mpType]
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 baiduComponentDestroy ($vm) { function baiduComponentDestroy ($vm) {
$vm.$children.forEach(childVm => { $vm.$children.forEach(childVm => {
childVm.$mp.component.detached() childVm.$mp.component.detached()
......
export { export {
mocks, mocks,
initRefs,
handleLink, handleLink,
triggerLink triggerLink,
initBehavior
} }
from '../../../mp-weixin/runtime/wrapper/index' from '../../../mp-weixin/runtime/wrapper/index'
export function initPage (pageOptions) { export function initPage (pageOptions) {
initComponent(pageOptions) return initComponent(pageOptions)
} }
export function initComponent (componentOptions) { export function initComponent (componentOptions) {
componentOptions.methods.$getAppWebview = function () { componentOptions.methods.$getAppWebview = function () {
return plus.webview.getWebviewById(`${this.__wxWebviewId__}`) return plus.webview.getWebviewById(`${this.__wxWebviewId__}`)
} }
return Component(componentOptions)
} }
import {
hasOwn
} from 'uni-shared'
const isArray = Array.isArray
const keyList = Object.keys
export default function equal (a, b) {
if (a === b) return true
if (a && b && typeof a === 'object' && typeof b === 'object') {
const arrA = isArray(a)
const arrB = isArray(b)
let i, length, key
if (arrA && arrB) {
length = a.length
if (length !== b.length) return false
for (i = length; i-- !== 0;) {
if (!equal(a[i], b[i])) return false
}
return true
}
if (arrA !== arrB) return false
const dateA = a instanceof Date
const dateB = b instanceof Date
if (dateA !== dateB) return false
if (dateA && dateB) return a.getTime() === b.getTime()
const regexpA = a instanceof RegExp
const regexpB = b instanceof RegExp
if (regexpA !== regexpB) return false
if (regexpA && regexpB) return a.toString() === b.toString()
const keys = keyList(a)
length = keys.length
if (length !== keyList(b).length) {
return false
}
for (i = length; i-- !== 0;) {
if (!hasOwn.call(b, keys[i])) return false
}
for (i = length; i-- !== 0;) {
key = keys[i]
if (!equal(a[key], b[key])) return false
}
return true
}
return false
}
import {
isFn,
cached,
camelize
} from 'uni-shared'
import deepEqual from './deep-equal'
const customizeRE = /:/g
const customize = cached((str) => {
return camelize(str.replace(customizeRE, '-'))
})
export const mocks = ['$id']
export function initRefs () {
}
function handleRef (ref) {
if (!ref) {
return
}
const refName = ref.props['data-ref']
const refInForName = ref.props['data-ref-in-for']
if (refName) {
this.$vm.$refs[refName] = ref.$vm || ref
} else if (refInForName) {
this.$vm.$refs[refInForName] = [ref.$vm || ref]
}
}
export function initPage (pageOptions, vueOptions) {
const {
lifetimes,
methods
} = pageOptions
pageOptions.onReady = lifetimes.ready
pageOptions.onUnload = function () {
lifetimes.detached.call(this)
methods.onUnload.call(this)
}
Object.keys(methods).forEach(method => {
if (method !== 'onUnload') {
pageOptions[method] = methods[method]
}
})
pageOptions['__r'] = handleRef
if (vueOptions.methods && vueOptions.methods.formReset) {
pageOptions['formReset'] = vueOptions.methods.formReset
}
delete pageOptions.lifetimes
delete pageOptions.methods
return Page(pageOptions)
}
function triggerEvent (type, detail, options) {
const handler = this.props[customize('on-' + type)]
if (!handler) {
return
}
const eventOpts = this.props['data-event-opts']
const target = {
dataset: {
eventOpts
}
}
handler({
type: customize(type),
target,
currentTarget: target,
detail
})
}
const IGNORES = ['$slots', '$scopedSlots']
function createObserver (isDidUpdate) {
return function observe (props) {
const prevProps = isDidUpdate ? props : this.props
const nextProps = isDidUpdate ? this.props : props
if (deepEqual(prevProps, nextProps)) {
return
}
Object.keys(prevProps).forEach(name => {
if (IGNORES.indexOf(name) === -1) {
const prevValue = prevProps[name]
const nextValue = nextProps[name]
if (!isFn(prevValue) && !isFn(nextValue) && !deepEqual(prevValue, nextValue)) {
this.$vm[name] = nextProps[name]
}
}
})
}
}
export function initComponent (componentOptions, vueOptions) {
const {
lifetimes,
properties,
behaviors
} = componentOptions
componentOptions.mixins = behaviors
const props = {
onTriggerLink: function () {}
}
Object.keys(properties).forEach(key => {
if (key !== 'vueSlots') {
props[key] = properties[key].value
}
})
componentOptions.props = props
if (my.canIUse('component2')) {
componentOptions.onInit = lifetimes.attached
}
componentOptions.didMount = lifetimes.ready
componentOptions.didUnmount = lifetimes.detached
if (my.canIUse('component2')) {
componentOptions.deriveDataFromProps = createObserver() // nextProps
} else {
componentOptions.didUpdate = createObserver(true) // prevProps
}
if (!componentOptions.methods) {
componentOptions.methods = {}
}
if (vueOptions.methods && vueOptions.methods.formReset) {
componentOptions.methods['formReset'] = vueOptions.methods.formReset
}
componentOptions.methods['__r'] = handleRef
componentOptions.methods.triggerEvent = triggerEvent
delete componentOptions.properties
delete componentOptions.behaviors
delete componentOptions.lifetimes
delete componentOptions.pageLifetimes
return Component(componentOptions)
}
export function initBehavior ({
properties
}) {
const props = {}
Object.keys(properties).forEach(key => {
props[key] = properties[key].value
})
return {
props
}
}
export function triggerLink (mpInstance, vueOptions) {
mpInstance.props.onTriggerLink(mpInstance.$vm || vueOptions)
}
export function handleLink (detail) {
if (detail.$mp) { // vm
if (!detail.$parent) {
detail.$parent = this.$vm
if (detail.$parent) {
detail.$parent.$children.push(detail)
detail.$root = this.$vm.$root
}
}
} else { // vueOptions
if (!detail.parent) {
detail.parent = this.$vm
}
}
}
export {
initRefs,
initBehavior
}
from '../../../mp-weixin/runtime/wrapper/index'
export const mocks = ['nodeId'] export const mocks = ['nodeId']
export function initPage (pageOptions) { export function initPage (pageOptions) {
initComponent(pageOptions) return initComponent(pageOptions)
} }
export function initComponent (componentOptions) { export function initComponent (componentOptions) {
componentOptions.messages = { componentOptions.messages = {
'__l': handleLink '__l': handleLink
} }
return Component(componentOptions)
} }
export function triggerLink (mpInstance, vueOptions) { export function triggerLink (mpInstance, vueOptions) {
......
export {
initBehavior
}
from '../../../mp-weixin/runtime/wrapper/index'
const instances = Object.create(null) const instances = Object.create(null)
export const mocks = ['__route__', '__webviewId__', '__nodeid__'] export const mocks = ['__route__', '__webviewId__', '__nodeid__']
export function initPage (pageOptions) { export function initPage (pageOptions) {
initComponent(pageOptions) return initComponent(pageOptions)
} }
export function initComponent (componentOptions) { export function initComponent (componentOptions) {
...@@ -13,28 +18,24 @@ export function initComponent (componentOptions) { ...@@ -13,28 +18,24 @@ export function initComponent (componentOptions) {
value: '' value: ''
} }
} }
const oldAttached = componentOptions.lifetimes.attached return Component(componentOptions)
componentOptions.lifetimes.attached = function () {
oldAttached.call(this)
// TODO 需要处理动态变化后的 refs
initRefs.call(this)
}
} }
function initRefs () { export function initRefs (vm) {
this.selectAllComponents('.vue-ref', (components) => { const mpInstance = vm.$scope
mpInstance.selectAllComponents('.vue-ref', (components) => {
components.forEach(component => { components.forEach(component => {
const ref = component.data.vueRef // 头条的组件 dataset 竟然是空的 const ref = component.data.vueRef // 头条的组件 dataset 竟然是空的
this.$vm.$refs[ref] = component.$vm || component vm.$refs[ref] = component.$vm || component
}) })
}) })
this.selectAllComponents('.vue-ref-in-for', (forComponents) => { mpInstance.selectAllComponents('.vue-ref-in-for', (forComponents) => {
forComponents.forEach(component => { forComponents.forEach(component => {
const ref = component.data.vueRef const ref = component.data.vueRef
if (!this.$vm.$refs[ref]) { if (!vm.$refs[ref]) {
this.$vm.$refs[ref] = [] vm.$refs[ref] = []
} }
this.$vm.$refs[ref].push(component.$vm || component) vm.$refs[ref].push(component.$vm || component)
}) })
}) })
} }
......
...@@ -24,8 +24,7 @@ function initTriggerEvent (mpInstance) { ...@@ -24,8 +24,7 @@ function initTriggerEvent (mpInstance) {
} }
} }
Page = function (options = {}) { function initHook (name, options) {
const name = 'onLoad'
const oldHook = options[name] const oldHook = options[name]
if (!oldHook) { if (!oldHook) {
options[name] = function () { options[name] = function () {
...@@ -37,16 +36,14 @@ Page = function (options = {}) { ...@@ -37,16 +36,14 @@ Page = function (options = {}) {
return oldHook.apply(this, args) return oldHook.apply(this, args)
} }
} }
return MPPage(options)
} }
const behavior = Behavior({ Page = function (options = {}) {
created () { initHook('onLoad', options)
initTriggerEvent(this) return MPPage(options)
} }
})
Component = function (options = {}) { Component = function (options = {}) {
(options.behaviors || (options.behaviors = [])).unshift(behavior) initHook('created', options)
return MPComponent(options) return MPComponent(options)
} }
export const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__'] export const mocks = ['__route__', '__wxExparserNodeId__', '__wxWebviewId__']
export function initPage () { export function initPage (pageOptions) {
return initComponent(pageOptions)
} }
export function initComponent () { export function initComponent (componentOptions) {
return Component(componentOptions)
} }
export function initBehavior (options) {
return Behavior(options)
}
export 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
}
})
}
export function triggerLink (mpInstance, vueOptions) { export function triggerLink (mpInstance, vueOptions) {
mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, { mpInstance.triggerEvent('__l', mpInstance.$vm || vueOptions, {
bubbles: true, bubbles: true,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册