ITADN
vuejs/core/Issues

[Vapor] compiler: custom directive with an inline object-literal value generates an arrow function with a bare `{ ... }` body

#15253ClosedMaXal 创建于 11 天前
M
MaXalcommented
### Vue version 3.6.0-rc.2 ### Link to minimal reproduction https://play.vuejs.org/#eNqVkU9rwzAMxb+K8GUJpM7+wA4hzRjbaYftMNgpMEKstgbXNrLiNpR+92mUwHbYYSchoaffe+ikHmPUeULVqDaNZCNDQp4i5CEG6no/Bp8Y8jPuA6yhQFfBFvljcBOWsO7g1HsAdJrxyE/BM3qWvZf3t1edmKzf2s1cLIoHXZRl78/LWYMXpg1eRFc7dC5c9b6tL2PBS8O4j25g7L5JbeyCR4gUIhLPUCTrBOlmOFDw2wqMJRzZZgSpKDXB5A1urEdTNm0dL2eMzZBXRlKte3WStOKu+eXn3KtOuCPugjNIbS2SxQIfwmLBCqBIs+fhCEgU6D+QCgLvkBq4+QvX1j/iq0p9ZqQkSvnXnb7X1ysa9a06fwFMxJ8l ### Steps to reproduce A vapor SFC with a custom directive that receives an inline object literal, the way object options are typically passed to directives (e.g. PrimeVue's `v-tooltip="{ value: ..., pt: ... }"`): ```vue <script setup vapor> const vDemo = (el, getValue) => { el.textContent = JSON.stringify(getValue?.()) } const description = 'hello' </script> <template> <div v-demo="{ value: description }">placeholder</div> <div v-demo="{ value: description, other: 1 }">placeholder</div> </template> ``` Canonical repro of the codegen itself (node, `vue@3.6.0-rc.2`): ```js import { compileTemplate } from 'vue/compiler-sfc' const out = compileTemplate({ id: 'x', filename: 'App.vue', source: `<div v-demo="{ value: description }">placeholder</div> <div v-demo="{ value: description, other: 1 }">p2</div>`, vapor: true, compilerOptions: { bindingMetadata: { vDemo: 'setup-const', description: 'setup-const' } }, }) console.log(out.code) ``` emits: ```js export function render(_ctx, $props, $emit, $attrs, $slots) { const n0 = t0() _withVaporDirectives(n0, [[_ctx.vDemo, () => { value: _ctx.description }]]) const n1 = t1() _withVaporDirectives(n1, [[_ctx.vDemo, () => { value: _ctx.description, other: 1 }]]) return [n0, n1] } ``` The directive value expression is wrapped in an arrow function without parenthesizing the object literal. ### What is expected? The getter should return the object: ```js _withVaporDirectives(n0, [[_ctx.vDemo, () => ({ value: _ctx.description })]]) ``` VDOM mode handles the same template correctly. ### What is actually happening? 1. **Single property, non-inline mode — silently wrong.** `() => { value: _ctx.description }` parses as an arrow with a *block body* containing a labeled statement, so the getter returns `undefined`. No compile error, no runtime error — the directive just receives `undefined` instead of the object. 2. **Two or more properties — SyntaxError.** `() => { value: _ctx.description, other: 1 }` is not valid JavaScript. In a Vite build this fails the build with `Expected a semicolon or an implicit semicolon after a statement, but found none` pointing into the generated SFC code. 3. **Inline mode (playground) — directive receives the raw object instead of a getter.** In the playground repro above, the directive's second argument is the object itself rather than a function, so `getValue?.()` throws `getValue is not a function`. ### System Info ```shell System: macOS 26.6 (arm64) Binaries: node v26.7.0, pnpm 11.18.0 npmPackages: vue 3.6.0-rc.2, @vitejs/plugin-vue 6.0.8, vite 8.2.1 ``` ### Any additional comments? _No response_
关闭于 11 天前 1 条评论