wip(compiler-ssr): v-bind with static keys
This commit is contained in:
parent
e71781dcab
commit
c059fc88b9
@ -301,9 +301,10 @@ export interface SequenceExpression extends Node {
|
|||||||
|
|
||||||
export interface ConditionalExpression extends Node {
|
export interface ConditionalExpression extends Node {
|
||||||
type: NodeTypes.JS_CONDITIONAL_EXPRESSION
|
type: NodeTypes.JS_CONDITIONAL_EXPRESSION
|
||||||
test: ExpressionNode
|
test: JSChildNode
|
||||||
consequent: JSChildNode
|
consequent: JSChildNode
|
||||||
alternate: JSChildNode
|
alternate: JSChildNode
|
||||||
|
newline: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CacheExpression extends Node {
|
export interface CacheExpression extends Node {
|
||||||
@ -648,13 +649,15 @@ export function createSequenceExpression(
|
|||||||
export function createConditionalExpression(
|
export function createConditionalExpression(
|
||||||
test: ConditionalExpression['test'],
|
test: ConditionalExpression['test'],
|
||||||
consequent: ConditionalExpression['consequent'],
|
consequent: ConditionalExpression['consequent'],
|
||||||
alternate: ConditionalExpression['alternate']
|
alternate: ConditionalExpression['alternate'],
|
||||||
|
newline = true
|
||||||
): ConditionalExpression {
|
): ConditionalExpression {
|
||||||
return {
|
return {
|
||||||
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
|
type: NodeTypes.JS_CONDITIONAL_EXPRESSION,
|
||||||
test,
|
test,
|
||||||
consequent,
|
consequent,
|
||||||
alternate,
|
alternate,
|
||||||
|
newline,
|
||||||
loc: locStub
|
loc: locStub
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -685,7 +685,7 @@ function genConditionalExpression(
|
|||||||
node: ConditionalExpression,
|
node: ConditionalExpression,
|
||||||
context: CodegenContext
|
context: CodegenContext
|
||||||
) {
|
) {
|
||||||
const { test, consequent, alternate } = node
|
const { test, consequent, alternate, newline: needNewline } = node
|
||||||
const { push, indent, deindent, newline } = context
|
const { push, indent, deindent, newline } = context
|
||||||
if (test.type === NodeTypes.SIMPLE_EXPRESSION) {
|
if (test.type === NodeTypes.SIMPLE_EXPRESSION) {
|
||||||
const needsParens = !isSimpleIdentifier(test.content)
|
const needsParens = !isSimpleIdentifier(test.content)
|
||||||
@ -694,15 +694,15 @@ function genConditionalExpression(
|
|||||||
needsParens && push(`)`)
|
needsParens && push(`)`)
|
||||||
} else {
|
} else {
|
||||||
push(`(`)
|
push(`(`)
|
||||||
genCompoundExpression(test, context)
|
genNode(test, context)
|
||||||
push(`)`)
|
push(`)`)
|
||||||
}
|
}
|
||||||
indent()
|
needNewline && indent()
|
||||||
context.indentLevel++
|
context.indentLevel++
|
||||||
push(`? `)
|
push(`? `)
|
||||||
genNode(consequent, context)
|
genNode(consequent, context)
|
||||||
context.indentLevel--
|
context.indentLevel--
|
||||||
newline()
|
needNewline && newline()
|
||||||
push(`: `)
|
push(`: `)
|
||||||
const isNested = alternate.type === NodeTypes.JS_CONDITIONAL_EXPRESSION
|
const isNested = alternate.type === NodeTypes.JS_CONDITIONAL_EXPRESSION
|
||||||
if (!isNested) {
|
if (!isNested) {
|
||||||
@ -712,7 +712,7 @@ function genConditionalExpression(
|
|||||||
if (!isNested) {
|
if (!isNested) {
|
||||||
context.indentLevel--
|
context.indentLevel--
|
||||||
}
|
}
|
||||||
deindent(true /* without newline */)
|
needNewline && deindent(true /* without newline */)
|
||||||
}
|
}
|
||||||
|
|
||||||
function genSequenceExpression(
|
function genSequenceExpression(
|
||||||
@ -748,15 +748,17 @@ function genCacheExpression(node: CacheExpression, context: CodegenContext) {
|
|||||||
function genTemplateLiteral(node: TemplateLiteral, context: CodegenContext) {
|
function genTemplateLiteral(node: TemplateLiteral, context: CodegenContext) {
|
||||||
const { push, indent, deindent } = context
|
const { push, indent, deindent } = context
|
||||||
push('`')
|
push('`')
|
||||||
for (let i = 0; i < node.elements.length; i++) {
|
const l = node.elements.length
|
||||||
|
const multilines = l > 3
|
||||||
|
for (let i = 0; i < l; i++) {
|
||||||
const e = node.elements[i]
|
const e = node.elements[i]
|
||||||
if (isString(e)) {
|
if (isString(e)) {
|
||||||
push(e.replace(/`/g, '\\`'))
|
push(e.replace(/`/g, '\\`'))
|
||||||
} else {
|
} else {
|
||||||
push('${')
|
push('${')
|
||||||
indent()
|
if (multilines) indent()
|
||||||
genNode(e, context)
|
genNode(e, context)
|
||||||
deindent()
|
if (multilines) deindent()
|
||||||
push('}')
|
push('}')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,6 +31,7 @@ export { noopDirectiveTransform } from './transforms/noopDirectiveTransform'
|
|||||||
// expose transforms so higher-order compilers can import and extend them
|
// expose transforms so higher-order compilers can import and extend them
|
||||||
export { transformModel } from './transforms/vModel'
|
export { transformModel } from './transforms/vModel'
|
||||||
export { transformOn } from './transforms/vOn'
|
export { transformOn } from './transforms/vOn'
|
||||||
|
export { transformBind } from './transforms/vBind'
|
||||||
|
|
||||||
// exported for compiler-ssr
|
// exported for compiler-ssr
|
||||||
export { processIfBranches } from './transforms/vIf'
|
export { processIfBranches } from './transforms/vIf'
|
||||||
|
@ -10,12 +10,6 @@ describe('ssr: element', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('static attrs', () => {
|
|
||||||
expect(
|
|
||||||
getCompiledString(`<div id="foo" class="bar"></div>`)
|
|
||||||
).toMatchInlineSnapshot(`"\`<div id=\\"foo\\" class=\\"bar\\"></div>\`"`)
|
|
||||||
})
|
|
||||||
|
|
||||||
test('nested elements', () => {
|
test('nested elements', () => {
|
||||||
expect(
|
expect(
|
||||||
getCompiledString(`<div><span></span><span></span></div>`)
|
getCompiledString(`<div><span></span><span></span></div>`)
|
||||||
@ -26,27 +20,71 @@ describe('ssr: element', () => {
|
|||||||
expect(getCompiledString(`<input>`)).toMatchInlineSnapshot(`"\`<input>\`"`)
|
expect(getCompiledString(`<input>`)).toMatchInlineSnapshot(`"\`<input>\`"`)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('v-html', () => {
|
describe('children override', () => {
|
||||||
expect(getCompiledString(`<div v-html="foo"/>`)).toMatchInlineSnapshot(
|
test('v-html', () => {
|
||||||
`"\`<div>\${_ctx.foo}</div>\`"`
|
expect(getCompiledString(`<div v-html="foo"/>`)).toMatchInlineSnapshot(
|
||||||
)
|
`"\`<div>\${_ctx.foo}</div>\`"`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('v-text', () => {
|
||||||
|
expect(getCompiledString(`<div v-text="foo"/>`)).toMatchInlineSnapshot(
|
||||||
|
`"\`<div>\${_interpolate(_ctx.foo)}</div>\`"`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('<textarea> with dynamic value', () => {
|
||||||
|
expect(
|
||||||
|
getCompiledString(`<textarea :value="foo"/>`)
|
||||||
|
).toMatchInlineSnapshot(
|
||||||
|
`"\`<textarea>\${_interpolate(_ctx.foo)}</textarea>\`"`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('<textarea> with static value', () => {
|
||||||
|
expect(
|
||||||
|
getCompiledString(`<textarea value="fo>o"/>`)
|
||||||
|
).toMatchInlineSnapshot(`"\`<textarea>fo>o</textarea>\`"`)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
test('v-text', () => {
|
describe('attrs', () => {
|
||||||
expect(getCompiledString(`<div v-text="foo"/>`)).toMatchInlineSnapshot(
|
test('static attrs', () => {
|
||||||
`"\`<div>\${_interpolate(_ctx.foo)}</div>\`"`
|
expect(
|
||||||
)
|
getCompiledString(`<div id="foo" class="bar"></div>`)
|
||||||
})
|
).toMatchInlineSnapshot(`"\`<div id=\\"foo\\" class=\\"bar\\"></div>\`"`)
|
||||||
|
})
|
||||||
|
|
||||||
test('<textarea> with dynamic value', () => {
|
test('v-bind:class', () => {
|
||||||
expect(getCompiledString(`<textarea :value="foo"/>`)).toMatchInlineSnapshot(
|
expect(
|
||||||
`"\`<textarea>\${_interpolate(_ctx.foo)}</textarea>\`"`
|
getCompiledString(`<div id="foo" :class="bar"></div>`)
|
||||||
)
|
).toMatchInlineSnapshot(
|
||||||
})
|
`"\`<div id=\\"foo\\"\${_renderClass(_ctx.bar)}></div>\`"`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
test('<textarea> with static value', () => {
|
test('v-bind:style', () => {
|
||||||
expect(
|
expect(
|
||||||
getCompiledString(`<textarea value="fo>o"/>`)
|
getCompiledString(`<div id="foo" :style="bar"></div>`)
|
||||||
).toMatchInlineSnapshot(`"\`<textarea>fo>o</textarea>\`"`)
|
).toMatchInlineSnapshot(
|
||||||
|
`"\`<div id=\\"foo\\"\${_renderStyle(_ctx.bar)}></div>\`"`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('v-bind:key (boolean)', () => {
|
||||||
|
expect(
|
||||||
|
getCompiledString(`<input type="checkbox" :checked="checked">`)
|
||||||
|
).toMatchInlineSnapshot(
|
||||||
|
`"\`<input type=\\"checkbox\\"\${(_ctx.checked)? \\" checked\\": \\"\\"}>\`"`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('v-bind:key (non-boolean)', () => {
|
||||||
|
expect(
|
||||||
|
getCompiledString(`<div :id="id" class="bar"></div>`)
|
||||||
|
).toMatchInlineSnapshot(
|
||||||
|
`"\`<div\${_renderAttr(\\"id\\", _ctx.id)} class=\\"bar\\"></div>\`"`
|
||||||
|
)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -38,7 +38,11 @@ describe('ssr: text', () => {
|
|||||||
"const { _interpolate } = require(\\"@vue/server-renderer\\")
|
"const { _interpolate } = require(\\"@vue/server-renderer\\")
|
||||||
|
|
||||||
return function ssrRender(_ctx, _push, _parent) {
|
return function ssrRender(_ctx, _push, _parent) {
|
||||||
_push(\`<div><span>\${_interpolate(_ctx.foo)} bar</span><span>baz \${_interpolate(_ctx.qux)}</span></div>\`)
|
_push(\`<div><span>\${
|
||||||
|
_interpolate(_ctx.foo)
|
||||||
|
} bar</span><span>baz \${
|
||||||
|
_interpolate(_ctx.qux)
|
||||||
|
}</span></div>\`)
|
||||||
}"
|
}"
|
||||||
`)
|
`)
|
||||||
})
|
})
|
||||||
|
@ -1,13 +0,0 @@
|
|||||||
import { compile } from '../src'
|
|
||||||
|
|
||||||
describe('ssr: v-bind', () => {
|
|
||||||
test('basic', () => {
|
|
||||||
expect(compile(`<div :id="id"/>`).code).toMatchInlineSnapshot(`
|
|
||||||
"const { _renderAttr } = require(\\"vue\\")
|
|
||||||
|
|
||||||
return function ssrRender(_ctx, _push, _parent) {
|
|
||||||
_push(\`<div\${_renderAttr(\\"id\\", _ctx.id)}></div>\`)
|
|
||||||
}"
|
|
||||||
`)
|
|
||||||
})
|
|
||||||
})
|
|
@ -45,7 +45,11 @@ describe('ssr: v-for', () => {
|
|||||||
_renderList(_ctx.list, (row, i) => {
|
_renderList(_ctx.list, (row, i) => {
|
||||||
_push(\`<div><!---->\`)
|
_push(\`<div><!---->\`)
|
||||||
_renderList(row, (j) => {
|
_renderList(row, (j) => {
|
||||||
_push(\`<div>\${_interpolate(i)},\${_interpolate(j)}</div>\`)
|
_push(\`<div>\${
|
||||||
|
_interpolate(i)
|
||||||
|
},\${
|
||||||
|
_interpolate(j)
|
||||||
|
}</div>\`)
|
||||||
})
|
})
|
||||||
_push(\`<!----></div>\`)
|
_push(\`<!----></div>\`)
|
||||||
})
|
})
|
||||||
@ -97,7 +101,11 @@ describe('ssr: v-for', () => {
|
|||||||
return function ssrRender(_ctx, _push, _parent) {
|
return function ssrRender(_ctx, _push, _parent) {
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
_renderList(_ctx.list, (i) => {
|
_renderList(_ctx.list, (i) => {
|
||||||
_push(\`<!----><span>\${_interpolate(i)}</span><span>\${_interpolate(i + 1)}</span><!---->\`)
|
_push(\`<!----><span>\${
|
||||||
|
_interpolate(i)
|
||||||
|
}</span><span>\${
|
||||||
|
_interpolate(i + 1)
|
||||||
|
}</span><!---->\`)
|
||||||
})
|
})
|
||||||
_push(\`<!---->\`)
|
_push(\`<!---->\`)
|
||||||
}"
|
}"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { compile } from '../src'
|
import { compile } from '../src'
|
||||||
|
|
||||||
export function getCompiledString(src: string): string {
|
export function getCompiledString(src: string): string {
|
||||||
return compile(src).code.match(/_push\((.*)\)/)![1]
|
return compile(src).code.match(/_push\(([^]*)\)/)![1]
|
||||||
}
|
}
|
||||||
|
@ -17,9 +17,11 @@ export function createSSRCompilerError(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const enum SSRErrorCodes {
|
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 } = {
|
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,
|
transformExpression,
|
||||||
trackVForSlotScopes,
|
trackVForSlotScopes,
|
||||||
trackSlotScopes,
|
trackSlotScopes,
|
||||||
noopDirectiveTransform
|
noopDirectiveTransform,
|
||||||
|
transformBind
|
||||||
} from '@vue/compiler-dom'
|
} from '@vue/compiler-dom'
|
||||||
import { ssrCodegenTransform } from './ssrCodegenTransform'
|
import { ssrCodegenTransform } from './ssrCodegenTransform'
|
||||||
import { ssrTransformElement } from './transforms/ssrTransformElement'
|
import { ssrTransformElement } from './transforms/ssrTransformElement'
|
||||||
@ -16,9 +17,8 @@ import { ssrTransformComponent } from './transforms/ssrTransformComponent'
|
|||||||
import { ssrTransformSlotOutlet } from './transforms/ssrTransformSlotOutlet'
|
import { ssrTransformSlotOutlet } from './transforms/ssrTransformSlotOutlet'
|
||||||
import { ssrTransformIf } from './transforms/ssrVIf'
|
import { ssrTransformIf } from './transforms/ssrVIf'
|
||||||
import { ssrTransformFor } from './transforms/ssrVFor'
|
import { ssrTransformFor } from './transforms/ssrVFor'
|
||||||
import { ssrVBind } from './transforms/ssrVBind'
|
import { ssrTransformModel } from './transforms/ssrVModel'
|
||||||
import { ssrVModel } from './transforms/ssrVModel'
|
import { ssrTransformShow } from './transforms/ssrVShow'
|
||||||
import { ssrVShow } from './transforms/ssrVShow'
|
|
||||||
|
|
||||||
export function compile(
|
export function compile(
|
||||||
template: string,
|
template: string,
|
||||||
@ -54,9 +54,9 @@ export function compile(
|
|||||||
ssrDirectiveTransforms: {
|
ssrDirectiveTransforms: {
|
||||||
on: noopDirectiveTransform,
|
on: noopDirectiveTransform,
|
||||||
cloak: noopDirectiveTransform,
|
cloak: noopDirectiveTransform,
|
||||||
bind: ssrVBind,
|
bind: transformBind, // reusing core v-bind
|
||||||
model: ssrVModel,
|
model: ssrTransformModel,
|
||||||
show: ssrVShow,
|
show: ssrTransformShow,
|
||||||
...(options.ssrDirectiveTransforms || {}) // user transforms
|
...(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_STYLE = Symbol(`renderStyle`)
|
||||||
export const SSR_RENDER_ATTRS = Symbol(`renderAttrs`)
|
export const SSR_RENDER_ATTRS = Symbol(`renderAttrs`)
|
||||||
export const SSR_RENDER_ATTR = Symbol(`renderAttr`)
|
export const SSR_RENDER_ATTR = Symbol(`renderAttr`)
|
||||||
|
export const SSR_RENDER_DYNAMIC_ATTR = Symbol(`renderDynamicAttr`)
|
||||||
export const SSR_RENDER_LIST = Symbol(`renderList`)
|
export const SSR_RENDER_LIST = Symbol(`renderList`)
|
||||||
|
|
||||||
// Note: these are helpers imported from @vue/server-renderer
|
// Note: these are helpers imported from @vue/server-renderer
|
||||||
@ -19,5 +20,6 @@ registerRuntimeHelpers({
|
|||||||
[SSR_RENDER_STYLE]: `_renderStyle`,
|
[SSR_RENDER_STYLE]: `_renderStyle`,
|
||||||
[SSR_RENDER_ATTRS]: `_renderAttrs`,
|
[SSR_RENDER_ATTRS]: `_renderAttrs`,
|
||||||
[SSR_RENDER_ATTR]: `_renderAttr`,
|
[SSR_RENDER_ATTR]: `_renderAttr`,
|
||||||
|
[SSR_RENDER_DYNAMIC_ATTR]: `_renderDynamicAttr`,
|
||||||
[SSR_RENDER_LIST]: `_renderList`
|
[SSR_RENDER_LIST]: `_renderList`
|
||||||
})
|
})
|
||||||
|
@ -5,11 +5,18 @@ import {
|
|||||||
TemplateLiteral,
|
TemplateLiteral,
|
||||||
createTemplateLiteral,
|
createTemplateLiteral,
|
||||||
createInterpolation,
|
createInterpolation,
|
||||||
createCallExpression
|
createCallExpression,
|
||||||
|
createConditionalExpression,
|
||||||
|
createSimpleExpression
|
||||||
} from '@vue/compiler-dom'
|
} from '@vue/compiler-dom'
|
||||||
import { escapeHtml } from '@vue/shared'
|
import { escapeHtml, isBooleanAttr, isSSRSafeAttrName } from '@vue/shared'
|
||||||
import { createSSRCompilerError, SSRErrorCodes } from '../errors'
|
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) => {
|
export const ssrTransformElement: NodeTransform = (node, context) => {
|
||||||
if (
|
if (
|
||||||
@ -66,12 +73,58 @@ export const ssrTransformElement: NodeTransform = (node, context) => {
|
|||||||
const { props } = directiveTransform(prop, node, context)
|
const { props } = directiveTransform(prop, node, context)
|
||||||
for (let j = 0; j < props.length; j++) {
|
for (let j = 0; j < props.length; j++) {
|
||||||
const { key, value } = props[j]
|
const { key, value } = props[j]
|
||||||
openTag.push(
|
if (key.type === NodeTypes.SIMPLE_EXPRESSION && key.isStatic) {
|
||||||
createCallExpression(context.helper(SSR_RENDER_ATTR), [
|
const attrName = key.content
|
||||||
key,
|
// static key attr
|
||||||
value
|
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 {
|
} else {
|
||||||
// no corresponding ssr directive transform found.
|
// 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'
|
import { DirectiveTransform } from '@vue/compiler-dom'
|
||||||
|
|
||||||
export const ssrVModel: DirectiveTransform = (dir, node, context) => {
|
export const ssrTransformModel: DirectiveTransform = (dir, node, context) => {
|
||||||
return {
|
return {
|
||||||
props: []
|
props: []
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { DirectiveTransform } from '@vue/compiler-dom'
|
import { DirectiveTransform } from '@vue/compiler-dom'
|
||||||
|
|
||||||
export const ssrVShow: DirectiveTransform = (dir, node, context) => {
|
export const ssrTransformShow: DirectiveTransform = (dir, node, context) => {
|
||||||
return {
|
return {
|
||||||
props: []
|
props: []
|
||||||
}
|
}
|
||||||
|
@ -33,13 +33,18 @@ export function renderAttrs(
|
|||||||
} else if (key === 'style') {
|
} else if (key === 'style') {
|
||||||
ret += ` style="${renderStyle(value)}"`
|
ret += ` style="${renderStyle(value)}"`
|
||||||
} else {
|
} else {
|
||||||
ret += renderAttr(key, value, tag)
|
ret += renderDynamicAttr(key, value, tag)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderAttr(key: string, value: unknown, tag?: string): string {
|
// render an attr with dynamic (unknown) key.
|
||||||
|
export function renderDynamicAttr(
|
||||||
|
key: string,
|
||||||
|
value: unknown,
|
||||||
|
tag?: string
|
||||||
|
): string {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
return ``
|
return ``
|
||||||
}
|
}
|
||||||
@ -56,6 +61,15 @@ export function renderAttr(key: string, value: unknown, tag?: string): string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Render a v-bind attr with static key. The key is pre-processed at compile
|
||||||
|
// time and we only need to check and escape value.
|
||||||
|
export function renderAttr(key: string, value: unknown): string {
|
||||||
|
if (value == null) {
|
||||||
|
return ``
|
||||||
|
}
|
||||||
|
return ` ${key}="${escapeHtml(value)}"`
|
||||||
|
}
|
||||||
|
|
||||||
export function renderClass(raw: unknown): string {
|
export function renderClass(raw: unknown): string {
|
||||||
return escapeHtml(normalizeClass(raw))
|
return escapeHtml(normalizeClass(raw))
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,8 @@ export {
|
|||||||
renderClass as _renderClass,
|
renderClass as _renderClass,
|
||||||
renderStyle as _renderStyle,
|
renderStyle as _renderStyle,
|
||||||
renderAttrs as _renderAttrs,
|
renderAttrs as _renderAttrs,
|
||||||
renderAttr as _renderAttr
|
renderAttr as _renderAttr,
|
||||||
|
renderDynamicAttr as _renderDynamicAttr
|
||||||
} from './helpers/renderAttrs'
|
} from './helpers/renderAttrs'
|
||||||
export { interpolate as _interpolate } from './helpers/interpolate'
|
export { interpolate as _interpolate } from './helpers/interpolate'
|
||||||
export { renderList as _renderList } from './helpers/renderList'
|
export { renderList as _renderList } from './helpers/renderList'
|
||||||
|
Loading…
Reference in New Issue
Block a user