Vue3常见api使用指南(TS版)
defineProps() 和 defineEmits()
- 内置函数,无需import导入,直接使用。
- 传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的范围。因此,传入的选项不能引用在 setup 范围中声明的局部变量(比如设置默认值时),但是,它可以引用导入(import)的变量,因为它们也在模块范围内。就是说props设置默认值的时候不能直接用setup里的变量,可以用import引入的数据
<script setup>
//props是响应式的不能解构
//方法1:不能设置默认值(使用withDefaults解决)
const props = defineProps({foo?: String,id: [Number, String],onEvent: Function, //Function类型metadata: null
})//方法2
const props = defineProps({ foo: { type: String, required: true, default: '默认值' }, bar: Number })//方法3-推荐:弊端:不能设置默认值(使用withDefaults解决)
interface Props {data?: number[]
}
//const props = defineProps<Props>();
//或const props = defineProps<{ data?: number[] }>();
const props = withDefaults(defineProps<Props>(), { data: () => [1, 2] })const emit = defineEmits(['change', 'delete']) //声明从父组件来的事件
//将事件传递出去
emit('change', 参数);
emit('delete', 参数);
</script>
defineExpose()
内置函数,无需import导入,直接使用。Vue3中的setup默认是封闭的,如果想要使用ref或者 $parent 获取到的组件的的变量或函数,被访问的组件须使用defineExpose将属性和方法暴露出去。使用方式参考获取DOM
获取DOM
官网Api
Vue3中,移除了 $children 属性
- ref
- $parent
- $root
<!--父组件parent.vue -->
<template><child ref="childRef"></child><div ref="divEl"></div>
</template>
<script setup lang="ts">
import child from './components/child.vue';
import type { ComponentInternalInstance } from 'vue';
//import { getCurrentInstance, ComponentInternalInstance } from 'vue'; 我用了自动导入,不需要引getCurrentInstance//方法一(常用推荐):
//typeof P 是获取到类,InstanceType<类>是拿到类的实例,一个是类一个是实例不一样
//为了获取组件的类型,我们首先需要通过 `typeof` 得到其类型,再使用 TypeScript 内置的 `InstanceType` 工具类型来获取其实例类型://获取组件。这个变量名和 DOM 上的 ref 属性必须同名,会自动形成绑定。变量名不能和组件名同名,即chilRef不能命名为child
let childRef = ref<InstanceType<typeof child> | null>(null); //获取dom
let divEl = ref<HTMLDivElement | null>(null)//方法二:(不推荐)
//这样写会标红:类型“ComponentInternalInstance | null”上不存在属性“proxy”。使用类型断言或非空断言
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
//或const { proxy } = getCurrentInstance()!;let parentNum = ref(1)onMounted(() => {console.log(divEl.value); //直接拿到dom本身console.log(childRef.value?.msg); //.value的方式调用子组件的数据和方法(defineExpose暴露)childRef.value?.open();console.log(proxy?.$refs); //proxy对象{childRef: Proxy(Object), divEl: div}
});
defineExpose({parentNum
})</script>
注意: 如果ref在v-for里,将会是一个数组,这里和vue2一样。使用childRef.value[0].msg
//子组件child.vue
<script setup lang="ts">
import type { ComponentInternalInstance } from 'vue'
let msg: string = '111';
const open = function() {console.log(222);}
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
onMounted(() => {//标红:类型“ComponentPublicInstance”上不存在属性“parentNum”console.log('parent', proxy?.$parent?.parentNum);
})
defineExpose({msg,open
})
</script>
useAttrs()
包含了父组件传递过来的所有属性(子组件内没有被defineProps和defineEmits声明的),包括 class 和 style 以及事件(相当于vue2中相当于listeners)。在vue2中,listeners)。在vue2中,listeners)。在vue2中,attrs 是接到不到 class 和 style 的
//parent.vue
<template><childfoo="222"foo2="333"class="child":style="{}"@test="handleTest"@test2="handleTest"></child>
</template>
<script setup lang="ts">
function handleTest() {}
</script>
//child.vue
<template><div></div>
</template>
<script setup lang="ts">const props = defineProps(['foo2'])const emits = defineEmits(['test2'])console.log(props); //{foo2: '333'}const attrs = useAttrs()console.log(attrs); // {foo: '222', class: 'child', style: {…}, onTest: f handleTest()}
</script>
全局注册
//vue2中
Vue.prototype.$axios = xxx//使用
this.$axios
# 扩展全局属性
//main.ts
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)app.config.globalProperties.name = '猪八戒'
app.mount('#app')<script setup lang="ts">
import type { ComponentInternalInstance } from 'vue';
// proxy 就是当前组件实例,可以理解为组件级别的 this,没有全局的、路由、状态管理之类的
const { proxy, appContext } = getCurrentInstance() as ComponentInternalInstance;//global 就是全局实例
const global = appContext.config.globalPropertiesconsole.log(global.name)
console.log(proxy?.name) //会标红
</script>
异步组件
## 异步组件,路由懒加载
设置组件名称
- 在 3.2.34 或以上的版本中,使用 <script setup> 的单文件组件会自动根据文件名生成对应的 name 选项,即使是在配合 <KeepAlive> 使用时也无需再手动声明。不写index.vue,写一个具象的组件名称
- 再加个平级的script标签(注意:两个script标签使用的语言要同步,lang="ts")
<script lang="ts" setup>
</script>
<script lang="ts">export default {name: 'draft',inheritAttrs: false,customOptions: {},};
</script>
3.defineOptions
这个宏可以用来直接在 <script setup> 中声明组件选项,而不必使用单独的 <script> 块
官网解释
<script lang="ts" setup>defineOptions({name:'draft'})
</script>
4.利用插件
- vite-plugin-vue-setup-extend-plus
- vite-plugin-vue-setup-extend(断点调试存在问题,未修复sourcemap is broken
- unplugin-vue-define-options error in production:defineOptions is not defined
//会报错[vueSetupExtend不是一个函数],删掉package.json 中的 type: module即可
//vite.config.ts
import { defineConfig, Plugin } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueSetupExtend from 'vite-plugin-vue-setup-extend-plus'export default defineConfig({plugins: [vue(), vueSetupExtend()],
})
//SFC
<template><div>hello world {{ a }}</div>
</template><script lang="ts" setup name="App" inheritAttrs="false">const a = 1
</script>
watch的使用
官网
当我们需要在数据变化时执行一些“副作用”:如更改 DOM、执行异步操作(发起网络请求等),我们可以使用 watch 函数:
- 监听基本数据类型
const name = ref('猪八戒')
// 监听 ref 属性
watch(name, (newValue, oldValue) => { })
监听对象
const obj = reactive({a: 1,b: 2,c: {d: 1,e: 2},f: []
})
//法一:深层次,当直接侦听一个响应式对象时,侦听器会自动启用深层模式:
//可以监听到obj.f = [1]和obj.c.d ++
watch(obj, (newValue, oldValue) => {
})//法二:深层次,必须写deep: true,不然浅层的也监听不到
watch(() => obj, (newValue, oldValue) => {
}, { deep: true })//法三:浅层, 监听不到obj.f = [1]和obj.c.d ++
watch(() => { ...obj }, (newValue, oldValue) => {
})
监听对象的某个属性
watch(() => obj.a, (newValue, oldValue) => {
})//如果是对象的属性是引用数据类型,必须加deep: true才能监听到
watch(() => obj.f, (newValue, oldValue) => {
}, { deep: true })
监听多个数据
//法一:
watch([() => obj.a, name], ([newA, newName], [oldA, oldName]) => {});
//法二:
watch(() => [obj.a, obj.b], (newValue, oldValue) => {
})
watchEffect
官网
- watch 默认是懒执行的:仅当数据源变化时,才会执行回调。可以传入immediate: true 选项来强制侦听器的回调立即执行
- watchEffect的回调会立即执行(依赖收集),不需要指定 immediate: true。在执行期间,它会在同步执行过程中,自动追踪所有能访问到的响应式属性。watch:手动指定依赖watchEffect:自动收集依赖(注意: 依赖太多各种坑)
- watchEffect 无法访问侦听数据的新值和旧值
//侦听器的回调使用与源完全相同的响应式状态是很常见的。例如下面的代码,在每当 `todoId` 的引用发生变化时使用侦听器来加载一个远程资源
const todoId = ref(1)
const data = ref(null)watch(todoId, async () => {const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)data.value = await response.json()
}, { immediate: true })//使用watchEffect简化代码,我们不再需要明确传递 `todoId` 作为源值.
watchEffect(async () => { const response = await fetch( `https://jsonplaceholder.typicode.com/todos/${todoId.value}`);data.value = await response.json()
})
- 使用哪种随你喜欢,如果不需要使用先前值(oldValue)并且希望立即执行就用watchEffect,可以少写一点代码。watch的自由度更高,watchEffect相当于封装了一层
- 推荐在大部分时候用 watch 显式的指定依赖以避免不必要的重复触发,也避免在后续代码修改或重构时不小心引入新的依赖。watchEffect 适用于一些逻辑相对简单,依赖源和逻辑强相关的场景
停止监听器
- 一个关键点是,侦听器必须用同步语句创建,这时它会在宿主组件卸载时自动停止。如果用异步回调创建一个侦听器,那么它不会绑定到当前组件上,你必须手动停止它,以防内存泄漏。
// 它会自动停止
watchEffect(() => {}) // ...这个则不会!
setTimeout(() => { watchEffect(() => {}) }, 100)//停止监听器
const unwatch = watchEffect(() => {}) // ...当该侦听器不再需要时 unwatch()//第二个参数是在发生变化时要调用的回调函数。这个回调函数接受三个参数:新值、旧值,以及一个用于注册副作用清理的回调函数。
//该回调函数会在副作用下一次重新执行前调用,可以用来清除无效的副作用,例如等待中的异步请求。
watch(id, async (newId, oldId, onCleanup) => {const { response, cancel } = doAsyncWork(newId)// 当 `id` 变化时,`cancel` 将被调用,// 取消之前的未完成的请求onCleanup(cancel)data.value = await response
})
computed
官网
//创建一个只读的计算属性 ref:
const count = ref(1)
const plusOne = computed(() => count.value + 1) console.log(plusOne.value) // 2
plusOne.value++ // 错误//创建一个可写的计算属性
onst count = ref(1)
const plusOne = computed({ get: () => count.value + 1, set: (val) => { count.value = val - 1 }
}) plusOne.value = 1 console.log(count.value) // 0
计算属性的 getter 应只做计算而没有任何其他的副作用,这一点非常重要,请务必牢记。举例来说,不要在 getter 中做异步请求或者更改 DOM!
CSS
- 样式穿透:Vue3 中不支持 /deep/ 或者 >>>写法, 支持:deep(.class)
<style scoped> .a :deep(.b) { /* ... */ }
</style>
css绑定js变量(v-bind):单文件组件的 <style> 标签支持使用 v-bind CSS 函数将 CSS 的值链接到动态的组件状态。
<script setup>
const theme = {color: 'red'
}
</script><template><p>hello</p>
</template><style scoped>
p {color: v-bind('theme.color');
}
</style>
provie和inject
//父级
const name = ref('猪八戒');
const changeName = (newName: string) => {name.value = newName;
};
provide('name', name);
provide('changeName', changeName); //更改name的方法//子级孙级
const name = inject('name') as string; //使用类型断言,不然会有红色波浪线
const changeName = inject('changeName') as Fn;
相关文章:
Vue3常见api使用指南(TS版)
defineProps() 和 defineEmits() 内置函数,无需import导入,直接使用。传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的范围。因此,传入的选项不能引用在 setup 范围中声明的局部变量(比如设置默认值时),但是…...
分布式 分布式事务 总结
前言 相关系列 《分布式 & 目录》《分布式 & 分布式事务 & 总结》《分布式 & 分布式事务 & 问题》 分布式事务 所谓分布式事务是指操作范围笼罩多个不同节点的事务。例如对于订单节点&库存节点而言,一次完整的交易需要同时调动两个节…...
onnx文件转pytorch pt模型文件
onnx文件转pytorch pt模型文件 1.onnx2torch转换及测试2.存在问题参考文献 从pytorch格式转onnx格式,官方有成熟的API;那么假如只有onnx格式的模型文件,该怎样转回pytorch格式? https://github.com/ENOT-AutoDL/onnx2torch提供了…...
智能座舱人机交互升级
我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源&…...
RabbitMQ中点对点(Point-to-Point)通讯方式的Java实现
RabbitMQ是一个广泛使用的开源消息代理软件,它实现了高级消息队列协议(AMQP)。RabbitMQ支持多种消息传递模式,其中最基本的是点对点(Point-to-Point)通讯方式。在这种模式下,消息生产者将消息发…...
爬虫实战:获取1688接口数据全攻略
引言 在电商领域,数据的重要性不言而喻。1688作为中国领先的B2B电商平台,提供了海量的商品数据。通过爬虫技术获取这些数据,可以帮助企业进行市场分析、价格监控和供应链管理。本文将详细介绍如何使用Python爬虫技术合法合规地获取1688接口数…...
生成树协议STP工作步骤
第一步:选择根桥 优先级比较:首先比较优先级,优先级值越小的是根桥MAC地址比较:如果优先级相同,则比较MAC地址。MAC地址小的是根桥。 MAC地址比较的时候从左往右,一位一位去比 第二步:所有非根…...
Android14 AOSP支持短按关机
修改frameworks/base/services/core/java/com/android/server/policy/PhoneWindowManager.java diff --git a/base/services/core/java/com/android/server/policy/PhoneWindowManager.java b/base/services/core/java/com/android/server/policy/PhoneWindowManager.java in…...
C# 和 go 关于can通信得 整理
在C#中开发CAN(Controller Area Network)通信接口时,确实有一些现成的NuGet包可以简化你的开发工作。这些库通常提供了与CAN硬件接口通信所需的基本功能,如发送和接收CAN消息。下面是一些常用的NuGet包: PCANBasic.NET…...
vue常用命令汇总
nvm 一个nodejs版本管理工具,解决node.js各种版本存在不兼容现象可以通过它可以安装和切换不同版本的node.js。 npm 可以管理 nodejs 的第三方插件。 vue-cli 是Vue提供的一个官方cli,专门为单页面应用快速搭建繁杂的脚手架。 nginx 是一个高性能的HTTP和反向代理we…...
【C++习题】18.逆波兰表达式求值
题目:逆波兰表达式求值 链接🔗:逆波兰表达式求值 题目: 代码: class Solution {public:int evalRPN(vector<string>& tokens) {stack<int> s;for (size_t i 0; i < tokens.size(); i){string&a…...
本地如何使用 yarn link 调试本地 npm 包
如何使用 yarn link 调试本地 npm 包: 在前端开发中,通常我们会开发并使用许多 npm 包来实现项目的功能。随着开发的深入,我们经常需要调试或修改某些 npm 包的源码。如果你正在开发一个 npm 包,并且希望在本地项目中进行调试&am…...
江恩45年一书的自己一点读书见解
读了下江恩的华尔街45年,有些浅薄的体会,记录下 江恩的华尔街45年里面,感触比较深刻的有以下几点: 1.为什么会亏钱 1.利用大仓位来过度交易,违背了资本安全的原则。买卖过于频繁 2.没有用止损单来保护你的交易。 3.缺…...
影响 Linux、Unix 系统的 CUPS 漏洞可导致 RCE
在经过大量炒作和第三方过早泄露信息之后,安全研究员 Simone Margaritelli 公布了有关通用 UNIX 打印系统 (CUPS) 中的四个零日漏洞的详细信息。 这些漏洞可被远程、未经身份验证的攻击者滥用,在易受攻击的 Linux 和类 Unix 系统上实现代码执行。 CUPS…...
【汇编】思考汇编中的两个基本问题
1. 若干年前的疑问 几年前还在大学学习汇编时,不管是考试还是课程设计,其实都很顺利。但是心里一直对什么时候使用哪个寄存器存在疑惑,编写汇编时,没有十足的把握,都是抱着试一试的心态去完成了课程任务。 工作八年有…...
Nest Dynamic modules 笔记
Nest Dynamic modules 文档地址👈 记录Dynamic modules是因为确实抽象,文档并没有很详细的指出不同方式创建动态模块的区别 两种不同的动态模块创建方式 静态模块传统动态模块方式实现三种不同的方法命名使用ConfigurableModuleBuilder异步动态模块如果…...
生成式AI、大模型、多模态技术开发与应用学习清单
学习目的: 了解AIGC发展现状与核心技术。 掌握Transformer核心开发技术。掌握向量数据库的工作原理、检索算法、主要开源数据库。掌握大模型调用、微调方法。掌握以GPT大语言模型为基础的工作原理。 掌握AIGC技术在跨模态领域的应用技术。了解GPT提示工程和AIGC的安…...
STM32 CubeMx HAL库 独立看门狗IWDG配置使用
看门狗这里我就不多介绍了,能搜到这篇文章说明你了解 总之就是一个单片机重启程序,设定好超时时间,在超时时间内没有喂狗,单片机就会复位 主要应用在单片机异常重启方面,比如程序跑飞(注意程序跑飞时你就…...
网络安全渗透测试概论
渗透测试,也称为渗透攻击测试是一种通过模拟恶意攻击者的手段来评估计算机系统、网络或应用程序安全性的方法。 目的 旨在主动发现系统中可能存在的安全漏洞、脆弱点以及潜在风险,以便在被真正的恶意攻击者利用之前,及时进行修复和加固&…...
【大数据技术基础】【记录Ubuntu 16.04升级到18.04】Ubuntu的一个版本升级到另一个版本
在 Ubuntu 操作系统中进行软件更新和系统升级 Ubuntu Kylin 16.04 LTS 系统进行系统升级到 Ubuntu 18.04.6 LTS 版本 升级提示:系统弹出提示框,告知用户有新版本的 Ubuntu 可用,询问用户是否想要升级。 认证窗口:显示了一个认证…...
基于SpringBoot + Vue的鲜花销售系统(角色:用户、商家、管理员)
文章目录前言一、详细操作演示视频二、具体实现截图三、技术栈1.前端-Vue.js2.后端-SpringBoot3.数据库-MySQL4.系统架构-B/S四、系统测试1.系统测试概述2.系统功能测试3.系统测试结论五、项目代码参考六、数据库代码参考七、项目论文示例结语前言 💛博主介绍&#…...
STM32+MATLAB数据采集避坑指南:你的串口丢包、乱码可能和这3个参数有关
STM32与MATLAB串口通信的稳定性优化:从参数配置到实战调试 在嵌入式系统与上位机通信的众多方案中,STM32与MATLAB通过串口进行数据交互是最为经典且广泛应用的组合之一。这种组合充分利用了STM32在实时控制方面的优势以及MATLAB在数据分析与可视化上的强…...
模糊聚类实战:用传递闭包法给教师教学质量打分,附Python完整代码
模糊聚类实战:用传递闭包法给教师教学质量打分 教育评价从来不是非黑即白的判断题。当我们试图对教师的教学质量进行分类时,传统的硬性划分方法往往掩盖了教师能力之间的渐变与过渡。四位教师在师德师表、教学过程等五项指标上的评分差异,可能…...
新鲜出炉!2026简历模板服务商推荐排行 专业评测榜 AI适配/全行业覆盖
一、摘要据中国人力资源开发研究会2026年行业报告显示,国内简历模板服务市场中,仅有30%的服务商能实现ATS系统通过率90%以上,求职者因简历模板不适配、内容不规范导致面试邀约率偏低,平均错失40%的求职机会;企业则因模…...
evo实战:A-LOAM在KITTI数据集上的多维度性能剖析
1. 从KITTI到ROS:数据格式转换实战 第一次接触KITTI数据集时,我被它那庞大的.bin点云文件搞得一头雾水。作为一个常年和ROS打交道的工程师,我深知bag格式才是SLAM算法的"通用语言"。这里分享一个我验证过的高效转换方案——使用lid…...
石油干线管道关键参数稳定自动控制系统(CAP)研究
石油干线管道关键参数稳定自动控制系统(CAP)研究 摘要 石油干线管道是国家能源输送的重要基础设施,其运行过程中的压力、流量等关键参数的稳定控制直接关系到管道的安全性与经济性。本文针对石油干线管道参数控制的非线性、大滞后、强耦合等特点,设计并实现了一套关键参数…...
Tickers:嵌入式无阻塞软件定时器库
1. 项目概述Tickers是一个轻量级、无阻塞的定时回调库,专为资源受限的嵌入式系统设计。其核心目标是彻底替代delay()函数,在不牺牲实时性、不引入线程调度开销的前提下,实现高精度、可重入、多实例的周期性函数调用。该库不依赖操作系统内核&…...
手把手教你为RK3568(arm64)交叉编译BlueZ:利用Buildroot已有环境快速出包
手把手教你为RK3568(arm64)交叉编译BlueZ:利用Buildroot已有环境快速出包 在嵌入式Linux开发中,蓝牙协议栈BlueZ的交叉编译一直是让开发者头疼的问题。特别是当目标平台采用arm64架构时,依赖库的复杂性和工具链的配置难…...
【SpringAIAlibaba新手村系列】(12)RAG 检索增强生成技术
第十二章 RAG 检索增强生成技术 版本标注 Spring AI: 1.1.2Spring AI Alibaba: 1.1.2.0 章节定位 本章的 RetrievalAugmentationAdvisor VectorStore 仍然是经典 RAG 入门方案。但 Spring AI Alibaba 1.1.2.x 官方代码已经进一步演进到 RAG Workflow 思路,典型流程…...
React on Rails 与 WebSocket 实时通信:完整实现指南
React on Rails 与 WebSocket 实时通信:完整实现指南 【免费下载链接】react_on_rails Integration of React Webpack Rails including server-side rendering of React, enabling a better developer experience and faster client performance. 项目地址: htt…...
