vue中watch的使用

vue中watch的使用

  vue中的watch是一个比较重要的概念,通过他我们可以检测data的变化,下面进行详细的介绍。

  watch定义方式如下:

{[key: string]: string | Function | Object  }

  即在watch中,

  • 键是一个字符串,它是被观测的对象。
  • 值可以是一个字符串,这个字符串是方法名。
  • 值还可以是一个函数,但不能使用箭头函数的形式,this会出现问题。
  • 值也可以是一个对象,其中包含回调函数可以其他一些选项:比如是否深度遍历。

  举例如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>vue</title>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.3.3/vue.js"></script>
</head>
<body>
    <script>
      var vm = new Vue({
        data: {
          a: 1,
          b: 2,
          c: {
            name: "JohnZhu"
          }
        },
        watch: {
          a: function (val, oldVal) {
            console.log('new a: %s, old a: %s', val, oldVal)
          },
          // 方法名
          b: 'someMethod',

          // 深度 watcher, 检测到变化,并打印出c.name变化前后的结果
          // 'c.name': {
          //   handler: function (val, oldVal) { 
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          //   deep: true
          // },

          // 报错 必须用c.name,否则在data下不能直接找到name
          // name: function () {
          //   console.log('new c: %s, old c: %s', val, oldVal);
          // }

          // 报错,键值必须是一个字符串,所以用引号括起来
          // c.name: {
          //   handler: function (val, oldVal) {
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          //   deep: true
          // }

          // 这里未检测到变化
          // c : {
          //   handler: function (val, oldVal) { 
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          //   deep: false
          // },
         
          // 成功检测到变化 
          // c : {
          //   handler: function (val, oldVal) { 
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          //   deep: true
          // },

          // 检测不到变化,因为参数 deep 的默认值是false
          // c : {
          //   handler: function (val, oldVal) { 
          //     console.log('new c: %s, old c: %s', val, oldVal);
          //   },
          // },
        },
        methods: {
          someMethod: function () {
            alert("b is changed");
          }
        }
      })
      vm.a = 2; // new: 2, old: 1
      vm.b = 666; // alert 666
      vm.c.name = "HTT";
    </script>
</body>
</html>

函数执行之后,分别在控制台中打印出new: 2, old:1 以及 alert 666。 

  • 可以看出, watch函数的参数中,第一个是改变之前的值,第二个是改变之后的值, 这两个参数非常有用。
  • 这里分别使用了 三种定义函数(或option)的方法。
  • 如果要观察data下一个对象的属性,我们可以使用 '对象.属性' 的方式, 注意: 一定要要引号。
  • 如果改变了一个对象的属性,就必须使用 deep: true, 否则检测不到变化。 

举例:

 

这样的一个组件,当我想要同级输入的字数并希望在字数达到一定的数目时,给出提示,就可以watch字数, 即v-model实现,当字数的length改变时,我们判断, 然后给出相应的提示:

最后贴出完整的代码:

<template>
  <div class="add-remark">
    <div class="input">
      <textarea maxlength="50" placeholder="请输入备注,最多50个字哦" v-model="message"></textarea>
      <span class="font-number" >{{message.length}}/50</span>
    </div>
    <div class="hint-content" v-on:click="handleHint($event)">
      <span class="hint">不吃辣</span>
      <span class="hint">少放辣</span>
      <span class="hint">多放辣</span>
      <span class="hint">不吃蒜</span>
      <span class="hint">不吃香菜</span>
      <span class="hint">不吃葱</span>
    </div>
    <div class="btn" v-on:click="goback">完成</div>
  </div>
</template>

<style scoped lang="less">
  @main-color: #51B1B0;
  @sub-color: #eeefef;
  div.add-remark {
    div.input {
      position: relative;
      padding: 0.2rem 0.5rem;
      textarea {
        box-sizing: border-box;
         100%;
        height: 4rem;
        font-size: 0.4rem;
        padding: 0.3rem;
        border: 0.0294rem solid @sub-color;
        &:focus {
          box-shadow: 0 0 0.0417rem @main-color;
        }
      }
      span.font-number {
        position: absolute;
        font-size: 0.4rem;
        color: #aaa;
        bottom: 0.5rem;
        right: 0.7rem;
      }
    }
    div.hint-content {
      padding: 0.2rem;
      span.hint {
        display: inline-block;
        margin: 0.2rem 0.3rem 0.2rem 0.3rem;
        padding: 0.25rem;
        border: 0.02rem solid @sub-color;
        border-radius: 0.1rem;
        &:active {
          background-color: @sub-color;
        }
      }
    }
    div.btn {
       9rem;
      height: 1rem;
      margin: 0.3rem auto;
      line-height: 1rem;
      text-align: center;
      background-color: @main-color;
      font-size: 0.45rem;
      font-weight: bold;
      color: white;
      border-radius: 0.2rem;
    }
  }
</style>

<script>
  export default {
    data () {
      return {
        message: ""
      }
    },
    watch: {
      message: function (val, oldValue) {
        if (val.length == 50) {
          this.$toast("备注最多输入50字哦");
        }
      }
    },
    methods: {
      handleHint: function (e) {
        if (e.target.nodeName.toLowerCase() == "span") {
          this.message += ("  " + e.target.innerHTML )
        }
      },
      goback () {
        this.$router.back();
      }
    }
  }
</script>
View Code

https://cn.vuejs.org/v2/api/#watch

http://www.jianshu.com/p/ffe50c5e3368

http://www.cnblogs.com/dupd/p/5887907.html

https://cn.vuejs.org/v2/guide/computed.html#Computed-属性-vs-Watched-属性、

仰天大笑出门去,我辈岂是蓬蒿人。

原文地址:https://www.cnblogs.com/zhuzhenwei918/p/6921053.html