Today , I will share script setup
with typescript
you some of the techniques used in combination. If these techniques can help you, remember to give me a like 👍
Environment construction
The environment construction will not be introduced in detail here, you can directly use the official method to create
npm init vue@latest
This command will install and execute create-vue
, it is the Vue
official project scaffolding tool. You'll TypeScript
see 测试
hints for optional features like and support:
✔ Project name: … <your-project-name>
✔ Add TypeScript? … No / Yes
✔ Add JSX Support? … No / Yes
✔ Add Vue Router for Single Page Application development? … No / Yes
✔ Add Pinia for state management? … No / Yes
✔ Add Vitest for Unit testing? … No / Yes
✔ Add Cypress for both Unit and End-to-End testing? … No / Yes
✔ Add ESLint for code quality? … No / Yes
✔ Add Prettier for code formatting? … No / Yes
Scaffolding project in ./<your-project-name>...
Done.
If you are not sure whether to enable a function, you can directly press the Enter key to select No
. After the project is created, install the dependencies and start the development server with the following steps:
cd <your-project-name>
npm install
npm run dev
ref()
ref()
Takes an internal value and returns a reactive, mutable ref
object that has only one pointer to its internal value property .value
.
type definition
function ref<T>(value: T): Ref<UnwrapRef<T>>
interface Ref<T> {
value: T
}
Annotate the type for ref()
ref()
There are three ways to label types:
-
ref()
Add a type to by the form of a generic parameter
import { ref } from 'vue'
const initCode = ref<string | number>('200')
-
If it is a type that encounters complex points, you can customize interface
it and then pass it in as a generic parameter
import { ref } from 'vue'
interface User {
name: string
age: string | number
}
const user = ref<User>({
name:'前端开发爱好者',
age: 20
})
-
Specify a more complex type for the value within by using Ref
this typeref
import { ref } from 'vue'
import type { Ref } from 'vue'
const initCode: Ref<string | number> = ref('200')
Three ways to recommend
It is recommended to use the 前两种
method. The first two methods are actually 泛型
marked in the form of
The third way requires an additional import:
import type { Ref } from 'vue'
So it is not very recommended (in line with the principle that one line can be written less is one line)
reactive()
reactive()
A reactive proxy that returns an object.
type definition
function reactive<T extends object>(target: T): UnwrapNestedRefs<T>
Annotate types for reactive()
reactive()
There are two ways to label types:
-
Add the type directly to the declared variable
import { reactive } from 'vue'
interface User {
name: string
age: string | number
}
const user:User = reactive({
name:"前端开发爱好者",
age:'20'
})
-
reactive()
Add a type to by the form of a generic parameter
import { reactive } from 'vue'
interface User {
name: string
age: string | number
}
const user = reactive<User>({
name:"前端开发爱好者",
age:'20'
})
Two ways are recommended
不推荐
Use reactive()
a generic parameter of , because the return value of deep ref unpacking is handled with a different type than the generic parameter. 推荐直接给声明的变量添加类型
.
computed()
Takes a getter
function and returns a read-only reactive ref
object, the return value of the getter
function . It can also accept get
an set
object with and functions to create a writable ref
object .
type definition
// 只读
function computed<T>(
getter: () => T,
debuggerOptions?: DebuggerOptions
): Readonly<Ref<Readonly<T>>>
// 可写的
function computed<T>(
options: {
get: () => T
set: (value: T) => void
},
debuggerOptions?: DebuggerOptions
): Ref<T>
Annotate the type for computed()
computed()
There are two ways to label types:
-
The type is deduced from the return value of its computed function
import { ref, computed } from 'vue'
const count = ref<number>(0)
// 推导得到的类型:ComputedRef<string>
const user = computed(() => count.value + '前端开发爱好者')
-
Explicitly specify the computed()
type
const user = computed<string>(() => {
// 若返回值不是 string 类型则会报错
return '前端开发爱好者'
})
Two ways are recommended
Although automatic type deduction is simple and fast, we still want 手动
to remove 指定
its type, which is more conducive to the maintainability of the code, so it is recommended that you use the generic parameter to explicitly specify the computed()
type
defineProps()
To get full type inference support when declaring props
options , we can use the defineProps
API, which will automatically be used script setup
in
Annotate types for defineProps()
-
Deduce the type from its arguments:
const props = defineProps({
name: { type: String, required: true },
age: Number
})
-
props
The type of is defined by a generic parameter
const props = defineProps<{
name: string
age?: number
}>()
Of course, we can also define the above generic parameters as a separateinterface
interface Props {
name: string
age?: number
}
const props = defineProps<Props>()
Although the above two methods can be very convenient
标注类型
, they lose the ability toprops
define default values.
At present, the official solution has also been given, but this solution is still experimental and required 显式地选择开启
.
// vite.config.js
export default {
plugins: [
vue({
reactivityTransform: true
})
]
}
defineProps()
Defaults are added via reactive destructuring of :
<script setup lang="ts">
interface Props {
name: string
age?: number
}
const { name = '前端开发爱好者', age = 100 } = defineProps<Props>()
</script>
defineEmits()
To get full type inference support when declaring emits
options , we can use the defineEmits
API, which will automatically be used script setup
in
Annotate types for defineEmits()
defineEmits()
Annotation Type Direct Recommendation 泛型
Form
import type { GlobalTheme } from 'naive-ui'
const emit = defineEmits<{
(e: 'setThemeColor', val: GlobalTheme): void
}>()
Although the official also recommends 运行时
a form of automatic derivation, but I do not recommend it very much
defineExpose()
defineExpose()
Compiler macros to explicitly specify the script setup
components to be exposed in the component property
, so that the parent component 模板ref
can obtain the instance of the current component by means of
Annotate types for defineExpose()
defineExpose()
Type deduction can directly use the parameter type to automatically deduce
<script setup>
import { ref } from 'vue'
const name = ref<string>('前端开发爱好者')
defineExpose({
name
})
provide()
provide()
Provides a value that can be injected by descendant components
type definition
function provide<T>(key: InjectionKey<T> | string, value: T): void
Annotate the type for provide()
For provide()
annotated types, Vue provides an InjectionKey
interface, which is Symbol
a and can be used to synchronize the type of injected values between providers and consumers
import type { InjectionKey } from 'vue'
// 建议声明 key (name) 放到公共的文件中
// 这样就可以在 inject 的时候直接导入使用
const name = Symbol() as InjectionKey<string>
provide(name, '前端开发爱好者') // 若提供的是非字符串值会导致错误
The above method is to mark the type by defining the type of the key, and there is another method to directly key
use 字符串
the form to add
provide('name', '前端开发爱好者')
inject()
inject()
Inject a value supplied by an ancestor component or the entire application
type definition
// 没有默认值
function inject<T>(key: InjectionKey<T> | string): T | undefined
// 带有默认值
function inject<T>(key: InjectionKey<T> | string, defaultValue: T): T
// 使用工厂函数
function inject<T>(
key: InjectionKey<T> | string,
defaultValue: () => T,
treatDefaultAsFactory: true
): T
Annotate the type for inject()
provide()
key
The type of is provided declaratively (the first form of the provide() type annotation)
inject()
You can directly import the declared key
to get the value provided by the parent component
// 由外部导入
const name = Symbol() as InjectionKey<string>
const injectName = inject(name)
If provide()
the key
directly used 字符串
form is added, it needs to be declared through the generic parameter
const injectName = inject<string>('name')
template ref
Templates ref
need to be created with an explicitly specified 泛型参数
and a 初始值 null
:
<img ref="el" class="logo" :src="Logo" alt="" />
const el = ref<HTMLImageElement | null>(null)
component ref
Sometimes, you may need to add a template ref to a child component in order to call the methods it exposes
<!-- Child.vue -->
<script setup lang="ts">
const handleLog = () => console.log('前端开发爱好者')
defineExpose({
open
})
</script>
In order to get MyModal
the type of , we first need to typeof
get its type through , and then use the TypeScript
built- in InstanceType
tool type to get its instance type:
<!-- parent.vue -->
<script setup lang="ts">
import Child from './Child.vue'
// 为子组件 ref 声明类型
const child = ref<InstanceType<typeof Child> | null>(null)
// 调用子组件中的方法
const getChildHandleLog = () => {
child.value?.handleLog()
}
</script>
event handler
Native DOM event annotation type
<template>
<input type="text" @change="handleChange" />
</template>
<script setup lang="ts">
function handleChange(event: Event) {
console.log((event.target as HTMLInputElement).value)
}
</script>
- EOF -
1. The wind and rain of Xidian and Chengdian
2. TikTok officially announced that it will store data on Oracle servers!
3. If the programmer is in jail, will he be arranged to write code?
Pay attention to "programmers' things" and star, don't miss things in the circle
Like and watching is the biggest support ❤️