Skip to content
This repository was archived by the owner on Dec 25, 2024. It is now read-only.

Commit 4bbc77e

Browse files
xiaoxiangmoeantfu
authored andcommitted
fix: dynamic v-bind and v-on
1 parent 2f390ba commit 4bbc77e

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/core/parseSFC.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,12 @@ const SIMPLE_EXPRESSION: NodeTypes.SIMPLE_EXPRESSION = 4
1414
const multilineCommentsRE = /\/\*\s(.|[\r\n])*?\*\//gm
1515
const singlelineCommentsRE = /\/\/\s.*/g
1616

17+
const BUILD_IN_DIRECTIVES_WIRH_ARGUMENT = new Set([
18+
'on',
19+
'bind',
20+
'slot',
21+
])
22+
1723
const BUILD_IN_DIRECTIVES = new Set([
1824
'if',
1925
'else',
@@ -36,6 +42,17 @@ const BUILD_IN_DIRECTIVES = new Set([
3642
// 'ref',
3743
])
3844

45+
function maybeHasDirectiveArgument(nameWithPrefixV: string) {
46+
const directiveName = nameWithPrefixV.replace(/^v-/, '')
47+
if (BUILD_IN_DIRECTIVES_WIRH_ARGUMENT.has(directiveName))
48+
return true
49+
50+
else if (BUILD_IN_DIRECTIVES.has(directiveName))
51+
return false
52+
53+
return true
54+
}
55+
3956
function parseDirective(comp: string, attr: string, body: string) {
4057
const elementNode = baseCompile(`<${comp} ${attr}="${body}" />`).ast.children[0]
4158
if (elementNode?.type !== ELEMENT) return undefined
@@ -122,7 +139,10 @@ export function parseSFC(code: string, id?: string, options?: ScriptSetupTransfo
122139
expressions.add(`(${value})`)
123140
}
124141

125-
if (key.startsWith('v-')) {
142+
if (
143+
['v-', '@[', ':['].some(prefix => key.startsWith(prefix))
144+
&& maybeHasDirectiveArgument(key)
145+
) {
126146
const parsedDirective = parseDirective(name, key, value)
127147
if (parsedDirective && !BUILD_IN_DIRECTIVES.has(parsedDirective.name))
128148
directives.add(camelize(parsedDirective.name))

test/__snapshots__/transform.test.ts.snap

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@ exports[`transform fixtures test/fixtures/ComponentsDirectives.vue 1`] = `
184184
"<template>
185185
<div>
186186
<FooView
187+
v-if=\\"now > 0\\"
187188
ref=\\"fooView\\"
188189
v-foo-bar=\\"message0\\"
189190
v-d0-demo:foo.a.b=\\"message1\\"
@@ -195,7 +196,8 @@ exports[`transform fixtures test/fixtures/ComponentsDirectives.vue 1`] = `
195196
v-d6-arg-dynamic-no-value:[direction3]
196197
v-d6-arg-dynamic-no-value:shouldNotUsed
197198
></FooView>
198-
<router-view></router-view>
199+
<button v-else-if=\\"now === 0\\" :[propNamePrefix+propName]=\\"1\\" @[eventPrefix.value+eventName]=\\"console.log($event)\\"></button>
200+
<router-view v-else></router-view>
199201
</div>
200202
</template>
201203
@@ -216,6 +218,14 @@ __sfc_main.setup = (__props, __ctx) => {
216218
const direction2 = ref('top');
217219
const direction3 = ref('top');
218220
const shouldNotUsed = ref('');
221+
const propNamePrefix = 'vue-';
222+
const propName = 'color';
223+
const eventPrefix = {
224+
value: 'vue-'
225+
};
226+
const eventName = '';
227+
const console = globalThis.console;
228+
const now = Date.now();
219229
return {
220230
fooView,
221231
message0,
@@ -225,7 +235,13 @@ __sfc_main.setup = (__props, __ctx) => {
225235
message4,
226236
direction1,
227237
direction2,
228-
direction3
238+
direction3,
239+
propNamePrefix,
240+
propName,
241+
eventPrefix,
242+
eventName,
243+
console,
244+
now
229245
};
230246
};
231247

test/fixtures/ComponentsDirectives.vue

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
<template>
22
<div>
33
<FooView
4+
v-if="now > 0"
45
ref="fooView"
56
v-foo-bar="message0"
67
v-d0-demo:foo.a.b="message1"
@@ -12,7 +13,8 @@
1213
v-d6-arg-dynamic-no-value:[direction3]
1314
v-d6-arg-dynamic-no-value:shouldNotUsed
1415
></FooView>
15-
<router-view></router-view>
16+
<button v-else-if="now === 0" :[propNamePrefix+propName]="1" @[eventPrefix.value+eventName]="console.log($event)"></button>
17+
<router-view v-else></router-view>
1618
</div>
1719
</template>
1820

@@ -31,4 +33,12 @@ const direction1 = ref('top')
3133
const direction2 = ref('top')
3234
const direction3 = ref('top')
3335
const shouldNotUsed = ref('')
36+
37+
const propNamePrefix = 'vue-'
38+
const propName = 'color'
39+
const eventPrefix = { value: 'vue-' }
40+
const eventName = ''
41+
42+
const console = globalThis.console
43+
const now = Date.now()
3444
</script>

0 commit comments

Comments
 (0)