From 1982ed631ac1ae5aedf7a0d00092ccf433fc5cd7 Mon Sep 17 00:00:00 2001 From: lyfeyaj Date: Fri, 9 Jun 2023 10:14:11 +0800 Subject: [PATCH 1/5] =?UTF-8?q?feat(takin):=20=E4=BC=98=E5=8C=96=E7=94=9F?= =?UTF-8?q?=E6=88=90=E5=99=A8=E9=80=BB=E8=BE=91=E5=A2=9E=E5=8A=A0=E6=A8=A1?= =?UTF-8?q?=E7=89=88=E8=A7=A3=E6=9E=90=E5=AF=B9=20<%=5F=20=E6=88=96=20=5F%?= =?UTF-8?q?>=20=E6=88=96=20-%>=20=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/takin/src/generator.ts | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/packages/takin/src/generator.ts b/packages/takin/src/generator.ts index 4502c99d..3c0397ea 100644 --- a/packages/takin/src/generator.ts +++ b/packages/takin/src/generator.ts @@ -321,12 +321,14 @@ export class Generator implements Required { * 生成终端的 prompts 问题 */ async prompting() { - this.answers = await prompts(this.questions, { - onCancel() { - // 用户取消时自动退出 - process.exit(0) - } - }) + if (this.questions?.length) { + this.answers = await prompts(this.questions, { + onCancel() { + // 用户取消时自动退出 + process.exit(0) + } + }) + } } /** @@ -361,10 +363,21 @@ export class Generator implements Required { /** * 拷贝模版文件 + * + * 基于 lodash.template 方法来解析模版,并增加了对 + * 1. <%_ _%> 的支持,可用于移除前后的空格或 Tab 符号 + * 2. 增加了对 -%> 的支持,可用于移除控制语句引入的换行符 * @param opts - 拷贝选项 */ async copyTemplate(opts: GeneratorCopyOptions) { - const tpl = await fs.readFile(opts.path, 'utf-8') + let tpl = await fs.readFile(opts.path, 'utf-8') + + // 移除控制语句前 <%_ _%> 后的空格或 Tab 符号 + tpl = tpl.replace(/[ \t]*<%_/gm, '<%').replace(/_%>[ \t]*/gm, '%>') + + // 移除控制语句结尾引入的换行符 + tpl = tpl.replace(/-%>(?:\r\n|\r|\n)?/gm, '%>') + const content = template(tpl)(opts.context) await fs.mkdirp(dirname(opts.to)) logger.success(`写入: ${relative(this.baseDir, opts.to)}`) From f907bb2333b46a4a03e0b1d926f8bd4491aed198 Mon Sep 17 00:00:00 2001 From: lyfeyaj Date: Tue, 13 Jun 2023 15:45:18 +0800 Subject: [PATCH 2/5] =?UTF-8?q?feat(plugin-compiler-alipay):=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E6=94=AF=E4=BB=98=E5=AE=9D=E8=BD=AC=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=20sjs=20=E4=B8=AD=20export=20default=20function=20xxx(){}=20?= =?UTF-8?q?=E7=9A=84=E8=BD=AC=E6=8D=A2=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/SjsParserPlugin.ts | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/packages/plugin-compiler-alipay/src/plugins/SjsParserPlugin.ts b/packages/plugin-compiler-alipay/src/plugins/SjsParserPlugin.ts index ab585664..cf3c6fd5 100644 --- a/packages/plugin-compiler-alipay/src/plugins/SjsParserPlugin.ts +++ b/packages/plugin-compiler-alipay/src/plugins/SjsParserPlugin.ts @@ -67,6 +67,41 @@ export default class AlipayCompilerSjsParserPlugin implements Plugin { ) } + /** + * 处理 export default function name() {} 的情况 + * 原因: 微信不支持 exports.default = name 这种语法,会报错 + * 这里转换为 module.exports = function name() {} + */ + if (ts.isFunctionDeclaration(node) && node.modifiers?.length) { + const exportKeyword = node.modifiers[0] + const exportDefaultKeyword = node.modifiers[1] + if ( + ts.isToken(exportKeyword) && + exportKeyword.kind === ts.SyntaxKind.ExportKeyword && + ts.isToken(exportDefaultKeyword) && + exportDefaultKeyword.kind === ts.SyntaxKind.DefaultKeyword + ) { + return factory.createExpressionStatement( + factory.createBinaryExpression( + factory.createPropertyAccessExpression( + factory.createIdentifier('module'), + factory.createIdentifier('exports') + ), + factory.createToken(ts.SyntaxKind.EqualsToken), + factory.createFunctionExpression( + undefined, + node.asteriskToken, + node.name, + node.typeParameters, + node.parameters, + node.type, + node.body + ) + ) + ) + } + } + return node }) ) From eacdf5e60898e2ad30533c1407d81c2eca0202b0 Mon Sep 17 00:00:00 2001 From: lyfeyaj Date: Tue, 13 Jun 2023 15:46:10 +0800 Subject: [PATCH 3/5] =?UTF-8?q?feat(plugin-compiler-alipay):=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E6=94=AF=E4=BB=98=E5=AE=9D=E8=BD=AC=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E4=B8=8D=E5=85=BC=E5=AE=B9=E9=80=89=E6=8B=A9=E5=99=A8=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E4=BF=A1=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../plugin-compiler-alipay/src/plugins/StyleParserPlugin.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/plugin-compiler-alipay/src/plugins/StyleParserPlugin.ts b/packages/plugin-compiler-alipay/src/plugins/StyleParserPlugin.ts index bba32cd6..f74ed14f 100644 --- a/packages/plugin-compiler-alipay/src/plugins/StyleParserPlugin.ts +++ b/packages/plugin-compiler-alipay/src/plugins/StyleParserPlugin.ts @@ -7,7 +7,7 @@ import { } from '@morjs/utils' import { isSimilarTarget } from '../constants' -const UNSUPPORT_SELECTOR_REGEXP = /(\s+[>|+]\s+)|\*/ +const UNSUPPORT_SELECTOR_REGEXP = /(\s+[>|+]\s+)|\*|\~/ /** * 支付宝 样式 文件转译 @@ -34,7 +34,7 @@ export default class AlipayCompilerStyleParserPlugin implements Plugin { ).length ) { logger.warnOnce( - `当前编译目标 ${target} 中的样式 不支持 "> * +" 等选择器\n` + + `当前编译目标 ${target} 中的样式 不支持 "> * + ~" 等选择器\n` + `文件路径: ${options.fileInfo.path}` ) } From 4780b28140551e0ae5b1d3cfe4e4b139928bb59c Mon Sep 17 00:00:00 2001 From: lyfeyaj Date: Tue, 13 Jun 2023 15:47:14 +0800 Subject: [PATCH 4/5] =?UTF-8?q?feat(plugin-compiler-alipay):=20=E5=AE=8C?= =?UTF-8?q?=E5=96=84=E6=94=AF=E4=BB=98=E5=AE=9D=E8=BD=AC=E5=BE=AE=E4=BF=A1?= =?UTF-8?q?=E6=97=B6=E6=A8=A1=E7=89=88=E4=B8=AD=E5=AF=B9=E9=83=A8=E5=88=86?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E8=B0=83=E7=94=A8=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/plugins/TemplateParserPlugin.ts | 51 +++++++++- .../src/templateProcessorToOther.ts | 98 ++++++++++++++++++- 2 files changed, 142 insertions(+), 7 deletions(-) diff --git a/packages/plugin-compiler-alipay/src/plugins/TemplateParserPlugin.ts b/packages/plugin-compiler-alipay/src/plugins/TemplateParserPlugin.ts index 1a89a7d4..5b2015c3 100644 --- a/packages/plugin-compiler-alipay/src/plugins/TemplateParserPlugin.ts +++ b/packages/plugin-compiler-alipay/src/plugins/TemplateParserPlugin.ts @@ -48,12 +48,13 @@ export default class AlipayCompilerTemplateParserPlugin implements Plugin { const sjsFileName = `${MOR_HELPER_FILE()}${sjsFileType}` const sjsHelperName = 'morSjs' - const sjsHelperFnName = `${sjsHelperName}.s` + // 判断是否存在 morSjs.xxx( 方法调用 + const sjsHelperFnRegExp = new RegExp(`${sjsHelperName}\\.[a-zA-Z]+\\(`) runner.hooks.postprocessorParser.tap(this.name, (content, options) => { if ( options.fileInfo.entryFileType === EntryFileType.template && content && - content.includes(sjsHelperFnName) + sjsHelperFnRegExp.test(content) ) { // 追加 sjs 文件 this.addSjsHelperSupport(entryHelper, sjsFileName) @@ -98,6 +99,7 @@ function hump2dash(humpStr) { } return result.join(''); } + // 微信无法使用 Object.keys for of for in 遍历对象 // 序列化后自行实现 function objectKeys(obj) { @@ -149,6 +151,7 @@ function objectKeys(obj) { walk(step); return keys; } + // sjs 脚本支持度有限,手动实现 assign function assign(target, from) { objectKeys(from).forEach(function (key) { @@ -168,8 +171,50 @@ function s(obj) { return obj; } +// 判断类型 +function toType(obj) { + return typeof obj; +} + +// 小写转换 +function toLowerCase(str) { + return typeof str === 'string' ? str.toLowerCase() : ''; +} + +// 大写转换 +function toUpperCase(str) { + return typeof str === 'string' ? str.toUpperCase() : ''; +} + +// 字符串或数组的 slice 方法支持 +function slice(arrOrStr, start, end) { + return arrOrStr.slice(start, end); +} + +// 字符串或数组的 includes 方法支持 +function includes(arrOrStr, part) { + return arrOrStr.indexOf(part) !== -1; +} + +// 字符串或数组的 indexOf 方法支持 +function indexOf(arrOrStr, part) { + return arrOrStr.indexOf(part); +} + +// 字符串或数组的 includes 方法支持 +function toString(str) { + return str.toString(); +} + module.exports = { - s: s + s: s, + toType: toType, + toLowerCase: toLowerCase, + toUpperCase: toUpperCase, + slice: slice, + includes: includes, + indexOf: indexOf, + toString: toString }; `, 'additional' diff --git a/packages/plugin-compiler-alipay/src/templateProcessorToOther.ts b/packages/plugin-compiler-alipay/src/templateProcessorToOther.ts index 315f83f7..4671a383 100644 --- a/packages/plugin-compiler-alipay/src/templateProcessorToOther.ts +++ b/packages/plugin-compiler-alipay/src/templateProcessorToOther.ts @@ -2,6 +2,7 @@ import { FileParserOptions, logger, posthtml, + tsTransformerFactory, typescript as ts } from '@morjs/utils' import { @@ -24,9 +25,14 @@ export const templateProcessorToOther = { onNode(node: posthtml.Node, options: FileParserOptions): void { processComponentCompatible(node, options) - // 处理模版字符串 if (node.content && node.content.length) { - node.content = node.content.map((value) => processTemplateString(value)) + node.content = node.content.map(function (value) { + // 处理函数调用 + return processAttrFuncionCall( + // 处理模版字符串 + processTemplateString(value) + ) + }) } }, @@ -53,9 +59,12 @@ export const templateProcessorToOther = { // a:else 检查 processAElseCheck(attrName, node, options) - // 模版字符串处理 if (node.attrs[attrName]) { - node.attrs[attrName] = processTemplateString(node.attrs[attrName]) + // 方法调用转换支持 + node.attrs[attrName] = processAttrFuncionCall( + // 模版字符串处理 + processTemplateString(node.attrs[attrName]) + ) } // 事件处理 @@ -400,3 +409,84 @@ function processStyleAttrObject( ) } } + +// 支持的函数调用 +const SUPPORT_FUNCTION_CALL_NAMES = [ + 'toLowerCase', + 'toUpperCase', + 'slice', + 'includes', + 'toString', + 'indexOf' +] +// 判断是否包含符合条件的调用方式 +const FUNCTION_CALL_REGEXP = new RegExp( + `(\\.(${SUPPORT_FUNCTION_CALL_NAMES.join('|')})\\(|typeof )` +) +/** + * 处理属性中的方法调用,支持: + * - typeof a === 'string' => morSjs.toType(a) === 'string' + * - a.toLowerCase() => morSjs.toLowerCase(a) + * - a.toUpperCase() => morSjs.toUpperCase(a) + * - a.slice(0,1) => morSjs.slice(a, 0, 1) + * - a.includes(b) => morSjs.includes(a, b) + * - a.indexOf(b) => morSjs.indexOf(a, b) + * - a.toString() => morSjs.toString(a) + */ +function processAttrFuncionCall(value: string) { + if (!value) return value + if (typeof value !== 'string') return value + if (!/{{(.*?)}}/.test(value)) return value + if (!FUNCTION_CALL_REGEXP.test(value)) return value + + return value.replace(/{{(.*?)}}/g, function (matchStr, captureStr) { + if (!FUNCTION_CALL_REGEXP.test(matchStr)) return matchStr + + ts.transpileModule(captureStr, { + compilerOptions: { + module: ts.ModuleKind.None, + target: ts.ScriptTarget.Latest, + noImplicitUseStrict: true + }, + transformers: { + before: [ + tsTransformerFactory(function (node) { + // 处理 typeof + if (ts.isTypeOfExpression(node)) { + captureStr = captureStr.replace( + node.getText(), + `morSjs.toType(${node.expression.getFullText().trim()})` + ) + } + + // 处理函数调用 + if ( + ts.isCallExpression(node) && + ts.isPropertyAccessExpression(node.expression) + ) { + const functionName = node.expression + .getChildAt(node.expression.getChildCount() - 1) + ?.getText?.() + if (SUPPORT_FUNCTION_CALL_NAMES.includes(functionName)) { + const arg1 = node.expression + .getText() + .replace(new RegExp(`\\.${functionName}$`), '') + const allArgs = [arg1].concat( + node.arguments.map((arg) => arg.getText()) + ) + + captureStr = captureStr.replace( + node.getText(), + `morSjs.${functionName}(${allArgs.join(',')})` + ) + } + } + return node + }) + ] + } + }) + + return `{{${captureStr}}}` + }) +} From 34d31915ac9cfd6c17fea6ab3f1315e0b232fa6c Mon Sep 17 00:00:00 2001 From: lyfeyaj Date: Tue, 13 Jun 2023 15:47:41 +0800 Subject: [PATCH 5/5] =?UTF-8?q?docs(docs):=20=E5=AE=8C=E5=96=84=E6=94=AF?= =?UTF-8?q?=E4=BB=98=E5=AE=9D=E8=BD=AC=E5=BE=AE=E4=BF=A1=E5=85=BC=E5=AE=B9?= =?UTF-8?q?=E6=80=A7=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../compatibilities/alipay-to-wechat.md | 144 +++++------------- 1 file changed, 42 insertions(+), 102 deletions(-) diff --git a/website/docs/guides/compatibilities/alipay-to-wechat.md b/website/docs/guides/compatibilities/alipay-to-wechat.md index 37204484..eb853185 100644 --- a/website/docs/guides/compatibilities/alipay-to-wechat.md +++ b/website/docs/guides/compatibilities/alipay-to-wechat.md @@ -4,13 +4,13 @@ ### props 必须完整 -- 问题表现:在支付宝小程序中,你可以在`props`中没有定义某个属性,但是在实际使用中直接引用`this.props.xx`,但是由于在微信小程序中需要对`props`进行分析并动态赋值,因此必须要有完整的`props`列表 -- 解决方案:将所有使用到的`props`属性都声明在`props`中 +- **问题表现:** 在支付宝小程序中,你可以在`props`中没有定义某个属性,但是在实际使用中直接引用`this.props.xx`,但是由于在微信小程序中需要对`props`进行分析并动态赋值,因此必须要有完整的`props`列表 +- **解决方案:** 将所有使用到的`props`属性都声明在`props`中 ### props 中的函数名字必须为 on 开头的 onEvent 格式 -- 问题表现:在支付宝中,自定义组件对外的函数入参都必须要求以 on 开头 -- 解决方案: +- **问题表现:** 在支付宝中,自定义组件对外的函数入参都必须要求以 on 开头 +- **解决方案:** ```javascript aComponent({ @@ -22,8 +22,8 @@ aComponent({ ### 样式覆盖优先级 -- 问题表现:微信中自定义组件的样式无法直接被覆盖 -- 解决方案:传入自定义组件的样式优先级比组件内的高即可 +- **问题表现:** 微信中自定义组件的样式无法直接被覆盖 +- **解决方案:** 传入自定义组件的样式优先级比组件内的高即可 ```html @@ -40,8 +40,8 @@ aComponent({ ### 获取 props 中的函数返回值 -- 问题表现:在支付宝小程序中,可以直接通过`const result = this.props.onClick()`来获取到传入的函数的返回值。由于在微信等端外小程序中事件处理机制差异过大,因此需要通过异步方式来处理。 -- 解决方案:**在所有获取函数返回值的地方都通过 await 来获取即可**。而传入的函数不需要做任何改动,按照正常的方式 return 即可 +- **问题表现:** 在支付宝小程序中,可以直接通过 `const result = this.props.onClick()` 来获取到传入的函数的返回值。由于在微信等端外小程序中事件处理机制差异过大,因此需要通过异步方式来处理。 +- **解决方案:** **在所有获取函数返回值的地方都通过 await 来获取即可**。而传入的函数不需要做任何改动,按照正常的方式 return 即可 - 参考代码: 传入方 @@ -61,8 +61,8 @@ aPage({ aComponent({ methods: { async onClick() { - const result = await this.props.onClick('1111111', '22222') // 需要await来拿返回值 - console.log(result) // 打印输出 'page-data' + const result = await this.props.onClick('1111111', '22222') // 需要await来拿返回值 + console.log(result) // 打印输出 'page-data' }, }, }, @@ -70,8 +70,8 @@ aComponent({ ### 获取各种事件中目标元素 data 属性时优先从 currentTarget 获取 -- 问题表现:微信中元素产生 tap 或 touch 事件时,target 中元素 data 属性为空,只有 currentTarget 属性有值 -- 解决方案:优先从 currentTarget 获取 +- **问题表现:** 微信中元素产生 tap 或 touch 事件时,target 中元素 data 属性为空,只有 currentTarget 属性有值 +- **解决方案:** 优先从 currentTarget 获取 ```javascript aPage({ @@ -84,63 +84,41 @@ aPage({ }) ``` -### 不能使用 default slot 默认插槽 +### 不能使用 `default slot` 默认插槽 -- 问题表现:在支付宝中可以设置组件的 slot 的默认内容,在组件调用方不传的 slot 的内容的时候默认展示出来。但是由于微信尚未支持该功能。可参考微信的回答:[https://developers.weixin.qq.com/community/develop/doc/0008a04f2b0f289fa907b450b56000](https://developers.weixin.qq.com/community/develop/doc/0008a04f2b0f289fa907b450b56000) -- 解决方案:目前没有办法抹平这种底层级别的差异,因此需要组件都自己传 slot 的内容来确保双端兼容性 +- **问题表现:** 在支付宝中可以设置组件的 `slot` 的默认内容,在组件调用方不传的 `slot` 的内容的时候默认展示出来。但是由于微信尚未支持该功能。可参考微信的回答:[https://developers.weixin.qq.com/community/develop/doc/0008a04f2b0f289fa907b450b56000](https://developers.weixin.qq.com/community/develop/doc/0008a04f2b0f289fa907b450b56000) +- **解决方案:** 目前没有办法抹平这种底层级别的差异,因此需要组件都自己传 `slot` 的内容来确保双端兼容性 -### 微信端没有 $spliceData +### 微信端没有 `$spliceData` -- 问题表现:在微信小程序没有 spliceData -- 解决方案:只使用 setData 或者判断环境再使用 - -### 使用 querySelector 需要甄别实例环境 - -- 问题表现:默认情况下通过`aBridge`来调用`querySelector`这个 api,由于`aBridge`无法动态去识别当前运行的实例环境,在微信小程序的自定义组件或包含自定义组件的页面中会异常。 -- 解决方案:微信端在自定义组件或包含自定义组件的页面中,应使用  `this.createSelectorQuery()`  来代替。可参考微信的官方文档:[https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createSelectorQuery.html](https://developers.weixin.qq.com/miniprogram/dev/api/wxml/wx.createSelectorQuery.html) +- **问题表现:** 在微信小程序没有 `spliceData` +- **解决方案:** 只使用 `setData` 或者判断环境再使用 --- ## AXML -### AXML 中不能使用 Array 的 slice/includes/indexOf 方法 - -- 问题表现:在微信小程序中,在 WXML 里面调用 Array 的 slice 方法是不会生效的,例如:'`wx:for="arr.slice(1)"`'这样的写法是不会有效的 -- 解决方案:在 JS 中处理成 data 变量或者使用 sjs 方法做一层封装。 - -### AXML 中不能使用 toLowerCase 或 toUpperCase 方法 - -- 问题表现:在微信小程序中,在 WXML 内调用`toLowerCase`或者是`toUpperCase`方法都是不会有效的,例如:`"{{'test'.toUpperCase()}}"`或者`"{{'TEST'.toLowerCase()}}"`这样的写法是不会生效的 -- 解决方案:在 JS 中处理成 data 变量或者使用 sjs 方法做一层封装。 - -### AXML 中不能使用 typeof 运算符 - -- 问题表现:在微信小程序中,并没有在 WXML 中支持 typeof 运算符,直接使用 typeof 会直接报错 -- 解决方案:在 JS 中处理成 data 变量或者使用 sjs 方法做一层封装。 - ### AXML 中动态定义高度要加 PX 单位 -- 问题表现:在微信小程序中,不加单位,高度不生效 -- 解决方案:加单位 +- **问题表现:** 在微信小程序中,不加单位,高度不生效 +- **解决方案:** 加单位 ![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2020/png/27413/1595323486788-7c509cb9-7d96-4ce2-872d-75cb285f3d45.png#height=1096&id=eF6j5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1096&originWidth=2008&originalType=binary&ratio=1&size=1657788&status=done&style=none&width=2008) ### AXML 中的 style 属性不能传递对象 -- 问题表现:在支付宝小程序中传入 style 对象,解析为微信小程序代码则会出现错误 +- **问题表现:** 在支付宝小程序中传入 style 对象,解析为微信小程序代码则会出现错误 - 问题解决:在支付宝小程序中使用字符串拼接(可引入变量) - 参考代码: -​ - 有问题的写法 👇🏻 ```html - + + ``` 改为 👇🏻 即可 @@ -150,14 +128,12 @@ aPage({ ``` -### AXML 中不支持 ```` 模版字符串 +### AXML 中不支持 `\`\`` 模版字符串 -- 问题表现:微信小程序中的 {{ }} 中无法使用模版字符串 +- **问题表现:** 微信小程序中的 {{ }} 中无法使用模版字符串 - 问题解决:将模版字符串替换为字符串拼接 `+` - 参考代码: -​ - ```html ``` @@ -170,51 +146,17 @@ aPage({ ### AXML 不能使用 `{{{}}}` 方式传递对象,除 template 的 data 属性之外,也不能使用解构语法 -- 问题表现:微信小程序中的 `{{{ }}}` 会报语法错误,也不能使用 `{{...data}}` +- **问题表现:** 微信小程序中的 `{{{ }}}` 会报语法错误,也不能使用 `{{...data}}` - 问题解决:在 js 文件中声明完整对象,然后再 axml 中直接传递,如 `{{data}}` --- ## SJS -### SJS 解决方案示例 - -`util.sjs` - -```javascript -const isType = (data, type) => typeof data === type -const toLowerCase = (str) => (isType(str, 'string') ? str.toLowerCase() : '') -const toUpperCase = (str) => (isType(str, 'string') ? str.toUpperCase() : '') -const slice = (arr, start) => arr.slice(start) - -export default { - isType, - toLowerCase, - toUpperCase, - slice -} -``` - -```diff -+ - -- typeof展示:typeof 'string' {{typeof 'string' === 'string'}} -+ typeof展示:typeof 'string' {{util.isType('string', 'string')}} - -- string的toLowerCase展示:STRING => {{'STRING'.toLowerCase()}} -+ string的toLowerCase展示:STRING => {{util.toLowerCase('STRING')}} - -- string的toUpperCase展示:string => {{'string'.toUpperCase()}} -+ string的toUpperCase展示:string => {{util.toUpperCase('string')}} - -- array的slice展示:[1,2,3] => {{[1,2,3].slice(1)}} -+ array的slice展示:[1,2,3] => {{util.slice([1,2,3], 1)}} -``` - ### 不能使用 namedExport -- 问题表现:在微信小程序中,只支持`module.exports`而在支付宝中是除了`export default {}` 以外还支持了 `export const x = 1;` 然后在 xml 中通过``来引用。而这套机制在微信中无法抹平,而`export default`已经能够满足所有业务诉求。 -- 解决方案:所有`sjs`中只采用`export default {}` +- **问题表现:** 在微信小程序中,只支持`module.exports`而在支付宝中是除了`export default {}` 以外还支持了 `export const x = 1;` 然后在 xml 中通过``来引用。而这套机制在微信中无法抹平,而`export default`已经能够满足所有业务诉求。 +- **解决方案:** 所有`sjs`中只采用`export default {}` --- @@ -222,26 +164,24 @@ export default { ### slider -- `track-size`属性在微信小程序下不能支持 - -​ - -​ +- `track-size` 属性在微信小程序下不能支持 ### scroll-view 中 flex 布局失效 -- 问题表现:在微信小程序中,sroll-view 使用 flex 布局会失效。 -- 解决方案: - - 方法一:在 scroll-view 内层再嵌套一层 view,对这个 view 使用 flex 布局;参考[https://segmentfault.com/q/1010000007532480](https://segmentfault.com/q/1010000007532480) - - 方法二:使用 enable-flex 属性 -- 问题示例 👇🏻 - -​ +- **问题表现:** 在微信小程序中,`sroll-view` 使用 `flex` 布局会失效。 +- **解决方案:** + - 方法一:在 `scroll-view` 内层再嵌套一层 `view`,对这个 `view` 使用 `flex` 布局;参考[https://segmentfault.com/q/1010000007532480](https://segmentfault.com/q/1010000007532480) + - 方法二:使用 `enable-flex` 属性 +- **问题示例 👇🏻** 例如: + 原始效果(横向布局) + ![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2020/png/269922/1601632677440-9660077f-a4aa-46de-a533-2cfe56aab189.png#height=42&id=QErf3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=86&originWidth=796&originalType=binary&ratio=1&size=14215&status=done&style=none&width=386) + 迁移之后代码(纵向布局) + ![image.png](https://intranetproxy.alipay.com/skylark/lark/0/2020/png/269922/1601632746857-85c9c822-00c4-4d49-8812-471373aca2f1.png#height=269&id=s5fTv&margin=%5Bobject%20Object%5D&name=image.png&originHeight=662&originWidth=244&originalType=binary&ratio=1&size=22908&status=done&style=none&width=99) --- @@ -250,12 +190,12 @@ export default { ### 使用自定义顶部导航栏时 -- 问题表现:在.json 文件中设置 `**"transparantTitle":"always"**` 时: +- **问题表现:** 在.json 文件中设置 **`"transparantTitle":"always"`** 时: - 微信端左上角的返回按钮和 home 按钮会无法显示,需要自定义 - - 支付宝仍可以获取到 **statusBarHeight **和 **titleBarHeight **的值,但微信获取到的 **titleBarHeight **值为零 -- 解决方案: + - 支付宝仍可以获取到 **statusBarHeight** 和 **titleBarHeight** 的值,但微信获取到的 **titleBarHeight** 值为零 +- **解决方案:** - 没有返回按钮的问题只能是前端手动添加 - - 微信侧可以通过 api:**wx.getMenuButtonBoundingClientRect() **获取到胶囊位置,手动计算出 title 部分高度,参考代码逻辑如下 👇🏻 + - 微信侧可以通过 api:**wx.getMenuButtonBoundingClientRect()** 获取到胶囊位置,手动计算出 title 部分高度,参考代码逻辑如下 👇🏻 ```javascript function getHeaderBar() {