代码改变世界

vue 如何在循环中 "监听" 的绑定v-model数据

2018-08-07 22:09 by 龙恩0707, ... 阅读, ... 评论, 收藏, 编辑

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>

查看效果-看控制台消息