TypeScriptデコレータを使用して、Vueにフォーム検証やその他の興味深い機能を実装します

序文

みなさん、こんにちは。最後のひばなです。

Typescriptデコレータは、非常に興味深い宣言方法です。デコレータを使用すると、プロキシパターンを簡単に実装して、コードをより簡潔にし、他のより興味深い機能を実現できます。前回の記事で、デコレータと自作のValidatorクラスを使用してフォーム検証を実装する方法を紹介しました。VUEでTypeScriptデコレータをフォーム検証を実装する方法を紹介しました。まだご覧になっていない場合は、最初にその記事にアクセスしてください。class-validator次に、別の方法を使用してフォーム検証を実装します。

useValidatorを使用する

useValidatorを使用する前に、前に記述したフォームクラスがどのように見えるかを見てみましょう。

class Profile {
    @IsOptional()
    avatar?: string

    @Length(2, 4, {message: '姓名长度应在2到4间'})
    realName: string

    @IsOptional()
    description?: string
}

@Reactive()
export class CreateUserForm extends Validator {
    @Length(4, 12, { message: '用户名长度应在4到12间' })
    username: string = ''

    @IsEmail({}, { message: '请填写正确的邮箱' })
    email: string = ''

    @IsMobilePhone('zh-CN', null, { message: '请输入正确的手机号码' })
    phone: string = ''

    @MinLength(4, { message: '密码长度不应低于4' })
    @MaxLength(12, { message: '密码长度不应大于12' })
    password: string = ''
 
    @Type(() => Profile)
    @ValidateNested()
    profile: Profile = new Profile()
}
复制代码

その中で、@ ReactiveデコレータとValidatorクラスは自分でカプセル化されており、他のフォーム検証デコレータはclass-validatorライブラリを使用しています。今は問題ないようですが、フォームが多い場合は、各フォームで@Reactiveを使用し、Validatorクラスを継承する必要があります。関連するフォームがあり、関連するフォームもValidatorクラスを継承している場合、非常に肥大化します。 。

export default defineComponent({
setup() {
    const form = new CreateUserForm()
    return  () => 
        <div>
            <field label='用户名' v-model={form.username} error={form.getError().username}></field>
            <field label='姓名' v-model={form.profile.realName} error={form.getError().profile?.realName}></field>
            <field label='邮箱' v-model={form.email} error={form.getError().email}></field>
            <field label='手机' v-model={form.phone} error={form.getError().phone}></field>
            <field label='密码' v-model={form.password} error={form.getError().password}></field>
            <button onClick={() => form.validate()}>验证</button>
            <button onClick={() => form.clearError()}>清空错误</button>
        </div> 
}})
复制代码

インスタンスからのフォームはValidatorクラスを継承し、getErrorやvalidateなどのメソッドを持っています。

フォームクラスが非常に純粋なクラスであり、検証フォームに使用されるフォームとデコレータのみであることを願っています。将来、他のニーズがある場合、拡張機能も非常に便利であり、継承後に純粋ではなくなります。 Validatorクラス。

その後、フォームとフォーム検証に関連するフォームとフォーム検証を区別するためにuseValidatorメソッドを実装しました。useValidatorの使用法は次のようになります。

export default defineComponent({
setup() {
    //往里面传入表单类,然后可以返回这些对象和方法,想用什么就解构出什么。
    const { form, errors, validateForm, clearError, toInit, toJSON } = useValidator(CreateUserForm)
    return () => (
            <div class='container'>
                <field label='用户名' v-model={form.username} error={errors.username}></field> 
                <field label='姓名' v-model={form.profile.avatar} error={errors.profile?.avatar}></field>
                <field label='邮箱' v-model={form.email} error={errors.email}></field>
                <field label='手机' v-model={form.phone} error={errors.phone}></field>
                <field label='密码' v-model={form.password} error={errors.password}></field>
                <div>
                    <button onClick={() => validateForm()}>验证</button>
                    <button onClick={() => clearError()}>取消验证</button>
                    <button onClick={() => toInit()}>初始化</button>
                </div>
            </div>
        )
}
})
复制代码

このように、useValidatorメソッドによって返される値は、各関数を明確に区別でき、フォームは単なる純粋なフォームです。必要な関数を分解します。

もちろん、内部の関数は継承されたクラスに似ていますが、1つはクラスのメソッドを呼び出すことであり、もう1つは関数によって返されるメソッドを使用することです。また、個人的な好みも少しあります。

PS:以下に示すように、非常に明確なコードプロンプトであるフォームデコレータを使用することには別の利点があります。

tip.gif

このプロパティのフォーム検証がどのように見えるかを知る必要はありません。プロパティで直接確認できますが、非常に便利ではありません。

フォームの初期値を動的に設定

前回の記事で、フォームの初期値はインターフェースを介して動的に設定されると述べたので、単純に実装します。たとえば、@ InjectUsernameを使用して初期値をusernameに設定すると、最后的Hibanausernameという値が返されます。

class CreateUserForm {
    @InjectUsername()
    @Length(4, 12, { message: '用户名长度应在4到12间'})
    username: string = ''
    //其他....
}
复制代码

@InjectUsernameデコレータを簡単に実装しましょう。

const api = {
    //一个获取用户名的api
    getUsername() {
        return Promise.resolve('最后的Hibana')
    }
}

const InjectUsername = () => (target: any, key: string) =>
    // 定义一个叫'inject:username'的元数据,传入获取用户名api的方法
    Reflect.defineMetadata('inject', api.getUsername, target, key)

// useInject来实现将api返回的值写入到username中
function useInject<T extends object>(form: T) {
    for (const key in form) {
        const api = Reflect.getMetadata('inject', form, key)
        if (api) {
            api().then(res => {
                form[key] = res
            })
        }
    }
}
复制代码

使い方も非常に簡単で、useInjectを呼び出すだけで、ユーザー名を動的に割り当てることができます。

export default defineComponent({
setup() {
    //往里面传入表单类,然后可以返回这些对象和方法,想用什么就解构出什么。
    const { form, errors, validateForm, clearError, toInit, toJSON } = useValidator(CreateUserForm)
    useInject(form)
    return () => ( 
         <div>
             {/* ..... */} 
         </div>
        )
}
})
复制代码

デコレータを使用しない場合は、セットアップでインターフェイスを呼び出して値を割り当てる必要があるかもしれません。デコレータを使用した後は、これらの操作を非表示にするのに役立ちます。

注:ここで実装したのは最も簡単な書き方です。実際、注意すべき詳細がたくさんあります。たとえば、呼び出されるほとんどのAPIインターフェイスはパラメーターを渡す必要があるため、パラメーターをどのように渡す必要がありますか?割り当てのデコレーターは、より一般的なものとして作成することもできます。useInjectは、読み込み、エラーなど、より多くの状態を返すことができます。 。、それも可能ですか?このパラメーターを渡します。

Typescriptデコレータ拡張

実際、デコレータはフォームクラスだけでなく、vueコンポーネント(クラスで記述されたもの)でも使用できます。ここでは、デコレータの可能な使用法の例も簡単に示します。

class Page {
    itemList = ref([])
    //可以实现一个Watch装饰器,监听params变化
    @Watch(page => page.loadData())
    params = reactive({
        pageIndex: 1,
        pageSize: 15,
        //...
    })

    loading = ref(false)

    @Message('加载成功','获取数据失败') // 成功/错误 消息提示
    @Loading() // 自动设置loading状态
    async loadData() {
        this.itemList = await getItemList(this.params)
    }
    
    @Debounce(1000) // debounce防止多次点击
    handleLoadClick() {
        this.loadData()
    }
}
复制代码

次に、おそらくこのように、セットアップで使用します。

export default defineComponent({
    setup() {
        const {itemList,loading,handleLoadClick} = useInject(Page)
        // ....
    }
})
复制代码

ここでは、これらのデコレータの書き込み方法を実装しません。興味のある友人は、自分でそれを試すことができます。

終わり

この記事では、フォーム検証を実装するためのuseValidatorメソッドと、デコレータの使用法を紹介しました。最初に述べたように、Typescriptデコレータは非常に興味深い宣言方法であり、デコレータはプロキシパターンを簡単に実装して、コードをより簡潔にし、他のより興味深い機能を実現できます。デコレータへの興味をかき立てられることを願っています。

さらに、フォームの検証に関連するコードに関心がある場合は、AndSpark / vue-class-validator(github.com)にアクセスできます。

おすすめ

転載: juejin.im/post/7077915014182469639