Vue3 完整学习笔记 - 第五部分

devtools/2025/2/5 8:46:32/

Vue3 完整学习笔记 - 第五部分

5. Vue3 高级特性与性能优化

5.1 shallow 系列 API

重点掌握:

  • shallowRef vs ref
  • shallowReactive vs reactive
  • 使用场景和性能影响

示例代码:

<script setup>
import { ref, shallowRef, reactive, shallowReactive } from 'vue'// shallowRef 示例
const normalRef = ref({ count: 0, nested: { value: 0 } })
const shallowCountRef = shallowRef({ count: 0, nested: { value: 0 } })// 深层响应
normalRef.value.nested.value++ // 触发更新
// 浅层响应
shallowCountRef.value.nested.value++ // 不触发更新
shallowCountRef.value = { count: 1, nested: { value: 1 } } // 触发更新// shallowReactive 示例
const state = shallowReactive({foo: 1,nested: {bar: 2}
})// 只有顶层属性是响应式的
state.foo++ // 触发更新
state.nested.bar++ // 不触发更新// 性能优化示例
const bigData = shallowRef({huge: new Array(10000).fill('data'),summary: { count: 0 }
})// 只有当完全替换对象时才触发更新
function updateBigData() {bigData.value = { ...bigData.value, summary: { count: bigData.value.summary.count + 1 } }
}
</script>

5.2 readonly 和 markRaw

重点掌握:

  • 只读数据的创建
  • 原始数据的标记
  • 性能优化场景

示例代码:

import { readonly, markRaw, reactive } from 'vue'// readonly 示例
const original = reactive({count: 0,nested: {value: 1}
})const copy = readonly(original)// 这将产生警告
copy.count++ // 仍然可以通过原始对象修改
original.count++ // markRaw 示例
class BigData {constructor() {this.data = new Array(10000).fill('data')}process() {// 复杂处理逻辑}
}const state = reactive({// 标记为非响应式bigData: markRaw(new BigData()),// 普通响应式数据counter: 0
})// bigData 的变化不会触发更新
state.bigData.data[0] = 'new data'
// counter 的变化会触发更新
state.counter++

5.3 customRef 自定义响应式

重点掌握:

  • 自定义 ref 的实现
  • 防抖/节流的实现
  • 追踪依赖和触发更新

示例代码:

import { customRef } from 'vue'// 创建防抖的ref
function useDebouncedRef(value, delay = 200) {let timeoutreturn customRef((track, trigger) => {return {get() {track() // 追踪依赖return value},set(newValue) {clearTimeout(timeout)timeout = setTimeout(() => {value = newValuetrigger() // 触发更新}, delay)}}})
}// 创建本地存储的ref
function useLocalStorageRef(key, defaultValue) {return customRef((track, trigger) => {return {get() {track()const value = localStorage.getItem(key)return value ? JSON.parse(value) : defaultValue},set(newValue) {localStorage.setItem(key, JSON.stringify(newValue))trigger()}}})
}// 使用示例
<script setup>
const searchQuery = useDebouncedRef('', 300)
const settings = useLocalStorageRef('app-settings', { theme: 'light' })// 自动防抖的搜索
watchEffect(() => {console.log('Searching for:', searchQuery.value)
})// 自动持久化的设置
watchEffect(() => {console.log('Theme changed:', settings.value.theme)
})
</script>

5.4 高级组件模式

重点掌握:

  • 递归组件
  • 异步组件优化
  • 函数式组件

示例代码:

<!-- RecursiveComponent.vue -->
<template><div class="tree-node"><div @click="toggle">{{ data.label }}<span v-if="hasChildren">[{{ expanded ? '-' : '+' }}]</span></div><div v-if="expanded && hasChildren" class="children"><RecursiveComponentv-for="child in data.children":key="child.id":data="child"/></div></div>
</template><script setup>
import { ref, computed } from 'vue'const props = defineProps(['data'])
const expanded = ref(false)
const hasChildren = computed(() => props.data.children?.length > 0
)const toggle = () => {expanded.value = !expanded.value
}
</script><!-- 函数式组件 -->
<script setup>
// 纯展示组件
const PureComponent = (props) => {return h('div', props.text)
}// 使用渲染函数的组件
const RenderComponent = {props: ['items'],setup(props) {return () => h('ul', props.items.map(item =>h('li', { key: item.id }, item.text)))}
}
</script>

5.5 性能优化技巧

重点掌握:

  • 组件懒加载
  • 虚拟列表
  • 大数据优化

示例代码:

<template><div><!-- 懒加载组件 --><Suspense><template #default><LazyComponent /></template><template #fallback><LoadingSkeleton /></template></Suspense><!-- 虚拟列表 --><VirtualList:items="items":item-size="50"v-slot="{ item }"><div class="item">{{ item.name }}</div></VirtualList></div>
</template><script setup>
import { defineAsyncComponent, ref } from 'vue'// 组件懒加载
const LazyComponent = defineAsyncComponent({loader: () => import('./HeavyComponent.vue'),delay: 200,timeout: 3000,errorComponent: ErrorComponent,loadingComponent: LoadingComponent
})// 虚拟列表组件
const VirtualList = {props: ['items', 'itemSize'],setup(props) {const containerRef = ref(null)const startIndex = ref(0)const endIndex = ref(0)// 计算可视区域内的项目const visibleItems = computed(() => {return props.items.slice(startIndex.value, endIndex.value)})// 监听滚动更新索引const handleScroll = () => {const container = containerRef.valuestartIndex.value = Math.floor(container.scrollTop / props.itemSize)endIndex.value = startIndex.value + Math.ceil(container.clientHeight / props.itemSize)}return {containerRef,visibleItems,handleScroll}}
}// 大数据优化
const useBigList = () => {const items = ref([])const loading = ref(false)// 分批加载数据const loadBatch = async (start, size = 100) => {loading.value = trueawait new Promise(resolve => setTimeout(resolve, 100))const batch = new Array(size).fill(null).map((_, i) => ({id: start + i,name: `Item ${start + i}`}))items.value.push(...batch)loading.value = false}// 初始加载onMounted(() => loadBatch(0))// 检测滚动到底部const handleScroll = (e) => {const { scrollHeight, scrollTop, clientHeight } = e.targetif (scrollHeight - scrollTop <= clientHeight * 1.5 && !loading.value) {loadBatch(items.value.length)}}return {items,loading,handleScroll}
}
</script>

5.6 开发工具与调试技巧

重点掌握:

  • Vue Devtools 的使用
  • 性能分析
  • 调试技巧

示例代码:

// 开发环境性能监控
if (process.env.NODE_ENV === 'development') {const { performance } = window// 监控组件渲染时间const componentRenderTiming = new Map()app.mixin({beforeCreate() {performance.mark(`${this.$options.name}-start`)},mounted() {performance.mark(`${this.$options.name}-end`)performance.measure(`${this.$options.name}`,`${this.$options.name}-start`,`${this.$options.name}-end`)const measurements = performance.getEntriesByName(this.$options.name)componentRenderTiming.set(this.$options.name, measurements[0].duration)}})
}// 调试辅助函数
const debugRef = (ref, name) => {watch(ref, (newVal, oldVal) => {console.log(`[${name}] changed:`, {old: oldVal,new: newVal})}, { deep: true })return ref
}// 使用示例
const count = debugRef(ref(0), 'count')
</script>

http://www.ppmy.cn/devtools/156224.html

相关文章

冯诺依曼系统及操作系统

目录 一.冯诺依曼体系结构 二.操作系统 三.系统调用和库函数概念 一.冯诺依曼体系结构 我们常见的计算机&#xff0c;如笔记本。我们不常见的计算机&#xff0c;如服务器&#xff0c;大部分都遵守冯诺依曼体系 截至目前&#xff0c;我们所认识的计算机&#xff0c;都是由一…

ip属地是根据所在位置定位的吗

在数字化时代&#xff0c;随着网络社交和电子商务的蓬勃发展&#xff0c;IP属地这一概念逐渐走入了大众的视野。许多平台开始显示用户的IP属地&#xff0c;这一举措旨在增强网络信息的透明度和真实性。然而&#xff0c;关于IP属地是否就是根据用户所在位置进行定位的问题&#…

接口测试通用测试用例

接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。 测试的重点是检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 现在很多系统前后端架构是分离的&#xff0c;从安全层面来说&#xff0c;只依赖前段进行限…

Ajax:重塑Web交互体验的人性化探索

在数字化时代&#xff0c;网页的交互性和响应速度已成为衡量用户体验的关键指标。Ajax&#xff08;Asynchronous JavaScript and XML&#xff09;&#xff0c;作为前端与后端沟通的桥梁&#xff0c;凭借其异步通信的能力&#xff0c;极大地提升了网页的动态性和用户友好度&…

Node.js 调用 DeepSeek API 完整指南

简介 本文将介绍如何使用 Node.js 调用 DeepSeek API&#xff0c;实现流式对话并保存对话记录。Node.js 版本使用现代异步编程方式实现&#xff0c;支持流式处理和错误处理。 1. 环境准备 1.1 系统要求 Node.js 14.0 或更高版本npm 包管理器 1.2 项目结构 deepseek-proje…

Caxa 二次开发 ObjectCRX-1 踩坑:环境配置以及 Helloworld

绝了&#xff0c;坑是真 nm 的多&#xff0c;官方给的文档里到处都是坑。 用的环境 ObjectCRX&#xff0c;以下简称 objcrx。 #1 安装环境 & 参考文档的大坑 #1.1 Caxa 提供的文档和环境安装包 首先一定要跟 Caxa 对应版本的帮助里提供的 ObjectCRX 安装器 (wizard) 匹配…

汽车中控屏HMI界面,安全和便捷是设计的两大准则。

在汽车智能化的浪潮中&#xff0c;汽车中控屏 HMI&#xff08;Human - Machine Interface&#xff0c;人机交互界面&#xff09;界面已成为车辆与驾驶者沟通的关键桥梁。它不仅集成了众多车辆功能的控制&#xff0c;还承担着信息展示与交互的重任。而在其设计过程中&#xff0c…

python学习笔记5-函数的定义

1.函数的定义&#xff1a; # def 是英⽂ define 的缩写def 函数名&#xff08;[参数1],[参数2]....[参数n]&#xff09;:函数体 关于函数名的定义&#xff0c;有几项需要注意的地方&#xff1a; • 函数名命名规则同变量名&#xff0c;要满⾜标识符命名规则 • 不能和系统…