技术:vue3+vant4
组件传值方式:provide+inject
要安装vue-i18n依赖,如果不需要,去掉引入这一块依赖以及哪里用到的就行
功能:
1:支持自定义表单类型
2:支持自定义正则校验
3:支持自定义输入内容格式化
4:支持下拉弹窗自定义开关
5:邮箱后缀自定义弹出
6:支持van组件表单内容属性自定义
组件:
<script lang="ts" setup>
const emit = defineEmits(['submit'])
const { t } = useI18n() //这里要安装vue-i18n依赖
interface FormItem {
type: string
label: string
key: string
required?: boolean
clearable?: boolean
rule?: any
inputType?: string
readonly?: boolean
placeholder?: string
maxlength?: number
hidden?: boolean
column?: any[]
column1?: any[]
position?: string
imgClickEvent?: () => void
imgUrl?: string
initInputRex?: boolean
inputRex?: RegExp
closeShowPicker: boolean
errorPickerTip: string
isShowInputTip?: boolean
}
const optionData = inject('optionData', {
column: [],
column1: [],
focusElement: '',
btnText: ''
})
const formRef = ref(null)
const formData = inject('formData', {})
const initDate = ref(['01', '01', '1980'])
const itemObj = reactive<any>({})
const showEmailPop = ref(false)
const showPicker = ref(false)
const showDatePopup = ref(false)
const validateResult = computed(() => formRef?.value?.getValidationStatus() ?? {})
function nextStep() {
(formRef.value as any).validate().then(() => {
emit('submit')
}).catch((error: any) => {
if (optionData) {
showToastByMsg(error[0].message)
}
})
}
function selectEmailAfter(value: string, item: FormItem) {
const isindex = formData[item.key].indexOf('@')
if (isindex > -1) {
formData[item.key] = formData[item.key].substring(0, isindex) + value
}
else {
formData[item.key] = formData[item.key] + value
}
}
function blurEvent(item: FormItem) {
formData[item.key] = String(formData[item.key]).trim()
if (item.type === 'email') {
setTimeout(() => {
showEmailPop.value = false
}, 10)
}
}
function confirmPicker(val: any, item: any) {
formData[item.key] = val.selectedValues && val.selectedValues[0]
if (item.sameWordByChangePop) {
showPicker.value = formData[item.key] === formData[item.sameWordByChangePop]
return
}
showPicker.value = false
}
function showPopupEven(item: FormItem) {
if (item.closeShowPicker) { // closeShowPicker 是否关闭弹窗
showPicker.value = false
if (item.errorPickerTip) {
showToastByMsg(t(item.errorPickerTip))
}
return
}
Object.assign(itemObj, item)
if (item.type === 'datetime') {
showDatePopup.value = true
}
else if (item.type === 'select') {
if (!item.closeShowPicker) { // showPicker
showPicker.value = true
}
}
}
function confirmDate(val: any, key: string) {
// formData[key] = handlerRate(val, 1)
formData[key] = val.selectedOptions.map(item => item.text).join('-')
showDatePopup.value = false
}
function minDate() {
const date = new Date()
date.setFullYear(date.getFullYear() - 70)
return date
}
function maxDate() {
const date = new Date()
date.setFullYear(date.getFullYear() - 18)
return date
}
// watch([showDatePopup, showPicker], ([showDatePopupVal, showPickerVal]) => {
// const isVisible = showDatePopupVal || showPickerVal
// console.warn('isVisible', isVisible)
// setBackSwitch({
// canBack: isVisible ? HandlePhysicalBack.BLOCK : HandlePhysicalBack.ALLOW,
// })
// })
onBeforeUnmount(() => {
// setBackSwitch({
// canBack: HandlePhysicalBack.ALLOW,
// })
})
provide('onClick'