封装第三方 UI 组件库
会想让 自定义的组件 能兼容 第三方的 类型,但会有如下的限制。
1. Vue3 setup 的 Typescript 语法限制
Ts 和 组合式 API setup 有语法上的限制。
接口或对象字面类型可以包含从其他文件导入的类型引用,但是,传递给 defineProps 的泛型参数本身不能是一个导入的类型:
import { Props } from './other-file'
// 不支持!
// 这是因为 Vue 组件是单独编译的,编译器目前不会抓取导入的文件以分析源类型。我们计划在未来的版本中解决这个限制。
defineProps<Props>()
2. 解决方案
上面说了,接口或对象字面量可以从其他文件导入类型。。那么
有两种方式解决:
- 使用 泛型 声明,但是使用 Vue 支持的 对同一个文件中的一个接口或对象类型字面量的引用
- 使用
defineProps运行时声明。 即在defineProps(buttonProps)参数里传入buttonProps类型值
import { Props, buttonProps } from './other-file'
// 1. 将 Props类型 定义当前文件内
interface Props2 extends <Props> {}
defineProps<Props2>() // 支持
interface Props3 {
props: Props
}
defineProps<Props3>() // 支持
// 2. 使用 buttonProps 传值给 defineProps
defineProps(buttonProps) // 支持
也可以使用普通的 组合 API + 选项 API 的模式
import { toRaw } from 'vue'
import { buttonProps } from 'element-plus'
import { defineComponent } from 'vue'
export default defineComponent({
// 组合api的props要求传一个值的,不能传递类型
// 所以这里不能用 ButtonProps,而需要使用 buttonProps
props: {
...buttonProps,
},
setup(props, context) {
return {
newProps: toRaw(props),
}
},
})