diff --git a/packages/compiler-core/src/options.ts b/packages/compiler-core/src/options.ts index 8cb753a6..f108edcf 100644 --- a/packages/compiler-core/src/options.ts +++ b/packages/compiler-core/src/options.ts @@ -29,7 +29,6 @@ export interface ParserOptions { export interface TransformOptions { nodeTransforms?: NodeTransform[] directiveTransforms?: Record - ssrDirectiveTransforms?: Record isBuiltInComponent?: (tag: string) => symbol | void // Transform expressions like {{ foo }} to `_ctx.foo`. // If this option is false, the generated code will be wrapped in a diff --git a/packages/compiler-core/src/transform.ts b/packages/compiler-core/src/transform.ts index 940e7fe4..4959fb7f 100644 --- a/packages/compiler-core/src/transform.ts +++ b/packages/compiler-core/src/transform.ts @@ -114,7 +114,6 @@ function createTransformContext( cacheHandlers = false, nodeTransforms = [], directiveTransforms = {}, - ssrDirectiveTransforms = {}, isBuiltInComponent = NOOP, ssr = false, onError = defaultOnError @@ -127,7 +126,6 @@ function createTransformContext( cacheHandlers, nodeTransforms, directiveTransforms, - ssrDirectiveTransforms, isBuiltInComponent, ssr, onError, diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index a9203d8f..23ece5ed 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -233,7 +233,8 @@ export type PropsExpression = ObjectExpression | CallExpression | ExpressionNode export function buildProps( node: ElementNode, context: TransformContext, - props: ElementNode['props'] = node.props + props: ElementNode['props'] = node.props, + ssr = false ): { props: PropsExpression | undefined directives: DirectiveNode[] @@ -320,9 +321,15 @@ export function buildProps( continue } - // special case for v-bind and v-on with no argument const isBind = name === 'bind' const isOn = name === 'on' + + // skip v-on in SSR compilation + if (ssr && isOn) { + continue + } + + // special case for v-bind and v-on with no argument if (!arg && (isBind || isOn)) { hasDynamicKeys = true if (exp) { @@ -360,7 +367,7 @@ export function buildProps( if (directiveTransform) { // has built-in directive transform. const { props, needRuntime } = directiveTransform(prop, node, context) - props.forEach(analyzePatchFlag) + !ssr && props.forEach(analyzePatchFlag) properties.push(...props) if (needRuntime) { runtimeDirectives.push(prop) @@ -446,12 +453,7 @@ function dedupeProperties(properties: Property[]): Property[] { const name = prop.key.content const existing = knownProps.get(name) if (existing) { - if ( - name === 'style' || - name === 'class' || - name.startsWith('on') || - name.startsWith('vnode') - ) { + if (name === 'style' || name === 'class' || name.startsWith('on')) { mergeAsArray(existing, prop) } // unexpected duplicate, should have emitted error during parse diff --git a/packages/compiler-dom/src/index.ts b/packages/compiler-dom/src/index.ts index 6013ba93..01673e84 100644 --- a/packages/compiler-dom/src/index.ts +++ b/packages/compiler-dom/src/index.ts @@ -56,5 +56,6 @@ export function parse(template: string, options: ParserOptions = {}): RootNode { }) } +export { transformStyle } from './transforms/transformStyle' export { DOMErrorCodes } from './errors' export * from '@vue/compiler-core' diff --git a/packages/compiler-dom/src/transforms/transformStyle.ts b/packages/compiler-dom/src/transforms/transformStyle.ts index cb58f53a..3c232db4 100644 --- a/packages/compiler-dom/src/transforms/transformStyle.ts +++ b/packages/compiler-dom/src/transforms/transformStyle.ts @@ -1,7 +1,9 @@ import { NodeTransform, NodeTypes, - createSimpleExpression + createSimpleExpression, + SimpleExpressionNode, + SourceLocation } from '@vue/compiler-core' // Parse inline CSS strings for static style attributes into an object. @@ -15,8 +17,7 @@ export const transformStyle: NodeTransform = (node, context) => { node.props.forEach((p, i) => { if (p.type === NodeTypes.ATTRIBUTE && p.name === 'style' && p.value) { // replace p with an expression node - const parsed = JSON.stringify(parseInlineCSS(p.value.content)) - const exp = context.hoist(createSimpleExpression(parsed, false, p.loc)) + const exp = context.hoist(parseInlineCSS(p.value.content, p.loc)) node.props[i] = { type: NodeTypes.DIRECTIVE, name: `bind`, @@ -33,7 +34,10 @@ export const transformStyle: NodeTransform = (node, context) => { const listDelimiterRE = /;(?![^(]*\))/g const propertyDelimiterRE = /:(.+)/ -function parseInlineCSS(cssText: string): Record { +function parseInlineCSS( + cssText: string, + loc: SourceLocation +): SimpleExpressionNode { const res: Record = {} cssText.split(listDelimiterRE).forEach(item => { if (item) { @@ -41,5 +45,5 @@ function parseInlineCSS(cssText: string): Record { tmp.length > 1 && (res[tmp[0].trim()] = tmp[1].trim()) } }) - return res + return createSimpleExpression(JSON.stringify(res), false, loc) } diff --git a/packages/compiler-ssr/__tests__/ssrElement.spec.ts b/packages/compiler-ssr/__tests__/ssrElement.spec.ts index 994fbeb8..7d807e46 100644 --- a/packages/compiler-ssr/__tests__/ssrElement.spec.ts +++ b/packages/compiler-ssr/__tests__/ssrElement.spec.ts @@ -46,6 +46,10 @@ describe('ssr: element', () => { getCompiledString(`\`"`) }) + + test('