美文网首页
VueTypes - vue props定义工具入门

VueTypes - vue props定义工具入门

作者: copyLeft | 来源:发表于2021-12-12 02:28 被阅读0次

    VueTypes vue props 类型定义工具, 使用链式调用的方式定义vue props

    简单例子

    <pre>import { string, number, array } from 'vue-types'
    {
    props: {
    title: string().def(''),
    count: number().def(0),
    menu: array<string>().def([])
    }
    }
    // 等价
    {
    props: {
    title: {
    type: String,
    default: ''
    },
    count: {
    type: Number,
    default: 0
    },
    menu: {
    type: Array as PropType<string[]>,
    default: []
    }
    }
    }</pre>

    比较之下, vueTypes 的编写方式要简洁不少。

    安装

    <pre>npm install vue-types --save
    or
    yarn add vue-types
    or
    pnpm i -S vue-types</pre>

    基础使用

    个人觉得TS环境下才是该工具的目标场景,所以下面默认在TS环境下。JS环境内的使用其他大致相同。

    类型定义函子

    官方文档说明,每一种类型定义工具都是一个返回vue props validation 的函子, 所以都是以函数调用的方式返回所需的类型定义

    • any 任意类型

    <pre>{
    content: any(),
    // 可接收具体的指定类型
    content: any<unknown>(),
    content: any<string>(),
    }</pre>

    觉得可以将 any() 看作其他类型定义的父类或原方法

    • bool 布尔

    <pre>{
    disabled: bool()
    }</pre>

    • string 字符

    <pre> enum Type {
    success = 'success',
    fail = 'fail'
    }
    {
    // 基础string类型
    title: string(),
    // 范围限制
    type: string<'success' | 'fail>, // 联合类型
    type: string<Type>(), // 枚举
    }
    // 枚举和联合类型,主要的区别在使用和指定默认值时

    // 联合类型使用模式匹配
    {
    // 指定默认值
    type: string<'success' | 'fail'>().def('success')
    }
    // 枚举必须使用指定的枚举值
    {
    type: string<Type>().def(Type.success)
    }
    // 所以枚举具有更强的约束性,联合类型具有更好的适应性。</pre>

    • number / integer 数字

    <pre>{
    // 基础类型
    pageNum: number(), // number
    // 范围限制
    pageSize number<10, 20, 50, 100>(),// 10 | 20 | 50 | 100
    // 整数
    jumpNum: integer()
    }</pre>

    • array 数组

    <pre>{
    // 任意数组
    list: array(), // unknown[]
    // 指定类型
    menu: array<string>(), // string[]
    // array 为泛型函数, 接收具体的数组元素类型
    }</pre>

    • Object 对象

    <pre>interface UserO {
    id: string
    name: string
    }
    class UserC{
    constructor( public name: string, public id: string ){
    }
    }
    {
    // 任意对象
    data: object // { [k: string]: any }
    // 指定类型
    usero: object<UserO>
    userc: object<UserC>
    }
    // 这里 userO userC 也符合模式匹配规则
    {
    user: object<UserO>.def(new UserC('name', 'id'))
    }</pre>

    • func 函数

    <pre>{
    // 任意函数
    action: func() // (...args: any[]) => any
    // 指定类型
    formatter: func<(s: string) => string>()
    onClick: func<(e: Event) => void>()
    }</pre>

    • symbol

    <pre>{
    valueKey: symbol()
    }</pre>

    公共方法

    所有类型定义函数都具有公共的工具方法

    • def 设置默认值

    <pre>{
    name: string().def(''),
    age: number().def(0),
    hobby: array<string>().def(() => ['sleep']),
    father: Object<Man>().def(() => ({...}))
    }</pre>

    • isRequired 必填

    <pre>{
    content: string().isRequired
    }</pre>

    校验函数

    • instanceOf 校验值是否属于某一类型

    <pre> class User{...}
    {
    user: instanceOf(User),
    title: instanceOf(String)
    }</pre>

    • oneOf 值必须为指定范围内的任一值

    <pre>{
    type: oneOf<'success' | 'fail'>(['success', 'fail']),
    // 等价定义
    type: onOf<['success', 'fail']>([''success', 'fail']),
    // 如果不指定具体的联合类型或元组, 自动推导的类型可能存在差异, 这由TS本身所决定的
    type: oneOf(['success', 'fail']) // string[]
    }
    // 需要注意的是,存在类似 oneOf 的定义,但行为不同
    {
    type: string<'success' | 'fail'>().isRequired
    // 虽然我们限定了 type 的类型值, 但是实际运行时,只会校验值是否存在,不会校验具体值是否在指定的
    // 类型范围内, 毕竟类型定义属于TS范围,并不参与实际的运行时
    } </pre>

    • oneOfType 值必须为指定范围内的任意定义

    <pre>{
    data: oneOfType([string(), Number, Object<User>() ]),
    // oneOfType 将校验传入的值,是否在指定类型内, 且可以与类型定义函数组合使用
    }
    // 需要注意的是,oneOfType 内部接收的是类型, 类型定义的公共函数是无效的
    {
    key: oneOfType([ string().def('defKey'), number() ]).isRequired
    // 这里 string().def('defKey') 是无效的,并不能屏蔽 isRequired
    }</pre>

    • arrayOf 指定数组类型校验

    <pre>{
    // 单一类型
    keys: arrayOf(String),
    // 联合类型
    keys: arrayOf(oneOfType([ string(), number()])) // string[] | number[]
    }</pre>

    • objectOf 对象属性值校验

    <pre>{
    maps: ObjectOf(string()).def({source: 'xx'}),
    maps: ObjectOf(string()).def({source: 00}), //将报错, 对象内的所有属性值必须满足类型定义
    }
    // 可以与oneOfType 一起使用
    {
    keys: objectOf(oneOfType([string(), number()])).def({a: 'k', b: 10})
    }
    // 虽然也可以与 oneOf 一起使用但结果并不如定义的预期
    {
    keys: ObjectOf(oneOf(['a', 'b'])).def({ key: 'xxx' })
    // 值并不能被限制为 'a' 'b', 这里属性值类型将被解析为 string
    }</pre>

    • shape 定义对象的具体结构

    <pre> interface User{
    name: string
    age: number
    }

    {
    user: shape<User>({
    name: string(),
    age: number()
    })
    }</pre>

    • custom 自定义校验函数

    <pre>interface Anime{
    type: string
    [k: string]: unknown
    }

    function isMonkey(a: Anime){
    return a.type === 'monkey'
    }

    export const props ={
    monkey: custom(isMonkey),
    // 等价
    monkey: {
    type: Object as PropType<Anime>,
    validator: isMonkey
    }
    }</pre>

    命名空间

    vueTypes 提供命名空间,可以将常用的定义或规则挂载在指定的命名空间下,方便调用。

    内置命名空间 , VueTypes

    <pre>import VueTypes, {string} from 'vue-types
    {
    message: VueTypes.string.isRequired,
    // 等价
    message: string().def('').isRequired
    }</pre>

    具体包含的函数以及规则,可查看官方文档

    自定义规则 / 扩展

    <pre>// custom-type.ts
    import VueTypes, {
    VueTypesInterface,
    VueTypeDef,
    } from 'vue-types'

    class Anime{
    constructor(public type: string){}
    }

    interface AnimeType extends VueTypesInterface{
    anime(type: string): VueTypeDef<Anime>
    }

    export const newTypes = VueTypes.extend<AnimeType>([
    {
    name: 'animeType',
    type: Object,
    validator: (type:string, v: Anime) => v.type === type
    }
    ])

    // component.vue
    {
    props: {
    monkey: newTypes.animeType('monkey')
    }
    }</pre>

    自定命名空间

    <pre>// 官方例子
    // core/types.js
    import VueTypes from 'vue-types'

    VueTypes.sensibleDefaults = {
    ...VueTypes.sensibleDefaults,
    string: 'hello',
    }

    // core/component.vue
    import VueTypes from './types'

    export default {
    props: {
    greeting: VueTypes.string, // default is 'hello'
    },
    }</pre>

    总结

    vue-types 提供了一种 props 定义和复用的方式,提高编写效率。但毕竟属于一类方言工具, 还是有学习和维护成本的。

    毕竟vue 的属性,方法已经够多的了。

    相关文章

      网友评论

          本文标题:VueTypes - vue props定义工具入门

          本文链接:https://www.haomeiwen.com/subject/kgalfrtx.html