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

build uni runtime(mp-alipay usingComponents)

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