Vue3 —— computed 计算属性及源码学习

news2025/1/17 0:09:35
  • 该文章是在学习 小满vue3 课程的随堂记录
  • 示例均采用 <script setup>,且包含 typescript 的基础用法

前言

本篇文章主要学习 computed基本使用方式简单购物车实战源码理解

一、基本使用

computed 支持两种定义方式:选项式函数式

1、选项式

  • 传入 对象格式,对象内部有 getset 函数
  • 可读可写
<div class="">
  firstName: <input type="text" v-model="firstName" />
  <br />
  lastName: <input type="text" v-model="lastName" />
  <br />
  fullName: {{ fullName }}
  <br />
  <button @click="change">设置fullName</button>
</div>
import { ref, reactive, computed } from "vue";

const firstName = ref<string>("张");
const lastName = ref<string>("三");
const fullName = computed({
  // get 函数用于获取
  get() {
    return firstName.value + "-" + lastName.value;
  },
  // set 函数用于设置
  set(newVal) {
    // 数组的解构赋值
    [firstName.value, lastName.value] = newVal.split("-");
  },
});

const change = () => {
  fullName.value = "李-四";
};

2、 函数形式

  • 只读,只能获取 不能修改
<div class="">
  firstName: <input type="text" v-model="firstName" />
  <br />
  lastName: <input type="text" v-model="lastName" />
  <br />
  fullName2: {{ fullName2 }}
</div>
const fullName2 = computed(() => {
  return firstName.value + "***" + lastName.value;
});

// 这里修改会报错:Cannot assign to 'value' because it is a read-only property
// fullName2.value = "王-五";

二、简单购物车实战

设计一个购物车,可以实现简单的 商品数量增减单种商品总价总计价格购物车搜索 功能

效果如图:

在这里插入图片描述

<div>
  <input
    type="text"
    v-model="keyword"
    placeholder="computed购物车案例——搜索"
    style="width: 400px"
  />
  <br />
  <table
    border
    width="500"
    cellspacing="0"
    cellpadding="0"
    style="margin-top: 10px"
  >
    <thead>
      <tr>
        <th>物品名称</th>
        <th>物品单价</th>
        <th>物品数量</th>
        <th>物品总价</th>
        <th>操作</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(item, index) in searchData" :key="index">
        <td>{{ item.name }}</td>
        <td>{{ item.price }}</td>
        <td>
          <button @click="item.num > 1 ? item.num-- : null">-</button>
          {{ item.num }}
          <button @click="item.num < 99 ? item.num++ : null">+</button>
        </td>
        <!-- 单个商品总价 -->
        <td>{{ item.num * item.price }}</td>
        <td>
          <button @click="del(index)">删除</button>
        </td>
      </tr>
    </tbody>
    <tfoot>
      <tr>
        <td>总价:{{ total }}</td>
      </tr>
    </tfoot>
  </table>
</div>
const keyword = ref<string>("");

interface Data {
  name: string;
  price: number;
  num: number;
}

// 原始数组
const data = reactive<Data[]>([
  {
    name: "小满的绿帽子",
    price: 100,
    num: 1,
  },
  {
    name: "小满的红衣服",
    price: 200,
    num: 1,
  },
  {
    name: "小满的黑袜子",
    price: 300,
    num: 1,
  },
]);

// 总价
const total = computed(() => {
  return data.reduce((pre, cur) => {
    return pre + cur.num * cur.price;
  }, 0);
});

// 删除
const del = (index: number) => {
  data.splice(index, 1);
};

// 搜索数组
const searchData = computed(() => {
  return data.filter((item) => item.name.includes(keyword.value));
});

三、源码学习记录

  • reactivity.cjs.prod.js 中搜索 function computed 即可找到位置
  • computed 使用了 脏值检测原理
  • 以下截图了源码中比较关键的两个函数
    在这里插入图片描述
    在这里插入图片描述

源码学习记录:

/**
 *
 * computed()
 *
 * 1、如果 computed 的第一个参数是函数,说明是只读的传入形式,将参数赋值给 getter, setter为空或在开发环境抛出警告
 *
 * 2、否则则为选项式传参,直接去第一个参数里面读 get 和 set 并赋值
 *
 *
 * ComputedRefImpl
 *
 * 1、这个类是创建 computed 的核心函数
 *
 * 2、_dirty:是否是脏的,是否需要重新计算(脏值检测原理!!),默认是 true(如果值没有发生变化,就会使用缓存中的值)
 *
 * 3、get value() 的写法,可以看出,内部是劫持了 value 属性 (ref)
 *
 *    - toRaw 先将 this 脱离 proxy 代理
 *    - _dirty 若为 true,则需要重新计算
 *
 *          - _dirty 设置为 false(下次不需要再走进来)
 *          - self.effect.run() 读取 return出来值的操作(根据依赖变化后计算出的新值)
 *
 *
 *    - _cacheable 若为 false,即缓存不可用,那肯定也是要走进重新计算的
 *    - 否则直接返回现有的值
 *
 * 4、构造函数 中的 ReactiveEffect,源码中搜索 class ReactiveEffect
 *
 *    - ReactiveEffect(fn, scheduler, scope)
 *    - 跟上一章学习的 effect 是一样的,对其进行扩展,支持了调度(scheduler)
 *          - effect(() => { 依赖函数 })
 *
 * 5、调度函数又是在哪里调用的?  trigger ->  triggerEffect 函数中调用
 *    - 也就是说 当依赖发生变化时,才会调用 scheduler
 *
 * 6、new ReactiveEffect 传入的 scheduler 函数体中会将 _dirty 置为 true(即依赖发生变化时,_dirty置为true)
 *      然后在 get value() 时,走进的就是 run(),即重新获取不读缓存
 *
 * 7、依赖未改变时,_dirty 一直是 false,再次访问就会取老的值,不会重新获取
 *
 */

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

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

相关文章

《安富莱嵌入式周报》第320期:键盘敲击声解码, 军工级boot设计,开源CNC运动控制器,C语言设计笔记,开源GPS车辆跟踪器,一键生成RTOS任务链表

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 视频版&#xff1a; https://www.bilibili.com/video/BV1Cr4y1d7Mp/ 《安富莱嵌入式周报》第320期&#xff1a;键盘敲击…

HASH索引,AVL树,B树,B+树的区别?

1. 什么是 Hash 1.1 Hash 函数 Hash 本身其实是一个函数&#xff0c;又被称为散列函数&#xff0c;它可以大幅提高我们对数据的检索效率。因为它是散列的&#xff0c;所以在存储数据的时候&#xff0c;它也是无序的。 Hash 算法是通过某种确定性的算法(例如MD5&#xff0c;S…

恢复删除的文件,3个宝藏恢复方法分享!

在对电脑的操作过程中误删了文件怎么办&#xff1f;删除的文件还可以恢复吗&#xff1f;快救救孩子吧&#xff01;一大堆重要文件被不小心删除了&#xff0c;真的很无助啊&#xff01;” 在电脑逐渐成为人们工作和生活不可缺少的工具时&#xff0c;存储和删除文件也变得更为方便…

自动化安装系统(二)

利用PXE实现自动化安装 PXE简介 PXE&#xff1a;Preboot Excution Environment&#xff0c;预启动执行环境&#xff0c;是由Intel公司研发&#xff0c;基于Client/Server的网络模式&#xff0c;支持远程主机通过网络从远端服务器下载映像&#xff0c;并由此支持通过网络启动操…

iOS textView支持超链接跳转

将某些文字变成高量可以点击的超链接核心功能代码 attri.addAttribute(NSAttributedString.Key.link, value:NSURL.init(string: "dctt:p/userPrivacy.html")!, range: NSRange.init(location: s.count - 4, length: 4) )textView.linkTextAttributes [NSAttributed…

解密 AI 客服;在不同硬件设备上运行大型语言模型的可能性

&#x1f989; AI新闻 &#x1f680; 微软必应首席执行官称必应聊天优于OpenAI的GPT-4&#xff0c;但成本更高 摘要&#xff1a;微软必应的首席执行官米哈伊尔・帕拉欣表示&#xff0c;必应聊天表现优于OpenAI的GPT-4&#xff0c;但使用了更高成本的检索增强推理技术。必应聊…

C语言的使用技巧--在IO操作中的移位和快速配置

在WB32F103&#xff08;ARM cortex m3内核&#xff0c;96Mhz&#xff09;的gpio初始化中有一段代码&#xff0c;充分的结合了硬件特征并使用C语言的技巧来快速的配置对应的GPIO的功能&#xff0c;堪称经典和楷模&#xff0c;代码异常简洁&#xff0c;执行速度快&#xff0c;配置…

【Qt6】QWindow类可以做什么

原来的水文标题是“用 VS Code 搞 Qt6”&#xff0c;想想还是直接改为“Qt6”&#xff0c;反正这个用不用 VS Code 也能搞。虽然我知道大伙伴们都很讨厌 CMake&#xff0c;但毕竟这厮几乎成了 C 的玩家规范了。Qt 也算识大体&#xff0c;支持用 CMake 来构建程序。所以&#xf…

“心理健康人工智能产学研创新联盟”揭牌成立|深兰科技

8月14日上午&#xff0c;“2023树洞救援年会”在上海举行&#xff0c;会上举行了“心理健康人工智能产学研创新联盟”的签约和揭牌仪式。“树洞行动救援团”创始人深兰科技科学院智能科学首席科学家、荷兰阿姆斯特丹自由大学人工智能系终身教授黄智生&#xff0c;深兰科技集团创…

ElementUI 树形表格的使用以及表单嵌套树形表格的校验问题等汇总

目录 一、树形表格如何添加序号体现层级关系 二、树形表格展开收缩图标位置放置&#xff0c;设置指定列 三、表单嵌套树形表格的校验问题以及如何给校验rules传参 普通表格绑定如下&#xff1a;这种方法只能校验表格的第一层&#xff0c;树形需要递归设置子级节点prop。 树…

RFID如何在汽车混流生产中进行车辆跟踪?

在汽车混流生产中&#xff0c;RFID技术可以对每个车辆进行唯一标识&#xff0c;从而实现车辆生产全程跟踪。实时确定车辆的位置、状态和生产过程&#xff0c;生产管理系统就能够对生产流程进行实时监控和管理&#xff0c;及时发现和解决问题&#xff0c;提高生产效率和质量。 焊…

SpringBoot之HandlerInterceptor拦截器的使用

&#x1f600;前言 本篇博文是关于拦截器-HandlerInterceptor的使用&#xff0c;希望你能够喜欢 &#x1f3e0;个人主页&#xff1a;晨犀主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是晨犀&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动…

对发卡涡(Hairpin vortex)初步认识

对发卡涡&#xff08;Hairpin vortex&#xff09;初步认识 Hairpin vortex是一种在流体动力学中常见的涡旋结构。它通常形成在流体中的强烈剪切区域&#xff0c;例如在河流、管道或飞机翼等流体流动中。Hairpin vortex的形状类似于一个发夹弯曲的形状&#xff0c;因此得名&…

(7)(7.1) 使用航点和事件规划任务

文章目录 前言 7.1.1 设置Home位置 7.1.2 视频&#xff1a;制作并保存多路点任务 7.1.3 视频&#xff1a;加载已保存的多航点任务 7.1.4 使用说明 7.1.5 提示 7.1.6 自动网格 7.1.7 任务指令 7.1.8 任务结束 7.1.9 任务重置 7.1.10 MIS_OPTIONS 7.1.11 任务再出发 …

【三维重建】【深度学习】【数据集】基于COLMAP制作自己的NeuS(DTU格式)数据集

【三维重建】【深度学习】【数据集】基于COLMAP制作自己的NeuS(DTU格式)数据集 提示:最近开始在【三维重建】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【三维重建】【深度学习】【数据集】基于COLMAP制作自己的NeuS(DTU格式)数据集前言下载…

浅析3D打印技术

目录 1.3D打印的概念 2.3D打印的发展过程 3.3D打印的应用领域 4.3D打印带来的技术变革 1.3D打印的概念 3D打印是一种制造技术&#xff0c;它使用逐层堆叠材料的方式来创建物体。与传统的加工方法相比&#xff0c;3D打印具有很多优势。 在3D打印中&#xff0c;一种叫做CAD&am…

深度解读智能化编码的技术架构与实践案例

向更智能、更兼容演进。 陈高星&#xff5c;演讲者 大家好&#xff0c;我是阿里云视频云的陈高星&#xff0c;今天和大家分享的主题是“多”维演进&#xff1a;智能化编码架构的研究与实践。 本次分享分为四部分&#xff1a;首先是视频编码与增强方向的业界趋势&#xff0c;其…

Apple Watch 9和Apple Watch 8功能差异对比:预期升级浅析

每年的这个时候,我们都会想知道Apple Watch Series 9和Apple Watch Series 8之间会有什么不同。随着苹果下一代智能手表预计将于9月上市,我们渴望了解该公司即将进行的升级。 Apple Watch Series 8是目前最好的智能手表,但根据Apple Watch Series 9的改进,它可能会成为我们…

为什么C语言全局变量初始化元素必须是常量,而局部变量可以不是常量

前言 &#xff08;1&#xff09;今天看到一个有意思的问题&#xff0c;在交流群中&#xff0c;一位网友问&#xff0c;全局变量为什么不能给变量。会出现initializer element is not constant报错&#xff0c;代码如下 #include <stdio.h>int a 1; int b a1; //这里会报…

Zabbix-6.4.4 邮箱告警SMS告警配置

目录 ​------------------------- # 邮箱告警 ---------------------------------- 1.安装mailx与postfix软件包 2.修改mailx配置文件 3. 创建文件夹 4. 编写mail-send.sh脚本 5. 将该脚本赋予执行权限 6. 进入web界面进行设置—> Alerts —> Media Types 7. 添…