]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-vapor): shorthand & no expression
author三咲智子 Kevin Deng <sxzz@sxzz.moe>
Wed, 6 Dec 2023 16:36:42 +0000 (00:36 +0800)
committer三咲智子 Kevin Deng <sxzz@sxzz.moe>
Wed, 6 Dec 2023 16:36:42 +0000 (00:36 +0800)
packages/compiler-vapor/__tests__/__snapshots__/compile.test.ts.snap
packages/compiler-vapor/__tests__/compile.test.ts
packages/compiler-vapor/src/transforms/transformElement.ts

index 863f8b2588d938c8ac16441fb2ea00e904f06b70..893ffc05b2954ff993d736936d281130425d0706 100644 (file)
@@ -44,11 +44,39 @@ export function render(_ctx) {
 }"
 `;
 
+exports[`compile > directives > v-bind > no expression (shorthand) 1`] = `
+"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
+
+export function render(_ctx) {
+  const t0 = _template("<div></div>")
+  const n0 = t0()
+  const { 0: [n1],} = _children(n0)
+  _effect(() => {
+    _setAttr(n1, "camel-case", undefined, _ctx.camelCase)
+  })
+  return n0
+}"
+`;
+
+exports[`compile > directives > v-bind > no expression 1`] = `
+"import { template as _template, children as _children, effect as _effect, setAttr as _setAttr } from 'vue/vapor';
+
+export function render(_ctx) {
+  const t0 = _template("<div></div>")
+  const n0 = t0()
+  const { 0: [n1],} = _children(n0)
+  _effect(() => {
+    _setAttr(n1, "id", undefined, _ctx.id)
+  })
+  return n0
+}"
+`;
+
 exports[`compile > directives > v-bind > should error if no expression 1`] = `
 "import { template as _template } from 'vue/vapor';
 
 export function render(_ctx) {
-  const t0 = _template("<div></div>")
+  const t0 = _template("<div arg=\\"\\"></div>")
   const n0 = t0()
   return n0
 }"
index 5b19c02fa17266d26f68c711d1bc7997e509b95b..9459ac00fdb254127beed2654261625e23388886 100644 (file)
@@ -71,8 +71,7 @@ describe('compile', () => {
         expect(code).matchSnapshot()
       })
 
-      // TODO: fix this test
-      test.fails('should error if no expression', async () => {
+      test('should error if no expression', async () => {
         const onError = vi.fn()
         const code = await compile(`<div v-bind:arg="" />`, { onError })
 
@@ -92,11 +91,10 @@ describe('compile', () => {
 
         expect(code).matchSnapshot()
         // the arg is static
-        expect(code).contains(JSON.stringify('<div arg="" ></div>'))
+        expect(code).contains(JSON.stringify('<div arg=""></div>'))
       })
 
-      // TODO: support shorthand syntax for v-bind #9451
-      test.fails('no expression', async () => {
+      test('no expression', async () => {
         const code = await compile('<div v-bind:id />', {
           bindingMetadata: {
             id: BindingTypes.SETUP_REF,
@@ -107,16 +105,17 @@ describe('compile', () => {
         expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
       })
 
-      // TODO: support shorthand syntax for v-bind #9451
-      test.fails('no expression (shorthand)', async () => {
-        const code = await compile('<div :id />', {
+      test('no expression (shorthand)', async () => {
+        const code = await compile('<div :camel-case />', {
           bindingMetadata: {
-            id: BindingTypes.SETUP_REF,
+            camelCase: BindingTypes.SETUP_REF,
           },
         })
 
         expect(code).matchSnapshot()
-        expect(code).contains('_setAttr(n1, "id", undefined, _ctx.id)')
+        expect(code).contains(
+          '_setAttr(n1, "camel-case", undefined, _ctx.camelCase)',
+        )
       })
 
       test('dynamic arg', async () => {
index 8ff3a5575fffc7081850f579824dd2a4d9ccffd7..c0d0a34508fb488cfd7bf43f42ae81300467fc90 100644 (file)
@@ -5,8 +5,9 @@ import {
   ErrorCodes,
   createCompilerError,
   ElementTypes,
+  createSimpleExpression,
 } from '@vue/compiler-dom'
-import { isBuiltInDirective, isVoidTag } from '@vue/shared'
+import { camelize, isBuiltInDirective, isVoidTag } from '@vue/shared'
 import { NodeTransform, TransformContext } from '../transform'
 import { VaporDirectiveNode, IRNodeTypes } from '../ir'
 
@@ -68,7 +69,7 @@ function transformProp(
     return
   }
 
-  const { arg, exp, loc } = prop
+  let { arg, exp, loc } = prop
   const directiveTransform = context.options.directiveTransforms[name]
   if (directiveTransform) {
     directiveTransform(prop, node, context)
@@ -84,19 +85,22 @@ function transformProp(
 
   switch (name) {
     case 'bind': {
-      if (!exp || !exp.content.trim()) {
-        context.options.onError(
-          createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
-        )
+      if (!arg) {
+        // TODO support v-bind="{}"
         return
       }
+      if (!exp) {
+        // shorthand syntax https://github.com/vuejs/core/pull/9451
+        const propName = camelize(arg.content)
+        exp = createSimpleExpression(propName, false, arg.loc)
+        exp.ast = null
+      }
 
-      if (exp === null) {
-        // TODO: Vue 3.4 supported shorthand syntax
-        // https://github.com/vuejs/core/pull/9451
-        return
-      } else if (!arg) {
-        // TODO support v-bind="{}"
+      if (!exp.content.trim()) {
+        context.options.onError(
+          createCompilerError(ErrorCodes.X_V_BIND_NO_EXPRESSION, loc),
+        )
+        context.template += ` ${arg.content}=""`
         return
       }