Closed magnificent007 closed 1 week ago
可以参考这里 https://github.com/varletjs/varlet/blob/dev/packages/varlet-ui/src/form/example/index.vue
里面有个 VarCustomFormComponent
组件,拓展多个可以参考这个组件封装
:rules="[() => model.name.length > 6 || 'Error', () => model.age > 10 || 'Error']"
也是一样的~
:rules="[() => model.name.length > 6 || 'Error', () => model.age > 10 || 'Error']"
也是一样的~
可以确定rules是个数组函数,我就是不清楚验证的数据要用什么格式?对象数组形式还是什么其它的格式?
可以参考这里 https://github.com/varletjs/varlet/blob/dev/packages/varlet-ui/src/form/example/index.vue
里面有个
VarCustomFormComponent
组件,拓展多个可以参考这个组件封装
查看了,但是还是不清楚,验证的数据需要什么格式?可以确定rules是个函数数组,验证的数据是否也要用对象数组?
不对验证数据格式有要求呀。本质 rules 是一个验证函数数组,组件自动判断验证时机,验证的时候只是执行函数,用户怎么写的就怎么执行。
不对验证数据格式有要求呀。本质 rules 是一个验证函数数组,组件自动判断验证时机,验证的时候只是执行函数,用户怎么写的就怎么执行。
不是的,您可能没理解我的意思。rules是个函数数组,我理解没有问题;我想知道的是要验证的数据 在多字段验证的情况下 需要传入什么格式?是对象数组还是其它形式?
没有格式要求。input 绑定的是什么值就验证什么值。
---原始邮件--- 发件人: @.> 发送时间: 2024年9月5日(周四) 下午4:47 收件人: @.>; 抄送: @.**@.>; 主题: Re: [varletjs/varlet] form扩展验证 (Issue #1747)
不对验证数据格式有要求呀。本质 rules 是一个验证函数数组,组件自动判断验证时机,验证的时候只是执行函数,用户怎么写的就怎么执行。
不是的,您可能没理解我的意思。rules是个函数数组,我理解没有问题;我想知道的是需要验证的数据需要传入什么格式?
— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>
没有格式要求。input 绑定的是什么值就验证什么值。
没有用input哦,里面是我自定义的多个输入操作,下面我提供下vue3代码片段和效果图
// 接入表单校验组件validate-form.tsx
import { Form } from '@varlet/ui'
import { nextTick, type SetupContext, type PropType } from 'vue'
type FComponentProps = {
readonly?: Partial<boolean>,
disabled?: Partial<boolean>,
validateTrigger?: Partial<Array<string>>,
rules?: Partial<Array<(v: any) => string | boolean>>,
validateValues: Array<string>
}
type Events = {
['update:validateValues'](validateValues: Objectable): void,
exposeFormInstance(i: Objectable): void
}
export type ExposeFormInstanceType = {
reset: () => void,
trigger: () => void,
validate: () => Promise<boolean>,
resetValidation: () => void
}
export const ValidateForm = (props: FComponentProps, context: SetupContext<Events>) => {
const { slots, emit, attrs } = context
const { useForm, useValidation } = Form
const { errorMessage, validateWithTrigger: _validateWithTrigger, validate: _validate, resetValidation } = useValidation()
const { bindForm, form } = useForm()
const validate = () => _validate(props.rules, props.validateValues)
function reset() {
emit('update:validateValues', [])
resetValidation()
}
function validateWithTrigger(trigger: any) {
nextTick(() => {
const { validateTrigger, rules, validateValues } = props
_validateWithTrigger(validateTrigger!, trigger, rules, validateValues)
})
}
function trigger() {
if (
props.readonly ||
props.disabled ||
form?.readonly.value ||
form?.disabled.value
) {
return
}
emit('update:validateValues', props.validateValues)
validateWithTrigger('onToggle')
}
emit('exposeFormInstance', { reset, trigger, validate, resetValidation })
bindForm?.({ reset, validate, resetValidation })
return (
<>
<var-space class="w-full z-99999" direction="column" size={[14, 0]}>
{ slots.main ? slots.main({ readonly: props.readonly, disabled: props.disabled, errorMessage: errorMessage.value }) : (<var-result type='empty' description='三无属性地带..!' />) }
{ slots.footer ? slots.footer({ readonly: props.readonly, disabled: props.disabled }) : (<></>) }
</var-space>
</>
)
}
ValidateForm.props = {
readonly: {
type: Boolean as PropType<Partial<boolean>>,
default: false
},
disabled: {
type: Boolean as PropType<Partial<boolean>>,
default: false
},
validateTrigger: {
type: Array as PropType<Partial<Array<string>>>,
default: () => ['onToggle']
},
rules: {
type: Array as PropType<Partial<Array<(v: any) => string | boolean>>>,
default: () => []
},
validateValues: {
type: Array as PropType<Array<string>>,
default: () => []
}
}
export default ValidateForm
// 使用
<script lang='ts' setup>
import { ref } from 'vue'
import { ValidateForm, type ExposeFormInstanceType } from '@/components/basic/validate-form/validate-form'
import { pull } from 'lodash-es'
// ------------------ 验证从这里开始 ------------------
const { getFormInstance, validate } = useForm()
const { characteristic, checkedCharacter } = useSelectCharacter()
function useSelectCharacter() {
const characteristic = ref<Array<string>>([])
const checkedCharacter = (e: any, additional: { readonly: boolean, disabled: boolean }) => {
if (additional.readonly || additional.disabled) return
const { id } = e.target.dataset
if (characteristic.value.includes(id)) {
pull(characteristic.value, id)
return
}
characteristic.value.push(id)
}
return {
characteristic,
checkedCharacter
}
}
function useForm() {
const formInstance = ref<ExposeFormInstanceType>()
function getFormInstance(instance: ExposeFormInstanceType) {
formInstance.value = instance
}
function validate() {
formInstance.value?.validate()
}
return {
formInstance,
getFormInstance,
validate
}
}
const questions = [
{
title: '标题1',
subtitle: '副标题1',
list: ['积极', '好学', '勇敢', '阳光']
},
{
title: '标题2',
subtitle: '副标题2',
list: ['消极', '懒惰', '胆小', '阴暗']
}
]
</script>
<template>
<ValidateForm
:readonly="false"
:disabled="false"
:rules="[v => v.length >= 1 || '至少选择1个', v => v.length >= 1 || '至少选择1个']"
v-model:validateValues="characteristic"
@exposeFormInstance="getFormInstance"
>
<template #main="{ readonly, disabled, errorMessage }">
<div class="character-wrapper box-border" v-for="q in questions" :key="q.title">
<span class="title block">{{ q.title }}</span>
<span class="subtitle">{{ q.subtitle }}</span>
<var-form-details :error-message="errorMessage" />
<div class="flex flex-wrap justify-between gap-row-6 mt-4" @click="checkedCharacter($event, { readonly, disabled })">
<var-paper
:class="['relative text-center', readonly || disabled ? 'disabled': '', characteristic.includes(i) ? 'active' : '']"
:ripple="!(readonly || disabled)"
width="30%"
height="4rem"
:elevation="2"
v-for="i in q.list"
:key="i"
:data-id="i"
>
<span class="leading-16 text-coolGray font-bold" :data-id="i">{{ i }}</span>
</var-paper>
</div>
</div>
</template>
<template #footer="{ readonly, disabled }">
<slot name="footer" :readonly="readonly" :disabled="disabled"></slot>
</template>
</ValidateForm>
<var-button
block
type="success"
loading-size="small"
loading-type="wave"
@click="validate"
>
验证
</var-button>
</template>
<style lang='scss' scoped>
.character-wrapper {
padding: 12px;
.title {
font-size: 18px;
font-weight: bold;
color: black;
}
.subtitle {
font-size: 14px;
color: gray;
}
}
.disabled::before {
content: '';
box-sizing: border-box;
background-color: rgba(0, 0, 0, 0.1);
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
right: 0;
bottom: 0;
z-index: 101;
}
.active::after {
content: '✔';
box-sizing: border-box;
background-color: green;
color: white;
font-size: 12px;
line-height: 1rem;
width: 1rem;
height: 1rem;
position: absolute;
top: 0;
right: 0;
z-index: 100;
}
</style>
想实现的效果图
我这边没问题,你这边提供的 tsx 代码可能存在问题,可以尝试按照图2修复。
关于form扩展验证问题,文档内只有单个字段,我想扩展多个字段的验证,rules 和 validateData 该以什么样的形式传入进行验证呢?