vue 如何在迴圈中 "監聽" 的繫結v-model資料

龍恩0707發表於2018-08-07

vue 如何在迴圈中 "監聽" 的繫結v-model資料

閱讀目錄

1.普通屬性的值進行監聽

vue中提供了一個watch方法,它用於觀察vue實列上的資料變動,來響應資料的變化。

下面我們來分別學習下使用watch對物件的屬性值進行監聽,有如下幾種,普通屬性的監聽,物件的屬性值的監聽。最後一種就是對input中的v-modle的動態陣列的資料屬性進行監聽,最後一種不是使用watch來監聽,本文的重點是最後一種的實現。在專案中會經常碰到使用v-model監聽資料的。

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      ul,li {list-style: none;}
      .list {float: left; width:200px;}
      button {float:left; margin-top:18px;}
    </style>
  </head>
  <body>
    <div id="app">
      <div style="width:100%;overflow:hidden;">
        <input type="text" v-model="count" />
      </div>
    </div>
  </body>
  <script src="https://tugenhua0707.github.io/vue/vue-watch/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        count: 1
      },
      watch: {
        count(newValue, oldValue) {
          console.log('新輸入的值為:'+newValue); // 會輸出新值
          console.log('原來的值為:'+oldValue); // 會輸出舊值
        }
      }
    })
  </script>
</html>

檢視效果-看控制檯訊息

2.監聽物件的變化

 如下程式碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      ul,li {list-style: none;}
      .list {float: left; width:200px;}
      button {float:left; margin-top:18px;}
    </style>
  </head>
  <body>
    <div id="app">
      <div style="width:100%;overflow:hidden;">
        <input type="text" v-model="tform.count" />
      </div>
    </div>
  </body>
  <script src="https://tugenhua0707.github.io/vue/vue-watch/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        tform: {
          count: 1
        }
      },
      watch: {
        tform: {
          handler(newValue, oldValue) {
            // newValue 和 oldValue 是一樣的
            console.log(newValue); 
            console.log(oldValue);
          },
          // 深度監聽 監聽物件,陣列的變化
          deep: true
        }
      }
    })
  </script>
</html>

檢視效果-看控制檯訊息

3.監聽物件中具體屬性值的變化

 如下程式碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      ul,li {list-style: none;}
      .list {float: left; width:200px;}
      button {float:left; margin-top:18px;}
    </style>
  </head>
  <body>
    <div id="app">
      <div style="width:100%;overflow:hidden;">
        <input type="text" v-model="tform.count" />
      </div>
    </div>
  </body>
  <script src="https://tugenhua0707.github.io/vue/vue-watch/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        tform: {
          count: ''
        }
      },
      watch: {
        'tform.count': {
          handler(newValue, oldValue) {
            console.log('變動之前的值:' + oldValue);
            console.log('變動後的值:'+ newValue); 
          },
          // 深度監聽 監聽物件,陣列的變化
          deep: true
        }
      }
    })
  </script>
</html>

檢視效果-看控制檯訊息

3.2 第二種方法 可以藉助 computed 如下程式碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      ul,li {list-style: none;}
      .list {float: left; width:200px;}
      button {float:left; margin-top:18px;}
    </style>
  </head>
  <body>
    <div id="app">
      <div style="width:100%;overflow:hidden;">
        <input type="text" v-model="tform.count" />
      </div>
    </div>
  </body>
  <script src="https://tugenhua0707.github.io/vue/vue-watch/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        tform: {
          count: ''
        }
      },
      computed: {
        newNum: function() {
          return this.tform.count;
        }
      },
      watch: {
        newNum: {
          handler(newVal, oldVal) {
            console.log('新值:' +newVal);
            console.log('原來的值:' +oldVal);
          },
          deep: true
        }
      }
    })
  </script>
</html>

檢視效果-看控制檯訊息

4.vue 如何在迴圈中 "監聽" 的繫結v-model資料

 現在有這麼一個需求,頁面上有多項輸入框,但是具體有多少項,我也不知道,它是通過"新增一項"按鈕點選事件,點選一下,就新增一項;如下圖這個樣子;

程式碼如下:

<ul class="list">
  <li>
    <label>第1項</label>
    <input type="text" v-model="item1" />
  </li>
  <li>
    <label>第2項</label>
    <input type="text" v-model="item2" />
  </li>
</ul>

我希望的是,如上程式碼 v-model="item1", item2, 依次類推 ... item(n);

然後會對input的輸入框值進行監聽,比如有這麼一個需求,如果輸入框的值小於0的話,讓input輸入框自動變為0,也就是說輸入框最小值為0,且為數字。

如果上面的 item1 和 item2 只有兩項的話,那麼我們可以使用watch來監聽 item1 和 item2屬性,但是如果頁面上有多項的話,這樣就不好使用watch來監聽資料了。所以我們可以換一種方式來監聽,使用input事件來監聽輸入框值的變化了。如下程式碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      ul,li {list-style: none;}
      .list {float: left; width:200px;}
      button {float:left; margin-top:18px;}
    </style>
  </head>
  <body>
    <div id="app">
      <div style="width:100%;overflow:hidden;">
        <ul class="list">
          <li v-for="(item, index) in arrs">
            <label>第{{index+1}}項</label>
            <input type="number" v-model="item.customItem" @input="changeFunc(item, index)"/>
          </li>
        </ul>
        <button @click="newadd">新增一項</button>
      </div>
    </div>
  </body>
  <script src="https://tugenhua0707.github.io/vue/vue-watch/vue.js"></script>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        count: 1,
        arrs: [{'value': 1, 'customItem': ''}]
      },
      methods: {
        newadd() {
          this.count++;
          this.arrs.push({'customItem': '', 'value': this.count});
        },
        changeFunc(item, index) {
          this.arrs[index].customItem = item.customItem;
          this.watchVal();
        },
        // 監聽值的變化
        watchVal() {
          const arrs = this.arrs;
          if (arrs.length > 0) {
            for (let i = 0; i < arrs.length; i++) {
              let customItem = arrs[i].customItem;
              if (customItem * 1 < 0) {
                this.$set(this.arrs[i], 'customItem', 0);
              }
            }
          }
        }
      }
    })
  </script>
</html>

檢視效果-看控制檯訊息

相關文章