浅谈Vue3 computed计算属性

news2025/1/11 23:46:20

什么是computed

官方给出的解释:接受一个 getter 函数,返回一个只读的响应式 ref 对象。该 ref 通过 .value 暴露 getter 函数的返回值。它也可以接受一个带有 get 和 set 函数的对象来创建一个可写的 ref 对象

// 只读
function computed<T>(
  getter: () => T,
  debuggerOptions?: DebuggerOptions
): Readonly<Ref<Readonly<T>>>

// 可写的
function computed<T>(
  options: {
    get: () => T
    set: (value: T) => void
  },
  debuggerOptions?: DebuggerOptions
): Ref<T>

从代码上看这么解释毫无破绽,甚至于说人尽可知。但是很少有人知道computed或者想了解其真正有用的几大特性

computed实用特性

1. 依赖追踪

import { reactive, computed } from 'vue'

const state = reactive({
  s1: 1,
  s2: 2
})
const info = computed(() => {
  return state.a + state.b
})

我们定义了一个响应式数据state和一个计算属性info , Vue会自动追踪info 依赖的数据state.s1和state.s2,并建立相应的依赖关系。
也就是只有state.s1和state.s2发生变化的时候,info 才会重新计算,info 都将丝毫不受影响。

2. 缓存
还是上面的例子,如果state.s1和state.s2一直都不再改变值了,那么我们读取info 的时候,它将会返回上一次计算的结果,而不是重新计算。

3. 懒计算

这个特性比较容易被忽略,简单地说只有计算属性真正被使用(读取)的时候才会进行计算,否则咱就仅仅是定义了一个变量而已。

 import { reactive, ref, toRefs , onMounted,watch,computed } from 'vue';

  const state = reactive({
    s1: 1,
    s2: 2
  })

  const info = computed(() => {
    console.log('初始执行计算')
    return state.s1+ state.s2
  })
  
  const handleEdit=(type)=>{
    console.log('step1', info.value)
    state.s1 = 3
    setTimeout(() => {
      // 而是要等到再次读取的时候才会触发重新计算
      console.log('step2', info.value)
    }, 100)
  }

在这里插入图片描述
了解完以上特性后我们回归到问题的本质,尝试构造一个符合以上特性的函数

1. 懒计算
依赖 effect 构造 (effect注册的回调都是立刻执行)

  const info = computed(() => {
    console.log('初始执行计算')
    return state.s1+ state.s2
  })

  //一个基础的effect
  const infoEffect = effect(() => {
    console.log('初始执行计算')// 立刻被打印
    const back = state.s1+ state.s2
    return back
  })
  
  const handleEdit=()=>{
    console.log(infoEffect)
  }

想要实现computed的懒执行,添加一个额外的参数lazy。它要实现的功能是:如果传递了lazy为true,副作用函数将不会立即执行,而是将执行的时机交还给用户,由用户决定啥时候执行
在这里插入图片描述

  //一个基础的effect
  const infoEffect = effect((fn, options = {}) => {
    const effectFn = () => {
      // ... 业务流
      // 新增加的res存储fn执行的结果
      const res = fn()
      // ... 业务流,返回结果
      return res
    }
    // 只有lazy不为true时才会立即执行
    if (!options.lazy) {
      effectFn()
    }
    //返回副作用函数让用户执行
    return effectFn
  })

改造一下

  //一个基础的effect
  const infoEffect = effect(() => {
    console.log('初始执行计算')// 立刻被打印
    const back = state.s1+ state.s2
    return back
  },
    {
      lazy: true
    }
  )
  const handleEdit=()=>{
    console.log(infoEffect())
  }

在这里插入图片描述
2. 依赖追踪

  function computed(getter){
    
    const effectFn = effect(getter, {
      lazy: true,
    })

    const info = {
      get value () {
        return effectFn()
      }
    }

    return info
  }

  const diInfo=computed(()=>{
    console.log('初始执行计算')
    return state.s1 + state.s2
  })
  
  const handleEdit=()=>{
    console.log(diInfo.value);
    state.s2 = 2
    console.log(diInfo.value)
  }

在这里插入图片描述
在这里插入图片描述
看似没有什么问题,但是这违背了computed的缓存特性

1.只有当其依赖的东西发生变化了才需要重新计算
2.否则就返回上一次执行的结果。

为了达成这个效果我们还需要进一步优化一下

  const computed=()=>{
    const effectFn = effect(getter, {
      lazy: true,
      // 数据发生变化后,不执行注册的回调,而是执行scheduler
      scheduler () {
        // 数据发生了变化后,则重新设置为dirty,那么下次就会重新计算
        dirty = true
      }
    })
    let value
    let dirty = true

    const info = {
      get value () {
        // 2. 只有数据发生变化了才去重新计算
        if (dirty) {
          value = effectFn()
          dirty = false
        }

        return value
      }
    }

    return info
  }
scheduler 任务调度的强大,不仅仅可以实现数组的异步批量更新、在computed和watch中也是必不可少的。
  const diInfo=computed(()=>{
    console.log('初始执行计算')
    return state.s1 + state.s2
  })
  
  const handleEdit=()=>{
    console.log(diInfo.value);
    state.s2=4
    console.log(diInfo.value)
  }

在这里插入图片描述
经过以上的各种操作你是否已经对computed有了一定了解呢

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/815634.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

远程控制软件安全吗?一文看懂ToDesk、RayLink、TeamViewer、Splashtop相关安全机制

目录 一、前言 二、远程控制中的安全威胁 三、国内外远控软件安全机制 【ToDesk】 【RayLink】 【Teamviewer】 【Splashtop】 四、安全远控预防 一、前言 近期&#xff0c;远程控制话题再一次引起关注。 据相关新闻报道&#xff0c;不少不法分子利用远程控制软件实施网络诈骗&…

直播预告 | 开源运维工具使用现状以及可持续产品的思考

运维平台自上世纪90年代开始进入中国市场&#xff0c;曾形成以传统四大外企&#xff1a;IBM、BMC、CA、HP为代表的头部厂商&#xff0c;还有一众从网管起家的国内厂商。2010年前后&#xff0c;出现了以Zabbix、Nagios、Cacti为代表的开源工具&#xff0c;后来又陆续出现了Prome…

如何计算文本的困惑度perplexity(ppl)

前言 本文关注在Pytorch中如何计算困惑度&#xff08;ppl&#xff09;为什么能用模型 loss 代表 ppl 如何计算 当给定一个分词后的序列 X ( x 0 , x 1 , … , x t ) X (x_0, x_1, \dots,x_t) X(x0​,x1​,…,xt​), ppl 计算公式为&#xff1a; 其中 p θ ( x i ∣ x &l…

Ansible之playbook剧本编写

一、playbook的相关知识 1.playbook简介 playbook是 一个不同于使用Ansible命令行执行方式的模式&#xff0c;其功能更强大灵活。简单来说&#xff0c;playbook是一个非常简单的配置管理和多主机部署系统&#xff0c;不同于任何已经存在的模式&#xff0c;可作为一个适合部署复…

3.5千伏硅化碳(SiC)深埋式超结二极管

目录 相关知识研究了什么文章创新点研究方法文章的结论 相关知识 在科学和工程技术领域&#xff0c;SEM通常是扫描电子显微镜&#xff08;Scanning Electron Microscope&#xff09;的缩写。因此&#xff0c;在 “外延SEM横截面图” 中&#xff0c;SEM指的是扫描电子显微镜&am…

分享一些精选的开源框架与代码!

今天主要是收集并精选了一些自己所了解和学习过的优秀的嵌入式开源框架代码和项目&#xff0c;不太了解的就不推荐给大家了&#xff0c;因为开源的东西实在是太多了&#xff0c;鱼龙混杂&#xff0c;所以取其精华去其糟粕是迫在眉睫的大事~ 当然也不要总是沉浸在开源的东西之中…

手把手教你Pytest+Allure2.X定制报告详细教程,给自己的项目量身打造一套测试报告-02(非常详细)

简介 俗话说“人靠衣服马靠鞍”一个项目做的在好&#xff0c;没有一分的漂亮的测试报告有时候也是很难在客户那边验收的&#xff0c;今天就带你们解决这一难题。 前边一篇文章是分享如何搭建pytestAllure的环境&#xff0c;从而生成一份精美的、让人耳目一新的测试报告&#…

【Linux 网络】 HTTPS协议原理 对称加密 非对称加密 数字证书

HTTPS协议 HTTPS协议和HTTP协议的区别什么是“加密” 和“解密”加密和解密的小故事 为什么要进行加密&#xff1f;臭名昭著的“运营商劫持”事件 常见加密方式对称加密非对称加密 数据摘要数字签名 HTTPS工作过程探究方案 1 &#xff1a; 只使用对称加密方案2 &#xff1a; 只…

微信小程序交易体验分常见问题指引

小程序交易体验分是为保障小程序用户的交易体验&#xff0c;促进开发者向用户提供更好的服务&#xff0c;帮助开发者更好的评估自身服务水平的机制。平台将对开发者在其小程序的违规行为进行判定&#xff0c;根据违规行为的严重程度对该小程序扣减不同分值的交易体验分&#xf…

Excel快捷键F1-F9详解:掌握实用快捷操作,提升工作效率

Excel是广泛应用于办公场景的优质电子表格软件&#xff0c;然而&#xff0c;许多人只是使用鼠标点击菜单和工具栏来完成操作&#xff0c;而忽略了快捷键的威力。在本文中&#xff0c;我们将详解Excel中的F1-F9快捷键&#xff0c;帮助您掌握实用的快捷操作&#xff0c;提升工作效…

多组学背景下的基因调控网络推断

染色质、转录因子和基因之间的相互作用产生了复杂的调节回路&#xff0c;可以表示为基因调节网络&#xff08;GRNs&#xff09;。GRNs的研究有助于了解疾病中细胞身份是如何建立、维持和破坏的。GRN可以从实验数据——历史上的大量组学数据——或文献中推断出来。单细胞多组学技…

图形化分析工具

1.图形化之短距分析 2.图形化之温度、CPU频率分析 3.常用指令集合 4.常见fastboot指令集合 5.模块之自动化分析–此项功能需要后续不断完善

再下一城丨美格智能座舱模组获头部新势力正式定点

近日&#xff0c;美格智能与国内领先的Tier1厂商密切协作&#xff0c;基于美格车载智能模组打造的智能座舱解决方案&#xff0c;成功获得国内某头部造车新势力的座舱域控制器项目定点&#xff0c;为其打造下一代智能座舱解决方案&#xff0c;创造更加沉浸和智能的座舱体验。 据…

C# Blazor 学习笔记(1):Blazor基础语法,组件化和生命周期

文章目录 前言基础语法路由Page 页面元素条件生成if / elseforforeach 绑定参数绑定(双向)事件绑定字典绑定 attributes 组件化如何使用Parameter 参数注入使用回调函数组件声明回调组件注入回调组件触发回调 直接控制 ref 生命周期App起始阶段&#xff1a;生命周期钩子阶段&am…

【产品文档】产品测试报告模板

今天和大家免费分享产品测试报告的文档模板。产品测试文档是在软件开发或产品开发过程中所编制的文件&#xff0c;用于记录测试计划、测试用例、测试结果和其他与产品测试相关的信息。它是测试团队或测试人员的重要工具&#xff0c;用于指导和管理测试过程&#xff0c;并与开发…

学网络安全,千万别棋差这一招

下午好&#xff0c;我的网工朋友 总感觉今年云计算的热度比网安高上不少&#xff0c;但网络安全在我心里依然是比较有意思的技术方向。 想学的人很多&#xff0c;想入门的人也很多。但找对方向和方法的人&#xff0c;很少很少。 网络安全到底怎么学&#xff1f; 其实入门这…

程序员有周末吗?

目录 一&#xff1a;周末的时间规划 二、提升周末体验感的好方法 三、一些数据 一&#xff1a;周末的时间规划 程序员有周末吗&#xff0c;是不是有的分大小周&#xff0c;好不容易轮到休息了&#xff0c;单位又搞什么团建&#xff0c;美名曰为了大家的健康。你要是为了大家…

高等数学中如何求渐近线

极限是数学中的一个重要概念&#xff0c;它描述了函数在某一点或无穷远处的行为。而渐近线是指函数图像在无穷远处的一条特殊直线&#xff0c;它与函数图像趋于无穷远时的趋势相似。 求渐近线的方法主要有以下几种&#xff1a; 1. 水平渐近线&#xff1a;当函数在无穷远处的极…

JavaScript作用域详解

目录 前言 什么是作用域 作用域类型 全局作用域 局部作用域 块级作用域 ES6之前 ES6以后 作用域链 变量提升 基础概念 优先级问题 闭包 定义 特点 使用场景 封装私有变量 延长变量周期 模块化、命名空间 缓存 ES6的作用域 const、let 块级作用域 变量提…

[css]margin-top不起作用问题(外边距合并)

在初学css时&#xff0c;会遇到突然间margin-top不起作用的情况。如下面&#xff1a; 情况一&#xff1a; 代码&#xff1a; <html> <head><style type"text/css"> * {margin:0;padding:0;border:0; }#outer {width:300px;height:300px;backgroun…