10000 fix(volar/jsx-directive): prevent convert v-model to value for radio … · vue-macros/vue-macros@55f28c9 · GitHub
[go: up one dir, main page]

Skip to content

Commit 55f28c9

Browse files
authored
fix(volar/jsx-directive): prevent convert v-model to value for radio and checkbox (#947)
* fix(volar/jsx-directive): prevent convert v-model to value when type is radio or checkbox * fix: test
1 parent 8a639eb commit 55f28c9

File tree

3 files changed

+34
-2
lines changed

3 files changed

+34
-2
lines changed

packages/jsx-directive/tests/__snapshots__/v-model.test.ts.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ const value = ref('value')
99
defineRender(() => (
1010
<div>
1111
<input {...{[value.value]: foo, ["onUpdate:" + value.value]: $event => foo = $event, [value.value + "Modifiers"]: { trim: true, number: true }}} />
12+
<input v-model={foo} type="checkbox" value="1"></input>
1213
{foo}
1314
</div>
1415
))

packages/jsx-directive/tests/fixtures/v-model/index.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const value = ref('value')
66
defineRender(() => (
77
<div>
88
<input v-model:$value_value$_trim_number={foo} />
9+
<input v-model={foo} type="checkbox" value="1"></input>
910
{foo}
1011
</div>
1112
))

packages/volar/src/jsx-directive/v-model.ts

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { replaceSourceRange } from 'muggle-string'
22
import { allCodeFeatures, type Code } from 'ts-macro'
33
import { getStart, getText, isJsxExpression } from '../common'
4-
import { getTagName, type JsxDirective, type TransformOptions } from './index'
4+
import {
5+
getOpeningElement,
6+
getTagName,
7+
type JsxDirective,
8+
type TransformOptions,
9+
} from './index'
510

611
export const isNativeFormElement = (tag: string): boolean => {
712
return ['input', 'select', 'textarea'].includes(tag)
@@ -160,7 +165,9 @@ function transform(
160165
const result = []
161166
result.push(
162167
...((isNative
163-
? [[modelValue, source, start + 2, allCodeFeatures]]
168+
? isRadioOrCheckbox(node, options)
169+
? 'v-model'
170+
: [[modelValue, source, start + 2, allCodeFeatures]]
164171
: [
165172
modelValue.slice(0, 3),
166173
[modelValue.slice(3), source, start, allCodeFeatures],
@@ -218,6 +225,29 @@ function transform(
218225
)
219226
}
220227

228+
function isRadioOrCheckbox(
229+
node: import('typescript').Node,
230+
options: TransformOptions,
231+
) {
232+
const { ts } = options
233+
const openingElement = getOpeningElement(node, options)
234+
if (!openingElement) return false
235+
const tagName = getText(openingElement.tagName, options)
236+
return (
237+
tagName === 'input' &&
238+
openingElement.attributes.properties.some((attr) => {
239+
return (
240+
ts.isJsxAttribute(attr) &&
241+
getText(attr.name, options) === 'type' &&
242+
attr.initializer &&
243+
ts.isStringLiteral(attr.initializer) &&
244+
(attr.initializer.text === 'radio' ||
245+
attr.initializer.text === 'checkbox')
246+
)
247+
})
248+
)
249+
}
250+
221251
function getModelsType(codes: Code[]) {
222252
codes.push(`
223253
type __VLS_NormalizeProps<T> = T extends object

0 commit comments

Comments
 (0)
0