英文:
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 -->
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论