mirror of https://github.com/vuejs/core.git
fix(compiler-vapor): treat attribute as dynamic if has dynamic key prop
This commit is contained in:
parent
6d098b6871
commit
2229d3ce20
|
@ -169,6 +169,20 @@ export function render(_ctx) {
|
|||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > dynamic arg w/ static attribute 1`] = `
|
||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProps as _setDynamicProps } from 'vue/vapor';
|
||||
|
||||
export function render(_ctx) {
|
||||
const t0 = _template("<div></div>")
|
||||
const n0 = t0()
|
||||
const { 0: [n1],} = _children(n0)
|
||||
_renderEffect(() => {
|
||||
_setDynamicProps(n1, { [_ctx.id]: _ctx.id, foo: "bar", checked: "" })
|
||||
})
|
||||
return n0
|
||||
}"
|
||||
`;
|
||||
|
||||
exports[`compiler v-bind > no expression (shorthand) 1`] = `
|
||||
"import { template as _template, children as _children, renderEffect as _renderEffect, setDynamicProp as _setDynamicProp } from 'vue/vapor';
|
||||
|
||||
|
|
|
@ -167,6 +167,55 @@ describe('compiler v-bind', () => {
|
|||
)
|
||||
})
|
||||
|
||||
test('dynamic arg w/ static attribute', () => {
|
||||
const { ir, code } = compileWithVBind(
|
||||
`<div v-bind:[id]="id" foo="bar" checked />`,
|
||||
)
|
||||
expect(code).matchSnapshot()
|
||||
expect(ir.effect[0].operations[0]).toMatchObject({
|
||||
type: IRNodeTypes.SET_DYNAMIC_PROPS,
|
||||
element: 1,
|
||||
props: [
|
||||
[
|
||||
{
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'id',
|
||||
isStatic: false,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'id',
|
||||
isStatic: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'foo',
|
||||
isStatic: true,
|
||||
},
|
||||
value: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'bar',
|
||||
isStatic: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
key: {
|
||||
type: NodeTypes.SIMPLE_EXPRESSION,
|
||||
content: 'checked',
|
||||
isStatic: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
],
|
||||
})
|
||||
expect(code).contains(
|
||||
'_setDynamicProps(n1, { [_ctx.id]: _ctx.id, foo: "bar", checked: "" })',
|
||||
)
|
||||
})
|
||||
|
||||
test('should error if empty expression', () => {
|
||||
const onError = vi.fn()
|
||||
const { ir, code } = compileWithVBind(`<div v-bind:arg="" />`, {
|
||||
|
|
|
@ -10,7 +10,6 @@ import {
|
|||
type ParentNode,
|
||||
type RootNode,
|
||||
type SimpleExpressionNode,
|
||||
type SourceLocation,
|
||||
type TemplateChildNode,
|
||||
type TemplateNode,
|
||||
defaultOnError,
|
||||
|
@ -46,7 +45,6 @@ export type DirectiveTransform = (
|
|||
export interface DirectiveTransformResult {
|
||||
key: SimpleExpressionNode
|
||||
value: SimpleExpressionNode
|
||||
loc: SourceLocation
|
||||
modifier?: '.' | '^'
|
||||
runtimeCamelize?: boolean
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ import {
|
|||
NodeTypes,
|
||||
type SimpleExpressionNode,
|
||||
createCompilerError,
|
||||
createSimpleExpression,
|
||||
} from '@vue/compiler-dom'
|
||||
import { isBuiltInDirective, isReservedProp, isVoidTag } from '@vue/shared'
|
||||
import type {
|
||||
|
@ -57,16 +58,18 @@ export const transformElement: NodeTransform = (node, context) => {
|
|||
function buildProps(
|
||||
node: ElementNode,
|
||||
context: TransformContext<ElementNode>,
|
||||
props: ElementNode['props'] = node.props,
|
||||
props: (VaporDirectiveNode | AttributeNode)[] = node.props as any,
|
||||
isComponent: boolean,
|
||||
) {
|
||||
const dynamicArgs: PropsExpression[] = []
|
||||
const dynamicExpr: SimpleExpressionNode[] = []
|
||||
let results: DirectiveTransformResult[] = []
|
||||
|
||||
function pushExpressions(...exprs: SimpleExpressionNode[]) {
|
||||
function pushDynamicExpressions(
|
||||
...exprs: (SimpleExpressionNode | undefined)[]
|
||||
) {
|
||||
for (const expr of exprs) {
|
||||
if (!expr.isStatic) dynamicExpr.push(expr)
|
||||
if (expr && !expr.isStatic) dynamicExpr.push(expr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,14 +80,22 @@ function buildProps(
|
|||
}
|
||||
}
|
||||
|
||||
for (const prop of props as (VaporDirectiveNode | AttributeNode)[]) {
|
||||
// treat all props as dynamic key
|
||||
const asDynamic = props.some(
|
||||
prop =>
|
||||
prop.type === NodeTypes.DIRECTIVE &&
|
||||
prop.name === 'bind' &&
|
||||
(!prop.arg || !prop.arg.isStatic),
|
||||
)
|
||||
|
||||
for (const prop of props) {
|
||||
if (
|
||||
prop.type === NodeTypes.DIRECTIVE &&
|
||||
prop.name === 'bind' &&
|
||||
!prop.arg
|
||||
) {
|
||||
if (prop.exp) {
|
||||
pushExpressions(prop.exp)
|
||||
pushDynamicExpressions(prop.exp)
|
||||
pushMergeArg()
|
||||
dynamicArgs.push(prop.exp)
|
||||
} else {
|
||||
|
@ -95,10 +106,10 @@ function buildProps(
|
|||
continue
|
||||
}
|
||||
|
||||
const result = transformProp(prop, node, context)
|
||||
const result = transformProp(prop, node, context, asDynamic)
|
||||
if (result) {
|
||||
results.push(result)
|
||||
pushExpressions(result.key, result.value)
|
||||
asDynamic && pushDynamicExpressions(result.key, result.value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -136,14 +147,26 @@ function transformProp(
|
|||
prop: VaporDirectiveNode | AttributeNode,
|
||||
node: ElementNode,
|
||||
context: TransformContext<ElementNode>,
|
||||
asDynamic: boolean,
|
||||
): DirectiveTransformResult | void {
|
||||
const { name } = prop
|
||||
if (isReservedProp(name)) return
|
||||
|
||||
if (prop.type === NodeTypes.ATTRIBUTE) {
|
||||
context.template += ` ${name}`
|
||||
if (prop.value) context.template += `="${prop.value.content}"`
|
||||
return
|
||||
if (asDynamic) {
|
||||
return {
|
||||
key: createSimpleExpression(prop.name, true, prop.nameLoc),
|
||||
value: createSimpleExpression(
|
||||
prop.value ? prop.value.content : '',
|
||||
true,
|
||||
prop.value && prop.value.loc,
|
||||
),
|
||||
}
|
||||
} else {
|
||||
context.template += ` ${name}`
|
||||
if (prop.value) context.template += `="${prop.value.content}"`
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
const directiveTransform = context.options.directiveTransforms[name]
|
||||
|
|
Loading…
Reference in New Issue