英文:
Vue CLI: Can I have a v-text-field's value change when another v-text-field changes, but at the same time be able to overwrite it?
问题
我有3个v-text-field。我希望只有在没有手动输入的情况下才自动计算t3(`vText1 + vText2`)。如果用户在t3中写入“230”,它应该忽略vTextC。但如果用户删除他们写的内容,vTextC应该再次成为文本字段的值。
<template>
<v-text-field ref="t1" v-model="vText1"/>
<v-text-field ref="t2" v-model="vText2"/>
<v-text-field ref="t3" :value="vTextC"/>
</template>
<script>
export default {
data() {
return {
vText1: 0,
vText2: 0
}
},
computed: {
vTextC() { return this.vText1 + this.vText2 }
}
}
</script>
英文:
I have 3 v-text-field. I want t3 to be automatically calculated (vText1 + vText2) only if there isn't manual input. If the user writes "230" in t3, it should ignore vTextC. But if the user deletes what they wrote, vTextC should again be the value for the text field.
<template>
<v-text-field ref="t1" v-model="vText1"/>
<v-text-field ref="t2" v-model="vText2"/>
<v-text-field ref="t3" value="vTextC"/>
</template>
<script>
export default {
data() {
return {
vText1 : 0,
vText2 : 0
}
},
computed:{
vTextC(){ return this.vText1 + this.vText2}
}
}
</script>
答案1
得分: 1
使用@input事件(在Vue 3中为@update:modelValue)来跟踪输入是否是手动输入。然后只在非手动模式下更新值:
const ButtonComponent = {
template: `
<v-card class="ma-2 pa-2" style="max-width: 400px;">
<v-text-field type="number" v-model.number="vText1" dense></v-text-field>
<v-text-field type="number" v-model.number="vText2" dense></v-text-field>
<v-text-field
type="number"
:label="isManual ? 'manual' : 'calculated'"
v-model.number="vText3"
@input="updateIsManual"
dense
></v-text-field>
</v-card>
`,
data() {
return {
vText1: 0,
vText2: 0,
vText3: 0,
isManual: false,
};
},
methods: {
calculateVText3() {
if (this.isManual) return;
this.vText3 = this.vText1 + this.vText2;
},
updateIsManual(value) {
this.isManual = value !== '';
if (!this.isManual) {
this.calculateVText3();
}
},
},
watch: {
vText1: 'calculateVText3',
vText2: 'calculateVText3',
},
};
new Vue({
el: '#app',
vuetify: new Vuetify(),
components: { 'button-component': ButtonComponent },
});
请注意,从用户体验的角度来看,这有点混乱,因为用户不知道如何从手动输入返回。可以查看下面的示例,使用复选框使其更加明确:
const ButtonComponent = {
template: `
<v-card class="ma-2 pa-2" style="max-width: 400px">
<v-text-field type="number" v-model.number="vText1" dense></v-text-field>
<v-text-field type="number" v-model.number="vText2" dense></v-text-field>
<v-text-field
type="number"
v-model.number="vText3"
:readonly="!calculateField3"
@focus="calculateField3 = false"
dense
>
<template #append-outer>
<v-checkbox
class="mt-0"
v-model="calculateField3"
label="calculate automatically"
@change="$event && calculateVText3()"
></v-checkbox>
</template>
</v-text-field>
</v-card>
`,
data() {
return {
vText1: 0,
vText2: 0,
vText3: 0,
calculateField3: true,
};
},
methods: {
calculateVText3() {
if (!this.calculateField3) return;
this.vText3 = this.vText1 + this.vText2;
},
},
watch: {
vText1: 'calculateVText3',
vText2: 'calculateVText3',
},
};
new Vue({
el: '#app',
vuetify: new Vuetify(),
components: { 'button-component': ButtonComponent },
});
请注意,这段代码在Vue.js和Vuetify环境中运行,用于创建一个带有输入字段的组件,可以根据用户选择自动计算或手动输入。
英文:
Use the @input event (@update:modelValue in Vue 3) to keep track of whether the input was made manually. Then update the value only when not in manual mode:
<!-- begin snippet: js hide: false console: false babel: false -->
<!-- language: lang-js -->
const ButtonComponent = {
template: `
<v-card class="ma-2 pa-2" style="max-width: 400px;">
<v-text-field type="number" v-model.number="vText1" dense/>
<v-text-field type="number" v-model.number="vText2" dense/>
<v-text-field
type="number"
:label="isManual ? 'manual' : 'calculated'"
v-model.number="vText3"
@input="updateIsManual"
dense
/>
</v-card>
`,
data() {
return {
vText1: 0,
vText2: 0,
vText3: 0,
isManual: false,
}
},
methods: {
calculateVText3() {
if (this.isManual) return
this.vText3 = this.vText1 + this.vText2
},
updateIsManual(value) {
this.isManual = value !== ''
if (!this.isManual) {
this.calculateVText3()
}
},
},
watch: {
vText1: 'calculateVText3',
vText2: 'calculateVText3',
},
}
new Vue({
el: '#app',
vuetify: new Vuetify(),
components: {'button-component': ButtonComponent}
})
<!-- language: lang-html -->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<button-component></button-component>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<!-- end snippet -->
Note that UX-wise, this is a bit messy, as users won't know how to get back from manual input. Have a look at the snippet for an example that uses a checkbox to make it more explicit:
<!-- begin snippet: js hide: true console: false babel: false -->
<!-- language: lang-js -->
const ButtonComponent = {
template: `
<v-card class="ma-2 pa-2" style="max-width: 400px">
<v-text-field type="number" v-model.number="vText1" dense/>
<v-text-field type="number" v-model.number="vText2" dense/>
<v-text-field
type="number"
v-model.number="vText3"
:readonly="calculateField3"
@focus="calculateField3 = false"
dense
>
<template #append-outer>
<v-checkbox
class="mt-0"
v-model="calculateField3"
label="calculate automatically"
@change="$event && calculateVText3()"
/>
</template>
</v-text-field>
</v-card>
`,
data() {
return {
vText1: 0,
vText2: 0,
vText3: 0,
calculateField3: true,
}
},
methods: {
calculateVText3() {
if (!this.calculateField3) return
this.vText3 = this.vText1 + this.vText2
},
},
watch: {
vText1: 'calculateVText3',
vText2: 'calculateVText3',
},
}
new Vue({
el: '#app',
vuetify: new Vuetify(),
components: {
'button-component': ButtonComponent
}
})
<!-- language: lang-html -->
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css" rel="stylesheet">
<div id="app">
<v-app>
<v-main>
<button-component></button-component>
</v-main>
</v-app>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js"></script>
<!-- end snippet -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论