VUE中计算属性(computed)与watch的区别

一般来说,既能用computed 实现又可以用 watch 监听来实现的功能,推荐用 computed,重点在于 computed 的缓存功能

computed计算属性是用来声明式的描述一个值依赖了其它的值,当所依赖的值或者变量改变时,计算属性也会跟着改变;它不能计算在data中已经定义过的变量,但是依赖的值必须是data中存在的值。

计算属性与方法的区别:计算属性是基于依赖(依赖就是data中的数据)进行缓存的,只要data中的数据不发生改变,计算属性中的方法是不需要执行的,一直使用缓存中的数据。而方法不依赖data中的数据,也没有缓存,每次调用都重新执行一遍。

  • 调用methods中的方法的时候 方法每次会重新调用
  • 计算属性方式:当多次调用 reverseString 的时候 只要里面的 num 值不改变,他会把第一次计算的结果直接返回直到data 中的num值改变 计算属性才会重新发生计算 这样如果是比较耗时的功能,没必要每次使用都要重新执行一次,这样会极大地浪费性能
  • 函数的调用时需要加()的 计算属性调用不需要加括号
<div id="app">
     <!--  
        当多次调用 reverseString  的时候 
        只要里面的 num 值不改变 他会把第一次计算的结果直接返回
		直到data 中的num值改变 计算属性才会重新发生计算
     -->
    <div>{{reverseString}}</div>
    <div>{{reverseString}}</div>
     <!-- 调用methods中的方法的时候  他每次会重新调用 -->
    <div>{{reverseMessage()}}</div>
    <div>{{reverseMessage()}}</div>
  </div>
  <script type="text/javascript">
    /*
      计算属性与方法的区别:计算属性是基于依赖进行缓存的,而方法不缓存
    */
    var vm = new Vue({
      el: '#app',
      data: {
        msg: 'Nihao',
        num: 100
      },
      methods: {
        reverseMessage: function(){
          console.log('methods')
          return this.msg.split('').reverse().join('');
        }
      },
      //computed  属性 定义 和 data 已经 methods 平级 
      computed: {
        //  reverseString   这个是我们自己定义的名字 
        reverseString: function(){
          console.log('computed')
          var total = 0;
          //  只有当data 中的 num 的值改变的时候  reverseString  会自动发生计算。否则就使用第一次计算的结果缓存。  
          for(var i=0;i<=this.num;i++){
            total += i;
          }
          // 这里一定要有return 否则 调用 reverseString 的 时候无法拿到结果    
          return total;
        }
      }
    });
  </script>

侦听器 watch(数据一旦发生变化就通知侦听器所绑定的方法)。watch 监听的是已经在 data 中定义的变量,当该变量变化时,会触发 watch 中的方法;

根据一个现有数据去生成一个新数据,并且这两个数据会永久的建立关系,还会建立缓存,当无关数据改变的时候,不会重新计算而是直接使用缓存中的值

  • 使用watch来响应数据的变化
  • 一般用于异步或者开销较大的操作
  • watch 中的属性 一定是data 中 已经存在的数据
  • 当需要监听一个对象的改变时,普通的watch方法无法监听到对象内部属性的改变,只有data中的数据才能够监听到变化,此时就需要deep属性对对象进行深度监听
  • 侦听器的应用场景:处理异步(ajax,定时任务)或开销较大(耗时)的操作
<div>{{Name}}</div>

data(){
	return {
		num:0,
		lastname:'',
		firstname:'',
	}
}
//当num的值发生变化时,就会调用num的方法,方法里面的形参对应的是num的新值和旧值
watch:{
	num:function(val,oldval){
    	console.log(val,oldval);
	}
},
//计算属性computed,计算的是Name依赖的值,它不能计算在data中已经定义过的变量。
computed:{
    Name:function(){
        return this.firstname+this.lastname;// 必须有return
    }
}

vue使用侦听器来禁止用户不间断重复提交(类似于防抖节流操作) 核心是使用Lodash插件中的方法

虽然计算属性在大多数情况下更合适,但有时也需要一个自定义的侦听器。这就是为什么 Vue 通过 watch 选项提供了一个更通用的方法,来响应数据的变化。当需要在数据变化时执行异步或开销较大的操作时,这个方式是最有用的。

<style>
    /* 这个style必须写在这个文件的上面,否则不起效果 */
    [v-cloak] {
      /* 元素隐藏    */
      display: none;
    }
  </style>
<div id="watch-example">
  <p>
    Ask a yes/no question:
    <input v-model="question" />
  </p>
  <p v-cloak>{{ answer }}</p>
</div>
<script src="js/vue.js"></script>
<!-- 因为 AJAX 库和通用工具的生态已经相当丰富,Vue 核心代码没有重复 -->
<!-- 提供这些功能以保持精简。这也可以让你自由选择自己更熟悉的工具。 -->
<script src="https://cdn.jsdelivr.net/npm/axios@0.12.0/dist/axios.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/lodash@4.13.1/lodash.min.js"></script>
<script>
  var watchExampleVM = new Vue({
    el: "#watch-example",
    data: {
      question: "",
      answer: "I cannot give you an answer until you ask a question!"
    },
    watch: {
      // 如果 `question` 发生改变,这个函数就会运行
      question: function(newQuestion, oldQuestion) {
        this.answer = "Waiting for you to stop typing...";
        this.debouncedGetAnswer();
      }
    },
    created: function() {
      // `_.debounce` 是一个通过 Lodash 限制操作频率的函数。
      // 在这个例子中,我们希望限制访问 yesno.wtf/api 的频率
      // AJAX 请求直到用户输入完毕才会发出。想要了解更多关于
      // `_.debounce` 函数 (及其近亲 `_.throttle`) 的知识,
      // 请参考:https://lodash.com/docs#debounce
      this.debouncedGetAnswer = _.debounce(this.getAnswer, 500);
    },
    methods: {
      getAnswer: function() {
        if (this.question.indexOf("?") === -1) {
          this.answer = "Questions usually contain a question mark. ;-)";
          return;
        }
        this.answer = "Thinking...";
        var vm = this;
        axios
          .get("https://yesno.wtf/api")
          .then(function(response) {
            vm.answer = _.capitalize(response.data.answer);
          })
          .catch(function(error) {
            vm.answer = "Error! Could not reach the API. " + error;
          });
      }
    }
  });
</script>


在这个示例中,使用 watch 选项允许我们执行异步操作 (访问一个 API),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。

除了 watch 选项之外,您还可以使用命令式的 vm.$watch API。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值