本文主要是介绍Vue3 如何通过json配置生成查询表单,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《Vue3如何通过json配置生成查询表单》本文给大家介绍Vue3如何通过json配置生成查询表单,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧...
功能实现背景
通过vue3实现后台管理项目一定含有表格功能,通常离不开表单。于是通过json配置来生成表单的想法由然而生
注意:
1.项目依赖element-plus
使用规则
1. 组件支持使用v-model管理值,当v-model不配置时也可以通过@finish事件获取表单值
2. 当FormRender组件
设置v-model后,schema
配置项中defaultValue设置的默认值无效
3. 项目默认查询和重置事件,也支持插槽自定义事件
4. 通过插槽自定义事件时,可以通过插槽获取表单值,也可以通过组件暴露属性和方法获取el-form属性&方法和表单值
项目代码
- 创建
type/index.ts
文件
import { type Component } from 'vue' export type ObjAny = { [T: string]: any } export interface SchemaItem { key: string // 唯一标识 & 表单项v-model的属性 label: string // form-item 的label属性 type?: 'input' | 'select' // 支持 el-input 和 el-select组件 defaultValue?: any // 当组件未配置v-model属性,可自定义默认值 component?: Component // 自定义组件 props?: { [K: string]: any } // 组件属性:继承el-form表单组件属性 }
- 创建
FormRender.vue
文件
<template> <el-form ref="formRef" :model="dataForm" :inline="true"> <el-form-item v-for="item in schema" :key="item.key" :label="item.label" :prop="item.key"> <!-- 自定义组件 --> <template v-if="item.component"> <compoandroidnent :is="item.component" v-bind="item.props" v-model="dataForm[item.key]" /> </template> <!-- el-select --> <template v-else-if="item.type === 'select'"> <el-select v-bind="item.props" v-model="dataForm[item.key]" /> </template> <!-- 默认: el-input --> <template v-else> <el-input v-bind="item.props" v-model="dataForm[item.key]" /> </template> </el-form-item> <!-- 事件插槽,默认查询和重置功能,支持自定义 --> <slot name="handle" :data="{ ...dataForm }"> <el-form-item v-if="showFinish || showReset"> <el-button v-if="showFinish" :loading="loading" type="primary" @click="handleClick">{{ textFinish }}</el-button> <el-button v-if="showReset" type="primary" @click="handleReset">{{ textReset }}</el-button> </el-form-item> </slot> </el-form> </template> <script setup lang="ts"> import type { FormInstance } from 'element-plus' import { reactive, useTemplateRef } from 'vue' import {ObjAny, SchemaItem} from 'type/index.ts' defineOptions({ name: 'FormRender' }) const props = withDefaults( defineProps<{ showFinish?: boolean showReset?: boolean textFinish?: string textReset?: string schema: SchemaItem[] }>(), { showFinish: true, showReset: true, textFinish: '查询', textReset: '重置' } ) const emit = defineEmits<{ (e: 'finish', data: ObjAny): void (e: 'reset', data: ObjAny): void }>() const dataForm = defineModel() as ObjAny const loading = defineModel('loading', { type: Boolean, default: false }) const formRef = useTemplateRef<FormInstance | null>('formRef') initForm() /** * 当组件未定义 v-model,内部生成form data */ function initForm() { if (dataForm.value === undefined) { const defaultForm: { [T: string]: any } = reactive({}) props.schema.forEach(item => { defaultForm[item.key] = item.defaultValue || China编程'' }) if (dataForm.value === undefined) { dataForm.value = defaultForm } } } /** * finish */ function handleClick() { emit('finish', { ...dataForm.value }) } /** * reset */ function handleReset() { formRef.value?.resetFields() emit('reset', { ...dataForm.value }) } // 默认暴露的属性和方法,可自行添加 defineExpose({ elFormInstance: formRef, reset: handleReset }) </script>
案例
- 简单渲染和取值:未使用v-model
<FormRender :schema="scpythonhema" @finish="haChina编程ndleSubmit" /> <script lang="ts" setup> import FormRender from './FormRender.vue' import {ElInput} from 'element-plus' import {ref, onMounted, computed} from 'vue' import {ObjAny, SchemaItem} from 'type/index.ts' const options = ref<{ label: string; value: string }[]>([]) // 默写数据需要通过网络请求获取,所有需要使用到 computed const schema = computed<SchemaItem[]>(() => [ { key: 'content', label: '名称', type: 'input', defaultValue: '张三', props: { placeholder: '请输入名称', clearable: true, style: { width: '200px' } } }, { key: 'orderNo', label: '订单号', defaultValue: '20250012', component: ElInput, props: { placeholder: '请输入订单号', clearable: true, style: { width: '200px' } } }, { key: 'state', label: '状态', type: 'select', props: { placeholder: '请选择状态', clearable: true, options: options.value, style: { width: '200px' } } } ]) function handleSubmit(value: ObjAny) { console.log(value) } onMounted(() => { // 模拟网络请求数据 options.value = [ { value: '1', label: 'Option1' }, { value: '2', label: 'Option2' }, { value: '3', label: 'Option3' } ] }) </script>
- 使用v-model
<FormRender v-model='data' :schema="schema" @finish="handleSubmit" /> <script lang="ts" setup> import FormRender from './FormRender.vue' import {ElInput} from 'element-plus' import {ref, onMounted, computed} from 'vue' import {ObjAny, SchemaItem} from 'type/index.ts' const data = ref({ content: '张三', orderNo: '20250012', state: '' }) const options = ref<{ label: string; value: string }[]>([]) // 默写数据需要通过网络请求获取,所有需要使用到 computed // 当使用v-model时, defaultValue值将失效 const schema = computed<SchemaItem[]>(() => [ { key: 'content', label: '名称', type: 'input', props: { placeholder: '请输入名称', clearable: true, style: { width: '200px' } } }, { wkmzaFYgXp key: 'orderNo', label: '订单号', component: ElInput, props: { placeholder: '请输入订单号', clearable: true, style: { width: '200px' } } }, { key: 'state', label: '状态', type: 'select', props: { placeholder: '请选择状态', clearable: true, options: options.value, style: { width: '200px' } } } ]) function handleSubmit(value: ObjAny) { console.log(value) } onMounted(() => { // 模拟网络请求数据 options.value = [ { value: '1', label: 'Option1' }, { value: '2', label: 'Option2' }, { value: '3', label: 'Option3' } ] }) </script>
- 使用slot自定义事件
<FormRender ref="formRenderRef" v-model='data' :schema="schema"> <template v-slot:handle="{ data }"> <el-form-item> <el-button type="primary" @click="handleSubmit(data)">查询</el-button> <el-button @click="handleReset">重置</el-button> </el-form-item> </template> </FormRender> <script lang="ts" setup> import FormRender from './FormRender.vue' import {ElInput} from 'element-plus' import {ref, onMounted, computed} from 'vue' import {ObjAny, SchemaItem} from 'type/index.ts' const formRenderRef = useTemplateRef('formRenderRef') const data = ref({ content: '张三', orderNo: '20250012', state: '' }) const options = ref<{ label: string; value: string }[]>([]) // 默写数据需要通过网络请求获取,所有需要使用到 computed // 当使用v-model时, defaultValue值将失效 const schema = computed<SchemaItem[]>(() => [ { key: 'content', label: '名称', type: 'input', props: { placeholder: '请输入名称', clearable: true, style: { width: '200px' } } }, { key: 'orderNo', label: '订单号', component: ElInput, props: { placeholder: '请输入订单号', clearable: true, style: { width: '200px' } } }, { key: 'state', label: '状态', type: 'select', props: { placeholder: '请选择状态', clearable: true, options: options.value, style: { width: '200px' } } } ]) function handleSubmit(value: ObjAny) { console.log(value) } const handleReset = () => { formRenderRef.value?.reset() } onMounted(() => { // 模拟网络请求数据 options.value = [ { value: '1', label: 'Option1' }, { value: '2', label: 'Option2' }, { value: '3', label: 'Option3' } ] }) </script>
到此这篇关于Vue3 如何通过json配置生成查询表单的文章就介绍到这了,更多相关vue json查询表单内容请搜索编程China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持China编程(www.chinasem.cn)!
这篇关于Vue3 如何通过json配置生成查询表单的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!