提交 0ae56fc0 编写于 作者: fxy060608's avatar fxy060608

fix(mp): component with v-show

上级 3672ac6f
export const COMPONENT_ON_LINK = 'onVI' export const COMPONENT_ON_LINK = 'onVI'
export const COMPONENT_BIND_LINK = '__l' export const COMPONENT_BIND_LINK = '__l'
export const COMPONENT_CUSTOM_HIDDEN = 'data-c-h'
export const COMPONENT_CUSTOM_HIDDEN_BIND = 'bind:-' + COMPONENT_CUSTOM_HIDDEN
...@@ -39,6 +39,12 @@ export interface MiniProgramCompilerOptions { ...@@ -39,6 +39,12 @@ export interface MiniProgramCompilerOptions {
filter?: { filter?: {
lang: string lang: string
} }
component?: {
/**
* 自定义组件自定义 hidden 属性用于实现 v-show
*/
vShow: string
}
directive: string directive: string
emitFile?: (emittedFile: EmittedAsset) => string emitFile?: (emittedFile: EmittedAsset) => string
} }
......
...@@ -23,7 +23,9 @@ export const VUE_REF_IN_FOR = 'r-i-f' ...@@ -23,7 +23,9 @@ export const VUE_REF_IN_FOR = 'r-i-f'
export function isUserComponent( export function isUserComponent(
node: RootNode | TemplateChildNode, node: RootNode | TemplateChildNode,
context: TransformContext context: {
isBuiltInComponent: TransformContext['isBuiltInComponent']
}
): node is ComponentNode { ): node is ComponentNode {
return ( return (
node.type === NodeTypes.ELEMENT && node.type === NodeTypes.ELEMENT &&
......
...@@ -16784,10 +16784,9 @@ const chooseFile = /* @__PURE__ */ defineAsyncApi(API_CHOOSE_FILE, ({ ...@@ -16784,10 +16784,9 @@ const chooseFile = /* @__PURE__ */ defineAsyncApi(API_CHOOSE_FILE, ({
}; };
resolve(res); resolve(res);
}); });
if (getInteractStatus()) {
fileInput.click(); fileInput.click();
} else { if (!getInteractStatus()) {
reject(t2("uni.chooseFile.notUserActivation")); console.warn(t2("uni.chooseFile.notUserActivation"));
} }
}, ChooseFileProtocol, ChooseFileOptions); }, ChooseFileProtocol, ChooseFileOptions);
let imageInput = null; let imageInput = null;
...@@ -16835,10 +16834,9 @@ const chooseImage = /* @__PURE__ */ defineAsyncApi(API_CHOOSE_IMAGE, ({ ...@@ -16835,10 +16834,9 @@ const chooseImage = /* @__PURE__ */ defineAsyncApi(API_CHOOSE_IMAGE, ({
}; };
resolve(res); resolve(res);
}); });
if (getInteractStatus()) {
imageInput.click(); imageInput.click();
} else { if (!getInteractStatus()) {
reject(t2("uni.chooseFile.notUserActivation")); console.warn(t2("uni.chooseFile.notUserActivation"));
} }
}, ChooseImageProtocol, ChooseImageOptions); }, ChooseImageProtocol, ChooseImageOptions);
let index$c = 0; let index$c = 0;
...@@ -17135,10 +17133,9 @@ const chooseVideo = /* @__PURE__ */ defineAsyncApi(API_CHOOSE_VIDEO, ({ sourceTy ...@@ -17135,10 +17133,9 @@ const chooseVideo = /* @__PURE__ */ defineAsyncApi(API_CHOOSE_VIDEO, ({ sourceTy
resolve(callbackResult); resolve(callbackResult);
} }
}); });
if (getInteractStatus()) {
videoInput.click(); videoInput.click();
} else { if (!getInteractStatus()) {
reject(t2("uni.chooseFile.notUserActivation")); console.warn(t2("uni.chooseFile.notUserActivation"));
} }
}, ChooseVideoProtocol, ChooseVideoOptions); }, ChooseVideoProtocol, ChooseVideoOptions);
const request = /* @__PURE__ */ defineTaskApi(API_REQUEST, ({ const request = /* @__PURE__ */ defineTaskApi(API_REQUEST, ({
......
...@@ -100,6 +100,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) { ...@@ -100,6 +100,7 @@ export function baseCompile(template: string, options: CompilerOptions = {}) {
event, event,
slot, slot,
lazyElement, lazyElement,
component,
} = options.miniProgram } = options.miniProgram
genTemplate(ast, { genTemplate(ast, {
class: clazz, class: clazz,
...@@ -110,6 +111,8 @@ export function baseCompile(template: string, options: CompilerOptions = {}) { ...@@ -110,6 +111,8 @@ export function baseCompile(template: string, options: CompilerOptions = {}) {
event, event,
slot, slot,
lazyElement, lazyElement,
component,
isBuiltInComponent: context.isBuiltInComponent,
}) })
} }
......
...@@ -100,6 +100,7 @@ export interface TemplateCodegenOptions ...@@ -100,6 +100,7 @@ export interface TemplateCodegenOptions
extends Omit<MiniProgramCompilerOptions, 'filter'> { extends Omit<MiniProgramCompilerOptions, 'filter'> {
scopeId?: string | null scopeId?: string | null
filename: string filename: string
isBuiltInComponent: Required<TransformOptions>['isBuiltInComponent']
} }
export type CompilerOptions = ParserOptions & TransformOptions & CodegenOptions export type CompilerOptions = ParserOptions & TransformOptions & CodegenOptions
...@@ -3,6 +3,7 @@ import { SLOT_DEFAULT_NAME, dynamicSlotName } from '@dcloudio/uni-shared' ...@@ -3,6 +3,7 @@ import { SLOT_DEFAULT_NAME, dynamicSlotName } from '@dcloudio/uni-shared'
import { import {
formatMiniProgramEvent, formatMiniProgramEvent,
isElementNode, isElementNode,
isUserComponent,
MiniProgramCompilerOptions, MiniProgramCompilerOptions,
} from '@dcloudio/uni-cli-shared' } from '@dcloudio/uni-cli-shared'
import { import {
...@@ -25,6 +26,7 @@ import { genExpr } from '../codegen' ...@@ -25,6 +26,7 @@ import { genExpr } from '../codegen'
import { ForElementNode, isForElementNode } from '../transforms/vFor' import { ForElementNode, isForElementNode } from '../transforms/vFor'
import { IfElementNode, isIfElementNode } from '../transforms/vIf' import { IfElementNode, isIfElementNode } from '../transforms/vIf'
import { findSlotName } from '../transforms/vSlot' import { findSlotName } from '../transforms/vSlot'
import { TransformContext } from '../transform'
interface TemplateCodegenContext { interface TemplateCodegenContext {
code: string code: string
directive: string directive: string
...@@ -32,6 +34,8 @@ interface TemplateCodegenContext { ...@@ -32,6 +34,8 @@ interface TemplateCodegenContext {
event: MiniProgramCompilerOptions['event'] event: MiniProgramCompilerOptions['event']
slot: MiniProgramCompilerOptions['slot'] slot: MiniProgramCompilerOptions['slot']
lazyElement: MiniProgramCompilerOptions['lazyElement'] lazyElement: MiniProgramCompilerOptions['lazyElement']
component: MiniProgramCompilerOptions['component']
isBuiltInComponent: TransformContext['isBuiltInComponent']
push(code: string): void push(code: string): void
} }
...@@ -45,6 +49,8 @@ export function generate( ...@@ -45,6 +49,8 @@ export function generate(
filename, filename,
directive, directive,
lazyElement, lazyElement,
isBuiltInComponent,
component,
}: TemplateCodegenOptions }: TemplateCodegenOptions
) { ) {
const context: TemplateCodegenContext = { const context: TemplateCodegenContext = {
...@@ -54,6 +60,8 @@ export function generate( ...@@ -54,6 +60,8 @@ export function generate(
scopeId, scopeId,
directive, directive,
lazyElement, lazyElement,
component,
isBuiltInComponent,
push(code) { push(code) {
context.code += code context.code += code
}, },
...@@ -266,7 +274,7 @@ function genElement(node: ElementNode, context: TemplateCodegenContext) { ...@@ -266,7 +274,7 @@ function genElement(node: ElementNode, context: TemplateCodegenContext) {
genNode(node, context) genNode(node, context)
}) })
} }
if (node.tagType === ElementTypes.COMPONENT) { if (isUserComponent(node, context)) {
tag = hyphenate(tag) tag = hyphenate(tag)
} }
const { push } = context const { push } = context
...@@ -333,7 +341,7 @@ export function genElementProps( ...@@ -333,7 +341,7 @@ export function genElementProps(
if (name === 'on') { if (name === 'on') {
genOn(prop, node, context) genOn(prop, node, context)
} else { } else {
genDirectiveNode(prop, context) genDirectiveNode(prop, node, context)
} }
} }
}) })
...@@ -341,7 +349,7 @@ export function genElementProps( ...@@ -341,7 +349,7 @@ export function genElementProps(
function genOn( function genOn(
prop: DirectiveNode, prop: DirectiveNode,
node: ElementNode, node: ElementNode,
{ push, event }: TemplateCodegenContext { push, event, isBuiltInComponent }: TemplateCodegenContext
) { ) {
const arg = (prop.arg as SimpleExpressionNode).content const arg = (prop.arg as SimpleExpressionNode).content
const exp = prop.exp as SimpleExpressionNode const exp = prop.exp as SimpleExpressionNode
...@@ -349,7 +357,7 @@ function genOn( ...@@ -349,7 +357,7 @@ function genOn(
const name = (event?.format || formatMiniProgramEvent)(arg, { const name = (event?.format || formatMiniProgramEvent)(arg, {
isCatch: modifiers.includes('stop') || modifiers.includes('prevent'), isCatch: modifiers.includes('stop') || modifiers.includes('prevent'),
isCapture: modifiers.includes('capture'), isCapture: modifiers.includes('capture'),
isComponent: node.tagType === ElementTypes.COMPONENT, isComponent: isUserComponent(node, { isBuiltInComponent }),
}) })
if (exp.isStatic) { if (exp.isStatic) {
push(` ${name}="${exp.content}"`) push(` ${name}="${exp.content}"`)
...@@ -360,8 +368,10 @@ function genOn( ...@@ -360,8 +368,10 @@ function genOn(
function genDirectiveNode( function genDirectiveNode(
prop: DirectiveNode, prop: DirectiveNode,
{ push }: TemplateCodegenContext node: ElementNode,
context: TemplateCodegenContext
) { ) {
const { push, component } = context
if (prop.name === 'slot') { if (prop.name === 'slot') {
if (prop.arg) { if (prop.arg) {
const arg = prop.arg as SimpleExpressionNode const arg = prop.arg as SimpleExpressionNode
...@@ -375,7 +385,13 @@ function genDirectiveNode( ...@@ -375,7 +385,13 @@ function genDirectiveNode(
) )
} }
} else if (prop.name === 'show') { } else if (prop.name === 'show') {
push(` hidden="{{!${(prop.exp as SimpleExpressionNode).content}}}"`) let hiddenPropName = 'hidden'
if (isUserComponent(node, context) && component && component.vShow) {
hiddenPropName = component.vShow
}
push(
` ${hiddenPropName}="{{!${(prop.exp as SimpleExpressionNode).content}}}"`
)
} else if (prop.arg && prop.exp) { } else if (prop.arg && prop.exp) {
const arg = (prop.arg as SimpleExpressionNode).content const arg = (prop.arg as SimpleExpressionNode).content
const exp = (prop.exp as SimpleExpressionNode).content const exp = (prop.exp as SimpleExpressionNode).content
......
...@@ -81,6 +81,9 @@ const miniProgram = { ...@@ -81,6 +81,9 @@ const miniProgram = {
dynamicSlotNames: true, dynamicSlotNames: true,
}, },
directive: 'tt:', directive: 'tt:',
component: {
vShow: uniCliShared.COMPONENT_CUSTOM_HIDDEN_BIND,
},
}; };
const options = { const options = {
vite: { vite: {
......
import { assert } from './testUtils' import { assert } from './testUtils'
describe('mp-baidu: transform component', () => { describe('mp-baidu: transform component', () => {
test(`component with v-show`, () => {
assert(
`<custom v-show="ok"/>`,
`<custom data-c-h="{{!a}}" u-i="2a9ec0b0-0" bind:__l="__l"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok }
}`
)
})
test(`match-media`, () => { test(`match-media`, () => {
assert( assert(
`<match-media/>`, `<match-media/>`,
......
...@@ -99,6 +99,9 @@ const miniProgram = { ...@@ -99,6 +99,9 @@ const miniProgram = {
dynamicSlotNames: true, dynamicSlotNames: true,
}, },
directive: 'qq:', directive: 'qq:',
component: {
vShow: uniCliShared.COMPONENT_CUSTOM_HIDDEN,
},
}; };
const options = { const options = {
vite: { vite: {
......
import path from 'path' import path from 'path'
import type { CompilerOptions } from '@vue/compiler-core' import type { CompilerOptions } from '@vue/compiler-core'
import { import {
COMPONENT_CUSTOM_HIDDEN,
MiniProgramCompilerOptions, MiniProgramCompilerOptions,
transformComponentLink, transformComponentLink,
transformMatchMedia, transformMatchMedia,
...@@ -29,6 +30,9 @@ export const miniProgram: MiniProgramCompilerOptions = { ...@@ -29,6 +30,9 @@ export const miniProgram: MiniProgramCompilerOptions = {
dynamicSlotNames: true, dynamicSlotNames: true,
}, },
directive: 'qq:', directive: 'qq:',
component: {
vShow: COMPONENT_CUSTOM_HIDDEN,
},
} }
export const options: UniMiniProgramPluginOptions = { export const options: UniMiniProgramPluginOptions = {
......
import { assert } from './testUtils' import { assert } from './testUtils'
describe('mp-baidu: transform component', () => { describe('mp-baidu: transform component', () => {
test(`component with v-show`, () => {
assert(
`<custom v-show="ok"/>`,
`<custom bind:-data-c-h="{{!a}}" u-i="2a9ec0b0-0" bind:__l="__l"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok }
}`
)
})
test(`match-media`, () => { test(`match-media`, () => {
assert( assert(
`<match-media/>`, `<match-media/>`,
......
...@@ -81,6 +81,9 @@ const miniProgram = { ...@@ -81,6 +81,9 @@ const miniProgram = {
dynamicSlotNames: true, dynamicSlotNames: true,
}, },
directive: 'tt:', directive: 'tt:',
component: {
vShow: uniCliShared.COMPONENT_CUSTOM_HIDDEN_BIND,
},
}; };
const options = { const options = {
vite: { vite: {
......
import path from 'path' import path from 'path'
import type { CompilerOptions } from '@vue/compiler-core' import type { CompilerOptions } from '@vue/compiler-core'
import { import {
COMPONENT_CUSTOM_HIDDEN_BIND,
MiniProgramCompilerOptions, MiniProgramCompilerOptions,
transformComponentLink, transformComponentLink,
transformMatchMedia, transformMatchMedia,
...@@ -32,6 +33,9 @@ export const miniProgram: MiniProgramCompilerOptions = { ...@@ -32,6 +33,9 @@ export const miniProgram: MiniProgramCompilerOptions = {
dynamicSlotNames: true, dynamicSlotNames: true,
}, },
directive: 'tt:', directive: 'tt:',
component: {
vShow: COMPONENT_CUSTOM_HIDDEN_BIND,
},
} }
export const options: UniMiniProgramPluginOptions = { export const options: UniMiniProgramPluginOptions = {
......
...@@ -24,9 +24,12 @@ import { ...@@ -24,9 +24,12 @@ import {
const debugNVueCss = debug('vite:uni:nvue-css') const debugNVueCss = debug('vite:uni:nvue-css')
const cssVars = `page{--status-bar-height:25px;--top-window-height:0px;--window-top:0px;--window-bottom:0px;--window-left:0px;--window-right:0px;--window-magin:0px}` const cssVars = `page{--status-bar-height:25px;--top-window-height:0px;--window-top:0px;--window-bottom:0px;--window-left:0px;--window-right:0px;--window-magin:0px}`
const shadowCss = `page::after{position:fixed;content:'';left:-1000px;top:-1000px;-webkit-animation:shadow-preload .1s;-webkit-animation-delay:3s;animation:shadow-preload .1s;animation-delay:3s}@-webkit-keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}@keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}` const shadowCss = `page::after{position:fixed;content:'';left:-1000px;top:-1000px;-webkit-animation:shadow-preload .1s;-webkit-animation-delay:3s;animation:shadow-preload .1s;animation-delay:3s}@-webkit-keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}@keyframes shadow-preload{0%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}100%{background-image:url(https://cdn.dcloud.net.cn/img/shadow-grey.png)}}`
const genComponentCustomHiddenCss = (name: string) =>
`[${name.replace(':', '')}="true"]{display: none !important;}`
export function createConfigResolved({ export function createConfigResolved({
style: { extname }, style: { extname },
template: { component },
}: UniMiniProgramPluginOptions): Plugin['configResolved'] { }: UniMiniProgramPluginOptions): Plugin['configResolved'] {
function normalizeCssChunkFilename(id: string, extname: string) { function normalizeCssChunkFilename(id: string, extname: string) {
return ( return (
...@@ -54,10 +57,15 @@ export function createConfigResolved({ ...@@ -54,10 +57,15 @@ export function createConfigResolved({
chunkCssCode(filename, cssCode) { chunkCssCode(filename, cssCode) {
cssCode = transformScopedCss(cssCode) cssCode = transformScopedCss(cssCode)
if (filename === 'app' + extname) { if (filename === 'app' + extname) {
const componentCustomHiddenCss =
(component &&
component.vShow &&
genComponentCustomHiddenCss(component.vShow)) ||
''
if (config.isProduction) { if (config.isProduction) {
return cssCode + shadowCss + cssVars return cssCode + shadowCss + cssVars + componentCustomHiddenCss
} else { } else {
return cssCode + cssVars return cssCode + cssVars + componentCustomHiddenCss
} }
} }
......
...@@ -57,6 +57,7 @@ export interface UniMiniProgramPluginOptions { ...@@ -57,6 +57,7 @@ export interface UniMiniProgramPluginOptions {
class: MiniProgramCompilerOptions['class'] class: MiniProgramCompilerOptions['class']
slot: MiniProgramCompilerOptions['slot'] slot: MiniProgramCompilerOptions['slot']
lazyElement?: MiniProgramCompilerOptions['lazyElement'] lazyElement?: MiniProgramCompilerOptions['lazyElement']
component?: MiniProgramCompilerOptions['component']
customElements?: string[] customElements?: string[]
filter?: { filter?: {
lang: string lang: string
...@@ -96,6 +97,7 @@ export function uniMiniProgramPlugin( ...@@ -96,6 +97,7 @@ export function uniMiniProgramPlugin(
filter: template.filter ? { lang: template.filter.lang } : undefined, filter: template.filter ? { lang: template.filter.lang } : undefined,
directive: template.directive, directive: template.directive,
lazyElement: template.lazyElement, lazyElement: template.lazyElement,
component: template.component,
emitFile, emitFile,
slot: template.slot, slot: template.slot,
}, },
......
import { assert } from './testUtils' import { assert } from './testUtils'
import { customElements } from '../src/compiler/options' import { customElements } from '../src/compiler/options'
describe('mp-weixin: transform component', () => { describe('mp-weixin: transform component', () => {
test(`component with v-show`, () => {
assert(
`<custom v-show="ok"/>`,
`<custom data-c-h="{{!a}}" u-i="2a9ec0b0-0" bind:__l="__l"/>`,
`(_ctx, _cache) => {
return { a: _ctx.ok }
}`
)
})
test(`built-in component`, () => { test(`built-in component`, () => {
const code = customElements.map((tag) => `<${tag}/>`).join('') const code = customElements.map((tag) => `<${tag}/>`).join('')
assert( assert(
......
...@@ -75,6 +75,9 @@ const miniProgram = { ...@@ -75,6 +75,9 @@ const miniProgram = {
canvas: [{ name: 'bind', arg: ['canvas-id', 'id'] }], canvas: [{ name: 'bind', arg: ['canvas-id', 'id'] }],
editor: [{ name: 'on', arg: ['ready'] }], editor: [{ name: 'on', arg: ['ready'] }],
}, },
component: {
vShow: uniCliShared.COMPONENT_CUSTOM_HIDDEN,
},
}; };
const projectConfigFilename = 'project.config.json'; const projectConfigFilename = 'project.config.json';
const options = { const options = {
......
import path from 'path' import path from 'path'
import type { CompilerOptions } from '@vue/compiler-core' import type { CompilerOptions } from '@vue/compiler-core'
import { import {
COMPONENT_CUSTOM_HIDDEN,
MiniProgramCompilerOptions, MiniProgramCompilerOptions,
transformComponentLink, transformComponentLink,
transformRef, transformRef,
...@@ -28,6 +29,9 @@ export const miniProgram: MiniProgramCompilerOptions = { ...@@ -28,6 +29,9 @@ export const miniProgram: MiniProgramCompilerOptions = {
canvas: [{ name: 'bind', arg: ['canvas-id', 'id'] }], canvas: [{ name: 'bind', arg: ['canvas-id', 'id'] }],
editor: [{ name: 'on', arg: ['ready'] }], editor: [{ name: 'on', arg: ['ready'] }],
}, },
component: {
vShow: COMPONENT_CUSTOM_HIDDEN,
},
} }
const projectConfigFilename = 'project.config.json' const projectConfigFilename = 'project.config.json'
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册