Я работаю над проектом VueJS (используя фреймворк Quasar). При создании компонента формы, например, для редактирования пользовательских настроек, у меня есть проверка внешнего интерфейса, чтобы проверить обязательные поля и т. Д. c. используя vuelidate, и я также хочу показать ошибки проверки серверной части. В настоящее время моя установка (для образца формы) выглядит следующим образом:
сценарий:
export default {
name: 'UserEditForm',
mixins: [formServerValidation],
data: function () {
return {
form: {
...
name: this.$store.state.currentUser.attributes.name,
currentPassword: 'winnerwinner',
serverErrors: {
// Todo: Autogenerate all server errors
}
}
}
},
methods: {
onSubmit () {
const name = this.form.name
const currentPassword = this.form.currentPassword
this.clearServerErrors()
this.$store.dispatch('updateUser', { name, currentPassword, }).then((result) => {
console.log("Server update success")
}).catch(err => {
console.log("Server update error")
const mappedErrors = this.mapServerErrors(err.response.data.errors)
merge(this.form.serverErrors, mappedErrors)
this.$refs.form.validate()
})
},
serverError: function (fieldName) {
return (value, vm) => {
return !(
Object.prototype.hasOwnProperty.call(vm, 'serverErrors') &&
Object.prototype.hasOwnProperty.call(vm.serverErrors, fieldName)
)
}
}
},
validation: {
form: {
...
name: {
required,
serverError: this.serverError('name')
},
currentPassword: {
required,
serverError: this.serverError('currentPassword')
},
...
}
}
}
шаблон:
<template>
<q-form @submit="onSubmit" ref="form">
...
<q-input
field-name="name"
type="text"
v-model="form.name"
label="Name"
lazy-rules
@input="clearServerError('name', $event)"
:rules="[
val => $v.form.name.required || 'Enter name',
val => $v.form.name.serverError || form.serverErrors.name,
]" />
<q-input
field-name="currentPassword"
type="password"
v-model="form.currentPassword"
label="Current password*"
lazy-rules
@input="clearServerError('currentPassword', $event)"
:rules="[
val => $v.form.currentPassword.required || 'Confirm password',
val => $v.form.currentPassword.serverError || form.serverErrors.currentPassword
]"
/>
...
<div>
<q-btn label="Save" type="submit" color="primary" />
</div>
</q-form>
</template>
Все это работает отлично, но кажется очень ВЛАЖНЫМ (не DRY). Я должен определить следующее для каждого поля вручную :
serverError: this.serverError('name')
в validation
- Правило
val => $v.form.name.serverError || form.serverErrors.name
в шаблоне @input="clearServerError('name', $event)"
в шаблоне
Но я знаю, что хочу сделать это для каждого ввода в моем компоненте формы, поэтому делать это вручную очень часто. для каждого входного компонента. Есть ли правильный способ «Vue -i sh» для DRY этого?
Я пытался найти все поля ввода, пройдя по всем потомкам моего компонента формы, используя $children
. Затем:
Я попытался решить 1.
, динамически определяя эти ошибки сервера, перебирая все входные компоненты.
2.
труднее справиться, так как вы не можете напрямую обновить свойство :rules
, поскольку Vue переопределит его при новом рендере родительского компонента. (Это также вызывает предупреждение, в котором говорится, что вам не следует напрямую обновлять свойства, а использовать v-model
et c.)
Я пытался решить 3.
, динамически определяя прослушиватели событий ввода из моего компонента формы, используя метод $on
на фактических компонентах ввода.
Метод DRY для 1 и 3, кажется, работает, но лучший ли это способ сделать это? А как правильно сушить 2?