序文
みなさん、こんにちは。最後のひばなです。
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:以下に示すように、非常に明確なコードプロンプトであるフォームデコレータを使用することには別の利点があります。
このプロパティのフォーム検証がどのように見えるかを知る必要はありません。プロパティで直接確認できますが、非常に便利ではありません。
フォームの初期値を動的に設定
前回の記事で、フォームの初期値はインターフェースを介して動的に設定されると述べたので、単純に実装します。たとえば、@ InjectUsernameを使用して初期値をusernameに設定すると、最后的Hibana
usernameという値が返されます。
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)にアクセスできます。