wip(compiler-ssr): v-bind with static keys
This commit is contained in:
@@ -17,9 +17,11 @@ export function createSSRCompilerError(
|
||||
}
|
||||
|
||||
export const enum SSRErrorCodes {
|
||||
X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM = DOMErrorCodes.__EXTEND_POINT__
|
||||
X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM = DOMErrorCodes.__EXTEND_POINT__,
|
||||
X_SSR_UNSAFE_ATTR_NAME
|
||||
}
|
||||
|
||||
export const SSRErrorMessages: { [code: number]: string } = {
|
||||
[SSRErrorCodes.X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM]: `Custom directive is missing corresponding SSR transform and will be ignored.`
|
||||
[SSRErrorCodes.X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM]: `Custom directive is missing corresponding SSR transform and will be ignored.`,
|
||||
[SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME]: `Unsafe attribute name for SSR.`
|
||||
}
|
||||
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
transformExpression,
|
||||
trackVForSlotScopes,
|
||||
trackSlotScopes,
|
||||
noopDirectiveTransform
|
||||
noopDirectiveTransform,
|
||||
transformBind
|
||||
} from '@vue/compiler-dom'
|
||||
import { ssrCodegenTransform } from './ssrCodegenTransform'
|
||||
import { ssrTransformElement } from './transforms/ssrTransformElement'
|
||||
@@ -16,9 +17,8 @@ import { ssrTransformComponent } from './transforms/ssrTransformComponent'
|
||||
import { ssrTransformSlotOutlet } from './transforms/ssrTransformSlotOutlet'
|
||||
import { ssrTransformIf } from './transforms/ssrVIf'
|
||||
import { ssrTransformFor } from './transforms/ssrVFor'
|
||||
import { ssrVBind } from './transforms/ssrVBind'
|
||||
import { ssrVModel } from './transforms/ssrVModel'
|
||||
import { ssrVShow } from './transforms/ssrVShow'
|
||||
import { ssrTransformModel } from './transforms/ssrVModel'
|
||||
import { ssrTransformShow } from './transforms/ssrVShow'
|
||||
|
||||
export function compile(
|
||||
template: string,
|
||||
@@ -54,9 +54,9 @@ export function compile(
|
||||
ssrDirectiveTransforms: {
|
||||
on: noopDirectiveTransform,
|
||||
cloak: noopDirectiveTransform,
|
||||
bind: ssrVBind,
|
||||
model: ssrVModel,
|
||||
show: ssrVShow,
|
||||
bind: transformBind, // reusing core v-bind
|
||||
model: ssrTransformModel,
|
||||
show: ssrTransformShow,
|
||||
...(options.ssrDirectiveTransforms || {}) // user transforms
|
||||
}
|
||||
})
|
||||
|
||||
@@ -7,6 +7,7 @@ export const SSR_RENDER_CLASS = Symbol(`renderClass`)
|
||||
export const SSR_RENDER_STYLE = Symbol(`renderStyle`)
|
||||
export const SSR_RENDER_ATTRS = Symbol(`renderAttrs`)
|
||||
export const SSR_RENDER_ATTR = Symbol(`renderAttr`)
|
||||
export const SSR_RENDER_DYNAMIC_ATTR = Symbol(`renderDynamicAttr`)
|
||||
export const SSR_RENDER_LIST = Symbol(`renderList`)
|
||||
|
||||
// Note: these are helpers imported from @vue/server-renderer
|
||||
@@ -19,5 +20,6 @@ registerRuntimeHelpers({
|
||||
[SSR_RENDER_STYLE]: `_renderStyle`,
|
||||
[SSR_RENDER_ATTRS]: `_renderAttrs`,
|
||||
[SSR_RENDER_ATTR]: `_renderAttr`,
|
||||
[SSR_RENDER_DYNAMIC_ATTR]: `_renderDynamicAttr`,
|
||||
[SSR_RENDER_LIST]: `_renderList`
|
||||
})
|
||||
|
||||
@@ -5,11 +5,18 @@ import {
|
||||
TemplateLiteral,
|
||||
createTemplateLiteral,
|
||||
createInterpolation,
|
||||
createCallExpression
|
||||
createCallExpression,
|
||||
createConditionalExpression,
|
||||
createSimpleExpression
|
||||
} from '@vue/compiler-dom'
|
||||
import { escapeHtml } from '@vue/shared'
|
||||
import { escapeHtml, isBooleanAttr, isSSRSafeAttrName } from '@vue/shared'
|
||||
import { createSSRCompilerError, SSRErrorCodes } from '../errors'
|
||||
import { SSR_RENDER_ATTR } from '../runtimeHelpers'
|
||||
import {
|
||||
SSR_RENDER_ATTR,
|
||||
SSR_RENDER_CLASS,
|
||||
SSR_RENDER_STYLE,
|
||||
SSR_RENDER_DYNAMIC_ATTR
|
||||
} from '../runtimeHelpers'
|
||||
|
||||
export const ssrTransformElement: NodeTransform = (node, context) => {
|
||||
if (
|
||||
@@ -66,12 +73,58 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
|
||||
const { props } = directiveTransform(prop, node, context)
|
||||
for (let j = 0; j < props.length; j++) {
|
||||
const { key, value } = props[j]
|
||||
openTag.push(
|
||||
createCallExpression(context.helper(SSR_RENDER_ATTR), [
|
||||
key,
|
||||
value
|
||||
])
|
||||
)
|
||||
if (key.type === NodeTypes.SIMPLE_EXPRESSION && key.isStatic) {
|
||||
const attrName = key.content
|
||||
// static key attr
|
||||
if (attrName === 'class') {
|
||||
openTag.push(
|
||||
createCallExpression(context.helper(SSR_RENDER_CLASS), [
|
||||
value
|
||||
])
|
||||
)
|
||||
} else if (attrName === 'style') {
|
||||
openTag.push(
|
||||
createCallExpression(context.helper(SSR_RENDER_STYLE), [
|
||||
value
|
||||
])
|
||||
)
|
||||
} else if (isBooleanAttr(attrName)) {
|
||||
openTag.push(
|
||||
createConditionalExpression(
|
||||
value,
|
||||
createSimpleExpression(' ' + attrName, true),
|
||||
createSimpleExpression('', true),
|
||||
false /* no newline */
|
||||
)
|
||||
)
|
||||
} else {
|
||||
if (isSSRSafeAttrName(attrName)) {
|
||||
openTag.push(
|
||||
createCallExpression(context.helper(SSR_RENDER_ATTR), [
|
||||
key,
|
||||
value
|
||||
])
|
||||
)
|
||||
} else {
|
||||
context.onError(
|
||||
createSSRCompilerError(
|
||||
SSRErrorCodes.X_SSR_UNSAFE_ATTR_NAME,
|
||||
key.loc
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// dynamic key attr
|
||||
// this branch is only encountered for custom directive
|
||||
// transforms that returns properties with dynamic keys
|
||||
openTag.push(
|
||||
createCallExpression(
|
||||
context.helper(SSR_RENDER_DYNAMIC_ATTR),
|
||||
[key, value]
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// no corresponding ssr directive transform found.
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { DirectiveTransform, createObjectProperty } from '@vue/compiler-dom'
|
||||
|
||||
export const ssrVBind: DirectiveTransform = (dir, node, context) => {
|
||||
if (!dir.exp) {
|
||||
// error
|
||||
return { props: [] }
|
||||
} else {
|
||||
// TODO modifiers
|
||||
return {
|
||||
props: [
|
||||
createObjectProperty(
|
||||
dir.arg!, // v-bind="obj" is handled separately
|
||||
dir.exp
|
||||
)
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DirectiveTransform } from '@vue/compiler-dom'
|
||||
|
||||
export const ssrVModel: DirectiveTransform = (dir, node, context) => {
|
||||
export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
|
||||
return {
|
||||
props: []
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { DirectiveTransform } from '@vue/compiler-dom'
|
||||
|
||||
export const ssrVShow: DirectiveTransform = (dir, node, context) => {
|
||||
export const ssrTransformShow: DirectiveTransform = (dir, node, context) => {
|
||||
return {
|
||||
props: []
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user