Vue watch和computed 使用和区别

computed 使用

computed是vue提供的计算属性,它可以像data中的数据一样去使用,只有computed依赖的属性变化的时候,computed才会重新求值。如字面意思一样,如果数据要通过复杂逻辑来得出结果,那么就推荐使用计算属性computed来处理。直接上代码:

<div id="example">
  <p>Original message: "{{ message }}"</p>
  <p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>

var vm = new Vue({
  el: '#example',
  data: {
    message: 'Hello'
  },
  computed: {
    // 计算属性的 getter
    reversedMessage: function () {
      // `this` 指向 vm 实例
      return this.message.split('').reverse().join('')
    }
  }
})

watch使用

watch是Vue 提供的一种更通用的方式来观察和响应 Vue 实例上的数据变动–侦听属性。watch更像是一个data的数据监听回调,可监听data、props和computed中的数据(参数中提供newValue和oldValue)。使用案例的代码如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title></title>
    <script src="lib/vue.min.js"></script>
    <script src="lib/vue-router-3.0.1.js"></script>
  </head>
  <body>
    <div id="app">
      <input type="text" v-model="firstname" />
    </div>
    <script type="text/javascript">
      var vm = new Vue({
        el:"#app",
        data:{
          firstname:"",
          lastname:""
        },
        methods:{},
        watch:{
          firstname:function(newValue,OldValue){
            console.log(newValue);
            console.log(OldValue);
          }
        }
      })
    </script>
  </body>
</html>

两者区别

很多人弄不明watch和computed的区别,不知该何时使用。
computed,计算属性:

  1. 其计算结果会被缓存,只有依赖数据发生改变,才会重新进行计算(当触发重新渲染,若依赖数据没有改变,则computed不会重新计算)。
  2. 不支持异步,当computed内有异步操作时无效,无法监听数据的变化的值。
  3. 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed。
    4.如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。computed中必须return一个值。

watch,监听属性:
4. 不支持缓存,数据变或者触发重新渲染时,直接会触发相应的操作。
2.watch支持异步。
5. 当一个属性发生变化时,需要执行对应的操作;一对多时,一般用watch。
6. 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数,immediate:组件加载立即触发回调函数执行,deep: 深度监听,为了发现对象内部值的变化,复杂类型的数据时使用,例如数组中的对象内容的改变,注意监听数组的变动不需要这么做。注意:deep无法监听到数组的变动和对象的新增,参考vue数组变异,只有以响应式的方式触发才会被监听到。

总结

一个数据依赖于其他几个数据(多个数据影响一个数据,多对一)时用computed;
一个数据变化影响多个数据(一对多)时,用watch。

爬坑(watch监听数组、对象)

watch在监听数组和对象时,有时会有问题。
1.数组
watch能监听到数组的的改变有:
(1)通过赋值的形式改变正在被监听的数组,例如this.watchArr = [1, 2, 3];
(2)通过splice(index,num,val)的形式改变正在被监听的数组;
(3)通过数组的push的形式改变正在被监听的
但是不能检测以下变动的数组:
(1)当你利用索引直接设置一个项时,例如:myVue.demo[1] = 5
(2)当你修改数组的长度时,例如:myVue.demo.length = 2
(3) 你想对数组嵌套对象进行监听的时候,这时就需要深度监听。

(使用vue的set方法,即 this.$set(Object,index,newdata) 。其中Object为你需要改变的数组,index为要改变的数组下标,newdata为新值。这样的话,watch中的监听事件就会被触发。)

2.对象

new Vue({
  data: {
    a: 100,
    msg:{
        channel:'音乐',
        style:'活泼'
    }
  },
  watch: {
    a: function (newval, oldVal) {
      console.log('new: %s, old: %s', newval, oldVal)
    }
  }
})

当你要监听的数据是对象内的某一属性,直接watch对象的属性(例如:msg.channel)就会报错。而监听整个对象的时候(eg:msg)会发现无论何时newval和oldVal的值都是一样的,这是因为msg这个对象的指向并没有发生改变,所以需要深度监测。

watch: {
    msg: {
        handler(newValue, oldValue) {
            console.log(newValue)
        },
        deep: true
    }
}

如果监听对象内的某一具体属性,可以通过computed做中间层来实现

computed: {
    channel() {
        return this.msg.channel
    }
},
watch:{
    channel(newValue, oldValue) {
        console.log( newval, oldVal)
    }
}

3.原因
当前2.几版本的Vue是基于Object.defineProperty来实现数据劫持(数据双向绑定)的,defineProperty存在着对数组和对象的监听问题,个人理解是,watch监听数组和对象的问题正是基于此。感兴趣的朋友可以去仔细了解一下Object.defineProperty。Vue最新3点几的版本要使用proxy来代替Object.defineProperty,原本说19年底发布的Vue3一直难产延期,好在现在已经发布了beat版。


如文中存在什么错误,欢迎大家指正

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值