使用@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 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}
})
<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>
请注意,在UX方面,这有点乱,因为用户不知道如何从手动输入返回.请看下面的代码片段,其中使用了一个复选框来使其更加明确:
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
}
})
<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>