Skip to content

Commit

Permalink
fix: cannot use v-model with value prop with radio input tag
Browse files Browse the repository at this point in the history
close #1775
  • Loading branch information
johnsoncodehk committed Aug 30, 2022
1 parent ef33bac commit 5015fd7
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 3 deletions.
44 changes: 41 additions & 3 deletions packages/vue-language-core/src/generators/template.ts
Expand Up @@ -517,7 +517,7 @@ export function generate(
},
);
tsCodeGen.addText(` `);
const { hasRemainStyleOrClass } = writeProps(node, false, 'props');
const { hasRemainStyleOrClass, failedExps } = writeProps(node, false, 'props');

if (endTagOffset === undefined) {
tsCodeGen.addText(`/>`);
Expand All @@ -536,7 +536,31 @@ export function generate(
capabilities: tagCapabilities,
},
);
tsCodeGen.addText(`>`);
tsCodeGen.addText(`>;\n`);
}

// fix https://github.com/johnsoncodehk/volar/issues/1775
for (const failedExp of failedExps) {
writeInterpolation(
failedExp.loc.source,
failedExp.loc.start.offset,
{
vueTag: 'template',
capabilities: capabilitiesSet.all,
},
'(',
')',
failedExp.loc,
);
const fb = formatBrackets.round;
if (fb) {
writeFormatCode(
failedExp.loc.source,
failedExp.loc.start.offset,
fb,
);
}
tsCodeGen.addText(';\n');
}

// fix https://github.com/johnsoncodehk/volar/issues/705#issuecomment-974773353
Expand Down Expand Up @@ -881,6 +905,7 @@ export function generate(

let styleCount = 0;
let classCount = 0;
const failedExps: CompilerDOM.SimpleExpressionNode[] = [];

for (const prop of node.props) {
if (
Expand All @@ -898,6 +923,13 @@ export function generate(
: prop.arg.loc.source
: getModelValuePropName(node, vueCompilerOptions.target);

if (propName_1 === undefined) {
if (prop.exp) {
failedExps.push(prop.exp);
}
continue;
}

if (prop.modifiers.some(m => m === 'prop' || m === 'attr')) {
propName_1 = propName_1.substring(1);
}
Expand Down Expand Up @@ -1185,7 +1217,10 @@ export function generate(
}
}

return { hasRemainStyleOrClass: styleCount >= 2 || classCount >= 2 };
return {
hasRemainStyleOrClass: styleCount >= 2 || classCount >= 2,
failedExps,
};

function writePropName(name: string, isStatic: boolean, sourceRange: SourceMaps.Range, data: EmbeddedFileMappingData, cacheOn: any) {
if (mode === 'props' && isStatic) {
Expand Down Expand Up @@ -2033,6 +2068,9 @@ function getModelValuePropName(node: CompilerDOM.ElementNode, vueVersion: number
if (tag === 'input' && type === 'checkbox')
return 'checked';

if (tag === 'input' && type === 'radio')
return undefined;

if (
tag === 'input' ||
tag === 'textarea' ||
Expand Down
11 changes: 11 additions & 0 deletions packages/vue-test-workspace/vue-tsc/input-radio/main.vue
@@ -0,0 +1,11 @@
<template>
<input v-model="picked" type="radio" value="One" />
<input v-model="checked" type="checkbox" value="Two" />
</template>

<script setup lang="ts">
import { ref } from "vue"
const picked = ref([])
const checked = ref([])
</script>

0 comments on commit 5015fd7

Please sign in to comment.