vue.js 观察者的newVal不会更改

z9gpfhce  于 7个月前  发布在  Vue.js
关注(0)|答案(1)|浏览(77)

我正在使用vue3options api
如下面的stackbiltz链路here所示
我有input,并且我想将在input中显示的值设置为例如4。每当用户试图输入小于4的值时,这看起来很荒谬,但是当我运行代码时,最初,如果我输入了小于4的值,那么在input中显示的值是4。这种情况是可以的。但是如果我第二次尝试输入另一个小于4的值,则input中的内容或值永远不会更改
你能告诉我怎么做吗?

方案

1st input: for input = 1 => it will change to 4..tha is oK
2nd input: for input = 3 => it will not change to 4...this is not ok because as long as the input is lower than 4, 4 must be displayed in the input box

字符串

i know that if the user successviley attempted to enter values lower than 4, the `input` witll display or will change automatically to be set to 4 for the first attempt only, and for the further attempts the value in the `input` will not change to 4 despite
the user enters values lower than 4 because the `newVal` of the `watcher` does not change. but i do not know how to overcome this problem

更新日期:2023年11月13日

如下面的代码所示,this.§forceUpdate是由SO社区的一个成员推荐使用的。我想知道是否有任何其他可能的解决方案来解决这个问题,而不诉诸this.§forceUpdate

代码:GUIEpochAgo.vue

<template>
    days ago:
    <input
        type="input"
        :value="compPropsVModelInputDaysAgo"
        @input="$emit('update:compPropsVModelInputDaysAgo', $event.target.value)"
        :disabled="isInputDaysAgoDisabled"
        @change="onInputDaysAgoChanged($event.target.value)"
    />
</template>

<script>

let debugTag = 'D.GUIEpochAgo.vue::';
let infoTag = 'I.GUIEpochAgo.vue::';
let verboseTag = 'V.GUIEpochAgo.vue::';
let warnTag = 'W.GUIEpochAgo.vue::';
let errorTag = 'E.GUIEpochAgo.vue::';
let WTFTag = 'WTF.GUIEpochAgo.vue::';
//
export default {
name: 'GUIEpochAgo',
data() {
    return {
    };
},
components: {},
props: {
    vModelInputDaysAgo: {
        type: null,
    },
    isInputDaysAgoDisabled: {
        type: Boolean,
        default: false,
    },
},
emits: ['vModelInputDaysAgo'],
computed: {
    compPropsVModelInputDaysAgo: {
        get() {
            console.log('get.compPropsVModelInputDaysAgo:', this.vModelInputDaysAgo);
            return this.vModelInputDaysAgo;
        },
        set(value) {
            console.log('set.compPropsVModelInputDaysAgo:', value);
            this.$emit('update:vModelInputDaysAgo', value);
        },
    },
},
methods: {
    onInputDaysAgoChanged(evt) {
        const msg = JSON.stringify({ msg: verboseTag + 'onInputDaysAgoChanged():', evt:evt, typeOfevt:typeof evt });
        console.log(msg);
        if (parseInt(evt) < 4) {
            evt = '4';
        }
        this.compPropsVModelInputDaysAgo = evt;
        this.$forceUpdate()
    },
},
};
</script>

<style>
</style>

代码:应用程序版本

<template>
  <div id="app">
   <div class="hello">
     <GUIEpochAgo
        v-model:vModelInputDaysAgo="vModelInputDaysAgo"
    ></GUIEpochAgo>
  </div>
  </div>
</template>

<script>
import GUIEpochAgo from './components/GUIEpochAgo.vue'

export default {
  name: 'App',
  data() {
    return {
      vModelInputDaysAgo: null,
    };
  },
  components: {
    GUIEpochAgo
  },
  watch: {
    vModelInputDaysAgo(newVal, oldVal) {
      if (isFinite(newVal)) {
          const newValAsFloat = parseFloat(newVal);
          if (newValAsFloat < 4) {
              this.vModelInputDaysAgo = '4';
          } else {
              this.vModelInputDaysAgo = newVal;
          }
      } else {
          this.vModelInputDaysAgo = 4;
      }
    },
  },
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

3pmvbmvn

3pmvbmvn1#

双向绑定以一种优化的方式工作,正如问题所示,它不包括在发出prop的同时通过prop提供更改值的情况。调试将显示input元素接收到新的prop,但没有更新,因为它没有被渲染器标记为已更改。
组件负责自己的验证是合理的,因此值可以限制在输入组件内。这要求它具有与父状态同步的内部状态:

<input
    type="input"
    v-model="value"
    :disabled="isInputDaysAgoDisabled"
/>

...

  data() {
    return {
      value: null,
    };
  },
  watch: {
    value: {
      immediate: true,
      handler(newVal) {
        this.compPropsVModelInputDaysAgo = this.value = Math.max(parseInt(newVal) || 0, 4);
      }
    },
    compPropsVModelInputDaysAgo: {
      immediate: true,
      handler(newVal) {
        this.value = Math.max(parseInt(newVal) || 0, 4);
      }
    },    
  }

字符串
两个观察者相互依赖需要覆盖所有可能导致递归的情况,比如不一致的'4'字符串和4数字值。

相关问题