typescript针对html元素如何使用
让我通过实例来说明 TypeScript 如何处理 HTML 元素:
- DOM 元素类型
// 基础元素引用
const menuContainer = ref<HTMLDivElement | null>(null)
const priceInput = ref<HTMLInputElement | null>(null)
const foodImage = ref<HTMLImageElement | null>(null)
// 在模板中使用
<template>
<div ref="menuContainer">
<input ref="priceInput" type="number" />
<img ref="foodImage" :src="imageUrl" />
</div>
</template>
- 事件处理
// 事件类型定义
function handleClick(event: MouseEvent): void {
console.log(event.clientX, event.clientY)
}
function handleInput(event: InputEvent): void {
const target = event.target as HTMLInputElement
console.log(target.value)
}
// 在模板中使用
<template>
<button @click="handleClick">点击</button>
<input @input="handleInput" />
</template>
- 自定义事件
// 定义事件类型
interface OrderEvent {
orderId: string
dishes: MenuItem[]
}
// 事件处理函数
function handleOrder(event: OrderEvent): void {
console.log(`订单 ${event.orderId} 包含 ${event.dishes.length} 个菜品`)
}
// 发出事件
const emit = defineEmits<{
(event: 'order', payload: OrderEvent): void
(event: 'cancel'): void
}>()
- 表单元素处理
interface FormElements extends HTMLFormControlsCollection {
username: HTMLInputElement
password: HTMLInputElement
}
interface OrderForm extends HTMLFormElement {
readonly elements: FormElements
}
function handleSubmit(event: SubmitEvent) {
event.preventDefault()
const form = event.target as OrderForm
const username = form.elements.username.value
const password = form.elements.password.value
}
// 在模板中使用
<template>
<form @submit="handleSubmit">
<input name="username" type="text" />
<input name="password" type="password" />
<button type="submit">提交</button>
</form>
</template>
- ref 和 reactive 的类型定义
// ref 的类型定义
const selectedDish = ref<MenuItem | null>(null)
const dishList = ref<MenuItem[]>([])
// reactive 的类型定义
interface State {
cart: MenuItem[]
totalPrice: number
isLoading: boolean
}
const state = reactive<State>({
cart: [],
totalPrice: 0,
isLoading: false
})
- 组件 Props 类型定义
// 定义 Props 接口
interface MenuProps {
category: string
dishes: MenuItem[]
isActive?: boolean // 可选属性
}
// 在组件中使用
defineProps<MenuProps>()
// 或者使用 withDefaults
withDefaults(defineProps<MenuProps>(), {
isActive: false
})
- 常见的 HTML 元素事件类型
// 鼠标事件
function handleMouseEvent(event: MouseEvent): void {
console.log(event.clientX, event.clientY)
}
// 键盘事件
function handleKeyEvent(event: KeyboardEvent): void {
if (event.key === 'Enter') {
// 处理回车键
}
}
// 触摸事件
function handleTouchEvent(event: TouchEvent): void {
const touch = event.touches[0]
console.log(touch.clientX, touch.clientY)
}
// 在模板中使用
<template>
<div
@mouseenter="handleMouseEvent"
@keydown="handleKeyEvent"
@touchstart="handleTouchEvent"
>
交互区域
</div>
</template>
- 自定义组件的 ref 类型
// 定义组件接口
interface MenuComponent {
reload: () => void
clear: () => void
}
// 使用组件 ref
const menuRef = ref<MenuComponent | null>(null)
// 调用组件方法
function refreshMenu() {
menuRef.value?.reload()
}
// 在模板中使用
<template>
<menu-component ref="menuRef" />
</template>
- 错误处理示例
// ❌ 错误示例
const element = document.querySelector('.menu') // 类型推断为 Element | null
// ✅ 正确示例
const element = document.querySelector('.menu') as HTMLDivElement
// 或者
const element = document.querySelector<HTMLDivElement>('.menu')
使用建议:
- 总是为 ref 和事件处理函数定义具体类型
- 使用 TypeScript 内置的 DOM 类型定义
- 避免使用
any
类型 - 利用 IDE 的类型提示功能
- 合理使用类型断言(as)
这些类型定义可以帮助你:
- 在开发时捕获潜在错误
- 提供更好的代码提示
- 提高代码的可维护性
- 使代码更加健壮