3. 计算属性(只要是对属性的操作都可以写在计算属性里)和watch

<div id="app">
    {{text}}
    <br>
    <!--将123,456,789变成789,456,123-->
    <!--这种写法太臃肿了,这里的表达式包含 3 个操作,并不是很清晰,所以在遇到复杂的逻辑时应该使用 计算属性-->
    {{text.split(',').reverse().join(',')}}
    <br>
    <!--使用计算属性后的代码-->
    {{reserve}}
</div>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      text: '123,456,789'
    },
    computed: {
      reserve(){
        return this.text.split(',').reverse().join(',')
      }
    }
  })
</script>

所有的计算属性都以函数的形式写在 Vue 实例内的computed 选项内,最终返回计算后的结果。

3.1. 计算属性用法

在一个计算属性里可以完成各种复杂的逻辑,包括运算、函数调用等,只要最终返回一个结果就可以。除了上例简单的用法, 计算属性还可以依赖多个 Vue 实例的数据,只要其中任一数据变化,计算属性就会重新执行,视图也会更新 。
实例 :展示两个购物车的物品总价

  <div id="app">
    {{priceSum}} /*44400-------我是app2里面的内容*/
  </div>
  <script>
    //需求:计算购物车中所有商品的价格
    var app2 = new Vue({
      el: '#aaa',
      data: {
        msg: '我是app2里面的内容'
      }
    })
    var app = new Vue({
      el: '#app',
      data: {
        //当package1和package2里面的数据改变,计算属性里的总价格也会同步改变
        package1: [
          {name: 'iphone',price: 3000,count:2},
          {name: 'ipad',price: 4000,count:3}
        ],
        package2: [
          {name: 'clother',price: 600,count:4},
          {name: 'computer',price: 12000,count:2},
        ]
      },
      computed: {
        priceSum(){
          var price1=0;
          var price2 = 0;
          for(var i =0;i<this.package1.length;i++){
            price1 += this.package1[i].price* this.package1[i].count
          }
          for(var i =0;i<this.package2.length;i++){
            price2 += this.package2[i].price* this.package2[i].count
          }
          return price1 + price2 +'-------'+app2.msg//这里可以通过计算属性访问app2实例里的内容
          //说明了计算属性还可以依赖多个 Vue 实例的数据
        }
      }
    })
  </script>

3.1.1. getter和setter

每一个计算属性都包含-个 getter 和一个 setter,我们上面的两个示例都是计算属性的默认用法 ,只是利用了 getter 来读取。在你需要时,也可以提供一个 setter 函数 , 当手动修改计算属性的值就像修改一个普通数据那样时,就会触发 setter函数,执行一些自定义的操作

  <div id="app">
    {{showName}}
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        firstName: 'wang',
        lastName: 'lifa'
      },
      computed: {
        //如果直接computed里的属性后面的值是function,那么默认就是调用了computed的getter方法
        //showName:function(){
        //  return this.firstName + this.lastName
        //}
        //等价于
        showName: {
          get:function(){
            return this.firstName + this.lastName
          }
        }
      }
    })
  </script>

setter的使用(直接this.computed里的对象名=’你新的值’,也就是你给它赋值的时候直接会调用set方法)

showName: {
  get:function(){
    return this.firstName + ' ' + this.lastName
  },
  set:function(newName){//set方法调用:直接this.showName= 'Wei,linlin'
    //newName是你设置的数据,也就是'Wei,linlin'
    var newName = newName.split(',')
    this.firstName = newName[0]
    this.lastName = newName[1]
  }
}

上面的代码当在页面上写this.showName=’Wei,linlin’的时候,页面上的名字就会从wanglifa变成weilinlin了

3.3. 计算属性缓存

小实例:

<div id="app">
{{reserve}} <br>
计算属性: <br>
{{now}} <br>
<br>
通过methods拿到的时间戳(方法必须加括号): <br>
{{this.now1()}}
</div>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      text: '123,456,789',
      msg:'222'
    },
    computed: {
      reserve: function(){
        return this.text.split(',').reverse().join(',')
      },
      now: function(){
        return Date.now()
      }
    },
    methods: {
      now1:function(){
        return Date.now()
      }
    }
  })
</script>

上面代码运行后页面显示如下:


但是当修改了text的值后,

通过methods方法获取的时间戳的值变了,而计算属性获取的一直没变。
因为上面页面中的{{reserve}}里有对text值的操作,也就是页面中挂载了text,所以当text的值发生改变,页面会重新渲染,而methods里的方法只要页面重新渲染,就会重新执行,所以上面的时间值更新了。

而msg属性页面中并没用到,所以即使它变了,页面也不会去渲染,故methods里的方法没有执行----->>总结:页面中的方法:如果是调用方法,只要页面重新渲染。方法就会重新执行,不需要渲染,则不需要重新执行。


上面代码因为计算属性里的时间戳没有依赖于任何属性,所以不管页面怎么渲染都不会发生变化,而最上面的{{reserve}}里的值,因为是依赖与text属性的,所以当text属性变化,它也会跟着变化----->>>总结:计算属性,不管渲染不渲染,只要计算属性依赖的数据未发生变化,就永远不变。

调用 methods 里的方法也可以与计算属性起到同样的作用。

结论: 没有使用计算属性,在 methods 里定义了一个方法实现了相同的效果,甚至该方法还可以接受参数,使用起来更灵活。既然使用 methods 就可以实现,那么为什么还需要计算属性呢?

原因就是:计算属性是基于它的依赖缓存的。 一个计算属性所依赖的数据发生变化时,它才会重新取值,所以text 只要不改变,计算属性也就不更新。

何时使用: -----------使用计算属性还是 methods 取决于你是否需要缓存,当遍历大数组和做大量计算时,应当使用 计算属性,除非你不希望得到缓存。

data和computed的区别
data函数只会在组件创建的时候运行一次,之后data里数据的改变只是在各个钩子里变化,而computed是只要依赖的数据变了,它就会运行,就会重新改变

watch

一个对象,键是需要观察的表达式,值是对应回调函数(函数里的形参第一个是新值,第二个是旧值)。值也可以是方法名,或者包含选项的对象。Vue 实例将会在实例化时调用 $watch(),遍历 watch 对象的每一个属性。也就是只要你监听的属性改变时,它就会调用它里面的方法

var vm = new Vue({
  data: {
    a: 1,
    b: 2,
    c: 3,
    d: 4,
    e: {
      f: {
        g: 5
      }
    }
  },
  watch: {
    //当a的值变化时,就会调用这个函数
    a: function (val, oldVal) {
      console.log('new: %s, old: %s', val, oldVal)
    },
    // 方法名
    b: 'someMethod',
    // 深度 watcher
    e: {
      //handler这个属性时自带的回调函数名
      handler: function (val, oldVal) { /* ... */ },
      //加上这句后,e这个对象里的任何一个属性值变化,都会执行这个函数
      deep: true
    },
    // 该回调将会在侦听开始之后被立即调用
    d: {
      handler: function (val, oldVal) { /* ... */ },
      immediate: true
    },
    // watch vm.e.f's value: {g: 5}
    'e.f': function (val, oldVal) { /* ... */ }
  }
})

watch对象里的属性会在实例化的时候通过$watch()来调用,也就是

watch:{
    a: function(val,oldVal){
        console.log(val)
    }
}
//上面的代码会在实例运行后自动调用,也就是调用this.$watch所以上面的代码就相当于变成了
this.$watch('a',function(val,oldVal){console.log(val)})
//这时候watch里面的键的函数就变成了这里的回调函数了
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,816评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,729评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,300评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,780评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,890评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,084评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,151评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,912评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,355评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,666评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,809评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,504评论 4 334
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,150评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,882评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,121评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,628评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,724评论 2 351

推荐阅读更多精彩内容