在vue3项目中使用TypeScript

在vue3项目中使用TypeScript

Vue 3是用TypeScript编写的,Vue3对ts有很好的支持 于是今天就想给大家分享下 vue3 结合 typescript 使用的一些用法和开发中遇到的一些问题,环境搭建大家可以自己使用官方文档的方式去搭建,如果这些技巧能够帮助到你,欢迎点赞收藏哦!

1.ts在vue3项目中使用的意义

  1. 能在你写代码法人时候避免你写错,漏写,能避免一些低级错误
  2. 写一些公用方法和全局配置对象的时候,用于提醒使用者别传错参数或者参数的值
  3. 编写组件的时候提示有木有写错props
  4. 使用一些第三方ts库,可以检测你有没用调用错方法和传错参数

2.vue3语法糖的支持typescript格式

typescript 复制代码
<script setup lang="ts">
//你的代码
</script>

3. 编写组件的时候提示props

下面例子

父组件

typescript 复制代码
<template>
<div class="test-con">
  <Child></Child>
</div>
</template>
<script setup lang="ts">
import Child from "./components/child13.vue"
</script>

子组件规定必须传的值 a和b

typescript 复制代码
<template>
  <div class="child-con">
    <p>我是子组件1</p>

  </div>
</template>
<script setup lang="ts">
defineProps<
    {
      a:number,
      b:string
    }
>()
</script>

如果不传的话 编辑器会有提示错误 网页vue也会提示

写的时候会有语法提示

传的类型不对也会有提示

也可以用接口interface去定义

typescript 复制代码
<template>
  <div class="child-con">
    <p>我是子组件1</p>
    {{a}}
  </div>
</template>
<script setup lang="ts">
interface Props {
  a:number,
  b:string
}
defineProps<Props>()

Props 默认值

当使用了 基于类型声明时,就失去了 默认值 能力。 Vue 提供了一个 Api 可以解决此问题, **withDefaults **编译器哄解决。 withDefaults 可以提供默认值的类型检查

typescript 复制代码
interface MyProps {
  phone: string | number,
  name ?: string,
  age : number | string
  hobby: {
    type: string,
    required: true
  }
}

const props =  withDefaults(defineProps<MyProps>(),{
  name:'张三',
  phone: '123123123123'
})

用ts能帮助开发人员更好的设计和开发组件

4.Emits 类型标注

typescript 复制代码
const emit = defineEmits<{
  (e: 'getId', id: number): void
}>()


emit('getId',2)

基于类型的声明使我们可以对所触发事件的类型进行更细粒度的控制

5.reactive 标注类型

通过一个接口来约束类型

typescript 复制代码
interface StudentInfoFormat {
  name: string,
  id: number,
  age: number,
  hobby ?: string
}
const info : StudentInfoFormat = reactive({name:'张三',id:2})

这样就有很好的类型提示。

6.为 ref() 标注类型

1.通过泛型参数的形式来给 ref()增加类型

typescript 复制代码
import { ref } from 'vue'
const testValue = ref<string | number>(100)

2.复杂类型可以定义interface等,然后再写进泛型中

typescript 复制代码
import { ref } from 'vue'
interface User {
  name: string
  age: string | number
}
const user = ref<User>({
  name:'前端开发爱好者',
  age: 20
})

7.computed 标注类型

typescript 复制代码
import { ref, computed } from 'vue'
//computed() 会自动从其计算函数的返回值上推导出类型
const count = ref(0)

// 推导得到的类型:ComputedRef<number>
const double = computed(() => count.value * 2)

// => TS Error: Property 'split' does not exist on type 'number'
const result = double.value.split('')
//泛型参数指定返回类型
interface User {
  name: string
  age: string | number
}
const userComputed = computed<User[]>(() => ([  { name: '前端开发爱好者', age: 20}]))

8.模板ref标注类型

有时,我们需要通过原生DOM 做一些操作,就需要获取到原生DOM.

html 复制代码
<el-input v-model="str" placeholder="" size="normal" clearable @change="" ref="formInputRef"></el-input>
//模板引用需要通过一个显式指定的泛型参数和一个初始值 null 来创建还有HTMLDivElement

const formInputRef = ref<HTMLInputElement | null>(null)

前端所有元素标签在ts中的类型

typescript 复制代码
interface Type {
    "a": HTMLAnchorElement;
    "abbr": HTMLElement;
    "address": HTMLElement;
    "applet": HTMLAppletElement;
    "area": HTMLAreaElement;
    "article": HTMLElement;
    "aside": HTMLElement;
    "audio": HTMLAudioElement;
    "b": HTMLElement;
    "base": HTMLBaseElement;
    "bdi": HTMLElement;
    "bdo": HTMLElement;
    "blockquote": HTMLQuoteElement;
    "body": HTMLBodyElement;
    "br": HTMLBRElement;
    "button": HTMLButtonElement;
    "canvas": HTMLCanvasElement;
    "caption": HTMLTableCaptionElement;
    "cite": HTMLElement;
    "code": HTMLElement;
    "col": HTMLTableColElement;
    "colgroup": HTMLTableColElement;
    "data": HTMLDataElement;
    "datalist": HTMLDataListElement;
    "dd": HTMLElement;
    "del": HTMLModElement;
    "details": HTMLDetailsElement;
    "dfn": HTMLElement;
    "dialog": HTMLDialogElement;
    "dir": HTMLDirectoryElement;
    "div": HTMLDivElement;
    "dl": HTMLDListElement;
    "dt": HTMLElement;
    "em": HTMLElement;
    "embed": HTMLEmbedElement;
    "fieldset": HTMLFieldSetElement;
    "figcaption": HTMLElement;
    "figure": HTMLElement;
    "font": HTMLFontElement;
    "footer": HTMLElement;
    "form": HTMLFormElement;
    "frame": HTMLFrameElement;
    "frameset": HTMLFrameSetElement;
    "h1": HTMLHeadingElement;
    "h2": HTMLHeadingElement;
    "h3": HTMLHeadingElement;
    "h4": HTMLHeadingElement;
    "h5": HTMLHeadingElement;
    "h6": HTMLHeadingElement;
    "head": HTMLHeadElement;
    "header": HTMLElement;
    "hgroup": HTMLElement;
    "hr": HTMLHRElement;
    "html": HTMLHtmlElement;
    "i": HTMLElement;
    "iframe": HTMLIFrameElement;
    "img": HTMLImageElement;
    "input": HTMLInputElement;
    "ins": HTMLModElement;
    "kbd": HTMLElement;
    "label": HTMLLabelElement;
    "legend": HTMLLegendElement;
    "li": HTMLLIElement;
    "link": HTMLLinkElement;
    "main": HTMLElement;
    "map": HTMLMapElement;
    "mark": HTMLElement;
    "marquee": HTMLMarqueeElement;
    "menu": HTMLMenuElement;
    "meta": HTMLMetaElement;
    "meter": HTMLMeterElement;
    "nav": HTMLElement;
    "noscript": HTMLElement;
    "object": HTMLObjectElement;
    "ol": HTMLOListElement;
    "optgroup": HTMLOptGroupElement;
    "option": HTMLOptionElement;
    "output": HTMLOutputElement;
    "p": HTMLParagraphElement;
    "param": HTMLParamElement;
    "picture": HTMLPictureElement;
    "pre": HTMLPreElement;
    "progress": HTMLProgressElement;
    "q": HTMLQuoteElement;
    "rp": HTMLElement;
    "rt": HTMLElement;
    "ruby": HTMLElement;
    "s": HTMLElement;
    "samp": HTMLElement;
    "script": HTMLScriptElement;
    "section": HTMLElement;
    "select": HTMLSelectElement;
    "slot": HTMLSlotElement;
    "small": HTMLElement;
    "source": HTMLSourceElement;
    "span": HTMLSpanElement;
    "strong": HTMLElement;
    "style": HTMLStyleElement;
    "sub": HTMLElement;
    "summary": HTMLElement;
    "sup": HTMLElement;
    "table": HTMLTableElement;
    "tbody": HTMLTableSectionElement;
    "td": HTMLTableDataCellElement;
    "template": HTMLTemplateElement;
    "textarea": HTMLTextAreaElement;
    "tfoot": HTMLTableSectionElement;
    "th": HTMLTableHeaderCellElement;
    "thead": HTMLTableSectionElement;
    "time": HTMLTimeElement;
    "title": HTMLTitleElement;
    "tr": HTMLTableRowElement;
    "track": HTMLTrackElement;
    "u": HTMLElement;
    "ul": HTMLUListElement;
    "var": HTMLElement;
    "video": HTMLVideoElement;
    "wbr": HTMLElement;
}

9.获取子组件的类型

有时候,我们需要直接操作子组件来获取它的状态和方法。 在Vue2.x 中,我们可以直接在子组件中绑定ref,然后通过 this.$refs.绑定的ref 就可以使用了。 在 Vue 3中,我们也是如此。但是在组合式API 中,调用的时候,不用this了,通过 ref.value 来操作。

**想要给给子组件标注类型时: ** 我们就需要先通过 typeof 来 获取组件的类型,然后通过TypeScript 内置的InstanceType 工具类型来获取其实例类型,就可以操作子组件了

typescript 复制代码
<script setup lang="ts">
	import TsComponent from '../TsComponent/index.vue'

	const tsRef = ref<InstanceType<typeof TsComponent> | null>(null)

	tsRef.value?.alerTest('测试')    //调用子组件方法
</script>

10.原生事件函数标注类型

在处理原生 DOM 事件时,应该为我们传递给事件处理函数的参数正确地标注类型

typescript 复制代码
<input type="text" @change="change">
const change = (e : Event) => {
    console.log((e.target as HTMLInputElement).value)
}
相关推荐
神之王楠3 分钟前
如何通过js加载css和html
javascript·css·html
余生H8 分钟前
前端的全栈混合之路Meteor篇:关于前后端分离及与各框架的对比
前端·javascript·node.js·全栈
花花鱼8 分钟前
@antv/x6 导出图片下载,或者导出图片为base64由后端去处理。
vue.js
程序员-珍10 分钟前
使用openapi生成前端请求文件报错 ‘Token “Integer“ does not exist.‘
java·前端·spring boot·后端·restful·个人开发
axihaihai15 分钟前
网站开发的发展(后端路由/前后端分离/前端路由)
前端
流烟默27 分钟前
Vue中watch监听属性的一些应用总结
前端·javascript·vue.js·watch
2401_8572979137 分钟前
招联金融2025校招内推
java·前端·算法·金融·求职招聘
茶卡盐佑星_1 小时前
meta标签作用/SEO优化
前端·javascript·html
与衫1 小时前
掌握嵌套子查询:复杂 SQL 中 * 列的准确表列关系
android·javascript·sql
Ink1 小时前
从底层看 path.resolve 实现
前端·node.js