Skip to content

Commit

Permalink
feat(core): support swan lifecycle-2-0 (#164)
Browse files Browse the repository at this point in the history
BREAKING CHANGE: swan lifecycle-2-0 is a breaking change
  • Loading branch information
allen-zh committed Aug 30, 2019
1 parent 8e472a9 commit e075dbb
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 32 deletions.
3 changes: 2 additions & 1 deletion packages/mars-core/__test__/unit/swan/swan.test.js
Expand Up @@ -156,14 +156,15 @@ describe('[swan]createComponent', () => {
// mock call methods
component.lifetimes.created.call(component);
expect(component.$vue).not.toBe(undefined);

component.lifetimes.attached.call(component);
// component intial setData omited
expect(setData).toHaveBeenCalledTimes(1);
component.$vue.a = 2;
component.$vue.$nextTick(() => {
expect(setData).toHaveBeenCalledTimes(2);
});

component.lifetimes.attached.call(component);
component.lifetimes.ready.call(component);
});
});
Expand Down
40 changes: 30 additions & 10 deletions packages/mars-core/src/base/createComponent.js
Expand Up @@ -3,6 +3,7 @@
* @author zhangwentao <winty2013@gmail.com>
*/

/* eslint-disable fecs-camelcase */
import {normalizeProps} from '../helper/props';
import {getPageInstance} from '../helper/instance';
import Vue from './vue/index';
Expand All @@ -22,7 +23,16 @@ function mountVue(VueComponent, setData) {
// 根据 compId 算出父实例的 comId
// const rootUID = this.data.rootUID;
// const rootMp = getApp().__pages__[rootUID];
const rootMp = getPageInstance(this);
// const rootMp = getPageInstance(this);
const rootMp = this.$$__page__;

// for swan new lifecycle-2-0
// will create page vm before component vm
if (config.$platform === 'swan' && rootMp && !rootMp.$vue) {
rootMp.$$__createVue__ && rootMp.$$__createVue__.call(rootMp);
delete rootMp.$$__createVue__;
}

const currentCompId = properties.compId;
const parentCompid = currentCompId.slice(0, currentCompId.lastIndexOf(','));
let parent;
Expand Down Expand Up @@ -65,7 +75,9 @@ function mountVue(VueComponent, setData) {
}
}

export function makeCreateComponent(handleProxy, handleModel, setData, callHook) {
export function makeCreateComponent(handleProxy, handleModel, setData, callHook, {
$api
}) {
return function (options) {
// TODO initData 包括 vue 实例的 data defaultProps 和 computed
let initData = typeof options.data === 'function' ? options.data() : (options.data || {});
Expand All @@ -78,7 +90,10 @@ export function makeCreateComponent(handleProxy, handleModel, setData, callHook)
compId: String,
ref: String,
rootComputed: Object,
rootUID: Number
rootUID: {
type: Number,
value: -1
}
});

let [VueComponent, vueOptions] = initVueComponent(Vue, options);
Expand All @@ -87,6 +102,7 @@ export function makeCreateComponent(handleProxy, handleModel, setData, callHook)
__isComponent__: true,
// for lifetimes before Vue mount
$vue: {
$api,
$options: options
},
properties: props,
Expand All @@ -113,21 +129,23 @@ export function makeCreateComponent(handleProxy, handleModel, setData, callHook)
},
lifetimes: {
created(...args) {
const rootMp = getPageInstance(this);
this.$$__page__ = rootMp;
if (process.env.NODE_ENV !== 'production' && config.debug && config.debug.lifetimes) {
console.log('[debug: mp lifetimes] created', this.data.compId);
}
if (config.$platform === 'swan') {
mountVue.call(this, VueComponent, setData);
}
this.$vue.$mp = {
scope: this
};
callHook.call(this, this.$vue, 'comp', 'created', args);
},
attached(...args) {
if (process.env.NODE_ENV !== 'production' && config.debug && config.debug.lifetimes) {
console.log('[debug: mp lifetimes] attached', this.data.compId);
}
if (config.$platform === 'wx') {
mountVue.call(this, VueComponent, setData);
}
// if (config.$platform === 'wx') {
mountVue.call(this, VueComponent, setData);
// }
callHook.call(this, this.$vue, 'comp', 'attached', args);
},
ready(...args) {
Expand All @@ -140,7 +158,7 @@ export function makeCreateComponent(handleProxy, handleModel, setData, callHook)
if (process.env.NODE_ENV !== 'production' && config.debug && config.debug.lifetimes) {
console.log('[debug: mp lifetimes] detached', this.data.compId);
}
callHook.call(this, this.$vue, 'comp', 'dettached', args);
callHook.call(this, this.$vue, 'comp', 'detached', args);
this.$vue && this.$vue.$destroy();
// remove swan binded vue instance from root __vms__
const page = getPageInstance(this);
Expand All @@ -151,6 +169,8 @@ export function makeCreateComponent(handleProxy, handleModel, setData, callHook)
vmData[curSwan] = null;
delete vmData[curSwan];
}
delete this.$vue;
delete this.$$__page__;
}
}
};
Expand Down
26 changes: 20 additions & 6 deletions packages/mars-core/src/base/createPage.js
Expand Up @@ -8,12 +8,18 @@
/* global getApp */

/* eslint-disable babel/new-cap */
/* eslint-disable fecs-camelcase */
import Vue from './vue/index';
import {mark, measure} from '../helper/perf';
import config from '../config';
import {state} from './state';

export function createVue(options, args, {setData}) {
const pages = getApp().__pages__;
const uid = this.__uid__ !== undefined ? this.__uid__ : ++pages.uid;
pages[uid] = this;
this.__uid__ = uid;

if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
const perfTagStart = `${this.route}-start`;
// const perfTagEnd = `${this.route}-end`;
Expand Down Expand Up @@ -70,20 +76,26 @@ export function makeCreatePage(pageMixin, {handleProxy, handleModel}, setData, c
options.mixins = [pageMixin];

return {
$$__createVue__() {
return createVue.call(this, options, [], {setData});
},
data: {},
handleProxy,
handleModel,
onLoad(...args) {
const pages = getApp().__pages__;
const uid = this.__uid__ !== undefined ? this.__uid__ : ++pages.uid;
pages[uid] = this;
this.__uid__ = uid;
let vm = this.$vue;
if (!vm) {
vm = createVue.call(this, options, args, {setData});
}
else {
const query = args[0];
vm.$mp.query = query;
vm.$mp.options = query;
}

if (process.env.NODE_ENV !== 'production' && config.debug && config.debug.lifetimes) {
console.log('[debug: mp pageHooks] onLoad', this.__uid__);
}

const vm = createVue.call(this, options, args, {setData});
// 先 callHook 保证数据可以初始化
const ret = callHook.call(this, this.$vue, 'page', 'onLoad', args);
mountVue.call(this, vm);
Expand All @@ -107,6 +119,8 @@ export function makeCreatePage(pageMixin, {handleProxy, handleModel}, setData, c
}

});
delete this.$vue;
delete this.$$__createVue__;
return ret;
},
onReady(...args) {
Expand Down
2 changes: 1 addition & 1 deletion packages/mars-core/src/config.js
Expand Up @@ -10,4 +10,4 @@ export default {
lifetimes: false
},
framework: process.env.MARS_CONFIG_FRAMEWORK
};
};
13 changes: 10 additions & 3 deletions packages/mars-core/src/helper/instance.js
Expand Up @@ -2,12 +2,19 @@
* @file props helper
* @author zhangwentao
*/
/* global getApp */
/* global getApp, getCurrentPages */

export function getPageInstance($mp) {
const uid = $mp.data.rootUID;
const pages = getApp().__pages__;
const page = pages[uid];
let page;
if (uid === -1) {
const pages = getCurrentPages();
page = pages[pages.length - 1];
}
else {
page = getApp().__pages__[uid];
}

if (!page) {
throw new Error(`cannot find page instance for $mp ${$mp.data.compId}`, $mp);
}
Expand Down
9 changes: 8 additions & 1 deletion packages/mars-core/src/swan/createComponent.js
Expand Up @@ -13,6 +13,7 @@ import {
} from './mixins';
import {setData} from './data';
import {callHook} from './lifecycle';
import $api from './nativeAPI';

import {
makeCreateComponent,
Expand All @@ -21,4 +22,10 @@ import {

export const vueCompCreator = makeVueCompCreator(getCompMixin);

export default makeCreateComponent(handleProxy, handleModel, setData, callHook);
export default makeCreateComponent(
handleProxy,
handleModel,
setData,
callHook,
{$api}
);
12 changes: 9 additions & 3 deletions packages/mars-core/src/wx/createComponent.js
Expand Up @@ -13,12 +13,18 @@ import {
} from './mixins';
import {setData} from './data';
import {callHook} from './lifecycle';
import $api from './nativeAPI';

import {
makeCreateComponent,
makeVueCompCreator
} from '../base/createComponent';

export const vueCompCreator = makeVueCompCreator(getCompMixin);


export default makeCreateComponent(handleProxy, handleModel, setData, callHook);
export default makeCreateComponent(
handleProxy,
handleModel,
setData,
callHook,
{$api}
);
9 changes: 2 additions & 7 deletions packages/mars-core/src/wx/createPage.js
Expand Up @@ -24,17 +24,11 @@ function makeCreatePage(pageMixin, {handleProxy, handleModel}, setData, callHook
data: {},
lifetimes: {
attached(...args) {
const pages = getApp().__pages__;
const uid = this.__uid__ !== undefined ? this.__uid__ : ++pages.uid;
pages[uid] = this;
this.__uid__ = uid;
createVue.call(this, options, args, {setData});

if (process.env.NODE_ENV !== 'production' && config.debug && config.debug.lifetimes) {
console.log('[debug: mp pageHooks] attached', this.__uid__);
}

const vm = createVue.call(this, options, args, {setData});
mountVue.call(this, vm);
}
},
methods: {
Expand All @@ -46,6 +40,7 @@ function makeCreatePage(pageMixin, {handleProxy, handleModel}, setData, callHook
}
// 先 callHook 保证数据可以初始化
const ret = callHook.call(this, this.$vue, 'page', 'onLoad', args);
mountVue.call(this, this.$vue);
return ret;
},
onUnload(...args) {
Expand Down

0 comments on commit e075dbb

Please sign in to comment.