feat: camel modifier for `v-bind` (#39)

This commit is contained in:
Rizumu Ayaka 2023-12-09 18:41:59 +08:00 committed by GitHub
parent 5f769745fa
commit 26308c51eb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 21 additions and 9 deletions

View File

@ -8,7 +8,7 @@ export function render(_ctx) {
const n0 = t0()
const { 0: [n1],} = _children(n0)
_effect(() => {
_setAttr(n1, "foo-bar", undefined, _ctx.id)
_setAttr(n1, "fooBar", undefined, _ctx.id)
})
return n0
}"

View File

@ -165,7 +165,7 @@ describe('compiler: transform v-bind', () => {
})
})
test.fails('.camel modifier', () => {
test('.camel modifier', () => {
const node = parseWithVBind(`<div v-bind:foo-bar.camel="id"/>`)
expect(node.effect[0].operations[0]).toMatchObject({
key: {
@ -179,7 +179,7 @@ describe('compiler: transform v-bind', () => {
})
})
test.fails('.camel modifier w/ no expression', () => {
test('.camel modifier w/ no expression', () => {
const node = parseWithVBind(`<div v-bind:foo-bar.camel />`)
expect(node.effect[0].operations[0]).toMatchObject({
key: {
@ -193,13 +193,13 @@ describe('compiler: transform v-bind', () => {
})
})
test.fails('.camel modifier w/ dynamic arg', () => {
test('.camel modifier w/ dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[foo].camel="id"/>`)
expect(node.effect[0].operations[0]).toMatchObject({
runtimeCamelize: true,
key: {
content: `foo`,
isStatic: false,
somethingShouldBeTrue: true,
},
value: {
content: `id`,
@ -289,8 +289,7 @@ describe('compiler: codegen v-bind', () => {
expect(code).contains('_setAttr(n1, _ctx.id, undefined, _ctx.id)')
})
// TODO: camel modifier for v-bind
test.fails('.camel modifier', () => {
test('.camel modifier', () => {
const code = compile(`<div v-bind:foo-bar.camel="id"/>`)
expect(code).matchSnapshot()

View File

@ -370,9 +370,11 @@ function genOperation(oper: OperationNode, context: CodegenContext) {
}
function genSetProp(oper: SetPropIRNode, context: CodegenContext) {
const { push, pushWithNewline, vaporHelper } = context
const { push, pushWithNewline, vaporHelper, helper } = context
pushWithNewline(`${vaporHelper('setAttr')}(n${oper.element}, `)
if (oper.runtimeCamelize) push(`${helper('camelize')}(`)
genExpression(oper.key, context)
if (oper.runtimeCamelize) push(`)`)
push(`, undefined, `)
genExpression(oper.value, context)
push(')')

View File

@ -60,6 +60,7 @@ export interface SetPropIRNode extends BaseIRNode {
element: number
key: IRExpression
value: IRExpression
runtimeCamelize: boolean
}
export interface SetTextIRNode extends BaseIRNode {

View File

@ -8,7 +8,7 @@ import { IRNodeTypes } from '../ir'
import type { DirectiveTransform } from '../transform'
export const transformVBind: DirectiveTransform = (dir, node, context) => {
let { arg, exp, loc } = dir
let { arg, exp, loc, modifiers } = dir
if (!arg) {
// TODO support v-bind="{}"
@ -21,6 +21,15 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => {
exp.ast = null
}
let camel = false
if (modifiers.includes('camel')) {
if (arg.isStatic) {
arg.content = camelize(arg.content)
} else {
camel = true
}
}
if (!exp.content.trim()) {
context.options.onError(
createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
@ -38,6 +47,7 @@ export const transformVBind: DirectiveTransform = (dir, node, context) => {
element: context.reference(),
key: arg,
value: exp,
runtimeCamelize: camel,
},
],
)