GVKun编程网logo

Vue 的计算属性如何实现缓存?(原理深入揭秘)(vue中的计算属性怎么使用)

20

关于Vue的计算属性如何实现缓存?和原理深入揭秘的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于javascript–在Vue.js中,如何禁用计算属性的缓存?、Vue中的计算属性与侦听属

关于Vue 的计算属性如何实现缓存?原理深入揭秘的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于javascript – 在Vue.js中,如何禁用计算属性的缓存?、Vue 中的计算属性与侦听属性的区别及应用、Vue 中的计算属性,方法,监听器、VUE 组件的计算属性详解等相关知识的信息别忘了在本站进行查找喔。

本文目录一览:

Vue 的计算属性如何实现缓存?(原理深入揭秘)(vue中的计算属性怎么使用)

Vue 的计算属性如何实现缓存?(原理深入揭秘)(vue中的计算属性怎么使用)

前言

很多人提起 Vue 中的 computed,第一反应就是计算属性会缓存,那么它到底是怎么缓存的呢?缓存的到底是什么,什么时候缓存会失效,相信还是有很多人对此很模糊。

本文以 Vue 2.6.11 版本为基础,就深入原理,带你来看看所谓的缓存到底是什么样的。

注意

本文假定你对 Vue 响应式原理已经有了基础的了解,如果对于 WatcherDep和什么是 渲染watcher 等概念还不是很熟悉的话,可以先找一些基础的响应式原理的文章或者教程看一下。视频教程的话推荐黄轶老师的,如果想要看简化实现,也可以先看我写的文章:

手把手带你实现一个最精简的响应式系统来学习Vue的data、computed、watch源码[1]

注意,这篇文章里我也写了 computed 的原理,但是这篇文章里的 computed 是基于 Vue 2.5 版本的,和当前 2.6 版本的变化还是非常大的,可以仅做参考。

示例

按照我的文章惯例,还是以一个最简的示例来演示。

<div id="app">
  <span @click="change">{{sum}}</span>
</div>
<script src="./vue2.6.js"></script>
<script>
  new Vue({
    el"#app",
    data() {
      return {
        count1,
      }
    },
    methods: {
      change() {
        this.count = 2
      },
    },
    computed: {
      sum() {
        return this.count + 1
      },
    },
  })
</script>

这个例子很简单,刚开始页面上显示数字 2,点击数字后变成 3

解析

回顾 watcher 的流程

进入正题,Vue 初次运行时会对 computed 属性做一些初始化处理,首先我们回顾一下 watcher 的概念,它的核心概念是 get 求值,和 update 更新。

  1. 在求值的时候,它会先把自身也就是 watcher 本身赋值给 Dep.target 这个全局变量。

  2. 然后求值的过程中,会读取到响应式属性,那么响应式属性的 dep 就会收集到这个 watcher 作为依赖。

  3. 下次响应式属性更新了,就会从 dep 中找出它收集到的 watcher,触发 watcher.update() 去更新。

所以最关键的就在于,这个 get 到底用来做什么,这个 update 会触发什么样的更新。

在基本的响应式更新视图的流程中,以上概念的 get 求值就是指 Vue 的组件重新渲染的函数,而 update 的时候,其实就是重新调用组件的渲染函数去更新视图。

而 Vue 中很巧妙的一点,就是这套流程也同样适用于 computed 的更新。

初始化 computed

这里先提前剧透一下,Vue 会对 options 中的每个 computed 属性也用 watcher 去包装起来,它的 get 函数显然就是要执行用户定义的求值函数,而 update 则是一个比较复杂的流程,接下来我会详细讲解。

首先在组件初始化的时候,会进入到初始化 computed 的函数

if (opts.computed) { initComputed(vm, opts.computed); }

进入 initComputed 看看

var watchers = vm._computedWatchers = Object.create(null);

// 依次为每个 computed 属性定义
for (const key in computed) {
  const userDef = computed[key]
  watchers[key] = new Watcher(
      vm, // 实例
      getter, // 用户传入的求值函数 sum
      noop, // 回调函数 可以先忽视
      { lazytrue } // 声明 lazy 属性 标记 computed watcher
  )

  // 用户在调用 this.sum 的时候,会发生的事情
  defineComputed(vm, key, userDef)
}

首先定义了一个空的对象,用来存放所有计算属性相关的 watcher,后文我们会把它叫做 计算watcher

然后循环为每个 computed 属性生成了一个 计算watcher

它的形态保留关键属性简化后是这样的:

{
    deps: [],
    dirtytrue,
    getter: ƒ sum(),
    lazytrue,
    valueundefined
}

可以看到它的 value 刚开始是 undefined,lazy 是 true,说明它的值是惰性计算的,只有到真正在模板里去读取它的值后才会计算。

这个 dirty 属性其实是缓存的关键,先记住它。

接下来看看比较关键的 defineComputed,它决定了用户在读取 this.sum 这个计算属性的值后会发生什么,继续简化,排除掉一些不影响流程的逻辑。

Object.defineProperty(target, key, { 
    get() {
        // 从刚刚说过的组件实例上拿到 computed watcher
        const watcher = this._computedWatchers && this._computedWatchers[key]
        if (watcher) {
          // ✨ 注意!这里只有dirty了才会重新求值
          if (watcher.dirty) {
            // 这里会求值 调用 get
            watcher.evaluate()
          }
          // ✨ 这里也是个关键 等会细讲
          if (Dep.target) {
            watcher.depend()
          }
          // 最后返回计算出来的值
          return watcher.value
        }
    }
})

这个函数需要仔细看看,它做了好几件事,我们以初始化的流程来讲解它:

首先 dirty 这个概念代表脏数据,说明这个数据需要重新调用用户传入的 sum 函数来求值了。我们暂且不管更新时候的逻辑,第一次在模板中读取到  {{sum}} 的时候它一定是 true,所以初始化就会经历一次求值。

evaluate () {
  // 调用 get 函数求值
  this.value = this.get()
  // 把 dirty 标记为 false
  this.dirty = false
}

这个函数其实很清晰,它先求值,然后把 dirty 置为 false。

再回头看看我们刚刚那段 Object.defineProperty 的逻辑,

下次没有特殊情况再读取到 sum 的时候,发现 dirty是false了,是不是直接就返回 watcher.value 这个值就可以了,这其实就是计算属性缓存的概念。

更新

初始化的流程讲完了,相信大家也对 dirty缓存 有了个大概的概念(如果没有,再仔细回头看一看)。

接下来就讲更新的流程,细化到本文的例子中,也就是 count 的更新到底是怎么触发 sum 在页面上的变更。

首先回到刚刚提到的 evalute 函数里,也就是读取 sum 时发现是脏数据的时候做的求值操作。

evaluate () {
  // 调用 get 函数求值
  this.value = this.get()
  // 把 dirty 标记为 false
  this.dirty = false
}

Dep.target 变更为 渲染watcher

这里进入 this.get(),首先要明确一点,在模板中读取 {{ sum }} 变量的时候,全局的 Dep.target 应该是 渲染watcher,这里不理解的话可以到我最开始提到的文章里去理解下。

全局的 Dep.target 状态是用一个栈 targetStack 来保存,便于前进和回退 Dep.target,至于什么时候会回退,接下来的函数里就可以看到。

此时的 Dep.target 是 渲染watcher,targetStack 是 [ 渲染watcher ] 。
get () {
  pushTarget(this)
  let value
  const vm = this.vm
  try {
    value = this.getter.call(vm, vm)
  } finally {
    popTarget()
  }
  return value
}

首先刚进去就 pushTarget,也就是把 计算watcher 自身置为 Dep.target,等待收集依赖。

执行完 pushTarget(this) 后,

Dep.target 变更为 计算watcher

此时的 Dep.target 是 计算watcher,targetStack 是 [ 渲染watcher,计算watcher ] 。

getter 函数,上一章的 watcher 形态里已经说明了,其实就是用户传入的 sum 函数。

sum() {
    return this.count + 1
}

这里在执行的时候,读取到了 this.count,注意它是一个响应式的属性,所以冥冥之中它们开始建立了千丝万缕的联系……

这里会触发 countget 劫持,简化一下

// 在闭包中,会保留对于 count 这个 key 所定义的 dep
const dep = new Dep()

// 闭包中也会保留上一次 set 函数所设置的 val
let val

Object.defineProperty(obj, key, {
  getfunction reactiveGetter ({
    const value = val
    // Dep.target 此时就是计算watcher
    if (Dep.target) {
      // 收集依赖
      dep.depend()
    }
    return value
  },
})

那么可以看出,count 会收集 计算watcher 作为依赖,具体怎么收集呢

// dep.depend()
depend () {
  if (Dep.target) {
    Dep.target.addDep(this)
  }
}

其实这里是调用 Dep.target.addDep(this) 去收集,又绕回到 计算watcheraddDep 函数上去了,这其实主要是 Vue 内部做了一些去重的优化。

// watcher 的 addDep函数
addDep (dep: Dep) {
  // 这里做了一系列的去重操作 简化掉 
  
  // 这里会把 count 的 dep 也存在自身的 deps 上
  this.deps.push(dep)
  // 又带着 watcher 自身作为参数
  // 回到 dep 的 addSub 函数了
  dep.addSub(this)
}

又回到 dep 上去了。

class Dep {
  subs = []

  addSub (sub: Watcher) {
    this.subs.push(sub)
  }
}

这样就保存了 计算watcher 作为 count 的 dep 里的依赖了。

经历了这样的一个收集的流程后,此时的一些状态:

sum 的计算watcher

{
    deps: [ count的dep ],
    dirtyfalse// 求值完了 所以是false
    value: 2// 1 + 1 = 2
    getter: ƒ sum(),
    lazytrue
}

count的dep:

{
    subs: [ sum的计算watcher ]
}

可以看出,计算属性的 watcher 和它所依赖的响应式值的 dep,它们之间互相保留了彼此,相依为命。

此时求值结束,回到 计算watchergetter 函数:

get () {
  pushTarget(this)
  let value
  const vm = this.vm
  try {
    value = this.getter.call(vm, vm)
  } finally {
    // 此时执行到这里了
    popTarget()
  }
  return value
}

执行到了 popTarget计算watcher 出栈。

Dep.target 变更为 渲染watcher

此时的 Dep.target 是 渲染watcher,targetStack 是 [ 渲染watcher ] 。

然后函数执行完毕,返回了 2 这个 value,此时对于 sum 属性的 get 访问还没结束。

Object.defineProperty(vm, ''sum'', { 
    get() {
          // 此时函数执行到了这里
          if (Dep.target) {
            watcher.depend()
          }
          return watcher.value
        }
    }
})

此时的 Dep.target 当然是有值的,就是 渲染watcher,所以进入了 watcher.depend() 的逻辑,这一步相当关键

// watcher.depend
depend () {
  let i = this.deps.length
  while (i--) {
    this.deps[i].depend()
  }
}

还记得刚刚的 计算watcher 的形态吗?它的 deps 里保存了 count 的 dep。

也就是说,又会调用 count 上的 dep.depend()

class Dep {
  subs = []
  
  depend () {
    if (Dep.target) {
      Dep.target.addDep(this)
    }
  }
}

这次的 Dep.target 已经是 渲染watcher 了,所以这个 count 的 dep 又会把 渲染watcher 存放进自身的 subs 中。

count的dep:

{
    subs: [ sum的计算watcher,渲染watcher ]
}

那么来到了此题的重点,这时候 count 更新了,是如何去触发视图更新的呢?

再回到 count 的响应式劫持逻辑里去:

// 在闭包中,会保留对于 count 这个 key 所定义的 dep
const dep = new Dep()

// 闭包中也会保留上一次 set 函数所设置的 val
let val

Object.defineProperty(obj, key, {
  setfunction reactiveSetter (newVal{
      val = newVal
      // 触发 count 的 dep 的 notify
      dep.notify()
    }
  })
})

好,这里触发了我们刚刚精心准备的 count 的 dep 的 notify 函数,感觉离成功越来越近了。

class Dep {
  subs = []
  
  notify () {
    for (let i = 0, l = subs.length; i < l; i++) {
      subs[i].update()
    }
  }
}

这里的逻辑就很简单了,把 subs 里保存的 watcher 依次去调用它们的 update 方法,也就是

  1. 调用 计算watcher 的 update
  2. 调用 渲染watcher 的 update

拆解来看。

计算watcher 的 update

update () {
  if (this.lazy) {
    this.dirty = true
  }
}

wtf,就这么一句话…… 没错,就仅仅是把 计算watcherdirty 属性置为 true,静静的等待下次读取即可。

渲染watcher 的 update

这里其实就是调用 vm._update(vm._render()) 这个函数,重新根据 render 函数生成的 vnode 去渲染视图了。

而在 render 的过程中,一定会访问到 sum 这个值,那么又回回到 sum 定义的 get 上:

Object.defineProperty(target, key, { 
    get() {
        const watcher = this._computedWatchers && this._computedWatchers[key]
        if (watcher) {
          // ✨上一步中 dirty 已经置为 true, 所以会重新求值
          if (watcher.dirty) {
            watcher.evaluate()
          }
          if (Dep.target) {
            watcher.depend()
          }
          // 最后返回计算出来的值
          return watcher.value
        }
    }
})

由于上一步中的响应式属性更新,触发了 计算 watcherdirty 更新为 true。所以又会重新调用用户传入的 sum 函数计算出最新的值,页面上自然也就显示出了最新的值。

至此为止,整个计算属性更新的流程就结束了。

缓存生效的情况

根据上面的总结,只有计算属性依赖的响应式值发生更新的时候,才会把 dirty 重置为 true,这样下次读取的时候才会发生真正的计算。

这样的话,假设 sum 函数是一个用户定义的一个比较耗费时间的操作,优化就比较明显了。

<div id="app">
  <span @click="change">{{sum}}</span>
  <span @click="changeOther">{{other}}</span>
</div>
<script src="./vue2.6.js"></script>
<script>
  new Vue({
    el"#app",
    data() {
      return {
        count1,
        other''Hello''
      }
    },
    methods: {
      change() {
        this.count = 2
      },
      changeOther() {
        this.other = ''ssh''
      }
    },
    computed: {
      // 非常耗时的计算属性
      sum() {
        let i = 100000
        while(i > 0) {
            i--
        }
        return this.count + 1
      },
    },
  })
</script>

在这个例子中,other 的值和计算属性没有任何关系,如果 other 的值触发更新的话,就会重新渲染视图,那么会读取到 sum,如果计算属性不做缓存的话,每次都要发生一次很耗费性能的没有必要的计算。

所以,只有在 count 发生变化的时候,sum 才会重新计算,这是一个很巧妙的优化。

总结

2.6 版本计算属性更新的路径是这样的:

  1. 响应式的值 count 更新
  2. 同时通知 computed watcher渲染 watcher 更新
  3. omputed watcher 把 dirty 设置为 true
  4. 视图渲染读取到 computed 的值,由于 dirty 所以 computed watcher 重新求值。

通过本篇文章,相信你可以完全理解计算属性的缓存到底是什么概念,在什么样的情况下才会生效了吧?

❤️感谢大家

1.如果本文对你有帮助,就点个赞支持下吧,你的「赞」是我创作的动力。

2.关注公众号「前端从进阶到入院」即可加我好友,我拉你进「前端进阶交流群」,大家一起共同交流和进步。

参考资料

[1]

手把手带你实现一个最精简的响应式系统来学习Vue的data、computed、watch源码: https://juejin.im/post/5db6433b51882564912fc30f


本文分享自微信公众号 - 前端从进阶到入院(code_with_love)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

javascript – 在Vue.js中,如何禁用计算属性的缓存?

javascript – 在Vue.js中,如何禁用计算属性的缓存?

Before 0.12.8,computed properties behave just like getters – every time you access it,the getter function is re-evaluated. In 0.12.8 this has been improved – computed properties are cached and lazily re-evaluated only when necessary.

对于我当前的项目,我实际上需要在每次访问时重新评估一些属性.当前懒惰评估不起作用的原因是因为在我的一些属性中还有其他“动态变量”不在Vue.js的监视下.

解决方法

根据文档,您可以简单地将缓存设置为false:
computed: {
  example: {
    cache: false,get: function () {
      return Date.Now() + this.msg
    }
  }
}

Vue 中的计算属性与侦听属性的区别及应用

Vue 中的计算属性与侦听属性的区别及应用

vue 是一个前端框架,其灵活性和易用性使其成为了越来越多开发者在前端开发过程中的首选。在 vue 中,计算属性和侦听属性是两种非常重要的属性,它们被广泛用于以数据驱动的开发模式中,本文将介绍这两种属性的区别及其应用。

  1. 计算属性

计算属性是依赖于一个或多个数据值,并通过计算得到新值的属性。在 Vue 的计算属性中,开发者只需要定义一个函数,并在函数中返回计算的结果即可。

比如,在 Vue 的模板中,我们经常需要将两个数据相加并展示其结果,可以这样定义一个计算属性:

1

2

3

4

5

computed: {

  total() {

    return this.num1 + this.num2;

  }

}

登录后复制

上述示例代码中,computed 是 Vue 实例的属性之一,表示计算属性,而 total 是我们自定义的计算属性名称,其中 this.num1 和 this.num2 是两个依赖项。

当 num1 或 num2 发生改变时,Vue 会自动重新计算 total 的值,并将结果展示出来。

立即学习“前端免费学习笔记(深入)”;

另外,当多个模板中需要用到同一种计算时,也可以将其封装成一个可复用的计算属性。

  1. 侦听属性

侦听属性是当一个指定的数据发生变化时,执行一些逻辑的属性。在 Vue 中,开发者可以通过 watch 属性来监听数据的变化。

比如,我们需要监听某个数据是否发生变化,并在变化时触发某些函数,可以这样使用侦听属性:

1

2

3

4

5

watch: {

  targetData(newVal, oldVal) {

    // do something

  }

}

登录后复制

在上述示例代码中,watch 是 Vue 实例的属性之一,表示侦听属性,targetData 是我们需要监听的数据,当其发生变化时,函数中的逻辑代码会被执行。

  1. 区别与应用

在 Vue 中,计算属性和侦听属性都是非常常用且重要的属性。它们的区别在于:

  • 计算属性是基于其依赖项来计算和返回新的值的,而侦听属性则是在数据变化时执行一些逻辑。
  • 计算属性适用于不会频繁发生变化的数据,而侦听属性适用于需要在数据变化时执行一些操作的场景。

对于这两种属性的应用,它们都可以用于实现复杂的业务逻辑,或优化代码的性能等。

比如,对于需要对数据进行复杂计算的场景,可以使用计算属性来提高代码的可读性和易维护性。而在需要根据数据的变化来执行后续操作的场景中,则可以使用侦听属性来实现需求。

总结

计算属性和侦听属性都是 Vue 中非常常用的属性。它们不仅能够实现复杂的业务逻辑,还能够提高代码的可读性和易维护性。在使用时需要根据具体场景来选择使用哪种属性,以达到更好的效果。

以上就是Vue 中的计算属性与侦听属性的区别及应用的详细内容,更多请关注php中文网其它相关文章!

Vue 中的计算属性,方法,监听器

Vue 中的计算属性,方法,监听器

计算属性

什么是计算属性呢,顾名思义就是计算后的属性,来看一段代码

<div id="app">
    {{firstName + '' '' + lastName}}      //这里展示出来的就是计算属性
</div>
let vm = new Vue({
    el:''#app'',
    data:{
        firstName: ''Dell'',
        lastName: ''Lee''
    }
})

从这里可以发现,计算属性是有一些逻辑在里面的,但是我们不想在模版中写复杂的逻辑,模版中只做简单的展示,我们能不能再模版中只做一个简单的展示{{fullName}}

computed

<div id="app">
    {{fullName}}
</div>
let vm = new Vue({
    el:''#app'',
    data:{
        firstName: ''Dell'',
        lastName: ''Lee''
    },
    //计算属性
    computed:{
        fullName(){
            return this.firstName + '' '' + this.lastName        
        }
   }
})

通过computed方法来写计算属性,fullName最后的值完全是通过firstNamelastName计算得来的。

计算属性有个非常重要的知识点,它是内置缓存的,怎么体现这点呢?

<div id="app">
    {{fullName}}
    {{age}}
</div>
let vm = new Vue({
    el:''#app'',
    data:{
        firstName: ''Dell'',
        lastName: ''Lee'',
        age:28
    },
    //计算属性
    computed:{
        fullName(){
            console.log(''计算了一次'')        //更新 age 时,这句话不执行,只有更新 fullName 依赖的值时,这句话才会被执行
            return this.firstName + '' '' + this.lastName        
        }
   }
})

当我更新age时,console.log(''计算了一次'')没有被执行,而当我更新fullName依赖的值firstName或者lastName时,这句话才会被执行。

除了使用计算属性来计算值以外,还可以用一个方法来实现methods

methods

<div id="app">
    {{fullName()}}      //这里调用方法需要加上括号
    {{age}}
</div>
let vm = new Vue({
    el:''#app'',
    data:{
        firstName: ''Dell'',
        lastName: ''Lee'',
        age:28
    },
    //方法
    methods: {
        fullName(){
            console.log(''计算了一次'')        //不管什么数据改变都会执行
            return this.firstName + '' '' + this.lastName
        }
    }
})

用这种方法写代码,其实是不如计算属性来的有效的,因为数据只要发生变化,console.log就会被执行,它内部没有缓存机制。

同样一个功能,用计算属性computed可以实现,用方法methods也可以实现,哪一种方式更好一些能,很显然是用计算属性更好些,因为它有缓存,性能更高

除了用计算属性、方法之外,还有没其他方法可以实现的,

watch

<div id="app">
    {{fullName}}
    {{age}}
</div>
let vm = new Vue({
    el:''#app'',
    data:{
        firstName: ''Dell'',
        lastName: ''Lee'',
        fullName: ''Dell Lee''
        age:28
    },
    //方法
    watch:{
        firstName(){
            console.log(''firstName 改变了,计算一次'')        //更新 age 时,这句话不执行,只有更新 fullName 依赖的值 firstName,这句话才会被执行
            this.fullName = this.firstName + '' '' + this.lastName
        },
        lastName(){
            console.log(''lastName 改变了,计算一次'')        //更新 age 时,这句话不执行,只有更新 fullName 依赖的值 lastName,这句话才会被执行
            this.fullName = this.firstName + '' '' + this.lastName
        }
    }
})

使用watch监听fullName的依赖值,当不是fullName依赖的内容改变时,console.log不会执行,只有当fullName依赖的内容发生改变时,console.log才会被执行。

虽然watch也能实现数据缓存,性能也不错,但相比computed来说,复杂了很多,所以如果一个功能既可以通过computed实现,methods实现,watch实现,优先推荐computed来实现,因为用这种方法写代码,既简洁,性能又不错。计算属性,方法,监听器

VUE 组件的计算属性详解

VUE 组件的计算属性详解

前言

  • 今天也是元气满满的一天,今天整理一下VUE组件的计算属性!~~
  • 开始我们的学习之旅

计算属性

  • 先引用一张图 来看一下计算属性之间的关联:

注意: methods和computed里的东西不能重名

  • method:定义方法,调用方法使用currentTime(),需要带括号
  • computed:定义计算属性,调用属性使用currenTime2,不需要带括号:this.message是为了能够让currentTime2观察到数据变化
  • 如何在方法中的值发生了变化,则缓存就会刷新!可以在控制台使用vm.message="HelloShit!"
 <div id=''app''>
        <audio :src="currentSrc" controls autoplay @ended=''handleEnded''></audio>
        <ul>
            <li :{active:index===currentIndex}'' v-for=''(item,index) in musicData'' :key=''item.id''
                @click=''handleClick(item.songSrc,index)''>
                <h2>{{item.id}}-歌名:{{item.name}}</h2>
                <p>{{item.author}}</p>
            </li>
        </ul>
        <button @click=''handleNext''>下一首</button>
    </div>

    <script src="./vue.js"></script>
    <script>
        const musicData = [{
                id: 1,
                name: ''杨宗纬 - 空白格'',
                author: ''杨宗纬'',
                songSrc: ''杨宗纬 - 空白格 (Live).mp3''
            },
            {
                id: 2,
                name: ''杨宗纬 - 其实都没有'',
                author: ''杨宗纬'',
                songSrc: ''杨宗纬 - 其实都没有.flac''
            },
            {
                id: 3,
                name: ''杨宗纬 - 我想要'',
                author: ''杨宗纬'',
                songSrc: ''杨宗纬 - 我想要 (Live).flac''
            }
        ];

        new Vue({
            el: ''#app'',
            data: {
                musicData,
                currentSrc: ''杨宗纬 - 空白格 (Live).mp3'',
                currentIndex: 0
            },
            methods: {
                handleClick(src, index) {
                    this.currentSrc = src;
                    this.currentIndex = index;
                },
                handleEnded() {
                    // // 下一首的播放
                    // this.currentIndex++;
                    // this.currentSrc = this.musicData[this.currentIndex].songSrc;
                    this.handleNext();
                },
                handleNext() {
                    this.currentIndex++;
                    if (this.currentIndex === this.musicData.length) {
                        this.currentIndex = 0;
                    }
                    this.currentSrc = this.musicData[this.currentIndex].songSrc
                }
            }
        })
    </script>
  • 在methods里定义了一个方法实现了和计算机属性相同的效果,甚至该方法还可以接受参数,使用起来更灵活,既然使用methods就可以实现,那为什么还需要计算机属性呢?原因就是计算机属性是基于它的依赖缓存的。一个计算机属性所依赖的数据发生变化时,它才会重新赋值,所以text只要不改变,计算机属性也就不会更新
  • 这里的Date.now()不是响应式依赖,所以计算机属性now不会更新。但是methods则不同,只要重新渲染,它就会被调用,因此函数也会被执行。

总结

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

到此这篇关于VUE 组件的计算属性详解的文章就介绍到这了,更多相关VUE 组件内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!

您可能感兴趣的文章:
  • Vue.js中的计算属性、监视属性与生命周期详解
  • Vue中监视属性和计算属性区别解析
  • Vue组件的计算属性和普通属性的区别说明

我们今天的关于Vue 的计算属性如何实现缓存?原理深入揭秘的分享已经告一段落,感谢您的关注,如果您想了解更多关于javascript – 在Vue.js中,如何禁用计算属性的缓存?、Vue 中的计算属性与侦听属性的区别及应用、Vue 中的计算属性,方法,监听器、VUE 组件的计算属性详解的相关信息,请在本站查询。

本文标签:

上一篇本科阶段,一门计算机相关课结束后,应该留下些什么?(计算机专业一节课多长时间)

下一篇计算机网络自顶向下方法。第 6 版(初学笔记)(计算机网络自顶向下方法第七版笔记)