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

文章目录

  • 前言
  • 一、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, cconst len = arr.lengthfor (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个位置的索引变为jresult.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.lengthv = result[u - 1]//把u值赋给resultwhile (u-- > 0) {                 //  最后通过p数组对result数组进行进行修订,取得正确的索引result[u] = vv = p[v]}return result
}

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


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

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

相关文章

Kafka3.0.0版本——Follower故障处理细节原理

目录 一、服务器信息二、服务器基本信息及相关概念2.1、服务器基本信息2.2、LEO的概念2.3、HW的概念 三、Follower故障处理细节 一、服务器信息 三台服务器 原始服务器名称原始服务器ip节点centos7虚拟机1192.168.136.27broker0centos7虚拟机2192.168.136.28broker1centos7虚拟…

怎样做一个知识库网站

经济和信息技术的蓬勃发展&#xff0c;知识资源成为了企业非常重要的无形资产。 当前&#xff0c;企业的核心竞争力不仅取决于硬件设备、财务实力、资源多寡、人员数量等生产因素&#xff0c;更加取决于企业对于知识的掌握、运用、传承和创新。 制作企业知识库&#xff0c;传…

IDEA快速设置全局JDK

出bug 了 JDK 不识别了&#xff0c;才想起来要设置jdk &#xff0c;现在一般查到的都是setting 设置全局的idea设置。但是老玩家的我怎么会不知道有一个设置全局jdk 的一个设置 setings 设置是对idea 的基础设置。 但是还有一个隐藏页面快捷键【CtrlAltShiftS】 接下来自己研究…

lucene国内镜像 极速下载

文章目录 国内镜像汇总-极速下载【JavaPub版】 lucene国内镜像 https://mirrors.cloud.tencent.com/apache/lucene/ 国内镜像汇总-极速下载【JavaPub版】

在PHP中安装Composer并管理Vue前端依赖包

系列文章目录 文章目录 系列文章目录前言一、安装Composer二、使用Composer管理PHP依赖包三、使用npm管理Vue前端依赖包总结 前言 在开发Web应用程序时&#xff0c;使用Composer来管理PHP的依赖包和Vue前端的依赖包是一种很常见的做法。Composer是PHP的包管理工具&#xff0c;…

JVM内存管理、内存分区:堆、方法区、虚拟机栈、本地方法栈、程序计数器

内存管理 内存分区 线程共享 堆 存放实例&#xff0c;字符串常量&#xff08;直接引用&#xff09;&#xff0c;静态变量&#xff0c;线程分配缓冲区&#xff08;TLAB线程私有&#xff09;。垃圾收集器管理的区域 方法区 非堆&#xff0c;和堆相对的概念。存储已被虚拟机加载的…

java中定时任务 schedule 分布式下没有锁住 时间不同步 执行滞后 相对时间 系统时间 spring springboot

java.util.Timer计时器可以进行&#xff1a;管理任务延迟执行(“如1000ms后执行任务”)&#xff0c;及周期性执行(“如每500ms执行一次该任务”)。 但是&#xff0c;Timer存在一些缺陷&#xff0c;应考虑使用ScheduledThreadPoolExecutor代替&#xff0c;Timer对调度的支持是基…

linux 权限管理命令

权限管理命令 权限的查看及含义 可以使用ls -l来查看每个文件或目录的权限&#xff0c;一共有十位 ls -ls--------------------------------------------------------------------rw-------. 1 root root 946 Feb 14 16:13 anaconda-ks.cfgdrwxr-xr-x. 2 root root 4096 Feb…

互联网摸鱼日报(2023-08-31)

互联网摸鱼日报(2023-08-31) 36氪新闻 融创中期业绩解读&#xff1a;物管、文旅增长态势明显 卓越商企服务公布上半年成绩单&#xff1a;夯实发展基础&#xff0c;高派息回馈股东 让手机连上卫星&#xff0c;到底有多难&#xff1f; 企业数字化转型不要盲目跟风瞎折腾 东方…

Qt 解析XML文件 QXmlStreamReader

如何使用QXmlStreamReader来解析格式良好的XML&#xff0c;Qt的文档中指出&#xff0c;它是一种更快、更方便的Qt自己的SAX解析器&#xff08;QXmlSimpleReader&#xff09;的替代&#xff0c;它也较快&#xff0c;在某种情况下&#xff0c;比DOM&#xff08;QDomDocument&…

c++ | time 小结

通过查看源码分析 namespace std {using ::clock_t; // clock_t x; X clock(); //获取程序跑了多久using ::time_t; // time_t y; y time(NULL); //从纪元开始计算 相当于程序从1970年开始跑// 获取当前时间 time_t current_time; //current_time time(NULL); //或…

【MySQL系列】-ORDER BY……HAVING详解及limit

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

MongoDB实验——在Java应用程序中操作 MongoDB 数据

在Java应用程序中操作 MongoDB 数据 1. 启动MongoDB Shell 2. 切换到admin数据库&#xff0c;使用root账户 3.开启Eclipse&#xff0c;创建Java Project项目&#xff0c;命名为MongoJava File --> New --> Java Project 4.在MongoJava项目下新建包&#xff0c;包名为mo…

Android scrollTo、scrollBy、以及scroller详解 自定义ViewPager

Scroller VelocityTracker VelocityTracker 是一个速度跟踪器&#xff0c;通过用户操作时&#xff08;通常在 View 的 onTouchEvent 方法中&#xff09;传进去一系列的 Event&#xff0c;该类就可以计算出用户手指滑动的速度&#xff0c;开发者可以方便地获取这些参数去做其他…

【期末复习笔记】计算机操作系统

计算机操作系统 进程的描述与控制程序执行进程进程的定义与特征相关概念定义特征进程与程序的区别 进程的基本状态和转换PCBPCB中的信息作用PCB的组织方式 线程进程与线程的比较 处理机调度与死锁处理机调度处理机调度的层次 调度算法处理机调度算法的目标处理机调度算法的共同…

大语言模型之五 谷歌Gemini

近十年来谷歌引领着人工智能方向的发展&#xff0c;从TensorFlow到TPU再到Transformer&#xff0c;都是谷歌在引领着&#xff0c;然而&#xff0c;在大语言模型上&#xff0c;却被ChatGPT&#xff08;OpenAI&#xff09;抢了风头&#xff0c;并且知道GPT-4&#xff08;OpenAI&a…

7.Oracle视图创建与使用

1、视图的创建与使用 在所有进行的SQL语句之中&#xff0c;查询是最复杂的操作&#xff0c;而且查询还和具体的开发要求有关&#xff0c;那么在开发过程之中&#xff0c;程序员完成的并不是是和数据库的所有内容&#xff0c;而更多的是应该考虑到程序的设计结构。可以没有一个项…

854之数据结构

一.线性表 1.顺序表 #include <iostream> #include<stdlib.h> using namespace std; #define max 100 typedef struct {int element[max];int last; } List; typedef int position ; void Insert(int x, position p, List &L) {position q;if (L.last > ma…

关于Vue CLI项目 运行发生了 less-lorder错误的解决方案

Module node found :Error: Can’t resolve ‘less-loader’ 报错 文章目录 Module node found :Error: Cant resolve less-loader 报错解决方案&#xff1a;安装 webpack 和 less安装 less-loader 问题&#xff1a; 在运行vue项目的时候发生&#xff1a; Module not found: Er…

删除无点击数据offer数据分析使用

梳理思路&#xff1a; 1、 获取 7month 和 8month fullreport 报表中 所有offer&#xff1b;输出结果&#xff1a;offerid&#xff0c; totalClickCount&#xff1b; 2、 分析数据7month totalClickCount0 and 8month totalClickCount0 的offer去除&#xff1b; result.…