Vue--watch(监视属性)

Vue--watch(监视属性),第1张

监视属性目录 天气案例注意:监视属性(watch)深度监视简写形式监视属性和计算属性的区别


天气案例

要求:点击按钮后改变天气,并且后台输出的也改变。

先自己做一下,用的很简单的methods

<div id="btnDemo">
    <h1>今天天气很{{weather}}</h1><br>
    <button @click="changeWeather()">切换天气</button>
</div>

<script type="text/javascript">
    const vm = new Vue({
      el:'#btnDemo',
      data: {
        weather: '凉爽'
      },
      methods: {
          changeWeather() {
            if(this.weather == '凉爽') {
                var fore = '凉爽';
                this.weather = '炎热';
                console.log("天气变化了,现在是:" + this.weather + ",原来是" + fore);
            } else if(this.weather == '炎热') {
                var fore = '炎热';
                this.weather = '凉爽';
                console.log("天气变化了,现在是:" + this.weather + ",原来是" + fore);
            }
          },
      }
    })
</script>

注意:

1.如果没用到vue,那么vue-devtools就不更新数据了(就算data那些数据改变了,vue-devtools也看不到)
2.当div绑定vm的时候,不管什么都会都vm实例中找,所以里面的@click="alert(1)"会报错,因为不会到除了vm的找(alert在windows)


监视属性(watch)
//事实上也是围绕data来进行改变,因为data一变,就会重新加载,从而实现动态变化。
<div id="btnDemo">
    <h1>今天天气很{{info}}</h1><br>
    <button @click="changeWeather()">切换天气</button>
</div>

<script type="text/javascript">
    Vue.config.productionTip = false;
    //当vm创建时候知道自己需要监视的时候,写进去
    const vm = new Vue({
      el:'#btnDemo',
      data: {
        isHot: true
      },
      methods: {
        changeWeather() {
            this.isHot = !this.isHot;
        }
      },
      computed: {
        info() {
            return this.isHot ? '炎热' : '凉爽';
        },
      },
      watch: {
        isHot: {
            immediate: true,	//初始化的时候就调用,也就是一进去就调用
            handler(newValue, oldValue) {
                console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') + 
                ",原来是" + (oldValue ? '炎热' : '凉爽'));
            }
        }
      }
    })
    
    //后续业务需求的时候,在外面写
    /*vm.$watch('isHot', {
        immediate: true,	//初始化的时候就调用,也就是一进去就调用
        handler(newValue, oldValue) {	
            console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') + 
            ",原来是" + (oldValue ? '炎热' : '凉爽'));
        }
    })*/
</script>

注意:
1.不仅可以监视属性,也可以监视计算属性(computed)。
2.监视不存在的属性,虽然不会报错,但是没有意义。


深度监视

1.当检视的属性的value是对象的时候({}),这时候监视的是它的地址值,而不是里面的对象属性。虽然可以直接将对象重新赋值,但是显然没有接下来的好用。
2.深度监视开启的话,对象内的属性变化也算是这个对象的值变化。
3.Vue默认可以监测到不管多里面的属性,如numbers.a.b…,但是watch不行,所以要把deep设置为true。

<div id="btnDemo">
    <button @click="numbers.a++">a加1,现在的a{{numbers.a}}</button><br>
    <button @click="numbers.b++">b加1,现在的b{{numbers.b}}</button>
</div>

<script type="text/javascript">
    Vue.config.productionTip = false;
    const vm = new Vue({
      el:'#btnDemo',
      data: {
        numbers: {
            a: 1,
            b: 2
        }
      },
      watch: {
        //监视多级结构中某个属性的变化
        'numbers.a': {
            handler() {
                console.log("某个值改变了")
            }
        },
        //监视对象内部值改变
        numbers: {
            deep: true,
            handler() {
                console.log("不管哪个值变了,我都变了");
            }
        }
      }
    })
</script>


简写形式

要想简写,那么就只有handler,也就是没有immediate、deep以及其他。

//平常写法
/*isHot: {
    immediate: true,
    deep: true,
    handler(newValue, oldValue) {
        console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') + 
        ",原来是" + (oldValue ? '炎热' : '凉爽'));
    }
}*/
//简写
isHot(newValue, oldValue) {
    console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') + 
        ",原来是" + (oldValue ? '炎热' : '凉爽'));
}

或者

vm.$watch('isHot',function(newValue, oldValue){
    console.log("天气变化,现在是" + (newValue ? '炎热' : '凉爽') + 
        ",原来是" + (oldValue ? '炎热' : '凉爽'));
})

注意:这里还是不能用箭头函数,this还是从vm变成了window


监视属性和计算属性的区别

1.computed可以完成的,watch都能完成。

//computed
computed: {
  fullName(){
    return this.lastName + '-' + this.firstName;
  }
}
//watch
watch: {
  firstName(val){
    this.fullName = this.lastName + '-' + val;
  },
  lastName(val){
    this.fullName = val + '-' + this.firstName;
  }
}

2.watch能完成的功能,computed不一定能完成,如:watch可以进行异步 *** 作,如以下

watch: {
  firstName(val){
    setTimeout(() => {	
    /*1.这里不能写为非箭头函数,
    因为箭头函数没有返回值,
    那么this向外查找才能找到this为vm,
    而如果是function,那么这个this就变成了window
    (定时器指定的回调是由js引擎回调的,并且指定了this就是window)
    2.具体this怎么找的:首先箭头函数没有this,
    向外找到了firstName这个普通函数形式的属性,
    而这个属性又是属于vm的,
    所以this就是vm
    这也就是为什么要写成普通函数的形式,
    因为用到this的时候会用到*/
      this.fullName = this.lastName + '-' + val;
    }, 1000);
  },
  lastName(val){
    this.fullName = val + '-' + this.firstName;
  }
}

但是computed做不到

//错误代码
computed: {
  fullName(){
    setTimeout(() => {
      return this.lastName + '-' + this.firstName;
    }, 1000);
  }
}

这里错误的原因就是return返回给了setTimeout内部的函数,但是并没有返回给fullName,导致fullName没有返回值,从而没法进行修改。

3.不被Vue管理的函数(定时器回调、ajax回调、promise回调),最好写成箭头形式,这样this指向的才是vm或组件实例对象。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1297052.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存