feat: 🎸 添加 didMount 和 willUnmount 两个基本的生命周期

This commit is contained in:
牧毅 2020-08-13 21:04:21 +08:00
parent 779ea7c718
commit e33a95e479
7 changed files with 153 additions and 47 deletions

View File

@ -2,6 +2,9 @@ export const RAX_CHUNK_NAME = {
ClassDidMountBegin: 'RaxComponentClassDidMountBegin', ClassDidMountBegin: 'RaxComponentClassDidMountBegin',
ClassDidMountContent: 'RaxComponentClassDidMountContent', ClassDidMountContent: 'RaxComponentClassDidMountContent',
ClassDidMountEnd: 'RaxComponentClassDidMountEnd', ClassDidMountEnd: 'RaxComponentClassDidMountEnd',
ClassWillUnmountBegin: 'RaxComponentClassWillUnmountBegin',
ClassWillUnmountContent: 'RaxComponentClassWillUnmountContent',
ClassWillUnmountEnd: 'RaxComponentClassWillUnmountEnd',
ClassRenderBegin: 'RaxComponentClassRenderBegin', ClassRenderBegin: 'RaxComponentClassRenderBegin',
ClassRenderPre: 'RaxComponentClassRenderPre', ClassRenderPre: 'RaxComponentClassRenderPre',
ClassRenderJSX: 'RaxComponentClassRenderJSX', ClassRenderJSX: 'RaxComponentClassRenderJSX',
@ -9,4 +12,7 @@ export const RAX_CHUNK_NAME = {
MethodsBegin: 'RaxComponentMethodsBegin', MethodsBegin: 'RaxComponentMethodsBegin',
MethodsContent: 'RaxComponentMethodsContent', MethodsContent: 'RaxComponentMethodsContent',
MethodsEnd: 'RaxComponentMethodsEnd', MethodsEnd: 'RaxComponentMethodsEnd',
LifeCyclesBegin: 'RaxComponentLifeCyclesBegin',
LifeCyclesContent: 'RaxComponentLifeCyclesContent',
LifeCyclesEnd: 'RaxComponentLifeCyclesEnd',
}; };

View File

@ -84,12 +84,33 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
linkAfter: [RAX_CHUNK_NAME.ClassDidMountBegin, RAX_CHUNK_NAME.ClassDidMountContent], linkAfter: [RAX_CHUNK_NAME.ClassDidMountBegin, RAX_CHUNK_NAME.ClassDidMountContent],
}); });
next.chunks.push({
type: ChunkType.STRING,
fileType: FileType.JSX,
name: RAX_CHUNK_NAME.ClassWillUnmountBegin,
content: `componentWillUnmount() {`,
linkAfter: [
CLASS_DEFINE_CHUNK_NAME.Start,
CLASS_DEFINE_CHUNK_NAME.InsVar,
CLASS_DEFINE_CHUNK_NAME.InsMethod,
RAX_CHUNK_NAME.ClassDidMountEnd,
],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: FileType.JSX,
name: RAX_CHUNK_NAME.ClassWillUnmountEnd,
content: `}`,
linkAfter: [RAX_CHUNK_NAME.ClassWillUnmountBegin, RAX_CHUNK_NAME.ClassWillUnmountContent],
});
next.chunks.push({ next.chunks.push({
type: ChunkType.STRING, type: ChunkType.STRING,
fileType: FileType.JSX, fileType: FileType.JSX,
name: RAX_CHUNK_NAME.ClassRenderBegin, name: RAX_CHUNK_NAME.ClassRenderBegin,
content: 'render() {', content: 'render() {',
linkAfter: [RAX_CHUNK_NAME.ClassDidMountEnd], linkAfter: [RAX_CHUNK_NAME.ClassDidMountEnd, RAX_CHUNK_NAME.ClassWillUnmountEnd],
}); });
next.chunks.push({ next.chunks.push({

View File

@ -1,3 +1,4 @@
import _ from 'lodash';
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator'; import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
import { RAX_CHUNK_NAME } from './const'; import { RAX_CHUNK_NAME } from './const';
@ -7,7 +8,6 @@ import {
BuilderComponentPlugin, BuilderComponentPlugin,
BuilderComponentPluginFactory, BuilderComponentPluginFactory,
ChunkType, ChunkType,
CodeGeneratorError,
FileType, FileType,
ICodeChunk, ICodeChunk,
ICodeStruct, ICodeStruct,
@ -34,53 +34,86 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
...pre, ...pre,
}; };
// TODO: Rax 程序的生命周期暂未明确,此处先屏蔽 // Rax 先只支持 didMount 和 willUnmount 吧
// @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5
// const ir = next.ir as IContainerInfo; const ir = next.ir as IContainerInfo;
const lifeCycles = ir.lifeCycles;
// if (ir.lifeCycles) { if (lifeCycles && !_.isEmpty(lifeCycles)) {
// const lifeCycles = ir.lifeCycles; Object.entries(lifeCycles).forEach(([lifeCycleName, lifeCycleMethodExpr]) => {
// const chunks = Object.keys(lifeCycles).map<ICodeChunk>(lifeCycleName => { const normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName;
// const normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName; const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName;
// const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName;
// if (normalizeName === 'constructor') {
// return {
// type: ChunkType.STRING,
// fileType: cfg.fileType,
// name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
// content: getFuncExprBody(
// (lifeCycles[lifeCycleName] as JSExpression).value,
// ),
// linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorStart]],
// };
// }
// if (normalizeName === 'render') {
// return {
// type: ChunkType.STRING,
// fileType: cfg.fileType,
// name: RAX_CHUNK_NAME.ClassRenderPre,
// content: getFuncExprBody(
// (lifeCycles[lifeCycleName] as JSExpression).value,
// ),
// linkAfter: [RAX_CHUNK_NAME.ClassRenderStart],
// };
// }
// return { next.chunks.push({
// type: ChunkType.STRING, type: ChunkType.STRING,
// fileType: cfg.fileType, fileType: cfg.fileType,
// name: CLASS_DEFINE_CHUNK_NAME.InsMethod, name: RAX_CHUNK_NAME.LifeCyclesContent,
// content: transformFuncExpr2MethodMember( content: `${exportName}: (${lifeCycleMethodExpr.value}),`,
// exportName, linkAfter: [RAX_CHUNK_NAME.LifeCyclesBegin],
// (lifeCycles[lifeCycleName] as JSExpression).value, });
// ),
// linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
// };
// });
// next.chunks.push.apply(next.chunks, chunks); if (normalizeName === 'didMount') {
// } next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: RAX_CHUNK_NAME.ClassDidMountContent,
content: `this._lifeCycles.${exportName}();`,
linkAfter: [RAX_CHUNK_NAME.ClassDidMountBegin],
});
} else if (normalizeName === 'willUnmount') {
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: RAX_CHUNK_NAME.ClassWillUnmountContent,
content: `this._lifeCycles.${exportName}();`,
linkAfter: [RAX_CHUNK_NAME.ClassWillUnmountBegin],
});
} else {
// TODO: print warnings? Unknown life cycle
}
});
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsVar,
content: `_lifeCycles = this._defineLifeCycles();`,
linkAfter: [CLASS_DEFINE_CHUNK_NAME.Start],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: RAX_CHUNK_NAME.LifeCyclesBegin,
content: `
_defineLifeCycles() {
const __$$lifeCycles = ({
`,
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd, CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod],
});
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
name: RAX_CHUNK_NAME.LifeCyclesEnd,
content: `
});
// 为所有的方法绑定上下文
Object.entries(__$$lifeCycles).forEach(([lifeCycleName, lifeCycleMethod]) => {
if (typeof lifeCycleMethod === 'function') {
__$$lifeCycles[lifeCycleName] = (...args) => {
return lifeCycleMethod.apply(this._context, args);
}
}
});
return __$$lifeCycles;
}
`,
linkAfter: [RAX_CHUNK_NAME.LifeCyclesBegin, RAX_CHUNK_NAME.LifeCyclesContent],
});
}
return next; return next;
}; };

View File

@ -46,7 +46,11 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
_defineMethods() { _defineMethods() {
const __$$methods = ({ const __$$methods = ({
`, `,
linkAfter: [RAX_CHUNK_NAME.ClassRenderEnd, CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod], linkAfter: [
RAX_CHUNK_NAME.ClassRenderEnd,
CLASS_DEFINE_CHUNK_NAME.InsPrivateMethod,
RAX_CHUNK_NAME.LifeCyclesEnd,
],
}); });
next.chunks.push({ next.chunks.push({

View File

@ -28,6 +28,8 @@ class Home$$Page extends Component {
this._dataSourceEngine.reloadDataSource(); this._dataSourceEngine.reloadDataSource();
} }
componentWillUnmount() {}
render() { render() {
const __$$context = this._context; const __$$context = this._context;

View File

@ -43,8 +43,16 @@ class Home$$Page extends Component {
_utils = this._defineUtils(); _utils = this._defineUtils();
_lifeCycles = this._defineLifeCycles();
componentDidMount() { componentDidMount() {
this._dataSourceEngine.reloadDataSource(); this._dataSourceEngine.reloadDataSource();
this._lifeCycles.didMount();
}
componentWillUnmount() {
this._lifeCycles.willUnmount();
} }
render() { render() {
@ -179,6 +187,29 @@ class Home$$Page extends Component {
return utils; return utils;
} }
_defineLifeCycles() {
const __$$lifeCycles = {
didMount: function didMount() {
this.utils.Toast.show(`Hello ${this.state.user.name}!`);
},
willUnmount: function didMount() {
this.utils.Toast.show(`Bye, ${this.state.user.name}!`);
},
};
//
Object.entries(__$$lifeCycles).forEach(([lifeCycleName, lifeCycleMethod]) => {
if (typeof lifeCycleMethod === 'function') {
__$$lifeCycles[lifeCycleName] = (...args) => {
return lifeCycleMethod.apply(this._context, args);
};
}
});
return __$$lifeCycles;
}
_defineMethods() { _defineMethods() {
const __$$methods = { const __$$methods = {
hello: function hello() { hello: function hello() {

View File

@ -52,7 +52,16 @@
], ],
}, },
props: {}, props: {},
lifeCycles: {}, lifeCycles: {
didMount: {
type: 'JSExpression',
value: 'function didMount(){\n this.utils.Toast.show(`Hello ${this.state.user.name}!`);\n}',
},
willUnmount: {
type: 'JSExpression',
value: 'function didMount(){\n this.utils.Toast.show(`Bye, ${this.state.user.name}!`);\n}',
},
},
methods: { methods: {
hello: { hello: {
type: 'JSExpression', type: 'JSExpression',