相关文章推荐
想出国的大象  ·  vue ...·  1 月前    · 
无聊的莴苣  ·  Vue 中 $set() 与 ...·  4 周前    · 
坚韧的跑步鞋  ·  Layui ...·  3 周前    · 
挂过科的镜子  ·  VUE 使用 select ...·  3 周前    · 
安静的麻辣香锅  ·  js ...·  1 年前    · 
独立的椰子  ·  python ...·  1 年前    · 
computed 2

computed通过this.message调用vue里data中的message值后乘以2(this 指向 app 实例), getMessage方法renturn的结果,在模版引擎中通过{{getMessage}}调用显示
在这里,getMessage函数被声明成app的一个getMessage属性,在控制台输出 app.getMessage 得到的结果是2,在控制台中我们输入

app.message = 2;
consoe.log(app.getMessage) //4

computed里的getMessage的值受app.message影响

computed和methods对比

以上计算属性,在methods中同样可以实现;

<div id="app">
    {{message}}
   <div>methods  {{getMessage()}}</div>
</div>
var app = new Vue({
      el: '#app',
      data: {
          message: 1,
      methods: {
          getMessage: function(){
              return this.message * 2;

同样浏览器显示结果为

methods 2

既然得到的结果都一样,那么这两个到底有什么区别呢,为什么要使用 computed? 带着这个疑惑,我们去详细分析。

计算属性是基于它们的响应式依赖进行缓存的

也就是说在computed中,getMessage的值是根据data中的message去相应变化的,如果在getMessage没有去调用data中的message,那么getMessage将不会再计算,官方🌰

computed: {
  now: function () {
    return Date.now()

无论我们调用now多少次,始终都是第一次计算的时间,因为Date.now()是不基于响应式的,我们将官网的例子改一下

computed: {
  now: function () {
    console.log(this.message);
    return Date.now()

不加任何返回只是打印了message,我们在浏览器控制台对 app.message做更改,

app.message = 2;

这时,发现了now的值也进行的更新,这说明只要在computed中添加message的内容,就和computed建立了响应式关系,当app.message更新时,now也会进行更新,对应的缓存方法now也进行了更新。为了进行减少性能的开销,避免重复调用getter方法,我们尽量使用computed缓存,如果不需要缓存,直接在methods使用方法就好了。

computed和watch

vue中提供watch来监听vue实例的属性变化,那么它和computed有什么不同呢?

首先我们先看一个例子

 var app = new Vue({
    el: '#app',
    data: {
        firstName: {
            a: 'Foo'
        lastName: 'Bar',
        fullName: 'Foo Bar'
    computed: {
        first(){
            return this.firstName;
        full(){
            return this.firstName.a +' '+this.lastName
    watch: {
        firstName: function (val) {
            this.fullName = val.a + ' ' + this.lastName
        lastName: function (val) {
            this.fullName = this.firstName.a + ' ' + val

分别定义了watch和computed,data里定义了firstName lastName fullName,注意,这里的firstName是一个对象,包含子属性a,

<div id="app">
  <div>data.firestName - firstName {{firstName.a}}</div>
  <div>watch - fullName {{fullName}}</div>
  <div>computed - {{first.a}}</div>
  <div>computed - {{full}}</div>
</div>

默认浏览器显示

data.firestName - firstName Foo
watch - fullName Foo Bar
computed - Foo
computed - Foo Bar

此时,我们在浏览器控制台输入app.firstName.a ='hello',得到结果如下:

data.firestName - firstName hello
watch - fullName Foo Bar
computed - hello
computed - hello Bar

我们发现watch中监控的firstNam并没有起到作用,fullname值并没有更新,难道watch不能使用?这时我又尝试在浏览器输入app.lastName = 'word',得到结果却更新了:

data.firestName - firstName hello
watch - fullName hello word
computed - hello
computed - hello word

computed和watch对比结论

1. watch不能对对象属性深层次的监听,watch如果需要实现深度监听,需要添加选项deep:true(默认是false)

2. watch可以不return,可以直接设置data值,computed需要return去调用值

3. computed默认只有getter方法,如果需要对computed进行赋值,需要我们自己去定义setter方法,否则浏览器会报错

4. watch还可以根据某个属性变化去执行异步操作,调用其他库的方法,这种在computed中是无法实现

computed setter定义的方式(这里直接抄官网的例子了)

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
复制代码
分类:
前端
标签: