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>

异步组件

## 异步组件,路由懒加载

设置组件名称

  1. 在 3.2.34 或以上的版本中,使用 <script setup> 的单文件组件会自动根据文件名生成对应的 name 选项,即使是在配合 <KeepAlive> 使用时也无需再手动声明。不写index.vue,写一个具象的组件名称
  2. 再加个平级的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;

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

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

相关文章

实战 | 某院校小程序记录

视频教程在我主页简介里 目录&#xff1a; 前言&#xff1a; 渗透思路 1.绕过前端 2.信息泄露 3.爆破用户账号密码 4.信息泄露2 结束 前言&#xff1a; 遇到一个学校小程序的站点&#xff0c;只在前端登录口做了校验&#xff0c;后端没有任何校验&#xff0c;奇葩弱口令离…

debian12学习笔记

前置条件 基于debian12官网的qcow2格式文件进行操作 安装ssh 登录虚拟机后安装ssh服务端 apt install openssh-server配置国内源 新增/etc/apt/sources.list.d/tsinghua.list 使用清华大学的源 https://www.cnblogs.com/shanhubei/p/18104430 deb https://mirrors.tuna.t…

ansible自动化运维(三)jinja2模板roles角色管理

相关文章ansible自动化运维&#xff08;一&#xff09;简介及清单,模块-CSDN博客ansible自动化运维&#xff08;二&#xff09;playbook模式详解-CSDN博客ansible自动化运维&#xff08;四&#xff09;运维实战-CSDN博客 三.Ansible jinja2模板 Jinja2是Python的全功能模板引…

数据结构 (35)分配类排序

前言 分配类排序是数据结构中的一种重要排序方法&#xff0c;其核心思想是利用分配和收集过程对元素进行排序&#xff0c;而无需比较元素之间的关键字。这种方法突破了基于关键字比较的排序算法的时间下界&#xff0c;可以达到线性时间复杂度O(n)。 一、分配类排序的基本概念 分…

微信小程序跳转其他小程序以及跳转网站

一、跳转其他小程序 1.1 知道appid和页面路径 wx.navigateToMiniProgram({appId: appid, // 替换为目标小程序 AppIDpath: pathWithParams, // 小程序路径envVersion: release, // 开发版、体验版或正式版success(res) {console.log("跳转到其他小程序成功&#xff01;&q…

利用卷积神经网络进行手写数字的识别

数据集介绍 MNIST&#xff08;Modified National Institute of Standards and Technology&#xff09;数据集是一个广泛使用的手写数字识别数据集&#xff0c;常用于机器学习和计算机视觉领域中的分类任务。它包含了从0到9的手写数字样本&#xff0c;常用于训练和测试各种图像…

Transformer入门(6)Transformer编码器的前馈网络、加法和归一化模块

文章目录 7.前馈网络8.加法和归一化组件9.组合所有编码器组件构成完整编码器 7.前馈网络 编码器块中的前馈网络子层如下图所示&#xff1a; 图1.32 – 编码器块 前馈网络由两个带有ReLU激活函数的全连接层组成。全连接层&#xff08;Fully Connected Layer&#xff09;有时也…

前端(async 和await)

1 async async 将 function 变为成为 async 函数 ●async 内部可以使用 await&#xff0c;也可以不使用&#xff0c;因此执行这个函数时&#xff0c;可以使用 then 和 catch 方法 ●async 函数的返回值是一个 Promise 对象 ●Promise 对象的结果由 async 函数执行的返回值决…

Java-25 深入浅出 Spring - 实现简易Ioc-01 Servlet介绍 基本代码编写

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

H.323音视频协议

概述 H.323是国际电信联盟&#xff08;ITU&#xff09;的一个标准协议栈&#xff0c;该协议栈是一个有机的整体&#xff0c;根据功能可以将其分为四类协议&#xff0c;也就是说该协议从系统的总体框架&#xff08;H.323&#xff09;、视频编解码&#xff08;H.263&#xff09;、…

WPF+MVVM案例实战与特效(四十)- 一个动态流水边框的实现

文章目录 1、运行效果2、案例实现1、PointAnimationUsingKeyFrames 关键帧动画2、矩形流水边框案例2、运行效果3、关键技术点3、案例拓展:其他形状实现1、圆形流水边框2、心形流水边3、完整页面代码4、运行效果5、总结1、运行效果 2、案例实现 1、PointAnimationUsingKeyFram…

微信小程序--创建一个日历组件

微信小程序–创建一个日历组件 可以创建一个日历组件&#xff0c;来展示当前月份的日期&#xff0c;并支持切换月份的功能。 一、目录结构 /pages/calendarcalendar.wxmlcalendar.scsscalendar.jscalendar.json二、calendar.wxml <view class"calendar"><…

【Linux-ubuntu通过USB传输程序点亮LED灯】

Linux-ubuntu通过USB传输程序点亮LED灯 一,初始化GPIO配置1.使能时钟2.其他寄存器配置 二&#xff0c;程序编译三&#xff0c;USB传输程序 一,初始化GPIO配置 1.使能时钟 使能就是一个控制信号&#xff0c;用于决定时钟信号是否能够有效的传递或者被使用&#xff0c;就像一个…

Rust之抽空学习系列(三)—— 编程通用概念(中)

Rust之抽空学习系列&#xff08;三&#xff09;—— 编程通用概念&#xff08;中&#xff09; 1、变量&可变性 在Rust中&#xff0c;变量默认是不可变的 fn main() {let x 5;println!("x is {}", x); }使用let来声明一个变量&#xff0c;此时变量默认是不可变…

Mybatis---事务

目录 引入 一、事务存在的意义 1.事务是什么&#xff1f; 2.Mybatis关于事务的管理 程序员自己控制处理的提交和回滚 引入 一、事务存在的意义 1.事务是什么&#xff1f; 多个操作同时进行,那么同时成功&#xff0c;那么同时失败。这就是事务。 事务有四个特性&#xf…

<项目代码>YOLOv8 车牌识别<目标检测>

项目代码下载链接 &#xff1c;项目代码&#xff1e;YOLOv8 车牌识别&#xff1c;目标检测&#xff1e;https://download.csdn.net/download/qq_53332949/90121387YOLOv8是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题…

跨平台开发技术的探索:从 JavaScript 到 Flutter

随着多平台支持和用户体验一致性在应用程序开发中变得越来越重要,开发者面临的挑战是如何在不同平台上保持代码的可维护性和高效性。本文将探讨如何利用现代技术栈,包括 Flutter、JavaScript、HTML5、WebAssembly、TypeScript 和 Svelte,在统一的平台上进行高效的跨平台开发…

华为eNSP:VRRP

一、VRRP背景概述 在现代网络环境中&#xff0c;主机通常通过默认网关进行网络通信。当默认网关出现故障时&#xff0c;网络通信会中断&#xff0c;影响业务连续性和稳定性。为了提高网络的可靠性和冗余性&#xff0c;采用虚拟路由冗余协议&#xff08;VRRP&#xff09;是一种…

Referer头部在网站反爬虫技术中的运用

网站数据的安全性和完整性至关重要。爬虫技术&#xff0c;虽然在数据收集和分析中发挥着重要作用&#xff0c;但也给网站管理员带来了挑战。为了保护网站数据不被恶意爬取&#xff0c;反爬虫技术应运而生。本文将探讨HTTP头部中的Referer字段在反爬虫技术中的应用&#xff0c;并…

【ArcGIS微课1000例】0135:自动生成标识码(长度不变,前面自动加0)

文章目录 一、加载实验数据二、BSM计算方法一、加载实验数据 加载专栏《ArcGIS微课实验1000例(附数据)》配套数据中0135.rar中的建筑物数据,如下图所示: 打开属性表,BSM为数据库中要求的字段:以TD_T 1066-2021《不动产登记数据库标准》为例: 计算出来的BSM如下图: 二、B…