Шуцзян надеется доставить удовольствие от внешнего интерфейса всем. Эта статья была включенаGitHub.com/маленькое дерево М…звездочка если хочешь ✨
Предисловие: В течение этого периода времени я работал над средними и фоновыми проектами в направлении к B, и частота контактов с формой будет больше.Я поделюсь некоторыми основами, связанными с данными форм по прихоти.
1. Обработка данных
Когда данные, отображаемые формой в представлении, не являются данными, требуемыми серверной частью, или данные, возвращаемые серверной частью, не соответствуют тому, что хочет отобразить внешний интерфейс, тогда требуется преобразование данных. общие сценарии.
Я предполагаю, что существует следующий набор базовых данных формы
data(){
return {
form:{
name: '商品名称',
id: '订单编号',
nickName: '商品别名',
num: '商品数量',
price:'价格',
tag: '0' // 1 表示特价 0 表示无特价
},
}
},
1.1 Сценарий 1: Отфильтровать данные, которые мне не нужны
Сценарий: В данных во фронтенде есть лишние поля, значит бэкенду эти поля не нужны, ненужные поля мы можем отсеять фильтрацией.
const noRequired = ['tag', 'nickName']; //不需要的字段
const formData = Object.keys(this.form)
.filter(each => !noRequired.includes(each))
.reduce((acc, key) => (acc[key] = this.form[key], acc), {});
1.2 Сценарий 2. Извлеките только те данные, которые мне нужны
Сценарий: бэкенду не нужно столько данных, сколько данных формы, и его можно использовать, когда нужна только его часть.
const formData= JSON.parse(
JSON.stringify(this.form,["nickName","price"])
);
1.3 Сценарий 3: перезапись данных
Сценарий: Доступно, когда некоторые поля в текущей форме необходимо заменить или перезаписать новыми данными.
Object.assign(this.form, {
tag: '商品1'
}
1.4 Сценарий 4: картирование полей
Доступно, когда текущее поле формы необходимо сопоставить с другими именами полей, значение ключа соответствующего имени изменяется на Имя следующим образом.
- сопоставление одного поля
const formData = JSON.parse(
JSON.stringify(this.form).replace(
/name/g,
'Name')
);
- Сопоставление нескольких полей
const mapObj = {
name: "Name",
nickName: "NickName",
tag: "Tag"
};
const formData = JSON.parse(
JSON.stringify(this.form).replace(
/name|nickName|tag/gi,
matched => mapObj[matched])
);
ps: На этом пути есть баг, знаете что это?
1.5 Сценарий 5: отображение данных
Когда поле имеет номер состояния 0, 1 и т. д., оно доступно, когда его необходимо преобразовать в соответствующее представление.Соответствующее поле тега выглядит следующим образом: 0 соответствует специальной цене, 1 соответствует отсутствию специальной цены, и выполняется преобразование отображения.
const formData = JSON.parse(JSON.stringify(this.form,(key,value)=>{
if(key == 'tag'){
return ['特价','无特价'][value];
}
return value;
}));
1.6 Сценарий 6: Слияние данных
Объединение данных, объединение полей данных формы, обратите внимание, что если поля совпадают, значения предыдущих полей данных формы будут перезаписаны
const query = { tenaId: '订单编号', id:'查询ID'}
const formData = {
...this.form,
query
}
2. Проверка формы
Когда данные формы заполнены, необходимо дополнительно отправить форму на внутренний сервер, но внешнему интерфейсу необходимо выполнить дополнительные данные, чтобы подтвердить, соответствует ли она правилам, например, является ли она обязательным элементом, будь то в формате номера мобильного телефона
2.1 Простая версия проверки одного поля
data() {
return {
schema:{
phone: {
required:true
},
}
};
},
methods: {
// 判断输入的值
validate(schema, values) {
for(field in schema) {
if(schema[field].required) {
if(!values[field]) {
return false;
}
}
}
return true;
},
}
console.log(this.validate(schema, {phone:'159195**34'}));
2.2 Простая версия проверки нескольких полей
data() {
return {
phoneForm: {
phoneNumber: '',
verificationCode: '',
tips:''
},
schema:{
phoneNumber: [{required: true, error: '手机不能为空'}, {
regex: /^1[3|4|5|6|7|8][0-9]{9}$/,
error: '手机格式不对',
}],
verificationCode: [{required: true, error: '验证码不能为空'}],
}
};
},
methods: {
// 判断输入的值
validate(schema, values) {
const valArr = schema;
for (const field in schema) {
if (Object.prototype.hasOwnProperty.call(schema, field)) {
for (const key of schema[field]) {
if (key.required) {
if (!valArr[field]) {
valArr.tips = key.error;
return false;
}
} else if (key.regex) {
if (!new RegExp(key.regex).test(valArr[field])) {
valArr.tips = key.error;
return false;
}
}
}
}
}
return true;
},
}
console.log(this.validate(this.schema, this.phoneForm);
2.3 Реализация проверки компонентов формы библиотеки компонентов Iview
Модуль компонента формы Iview в основном состоит из Form и FormItem.
- Форма в основном заключает в себе форму
- FormItem — это пакет, который в основном используется для упаковки некоторых элементов управления формы, подсказок и правил проверки.
Мы можем четко видеть, что компонент формы IView является методом формирования аутентификации через библиотеку инструментов Async-Validator.
- Базовое использование асинхронного валидатора
Официальный пример выглядит следующим образом👇Ссылка на документацию
import schema from 'async-validator';
var descriptor = {
address: {
type: "object", required: true,
fields: {
street: {type: "string", required: true},
city: {type: "string", required: true},
zip: {type: "string", required: true, len: 8, message: "invalid zip"}
}
},
name: {type: "string", required: true}
}
var validator = new schema(descriptor);
validator.validate({ address: {} }, (errors, fields) => {
// errors for address.street, address.city, address.zip
});
В компоненте формы iview в основном определено, что использование field.validate в функции проверки является методом вызова async-validator, который используется для управления проверкой в компоненте элемента формы.
// ViewUI/src/components/form/form.vue
methods:{
validate(callback) {
return new Promise(resolve => {
let valid = true;
let count = 0;
this.fields.forEach(field => {
field.validate('', errors => {
if (errors) {
valid = false;
}
// 检验已完成的校验的数量是否完全,则返回数据有效
if (++count === this.fields.length) {
// all finish
resolve(valid);
if (typeof callback === 'function') {
callback(valid);
}
}
});
});
});
},
//针对单个的校验
validateField(prop, cb) {
const field = this.fields.filter(field => field.prop === prop)[0];
if (!field) {throw new Error('[iView warn]: must call validateField with valid prop string!'); }
field.validate('', cb);
}
//表单规则重置
resetFields() {
this.fields.forEach(field => {
field.resetField();
});
},
},
created () {
//通过FormItem定义的prop来收集需要校验的字段,
this.$on('on-form-item-add', (field) => {
if (field) this.fields.push(field);
return false;
});
// 移除不需要的字段
this.$on('on-form-item-remove', (field) => {
if (field.prop) this.fields.splice(this.fields.indexOf(field), 1);
return false;
});
}
Правила в this.fields, участвующие в Form.vue, поступают, прослушивая push «on-form-item-add» во время его жизненного цикла создания, а событие «on-form-item-add» отправляется элементом формы. Компонент запускает соответствующее событие и передает соответствующий экземпляр для создания ассоциации данных.Ниже приведено содержимое функции жизненного цикла элемента формы:
// ViewUI/src/components/form/form-item.vue
mounted () {
// 如果定义了需要验证的字段
if (this.prop) {
// 向父亲Form组件添加field
this.dispatch('iForm', 'on-form-item-add', this);
Object.defineProperty(this, 'initialValue', {
value: this.fieldValue
});
this.setRules();
}
},
beforeDestroy () {
// 移除之前删除form中的数据字段
this.dispatch('iForm', 'on-form-item-remove', this);
}
methods: {
setRules() {
//获取所有规则
let rules = this.getRules();
if (rules.length&&this.required) {
return;
}else if (rules.length) {
rules.every((rule) => {
this.isRequired = rule.required;
});
}else if (this.required){
this.isRequired = this.required;
}
this.$off('on-form-blur', this.onFieldBlur);
this.$off('on-form-change', this.onFieldChange);
this.$on('on-form-blur', this.onFieldBlur);
this.$on('on-form-change', this.onFieldChange);
},
getRules () {
let formRules = this.form.rules;
const selfRules = this.rules;
formRules = formRules ? formRules[this.prop] : [];
return [].concat(selfRules || formRules || []);
},
validate(trigger, callback = function () {}) {
let rules = this.getFilteredRule(trigger);
if (!rules || rules.length === 0) {
if (!this.required) {
callback();
return true;
}else {
rules = [{required: true}];
}
}
// 设置AsyncValidator的参数
this.validateState = 'validating';
let descriptor = {};
descriptor[this.prop] = rules;
const validator = new AsyncValidator(descriptor);
let model = {};
model[this.prop] = this.fieldValue;
validator.validate(model, { firstFields: true }, errors => {
this.validateState = !errors ? 'success' : 'error';
this.validateMessage = errors ? errors[0].message : '';
callback(this.validateMessage);
});
this.validateDisabled = false;
},
}
Заинтересованные партнеры могут изучить конкретную реализацию проверки формы библиотеки компонентов iview посредством изучения исходного кода на этой основе.
2.4 Валидация реализации элемента формы компонента библиотеки компонентов ElForm
Принцип проверки компонента формы ElForm элемента очень похож на библиотеку компонентов iview, упомянутую в предыдущем разделе, поэтому я не буду делать здесь большое введение, просто "перейдите к таланту" -----Исходная ссылка
2.5 Общие правила проверки
Используйте различные обычные правила, чтобы ограничить соответствие различных типов данных формы требованиям.
- Это номер мобильного телефона:
/^1[3|4|5|6|7|8][0-9]{9}$/
- Это все числа:
/^[0-9]+$/
- Это почтовый ящик:
/^([A-Za-z0-9_\-\.])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/
- Это удостоверение личности:
/^(^[1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3}$)|(^[1-9]\d{5}[1-9]\d{3}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])((\d{4})|\d{3}[Xx])$)$/
- Это URL:
/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/
- Это ИП:
/((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}/