【问题标题】:When data is changed within the watch function, dom does not update当 watch 函数中的数据发生变化时,dom 不会更新
【发布时间】:2022-01-13 12:27:23
【问题描述】:

下面是组件中的数据

data: function () {
      return {
        sltAreaStyle: {
          paddingTop: "3%",
        },
        checkedTypes: ["krw", "btc", "usdt"],
      };
    },

下面是checkedTypes数据的watch函数

watch: {
      checkedTypes: {
        handler: function (newVal, oldVal) {
          if (newVal.length < 1) {
              alert("Choose one or more.");
              var last = oldVal[0];
              this.$data.checkedTypes = [last];
            
          }
        },
      },
    },

下面是我的html模板

<div class="ckbxArea">
        <input type="checkbox" value="krw" v-model="checkedTypes">KRW</input>
        <input type="checkbox" value="btc" v-model="checkedTypes">BTC</input>
        <input type="checkbox" value="usdt" v-model="checkedTypes">USDT</input>
      </div>

当所有复选框都未选中时,我想将最后一个值更改为 checkedTypes 数据。 如果第一个复选框最终未选中,checkedTypes 将是“krw”,如 checkedTypes = ['krw'] checkedTypes 数据是 ['krw'],但所有复选框标签都未选中。也就是dom没有更新。我认为我不太了解 Vue 的生命周期。我认为这个问题与v-model和组件的生命周期有关,但我不知道问题是什么。请解释为什么会出现这个问题并告诉我如何解决它。

【问题讨论】:

    标签: vue.js v-model


    【解决方案1】:

    这更多是关于 v-modeleld 输入控件的 Vue 渲染机制。

    检查一下:

    1. 只选中最后一个复选框,因此模型值为['krw']
    2. 取消选中最后一个复选框
    3. Watcher 已执行 - 新模型值为 [] 但 watcher 立即将其设置为 与以前相同的值 ... ['krw']
    4. Vue 重新渲染模板(请参阅控制台中的消息)但由于 v-model 值与上次渲染期间相同,它不会更新复选框

    此类情况的简单解决方案是使用nextTick 将更新推迟到下一个渲染周期

    this.$nextTick(() => {
      this.checkedTypes = [last];
    })
    

    new Vue({
      el: "#app",
      data: function () {
        return {
          checkedTypes: ["krw", "btc", "usdt"],
        };
      },
      updated() {
        console.log("Component updated")
      },
      watch: {
        checkedTypes: {      
          handler: function (newVal, oldVal) {
            if (newVal.length < 1) {
              alert("Choose one or more.");
              //console.log("Choose one or more.");
              var last = oldVal[0];
              // this.checkedTypes = [last];
              
              this.$nextTick(() => {
                this.checkedTypes = [last];
              })
            }
          },
        },
      },
    })
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.js"></script>
    <div id="app">
      <input type="checkbox" value="krw" v-model="checkedTypes"/> KRW
      <input type="checkbox" value="btc" v-model="checkedTypes"/> BTC
      <input type="checkbox" value="usdt" v-model="checkedTypes"/> USDT
      
      <pre>{{ checkedTypes }}</pre>
    </div>

    【讨论】:

      猜你喜欢
      • 2016-06-26
      • 2017-11-25
      • 1970-01-01
      • 2022-10-24
      • 1970-01-01
      • 1970-01-01
      • 2015-05-21
      • 2018-07-24
      • 1970-01-01
      相关资源
      最近更新 更多