android自定义viiew三种方式,仿iview实现自定义form组件

思路:拆分为三个组件:Form、FormItem、Input(后续可进行扩展)

Form:表单功能,配置校验规则,并可触发子组件的校验和重置(后续可继续封装)

FormItem:展示label,且根据属性props判断是否需校验

Input:原生input,当兼听到input时,上报,实现双向绑定并触发校验

表单的使用

// login组件

提交

重置

import eleForm from "@/components/form/ele-form/ele-form"

import eleFormItem from '@/components/form/ele-form-item/ele-form-item'

import eleInput from '@/components/form/ele-input/ele-input'

export default {

components: {

eleForm,

eleFormItem,

eleInput

},

data() {

return {

formValidate: {

username: '',

password: ''

},

ruleValidate: {

username: [{ required: true, message: '请输入用户名', trigger: 'change' }],

password: [{ required: true, message: '请输入密码', trigger: 'change' }]

}

}

},

mounted() {

},

methods: {

input(value, type) {

this.formValidate[type] = value

},

handleSubmit(name) {

this.$refs[name].validate(valid => {

console.log(valid)

});

},

handleReset(name) {

this.$refs[name].resetFields();

}

}

}

form组件:

给form-item预留槽位

将数据传递给后代便于它们访问数据模型和校验规则

// ele-form

export default {

// 一个对象,或者是一个返回对象的函数。里面包含要给子孙后代的东西,也就是属性和属性值

provide() {

return {

// 表单实例

form: this

}

},

props: {

// 表单数据对象

model: {

type: Object, required: true, default: () => {}

},

// 表单验证规则

rules: {

type: Object, default: () => {}

},

// 表单域标签的宽度,所有的 FormItem 都会继承 Form 组件的 label-width 的值

'label-width': {

type: Number, default: 100

}

},

data() {

return {

}

},

methods: {

async validate(callback) {

const tasks = this.$children.filter(item => item.prop).map(item => item.validate())

const results = await Promise.all(tasks)

if (results.some(valid => !valid)) {

// 校验失败

callback(false)

} else {

// 校验成功

callback(true)

}

},

resetFields() {

const tasks = this.$children.filter(item => item.prop)

tasks.forEach(item => {

item.errorMessage = ''

item.form.model[item.prop] = ''

})

}

},

}

formItem组件:

任务1:给Input预留插槽 - slot

任务2:展示label和校验信息

任务3:进行校验

// ele-form-item

{{label}}

{{errorMessage}}

import Validator from 'async-validator'

import { Promise } from 'q'

export default {

// 一个字符串数组,或者是一个对象

inject: [ 'form' ],

props: {

label: {

type: String,

default: ''

},

prop: {

type: String,

default: ''

}

},

data() {

return {

errorMessage: ''

}

},

created() {

this.$on('validate', this.validate)

},

methods: {

validate() {

return new Promise(resolve => {

// 制定校验规则

const descriptor = { [this.prop]: this.form.rules[this.prop] }

// 创建校验器

const validator = new Validator(descriptor)

// 执行校验

validator.validate(

descriptor,

errors => {

console.log(errors, this.form.model[this.prop])

if (errors && errors.length) {

this.errorMessage = errors[0].message

resolve(false)

} else {

this.errorMessage = ''

resolve(true)

}

}

)

})

}

},

}

input组件:

任务1:实现自定义组件双向绑定功能,v-model是语法糖,实现自定义组件双绑需要指定:value和@input

任务2:值发生变化时通知Form组件实现双向绑定,并且通知FormItem组件触发校验

export default {

props: {

type: {

type: String,

default: 'text'

},

value: {

type: String,

default: ''

}

},

data() {

return {

}

},

methods: {

// 当数据发生变化时

onInput(event) {

// 通知父组件,实现双向绑定

this.$emit('input', event.target.value)

// 通知 FormItem 执行校验

this.$parent.$emit('validate')

}

}

}

遗留问题:async-validator会报错XXX is not a string

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值