diff --git a/packages/uni-cli-shared/src/mp/template.ts b/packages/uni-cli-shared/src/mp/template.ts index 2249c6c0ec7..58a53b432a7 100644 --- a/packages/uni-cli-shared/src/mp/template.ts +++ b/packages/uni-cli-shared/src/mp/template.ts @@ -100,6 +100,10 @@ export interface MiniProgramCompilerOptions { } directive: string emitFile?: (emittedFile: EmittedAsset) => string + /** + * 允许作为 v-for 子节点并保留 key 的组件列表 + */ + keyEnabledElements?: string[] } export interface MiniProgramFilterOptions { id: string diff --git a/packages/uni-mp-compiler/src/compile.ts b/packages/uni-mp-compiler/src/compile.ts index 3fc9d29997c..61be6d894d2 100644 --- a/packages/uni-mp-compiler/src/compile.ts +++ b/packages/uni-mp-compiler/src/compile.ts @@ -120,6 +120,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) { lazyElement, component, checkPropName, + keyEnabledElements, } = options.miniProgram genTemplate(ast, { class: clazz, @@ -135,6 +136,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) { isBuiltInComponent: context.isBuiltInComponent, isMiniProgramComponent: context.isMiniProgramComponent, checkPropName, + keyEnabledElements, autoImportFilters: context.autoImportFilters, filter: options.miniProgram?.filter, }) diff --git a/packages/uni-mp-compiler/src/template/codegen.ts b/packages/uni-mp-compiler/src/template/codegen.ts index a12400946a5..f62fd19e255 100644 --- a/packages/uni-mp-compiler/src/template/codegen.ts +++ b/packages/uni-mp-compiler/src/template/codegen.ts @@ -54,6 +54,7 @@ export interface TemplateCodegenContext { isMiniProgramComponent: TransformContext['isMiniProgramComponent'] push(code: string): void checkPropName: TemplateCodegenOptions['checkPropName'] + keyEnabledElements: TemplateCodegenOptions['keyEnabledElements'] } /** @@ -88,6 +89,7 @@ export function generate( isBuiltInComponent, isMiniProgramComponent, checkPropName, + keyEnabledElements, component, autoImportFilters, filter, @@ -105,6 +107,7 @@ export function generate( isBuiltInComponent, isMiniProgramComponent, checkPropName, + keyEnabledElements, push(code) { context.code += code }, diff --git a/packages/uni-mp-compiler/src/transforms/vFor.ts b/packages/uni-mp-compiler/src/transforms/vFor.ts index 700aff910e3..aaa3a256944 100644 --- a/packages/uni-mp-compiler/src/transforms/vFor.ts +++ b/packages/uni-mp-compiler/src/transforms/vFor.ts @@ -185,16 +185,20 @@ export const transformFor = createStructuralDirectiveTransform( scopes.vFor-- if (isTemplateNode(node)) { node.children.some((c) => { - if (c.type === NodeTypes.ELEMENT && !isForElementNode(c)) { + if (isElementNode(c) && !isForElementNode(c)) { const key = findProp(c, 'key') if (key) { - context.onError( - createCompilerError( - ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT, - key.loc + const keyEnabledElements = + context.miniProgram.keyEnabledElements || [] + if (!keyEnabledElements.includes(c.tag)) { + context.onError( + createCompilerError( + ErrorCodes.X_V_FOR_TEMPLATE_KEY_PLACEMENT, + key.loc + ) ) - ) - return true + return true + } } } }) diff --git a/packages/uni-mp-vite/src/plugin/index.ts b/packages/uni-mp-vite/src/plugin/index.ts index 63d6ea6a37b..a09a9832f5f 100644 --- a/packages/uni-mp-vite/src/plugin/index.ts +++ b/packages/uni-mp-vite/src/plugin/index.ts @@ -96,6 +96,7 @@ export interface UniMiniProgramPluginOptions { generate: Parameters[0] } compilerOptions?: CompilerOptions + keyEnabledElements?: MiniProgramCompilerOptions['keyEnabledElements'] checkPropName?: MiniProgramCompilerOptions['checkPropName'] } style: { @@ -141,6 +142,7 @@ export function uniMiniProgramPlugin( component: template.component, emitFile, slot: template.slot, + keyEnabledElements: template.keyEnabledElements, checkPropName: template.checkPropName, }, compilerOptions: template.compilerOptions, diff --git a/packages/uni-mp-weixin/__tests__/component.spec.ts b/packages/uni-mp-weixin/__tests__/component.spec.ts index deb5f5f4775..915cca1b8d8 100644 --- a/packages/uni-mp-weixin/__tests__/component.spec.ts +++ b/packages/uni-mp-weixin/__tests__/component.spec.ts @@ -309,6 +309,24 @@ describe('mp-weixin: transform component', () => { ) }) + test('editor-protal', () => { + assert( + ``, + ``, + `(_ctx, _cache) => { + return { a: _ctx.blockId } +}` + ) + + assert( + ``, + ``, + `(_ctx, _cache) => { + return { a: _f(_ctx.customBlockList, (item, k0, i0) => { return { a: item.blockId, b: item.blockId }; }) } +}` + ) + }) + // 暂不上线,先注释掉 // test('input > keyboard-accessory', () => { // assert( diff --git a/packages/uni-mp-weixin/src/compiler/options.ts b/packages/uni-mp-weixin/src/compiler/options.ts index 78c63fc6e18..c3ea4294304 100644 --- a/packages/uni-mp-weixin/src/compiler/options.ts +++ b/packages/uni-mp-weixin/src/compiler/options.ts @@ -62,6 +62,7 @@ export const customElements = [ 'open-data-list', 'open-data-item', 'selection', + 'editor-portal', ...getNativeTags(process.env.UNI_INPUT_DIR, process.env.UNI_PLATFORM), ] @@ -134,6 +135,7 @@ export function getMiniProgramOptions( lang: 'wxs', setStyle: true, }, + keyEnabledElements: ['editor-portal'], } }