Vue3 学习 组合式API setup语法糖 响应式 指令 DIFF(一)

news2024/11/15 1:32:57

文章目录

  • 前言
  • 一、Composition Api
  • 二、setup语法糖
  • 三、响应式
    • ref
    • reactive
  • 四、其他一些关键点
    • v-pre
    • v-once
    • v-memo
    • v-cloak
  • 五、虚拟Dom
  • 五、diff算法


前言

本文用于记录学习Vue3的过程


一、Composition Api

我觉得首先VUE3最大的改变就是对于代码书写的改变,从原来选择式API变成现在的组合式API方式,Vue3也是支持选择式的,他能让我们的代码逻辑不再满屏跳转,让代码更具有逻辑性,当然我觉得也更好调试了。

二、setup语法糖

< script setup>  
 是在单文件组件 (SFC) 中使用组合式 API 的编译时语法糖。
 当同时使用 SFC 与组合式 API 时该语法是默认推荐。相比于普通的 <script> 语法,它具有更多优势:
  • 更少的样板内容,更简洁的代码。
  • 能够使用纯 TypeScript 声明 props 和自定义事件。
  • 更好的运行时性能 (其模板会被编译成同一作用域内的渲染函数,避免了渲染上下文代理对象)。
  • 更好的 IDE 类型推导性能 (减少了语言服务器从代码中抽取类型的工作)。

三、响应式

Vue3中响应式是整个框架的核心,要使用响应式就须通过 ref 或者 reactive将常量变为响应式
其中可以搭配下列API简化开发(在之后的文章中介绍)
computed()
readonly()
watchEffect()
watchPostEffect()
watchSyncEffect()
watch()

在进阶响应式还有其他响应式API

ref

ref 可以绑定一些基本数据类型,比如字符串、数字等。ref实际上是通过对象自身value属性的get和set方法来拦截value属性达到响应式的。
所以使用ref定义的数据的时候,都是以 xxx.value来使用。

ref

使用ref也是有好处的,在将其封装到一个对象中的时候,所有的基本数据类型格式都是统一的,在数据传输的时候传输的也是对象地址,而不是值,这保证了数据的统一性。

基本数据类型
ref:
深层次的响应式,一般用来做普通类型的响应式如,除arr\object的数据类型,底层arr和object实现也是走reactive
可以获取dom元素具体使用场景在 组件通讯–>06_ref-children-parent中

isRef:
用来判断某个对象是否为响应式对象 传入参数:变量,返回结果为:boolean

shallowRef:
浅层次的响应式(只会在响应到 xxx.value)
第三方库对象代理不能用proxy时可以用这个
注:不能和ref混用,当两者变量同时出现在template中shallowRef会被影响视图的更新
ref底层调用triggerRefValue–>triggerEffects 使得强制更新收集的依赖,

triggerRef:
强制更新收集的依赖

customRef:
自定义响应式,浅层次的响应式


reactive

reactive:
对类型进行了约束,不能绑定普通数据类型,只能绑定引用类型:Array Object Map Set
reactive proxy不能直接赋值,否则破坏响应式对象
解决:数组 可以push加解构
添加对象将数组当成属性使用

readonly:
用来将其变为只读的
注:与 reactive一起使用时没有作用

shallowReactive
浅层响应式,与shallowRef类似,存在相同的问题和reactive一起使用会影响响应

四、其他一些关键点

v-pre

跳过该标签以及子标签的编译按照原内容显示

<span v-pre>{{ this will not be compiled }}</span>

v-pre

v-once

使用该命令可以让该标签以及子标签只渲染一次,并在未来跳过更新。

<!-- 单个元素 -->
<span v-once>This will never change: {{msg}}</span>
<!-- 带有子元素的元素 -->
<div v-once>
  <h1>comment</h1>
  <p>{{msg}}</p>
</div>
<!-- 组件 -->
<MyComponent v-once :comment="msg" />
<!-- `v-for` 指令 -->
<ul>
  <li v-for="i in list" v-once>{{i}}</li>
</ul>

使用场景:

  • 不需要数据响应式的标签上
<script setup>
import { ref } from 'vue'

const msg = ref('Hello World!')
</script>

<template>
  <h1 v-once>{{ msg }}</h1>
  <input v-model="msg">
</template>

v-once

v-memo

v-memo也具有v-once的功能与v-once不同的是,v-memo可以传 条件,能更好的控制模板的缓存,在其中可以传一个逻辑,也可以传一个变量来控制。

// 当valueA和valueB不变的时候不更新
<div v-memo="[valueA, valueB]">
  ...
</div>
// 当item.id === selected条件成立不更新
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
  <p>ID: {{ item.id }} - selected: {{ item.id === selected }}</p>
  <p>...more child nodes</p>
</div>

值得注意的是如果不传任何东西,效果和v-once一样。

当搭配 v-for 使用 v-memo,确保两者都绑定在同一个元素上。v-memo 不能用在 v-for 内部。

v-cloak

用于隐藏尚未完成编译的 DOM 模板

使用场景

  • 在数据未完全挂载到实例上时,会出现如v-pre指令的原始内容效果的”未编译模板闪现“的情况

搭配 [v-cloak] { display: none } css属性,可以避免这种情况,v-cloak会一直挂载在标签上直到组件编译完成前都隐藏原始模板,最后他会自动移除。

五、虚拟Dom

虚拟Dom的存在大大降低了 操作真实DOM的代价,因为一个真实DOM结点上的属性有很多,通过对虚拟DOM的预操作让真实DOM以最小的代价更新视图。虚拟DOM是JS对象,里面储存了关于结点的信息。

真实DOM属性

<div></div>

真实DOM属性

虚拟DOM结点

<div id="app">
  	<h1>hello world!</h1>
</div>

对应的虚拟DOM为

{
    tagName: 'div',
    props: {
      	id: 'app'
    },
    children: [
      	{
          	tagName: 'h1',
      		props: {},
           	children: ['hello world!']
        }
    ]
}

五、diff算法

diff算法的目的就是用来以最少的代价操作DOM,就是能复用的绝不新建,以最少的移动操作DOM。

Vue3中diff算法相比Vue2来说,有了很大的提升,主要靠他最长增长子序列算法来提升移动Dom代价。


Vue2更新结点的操纵主要有(同级对比,深度优先遍历)

  • 如果新节点有子节点而老节点没有子节点,则判断老节点是否有文本内容,如果有就清空老节点的文本内容,然后为其新增子节点。
  • 如果新节点没有子节点而老节点有子节点,则先删除老节点的子节点,然后设置文本内容。
  • 如果新节点没有子节点,老节点也没有子节点,则进行文本的比对,然后设置文本内容。
  • 如果新节点有子节点,老节点也有子节点,则进行新老子节点的比对,然后进行新增、移动、删除的操作,这就是diff 算法发生的地方。

Vue2中是通过双端对比算法来进行DOM的操作,主要操作有:

  • 头(新)<===>头(旧)
  • 尾(新)<===>尾(旧)
  • 头(旧)<===>尾(新)
  • 尾(新)<===>头(旧)

在比较过程中如果存在相同就移动复用,出现多的或者少的就进行新增和删除操作。

最后对于旧DOM中多的没有比对的就删除,新DOM没有比对的就新增。


Vue3中,分为两种情况,有key和没有key的标识,key也就是标签上的key,大多在使用v-for时,key比较常见。

  • 没有key

没有Key时,,总共分为三步

  •  -    头(新)<----> 头(旧)
     从左到右依次比对,相同就直接复用,一直到不同
     -    尾(新)<----> 尾(旧)
     从右到左依次比对,相同就直接复用,一直到不同
     -  更新和删除操作
     剩余结点如果多了就删除,少了就新增。(删除在前,新增在后)
    

  • 有key

有key时,会经过五步,,其中最重要的为第五步,也是运用了最长递增子序列算法的步骤

    • 前序比较
      从左到右依次比对,相同就直接复用,一直到不同
    • 后序比较
      从右到左依次比对,相同就直接复用,一直到不同
    • 检查新增
      有需要新增则新增
    • 检查删除
      有需要删除则删除
    • 剩余结点数新旧一样 (无序)特殊处理
      • 构建新结点的映射关系
      • 新增或者删除结点
      • move为true求最长递增子序列
        得到移动结点的最小代价,时间复杂度为O(nlogn)
      • 移动不在序列里的结点

最长递增子序列:

// 贪心+二分
function getSequence(arr: number[]): number[] {
  const p = arr.slice() //  保存原始数据
  const result = [0]    //  存储最长增长子序列的索引数组
  let i, j, u, v, c
  const len = arr.length
  for (i = 0; i < len; i++) {
    const arrI = arr[i]
    if (arrI !== 0) {
      j = result[result.length - 1]  //  j是子序列索引最后一项
      if (arr[j] < arrI) {            //  如果arr[i] > arr[j], 当前值比最后一项还大,可以直接push到索引数组(result)中去
        p[i] = j                    //  p记录第i个位置的索引变为j
        result.push(i)
        continue
      }
      u = 0                          //  数组的第一项
      v = result.length - 1          //  数组的最后一项
      while (u < v) {                //  如果arrI <= arr[j] 通过二分查找,将i插入到result对应位置;u和v相等时循环停止
        c = (u + v) >> 1             //  二分查找
        if (arr[result[c]] < arrI) {
          u = c + 1                   //  移动u
        } else {
          v = c                      //  中间的位置大于等于i,v=c
        }
      }
      if (arrI < arr[result[u]]) {
        if (u > 0) {
          p[i] = result[u - 1]         //  记录修改的索引
        }
        result[u] = i                 //  更新索引数组(result)
      }
    }
  }
  u = result.length
  v = result[u - 1]
  //把u值赋给result
  while (u-- > 0) {                 //  最后通过p数组对result数组进行进行修订,取得正确的索引
    result[u] = v
    v = p[v]
  }
  return result
}

所以对于key的运用一定程度上能提升性能。


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

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

相关文章

《自然语言处理》chapter7-预训练语言模型

这是阅读《自然语言处理-基于预训练模型的方法》的学习笔记&#xff0c;记录学习过程&#xff0c;详细的内容请大家购买书籍查阅。 同时参考沐神的两个视频&#xff1a; GPT&#xff0c;GPT-2&#xff0c;GPT-3 论文精读【论文精读】 BERT 论文逐段精读【论文精读】 概述 自然…

如何保证跨境传输的安全性?

随着互联网时代的到来&#xff0c;全球文件传输频率不断增加&#xff0c;市场经济的发展也对信息共享提出更高要求。传统电话交流已无法满足跨国企业的需求&#xff0c;企业内部诸如Web、电子邮件、企业资源计划&#xff08;ERP&#xff09;、网络电话&#xff08;VOIP&#xf…

SAP ABAP 代码调优检查工具及性能调优

一&#xff1a;代码检查工具 ABAP 测试仪表盘(ATC) 所有检查工具, 豁免处理, 结果存储的中心 代码检查器 (SCI) 提供给客户&#xff0c;合作伙伴和SAP的做代码相关检查的开放式架构 扩展程序检查(SLIN) 扩展的代码检查&#xff0c;用来分析源代码 SAP NetWeaver 应用服务器&a…

VMware虚拟机网络连接设置——NAT模式(Windows版)

首先参考VMware虚拟机网络连接设置——仅主机模式&#xff08;Windows版&#xff09;_vmware仅主机模式_Mr.LiuZB的博客-CSDN博客配置&#xff0c;网络还是不通&#xff0c;再结合Linux 虚拟机和主机互通 [万能方法]_linux虚拟机与主机网络连接_核桃胡子的博客-CSDN博客 配置&…

AD域中批量添加域用户

首先在C盘中建立一个文件&#xff0c;名字为file.csv 格式如下 根据CSV文件的ABCDE列来进行识别的 然后我们在cmd命令行中输入一下命令 for /f "tokens1,2,3,4,5 delims," %a in (C:file.csv) do dsadd user "cn%c,ou业务部,ou博迈科技,dcBMKJ,dccom" -s…

Qt应用开发(基础篇)——消息对话框 QMessageBox

一、前言 QMessageBox类继承于QDialog&#xff0c;是一个模式对话框&#xff0c;常用于通知用户或向用户提出问题并接收答案。 对话框QDialog QMessageBox消息框主要由四部分组成&#xff0c;一个主要文本text&#xff0c;用于提醒用户注意某种情况;一个信息文本informativeTex…

linux c编程之“hello world”一

文章目录 hello world开始学习汇编文件 hello.s第1行第2行第3行第4行第5行第6行第7行第8行第9行第10行第11行第12行第13行 X [注]&#xff1a;环境说明&#xff1a; OS&#xff1a;CentOS 7 GCC&#xff1a; 4.8.5 其他环境下的结果可能不尽相同。 声明&#xff1a;本文是我的一…

10年前的显卡 NVIDIA_Quadro_FX_5800

NVIDIA_Quadro_FX_5800 主要参数核心频率610 MHzTurbo频率流处理单元240 个核心架构Tesla 2.0 共71款GPU代号GT200B生产工艺55 nmTDP功耗189W 内存参数内存频率1600 Mbps内存类型GDDR3内存位宽512 bit最大显存4 GB 参数补充晶体管数量1,400 million代工厂TSMC核心面积470 mm二…

python web 开发与 Node.js + Express 创建web服务器入门

目录 1. Node.js Express 框架简介 2 Node.js Express 和 Python 创建web服务器的对比 3 使用 Node.js Express 创建web服务器示例 3.1 Node.js Express 下载安装 3.2 使用Node.js Express 创建 web服务器流程 1. Node.js Express 框架简介 Node.js Express 是一种…

无涯教程-Android Intent Standard Extra Data函数

下表列出了各种重要的Android Intent Standard Extra Data。您可以查看Android官方文档以获取额外数据的完整列表- Sr.NoExtra Data & Description1 EXTRA_ALARM_COUNT 用作AlarmManager intents(意图)中的int Extra字段,以告诉正在调用的应用程序intents(意图)释放了多少…

java八股文面试[多线程]——指令重排序

关于a的操作&#xff0c;由原来的6个指令&#xff0c;变成了4个指令。 1. 指令重排序的介绍 1&#xff09;指令重排序的类型 在执行程序时为了提高性能&#xff0c;编译器和处理器常常会对指令做重排序。 重排序分三种类型&#xff1a;编译器优化的重排序 编译器在不改变单线…

深度分析:如何轻松掌握文件大小管理

大家好&#xff0c;今天我要与大家分享一个实用至极的脚本。简单易用&#xff0c;但效果却让人惊艳。它可以在几秒钟内完成文件大小的统计&#xff0c;并生成一份统计信息。 功能概览 完整性分析&#xff1a;一次性告诉你不同大小区间的文件分布&#xff0c;让你一目了然。 速…

【Unity】常见的角色移动旋转

在Unity 3D游戏引擎中&#xff0c;可以使用不同的方式对物体进行旋转。以下是几种常见的旋转方式&#xff1a; 欧拉角&#xff08;Euler Angles&#xff09;&#xff1a;欧拉角是一种常用的旋转表示方法&#xff0c;通过绕物体的 X、Y 和 Z 轴的旋转角度来描述物体的旋转。在Un…

七、MySQL(DML)如何往表中添加数据?

1、基础语法&#xff1a; &#xff08;1&#xff09;一对一添加数据&#xff1a; 一次只能添加一组数据&#xff0c;可以指定对应字段 insert into 表名 (字段名1,字段名2,……) values (数值1.数值2&#xff0c;……) &#xff08;2&#xff09;给全部字段添加数据&#…

vmware安装centos7虚拟机图文详解

1.打开vmware&#xff0c;点击创建新的虚拟机 2.选择自定义&#xff08;高级&#xff09;&#xff0c;下一步 3.下一步 4.选择稍后安装操作系统 5.操作系统选择linux&#xff0c;版本选择centos7 64位&#xff0c;下一步 6.创建文件夹&#xff0c;选择虚拟机存放的位置&#x…

Exactly Protocol 攻击事件原理分析

Exactly Protocol 攻击事件原理分析 8 月 18 日&#xff0c;Exactly protocol 遭遇黑客攻击&#xff0c;攻击者已获利约 1204 万美元。 安全公司Safful对此事件第一时间进行了技术分析&#xff0c;并总结了安全防范手段&#xff0c;希望后续项目可以引以为戒&#xff0c;共筑区…

企业小件固定资产怎么管理,有什么有效方式?

小件固定资产是指价值较低、使用寿命较短的固定资产&#xff0c;一般用于生产、制造、维修等领域。一些常见的行业中广泛使用小件固定资产&#xff1a;  制造业&#xff1a;小件固定资产在制造业中应用广泛&#xff0c;如机器设备、工具、测量仪器等。  建筑业&#xff1a;…

Spring Boot业务系统如何实现海量数据高效实时搜索

1.概述 我们都知道随着业务系统的发展和使用&#xff0c;数据库存储的业务数据量会越来越大&#xff0c;逐渐成为了业务系统的瓶颈。在阿里巴巴开发手册中也建议&#xff1a;单表行数超过500万行或者单表容量超过2GB才推荐进行分库分表&#xff0c;如果预计三年后数据量根本达…

科创板50etf和科创50etf的区别不同点?一定要看!

很多在交易期权的时候会对科创50ETF期权和科创板50ETF期权标的物选择有疑问&#xff0c;两者与有何区别呢&#xff0c;选择哪个比较合适&#xff0c;别着急&#xff0c;下文为大家介绍科创板50etf和科创50etf的区别不同点&#xff1f;一定要看&#xff01;本文来自&#xff1a;…

谁做的方案,竟把财务数据分析套路都摸透了

来不及计算组合多变又复杂量大的财务数据分析指标&#xff1f;不知道该用哪些财务数据分析方法技巧&#xff1f;不知道怎么把信息量巨大的财务数据分析报表做得易读易理解&#xff1f;别担心&#xff0c;奥威BI数据可视化工具都把套路摸透了&#xff0c;并提出一套系统、标准化…