【Vue原理解析】之异步与优化
引言
Vue是一款流行的JavaScript框架,它提供了一些强大的特性来提升应用程序的性能和用户体验。在本文中,我们将深入探讨Vue的异步更新机制和一些优化技巧,帮助您更好地理解和应用这些特性。
异步更新机制
Vue使用异步更新机制来提高渲染性能。当数据发生变化时,Vue并不立即重新渲染整个组件树,而是将更新操作推入一个队列中,并在下一个事件循环中执行。这样可以将多个数据变化合并为一个更新操作,减少不必要的重复渲染。
nextTick方法
Vue提供了nextTick方法来处理异步更新。它接受一个回调函数作为参数,在下次DOM更新循环结束后执行该回调函数。这样可以确保在DOM更新完成后再进行一些操作。
<template><div><p>{{ message }}</p><button @click="updateMessage">Update Message</button></div>
</template><script>
export default {data() {return {message: "Hello, Vue!",}},methods: {updateMessage() {this.message = "Updated Message"this.$nextTick(() => {console.log("DOM updated")})},},
}
</script>
$forceUpdate
合理使用$forceUpdate方法来强制组件重新渲染,尤其在某些特殊情况下需要手动触发组件更新时。
<template><div><p>{{ message }}</p><button @click="updateMessage">Update Message</button></div>
</template>
<script>
export default {data() {return {message: "Hello, Vue!",}},methods: {updateMessage() {// 手动修改DOM元素的内容document.querySelector("p").textContent = "Updated Message"// 强制组件重新渲染this.$forceUpdate()},},
}
</script>
在上述代码中,我们定义了一个包含一个按钮的Vue组件。当点击按钮时,会手动修改DOM元素的内容,并通过调用$forceUpdate方法强制组件重新渲染。这样可以确保即使数据没有发生变化,也能强制刷新组件以更新视图。 需要注意的是,在大多数情况下,Vue会自动追踪数据变化并进行相应的更新,不需要手动触发组件更新。只有在特殊情况下(如直接修改DOM元素),才需要使用$forceUpdate方法。 然而,应该谨慎使用$forceUpdate方法,因为它会跳过Vue的优化机制,并可能导致性能下降。只有在确实需要手动触发组件更新时,才应该使用$forceUpdate方法。
$set
<template><div><ul><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul><button @click="addItem">Add Item</button></div>
</template><script>
export default {data() {return {items: [],}},methods: {addItem() {const newItem = { id: Date.now(), name: "New Item" }this.$set(this.items, this.items.length, newItem)},},
}
</script>
在上述代码中,我们定义了一个包含一个按钮的Vue组件。当点击按钮时,会向items数组中添加一个新的项。通过使用this.$set方法,我们可以确保新添加的项是响应式的,并能够触发视图更新。
优化技巧
除了异步更新机制,Vue还提供了一些优化技巧来进一步提升应用程序的性能和用户体验。
列表渲染优化
在列表渲染时,为每个列表项添加唯一的key属性可以帮助Vue更高效地更新DOM。Vue会根据key属性来判断哪些列表项需要更新,哪些需要新增或删除。
<template><ul><li v-for="item in items" :key="item.id">{{ item.name }}</li></ul>
</template><script>
export default {data() {return {items: [{ id: 1, name: "Item 1" },{ id: 2, name: "Item 2" },{ id: 3, name: "Item 3" },],}},
}
</script>
计算属性和侦听器
使用计算属性可以缓存计算结果,避免重复计算。而侦听器可以监听数据的变化,并在变化时执行相应的操作,避免不必要的计算。
<template><div><p>Width: {{ width }}</p><p>Height: {{ height }}</p><p>Area: {{ area }}</p></div>
</template><script>
export default {data() {return {width: 10,height: 5,}},computed: {area() {return this.width * this.height},},watch: {width(newWidth) {console.log("Width changed:", newWidth)},height(newHeight) {console.log("Height changed:", newHeight)},},
}
</script>
合理使用keep-alive
使用keep-alive组件可以缓存组件的状态,避免重复渲染和销毁。特别适用于包含表单输入、列表等需要保留状态的场景。
<template><div><keep-alive><component :is="currentComponent"></component></keep-alive><button @click="toggleComponent">Toggle Component</button></div>
</template><script>
import ComponentA from "./ComponentA.vue"
import ComponentB from "./ComponentB.vue"export default {data() {return {currentComponent: "ComponentA",}},components: {ComponentA,ComponentB,},methods: {toggleComponent() {this.currentComponent =this.currentComponent === "ComponentA" ? "ComponentB" : "ComponentA"},},
}
</script>
懒加载(Lazy Loading)
合理使用懒加载(Lazy Loading)来延迟加载组件或资源,减少初始加载时间
// vue2
const MyComponent = () => import('./MyComponent.vue')// vue3
import { defineAsyncComponent } from 'vue'const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue'))
在上述代码中,我们使用defineAsyncComponent函数来定义异步组件。该函数接受一个返回import()函数的回调作为参数,用于动态导入组件文件。这样,在需要使用AsyncComponent组件时才会进行实际的加载。
与Vue 2不同,Vue 3中的异步组件不再需要通过动态导入返回一个Promise对象。而是直接通过defineAsyncComponent函数来定义异步组件。 需要注意的是,在Vue 3中,异步组件默认会自动进行Suspense处理。可以在父级组件中使用<Suspense>包裹异步组件,并提供一个fallback内容作为加载过程中显示的占位符。
<template><div><Suspense><template #default><AsyncComponent /></template><template #fallback><div>Loading...</div></template></Suspense></div>
</template>
函数式组件(Functional Components)
当使用Vue的函数式组件时,可以通过functional选项来定义一个函数式组件。下面是一个示例,展示了如何使用Vue的函数式组件:
<template functional><div><p>{{ props.message }}</p><button @click="props.onClick">Click me</button></div>
</template>
在上述代码中,我们使用<template functional>来定义一个函数式组件。在函数式组件中,我们可以通过props对象来访问传递给组件的属性。这样可以避免创建响应式数据和实例状态。 需要注意的是,在函数式组件中无法使用data、computed、methods等选项。如果需要计算属性或方法,可以通过传递额外的参数来实现。
<template functional><div><p>{{ computeMessage(props.message) }}</p></div>
</template>
<script>
export default {methods: {computeMessage(message) {return message.toUpperCase()},},
}
</script>
在上述代码中,我们通过传递额外的参数来调用计算属性computeMessage。 通过合理使用函数式组件,我们可以减少不必要的实例化和响应式开销,并提升应用程序的性能。特别适用于那些没有状态或只依赖传入属性的简单组件。 需要注意的是,函数式组件不支持在模板中使用自定义指令和过滤器,并且无法访问Vue实例上的方法和属性。
另:使用虚拟滚动(Virtual Scrolling)或分页加载等技术来处理大量数据列表,避免一次性渲染大量DOM元素。
注意事项
- 避免频繁地使用
$forceUpdate方法,因为它会跳过Vue的优化机制,可能导致性能下降。 - 当使用异步更新机制时,需要注意避免对异步更新的数据进行同步操作,以免引起意外的结果。
- 在使用
v-for渲染大量列表时,尽量避免在每个列表项中使用复杂的计算属性或方法,以减少不必要的计算开销。
总结
在本文中,我们深入探讨了Vue的异步更新机制和一些优化技巧。异步更新机制通过将多个数据变化合并为一个更新操作,提高了渲染性能。而优化技巧如列表渲染优化、计算属性和侦听器、合理使用keep-alive等,进一步提升了应用程序的性能和用户体验。
通过合理应用这些特性和技巧,您可以构建出更高效、更流畅的Vue应用程序。
相关文章:
【Vue原理解析】之异步与优化
引言 Vue是一款流行的JavaScript框架,它提供了一些强大的特性来提升应用程序的性能和用户体验。在本文中,我们将深入探讨Vue的异步更新机制和一些优化技巧,帮助您更好地理解和应用这些特性。 异步更新机制 Vue使用异步更新机制来提高渲染性…...
mybatis、mysql 创建时间(create_time)异常自动更新为当前时间
目录标题 一、问题二、原因三、解决 一、问题 bug: mybatis更新代码没有修改时间,但是时间会自动更新为当前时间。 。。。 被坑了挺久 二、原因 可能是创建表的时候, Navicat Premium 等可视化工具给你整活了。。。 三、解决 取消勾选。 注意&…...
shardingsphere 加载慢 优化
shardingsphere加载慢 优化 原因: 启动速度变慢(元数据扫描耗时较长) 占用内存增多(大量单表和元数据对象) 那是因为默认扫描1张表.一张一张加载巨慢,添加以下配置增加到20张表同时扫描 错误: 如果你数据库最大连接不到20就会报错,请按照数据…...
我这些年对于自动化测试的理解
📢专注于分享软件测试干货内容,欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!📢交流讨论:欢迎加入我们一起学习!📢资源分享:耗时200小时精选的「软件测试」资…...
Java安全架构 JCA、JCE、JSSE、JAAS
Java语言拥有三大特征:平台无关性、网络移动性和安全性,而Java安全体系结构对这三大特征提供了强大的支持和保证, Java安全体系结构总共分为4个部分: (1)JCA( Java Cryptography Architecture…...
面试经典(4/150)删除有序数组中的重复项 II
面试经典(4/150)删除有序数组中的重复项 II 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使得出现次数超过两次的元素只出现两次 , 返回删除后数组的新长度。不要使用额外的数组空间,你必须在 原…...
使用WildCard充值ChatGPT Plus 会员
登录 wildCard官网 基于国内手机号注册账号,使用支付宝验证付款即可自动申请国外银行卡,WildCard的开卡费是9.9美元, 没有后续的月费用.订阅chatgpt plus会员服务的操作图文指南见链接 chatgpt plus会员订阅指南...
element-plus使用el-date-picker组件时,如何禁止用户选择当前时间之后的日时分秒
element-plus使用el-date-picker组件时,如何禁止用户选择当前时间之后的日时分秒 例: 当前时间为2023-11-15 14.24,不能选择这之后的时分秒。(禁止用户选择2023-11-15 14.28) <el-date-pickerv-model"form.s…...
keepalived安装配置(服务器主备、负载均衡)
系统拓扑 安装keepalived 主备服务器上都需要安装 在线安装 yum install -y keepalived 离线安装 # todo 服务器准备 虚拟机ip:192.168.11.56 主服务器:192.168.11.53 备服务器:192.168.11.54 配置文件修改 keepalived安装之后&…...
盘点一款制作电子杂志的网站,小白也能快速上手
电子杂志作为一种时尚、环保、便捷的宣传形式,越来越受到各行各业的青睐。无论是企业宣传、产品推广,还是个人分享,电子杂志都能展现出独特的魅力。而制作电子杂志,不再是专业人士的专属,现在小白也能快速上手&#…...
全域全自主建设,亚信科技AntDB数据库助力广电5G业务上线运行
自2019年6月,中国广电成功获得5G牌照以来,迅速推进网络建设目标,成为5G网络覆盖广、应用场景多、用户体验出色的第四大运营商。其依托全球独有的700MHz频谱资源,具备覆盖能力强、容量足、速率高的优势。通过不断深化和中国移动的共…...
使用 SSH 密钥进行身份验证
使用 SSH 密钥进行身份验证可以提高安全性,并免去每次登录时输入密码的麻烦。以下是使用 SSH 密钥进行身份验证的步骤: 生成密钥对:在本地计算机上生成 SSH 密钥对。打开终端并执行以下命令: ssh-keygen -t rsa -b 4096这将生成…...
国内最受欢迎的电商API接口调用京东商品详情数据
国内实用的API接口 国内最受欢迎的7大API供应平台对比和介绍 本文将介绍7款API供应平台:电商API数据、百度e、Apix、数说聚合、通联数据、HaoService、datasift 。排名不分先后! 免费实用的API接口 第一部分 1、电商数据(API数据接口_开发者…...
windows远程桌面登录ubuntu,黑屏闪退,
首先需要安装xrdp以后才能远程登录,安装命令 sudo apt-get install xrdp 这里需要注意一个问题,如果在ubuntu 本地登录的情况下,windows远程登录会出现黑屏甚至闪退的问题。原因是本地登录和远程登陆是互斥的,本地登录了就不能远…...
12-使用vue2实现todolist待办事项
个人名片: 😊作者简介:一名大二在校生 🤡 个人主页:坠入暮云间x 🐼座右铭:懒惰受到的惩罚不仅仅是自己的失败,还有别人的成功。 🎅**学习目标: 坚持每一次的学习打卡 文章…...
微信小程序授权登录?
wxml <!-- 示例:在wxml中创建一个授权登录按钮 --> <button bindtap"getUserInfo">授权登录</button> js // 用户点击授权登录按钮时触发的事件处理函数getUserInfo: function (e) {wx.getUserProfile({desc: 用于完善会员资料, // 授…...
React 18 + Hooks +Ts 开发中遇到的问题及解决方案!
这篇文章是用来专门记录关于React 18 Hooks Ts 开发中遇到的问题及解决方案 Q1 问题描述: TS7016: Could not find a declaration file for module js-export-excel. /Users/zhangliangliang/WebstormProjects/daizhang-system-front/node_modules/js-export-exc…...
推荐一个非常好用的uniapp的组件库【TMUI3.0】
文章目录 前言官网地址如何使用?注意事项后言 前言 hello world欢迎来到前端的新世界 😜当前文章系列专栏:前端系列文章 🐱👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果…...
LeetCode(19)最后一个单词的长度【数组/字符串】【简单】
目录 1.题目2.答案3.提交结果截图 链接: 58. 最后一个单词的长度 1.题目 给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。 单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。 …...
使用Docker本地安装部署Drawio绘图工具并实现公网访问
目录 前言 1. 使用Docker本地部署Drawio 2. 安装cpolar内网穿透工具 3. 配置Draw.io公网访问地址 4. 公网远程访问Draw.io 前言 提到流程图,大家第一时间可能会想到Visio,不可否认,VIsio确实是功能强大,但是软件为收费&…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
安卓基础(aar)
重新设置java21的环境,临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的: MyApp/ ├── app/ …...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程
STM32F1 本教程使用零知标准板(STM32F103RBT6)通过I2C驱动ICM20948九轴传感器,实现姿态解算,并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化,适合嵌入式及物联网开发者。在基础驱动上新增…...
comfyui 工作流中 图生视频 如何增加视频的长度到5秒
comfyUI 工作流怎么可以生成更长的视频。除了硬件显存要求之外还有别的方法吗? 在ComfyUI中实现图生视频并延长到5秒,需要结合多个扩展和技巧。以下是完整解决方案: 核心工作流配置(24fps下5秒120帧) #mermaid-svg-yP…...
规则与人性的天平——由高考迟到事件引发的思考
当那位身着校服的考生在考场关闭1分钟后狂奔而至,他涨红的脸上写满绝望。铁门内秒针划过的弧度,成为改变人生的残酷抛物线。家长声嘶力竭的哀求与考务人员机械的"这是规定",构成当代中国教育最尖锐的隐喻。 一、刚性规则的必要性 …...
Qwen系列之Qwen3解读:最强开源模型的细节拆解
文章目录 1.1分钟快览2.模型架构2.1.Dense模型2.2.MoE模型 3.预训练阶段3.1.数据3.2.训练3.3.评估 4.后训练阶段S1: 长链思维冷启动S2: 推理强化学习S3: 思考模式融合S4: 通用强化学习 5.全家桶中的小模型训练评估评估数据集评估细节评估效果弱智评估和民间Arena 分析展望 如果…...
Excel 怎么让透视表以正常Excel表格形式显示
目录 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总 1、创建数据透视表 2、设计 》报表布局 》以表格形式显示 3、设计 》分类汇总 》不显示分类汇总...
Qt 按钮类控件(Push Button 与 Radio Button)(1)
文章目录 Push Button前提概要API接口给按钮添加图标给按钮添加快捷键 Radio ButtonAPI接口性别选择 Push Button(鼠标点击不放连续移动快捷键) Radio Button Push Button 前提概要 1. 之前文章中所提到的各种跟QWidget有关的各种属性/函数/方法&#…...
AI书签管理工具开发全记录(十八):书签导入导出
文章目录 AI书签管理工具开发全记录(十八):书签导入导出1.前言 📝2.书签结构分析 📖3.书签示例 📑4.书签文件结构定义描述 🔣4.1. 整体文档结构4.2. 核心元素类型4.3. 层级关系4.…...
