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?

huangapple go评论53阅读模式
英文:

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.

&lt;template&gt;
    &lt;v-text-field ref=&quot;t1&quot; v-model=&quot;vText1&quot;/&gt;
    &lt;v-text-field ref=&quot;t2&quot; v-model=&quot;vText2&quot;/&gt;
    &lt;v-text-field ref=&quot;t3&quot; value=&quot;vTextC&quot;/&gt;
&lt;/template&gt;
&lt;script&gt;
    export default {
       data() {
           return {
               vText1 : 0,
               vText2 : 0
           }
       },
       computed:{
           vTextC(){ return this.vText1 + this.vText2}
       }
    }
&lt;/script&gt;

答案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: `
  &lt;v-card class=&quot;ma-2 pa-2&quot; style=&quot;max-width: 400px;&quot;&gt;
    &lt;v-text-field type=&quot;number&quot; v-model.number=&quot;vText1&quot; dense/&gt;
    &lt;v-text-field type=&quot;number&quot; v-model.number=&quot;vText2&quot; dense/&gt;
    &lt;v-text-field
      type=&quot;number&quot;
      :label=&quot;isManual ? &#39;manual&#39; : &#39;calculated&#39;&quot;
      v-model.number=&quot;vText3&quot;
      @input=&quot;updateIsManual&quot;
      dense
    /&gt;
  &lt;/v-card&gt;
 `,
  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 !== &#39;&#39;
      if (!this.isManual) {
        this.calculateVText3()
      }
    },
  },
  watch: {
    vText1: &#39;calculateVText3&#39;,
    vText2: &#39;calculateVText3&#39;,
  },
}

new Vue({
  el: &#39;#app&#39;,
  vuetify: new Vuetify(),
  components: {&#39;button-component&#39;: ButtonComponent}
})

<!-- language: lang-html -->

&lt;link href=&quot;https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link href=&quot;https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link href=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css&quot; rel=&quot;stylesheet&quot;&gt;

&lt;div id=&quot;app&quot;&gt;
  &lt;v-app&gt;
    &lt;v-main&gt;
     &lt;button-component&gt;&lt;/button-component&gt;
    &lt;/v-main&gt;
  &lt;/v-app&gt;
&lt;/div&gt;

&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js&quot;&gt;&lt;/script&gt;

<!-- 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: `
  &lt;v-card class=&quot;ma-2 pa-2&quot; style=&quot;max-width: 400px&quot;&gt;
    &lt;v-text-field type=&quot;number&quot; v-model.number=&quot;vText1&quot; dense/&gt;
    &lt;v-text-field type=&quot;number&quot; v-model.number=&quot;vText2&quot; dense/&gt;
    &lt;v-text-field
      type=&quot;number&quot;
      v-model.number=&quot;vText3&quot;
      :readonly=&quot;calculateField3&quot;
      @focus=&quot;calculateField3 = false&quot;
      dense
    &gt;
      &lt;template #append-outer&gt;
        &lt;v-checkbox
          class=&quot;mt-0&quot;
          v-model=&quot;calculateField3&quot;
          label=&quot;calculate automatically&quot;
          @change=&quot;$event &amp;&amp; calculateVText3()&quot; 
        /&gt;
      &lt;/template&gt;
    &lt;/v-text-field&gt;
  &lt;/v-card&gt;
 `,
  data() {
    return {
      vText1: 0,
      vText2: 0,
      vText3: 0,
      calculateField3: true,
    }
  },
  methods: {
    calculateVText3() {
      if (!this.calculateField3) return
      this.vText3 = this.vText1 + this.vText2
    },
  },
  watch: {
    vText1: &#39;calculateVText3&#39;,
    vText2: &#39;calculateVText3&#39;,
  },
}

new Vue({
  el: &#39;#app&#39;,
  vuetify: new Vuetify(),
  components: {
    &#39;button-component&#39;: ButtonComponent
  }
})

<!-- language: lang-html -->

&lt;link href=&quot;https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link href=&quot;https://cdn.jsdelivr.net/npm/@mdi/font@6.x/css/materialdesignicons.min.css&quot; rel=&quot;stylesheet&quot;&gt;
&lt;link href=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.min.css&quot; rel=&quot;stylesheet&quot;&gt;

&lt;div id=&quot;app&quot;&gt;
  &lt;v-app&gt;
    &lt;v-main&gt;
     &lt;button-component&gt;&lt;/button-component&gt;
    &lt;/v-main&gt;
  &lt;/v-app&gt;
&lt;/div&gt;

&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vue@2.x/dist/vue.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://cdn.jsdelivr.net/npm/vuetify@2.x/dist/vuetify.js&quot;&gt;&lt;/script&gt;

<!-- end snippet -->

huangapple
  • 本文由 发表于 2023年7月3日 16:23:20
  • 转载请务必保留本文链接:https://go.coder-hub.com/76603026.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定