vue3中,渲染动态表单(三)——梳理动态表单的几种类型、树结构表格row-key、父子传值之props、emit和defineEmits & ElLoading组件用法和post请求动态地址
效果图
1-主页面
2-树结构表格
3-新增
4-编辑
1、主页
index.vue
<span class="text-btn" @click="edit(scope.row)">定义申请表</span> <script> const edit = (row: any) => { console.log(row); router.push('/myCenter/defineForm') } </script>
2、定义申请表管理
src\views\myCenter\applyForm\components\defineForm.vue
<!-- @Description 申请表管理 - 定义申请表 @author wdd @date 2023/12/13 --> <template> <centerHead title="定义申请表"></centerHead> <div class="content"> <div class="left"> <el-button type="primary" @click="add">新增</el-button> <el-table ref="tableRef" border class="table-style" :data="tableData" lazy :load="treeLoad" row-key="id" stripe style="width: 100%; margin-bottom: 20px" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" @selection-change="handleChange"> <el-table-column prop="name" align="center" label="字段名称"></el-table-column> <el-table-column prop="prop" align="center" label="字段参数"></el-table-column> <el-table-column prop="type" align="center" label="字段类型"></el-table-column> <el-table-column prop="rules" align="center" label="是否必填"></el-table-column> <el-table-column prop="placeholder" align="center" label="提示语"></el-table-column> <el-table-column prop="sort" align="center" label="字段序号"></el-table-column> <el-table-column prop="hasChildren" align="center" label="是否有子集"></el-table-column> <el-table-column label="操作" align="right" width="160"> <template #default="scope"> <span class="text-btn" v-if="scope.row.hasChildren" @click="edit('addChild',scope.row)">新增子项</span> <span class="text-btn" @click="edit('edit',scope.row)">编辑</span> <span class="del-btn" @click="onDelete(scope.row)">删除</span> </template> </el-table-column> </el-table> <div> <el-button type="primary" @click="onSave">提交</el-button> <el-button type="primary" @click="see">生成预览</el-button> </div> <FieldInfo v-if="showField" v-model:dialogVisible="showField" :info-data="fieldInfo" @emit-confirm="confirmOk" /> <ExampleInfo v-if="showExample" v-model:dialogVisible="showExample" :info-data="exampleInfo" @emit-confirm="exampleOk" /> </div> </div> </template> <script lang="ts" setup> import { ref } from 'vue'; import { useRouter } from 'vue-router' import { ElMessage, ElMessageBox } from 'element-plus' import FieldInfo from './fieldInfo.vue' import ExampleInfo from './exampleInfo.vue' const router = useRouter(); const tableData = ref([{ id: 1, name: '姓名', prop: 'name', type: '输入框', rules: '是', placeholder: '请输入', sort: 1, hasChildren: false }, { id: 2, name: '性别', prop: 'sex', type: '下拉框', rules: '是', placeholder: '请选择', sort: 2, hasChildren: false }, { id: 3, name: '备注', prop: 'notes', type: '多行文本', rules: '否', placeholder: '请输入', sort: 3, hasChildren: false }, { id: 4, name: '手机号', prop: 'telephone', type: '手机', rules: '是', placeholder: '请输入', sort: 4, hasChildren: false }, { id: 5, name: '身份证号', prop: 'IDCard', type: '身份证号', rules: '否', placeholder: '请输入', sort: 5, hasChildren: false }, { id: 6, name: '邮箱', prop: 'email', type: '邮箱', rules: '否', placeholder: '请输入', sort: 6, hasChildren: false }, { id: 7, name: '年龄', prop: 'age', type: '数字', rules: '否', placeholder: '请输入', sort: 7, hasChildren: false }, { id: 8, name: '金额', prop: 'money', type: '数字', rules: '否', placeholder: '请输入', sort: 8, hasChildren: false }, { id: 9, name: '作品来源', prop: 'source', type: '单选', rules: '是', sort: 9, hasChildren: false }, { id: 10, name: '项目属性', prop: 'attribute', type: '多选', rules: '是', sort: 10, hasChildren: false }, { id: 11, name: '年度', prop: 'year', type: '年度', rules: '是', placeholder: '请选择', sort: 11, hasChildren: false }, { id: 12, name: '月份', prop: 'month', type: '年月', placeholder: '请选择', rules: '是', sort: 12, hasChildren: false }, { id: 13, name: '出生日期', prop: 'birthday', type: '日期', placeholder: '请选择', rules: '是', sort: 13, hasChildren: false }]) const showField = ref(false) const fieldInfo = ref({}) const add = () => { showField.value = true fieldInfo.value = { // id: fieldId, typeName: 'add' } } const confirmOk = () => { tableData.value = [] // getList() } const edit = (type: any, row: any) => { showField.value = true row.typeName = type // row.fieldId = directoryId fieldInfo.value = { ...row } router.push('/myCenter/defineForm') } // 懒加载 const treeLoad = (tree, treeNode, resolve) => { setTimeout(() => { const params = { pid: tree.id, } const dataList = ref([]) maps.set(tree.id, { tree, treeNode, resolve }) post(constant.ieopCollaborate + '/collaborate/directory/list', params).then((res) => { const data = res.data.data || [] data.forEach((el) => { if (el.hasChildren) { el.children = null } }) dataList.value = data resolve(dataList.value) }) }, 200) } // 批量删除 const ids = ref([]) const handleChange = (val: any) => { ids.value = val.map((item: any) => item.id) } const onDelete = (row: any) => { console.log(row); ElMessageBox.confirm('此操作将删除该费率, 是否继续?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning' }).then(() => { ElMessage.success('删除成功!') history.go(0) }).catch(() => { ElMessage.error('删除失败!') }) } const showExample = ref(false) const exampleInfo = ref({}) const see = () => { showExample.value = true exampleInfo.value = { // id: fieldId, // typeName: 'add' } } const exampleOk = () => { // tableData.value = [] // getList() } const onSave = () => { } </script> <style lang="scss" scoped> .content { margin-top: 20px; margin-right: 20px; width: 90%; .text-btn { font-size: 12px; color: #409EFF; margin-left: 4px; cursor: pointer; } .del-btn { font-size: 12px; color: #F56C6C; margin-left: 4px; cursor: pointer; } .el-button { float: right; margin: 0 0 10px 10px; } .left { padding-left: 16px; .el-table { margin: 20px 0; } } } </style>
3、新增申请表字段
src\views\myCenter\applyForm\components\fieldInfo.vue
<!-- @Description 申请表管理 - 定义申请表 - 新增/编辑字段弹框 @author wdd @date 2023/12/14 --> <template> <div> <el-dialog :title="titleText" v-model="dialogVisible" :close-on-press-escape="false" :close-on-click-modal="false" width="36%"> <div style="padding-right:40px"> <el-form label-width="100px" ref="formRef" :model="formInline"> <el-form-item label="字段名称:" prop="name" :rules="{ required: true, message: '请输入', trigger: 'blur', }"> <el-input v-model="formInline.name"></el-input> </el-form-item> <el-form-item label="字段参数:" prop="prop" :rules="{ required: true, message: '请输入', trigger: 'blur', }"> <el-input v-model="formInline.prop"></el-input> </el-form-item> <!-- 动态表单类型 typeList --> <el-form-item label="字段类型:" prop="type" :rules="{ required: true, message: '请输入', trigger: 'blur', }"> <el-select v-model="formInline.type" placeholder="请选择" style="width:100%"> <el-option v-for="item in typeList" :key="item.value" :label="item.label" :value="item.value"> </el-option> </el-select> </el-form-item> <el-form-item label="是否必填:" prop="rules"> <el-radio-group v-model="formInline.rules" class="ml-4"> <!-- <el-radio label="1" size="large">是</el-radio> <el-radio label="2" size="large">否</el-radio> --> <el-radio :label="'是'">是</el-radio> <el-radio :label="'否'">否</el-radio> </el-radio-group> </el-form-item> <el-form-item label="字段序号:" prop="sort" :rules="{ required: true, message: '请输入', trigger: 'blur', }"> <el-input placeholder="请输入大于0的正整数" @input="changeSort" v-model="formInline.sort"></el-input> </el-form-item> <el-form-item label="提示语:" prop="placeholder"> <el-select style="width:100%" v-model="formInline.placeholder"> <el-option value="请输入" label="请输入"></el-option> <el-option value="请选择" label="请选择"></el-option> </el-select> </el-form-item> <el-form-item v-if="formInline.hasChildren" label="是否有子集:" prop="hasChildren"> <el-radio-group v-model="formInline.hasChildren" class="ml-4"> <el-radio :label="true">是</el-radio> <el-radio :label="false">否</el-radio> </el-radio-group> </el-form-item> </el-form> </div> <template #footer> <span slot="footer" class="dialog-footer"> <el-button link type="primary" @click="dialogVisible = false">取消</el-button> <el-button type="primary" @click="confirm()">确定</el-button> </span> </template> </el-dialog> </div> </template> <script lang="ts" setup> import { ref, defineProps, defineEmits, computed, watch, inject } from 'vue'; import { post } from "@/utils/path.js"; import { ElLoading, ElMessage } from "element-plus"; const formRef = ref() const dataObj = ref() const titleText = ref('') const constant = inject('constant') const formInline = ref({ name: '', prop: '', type: '', sort: '', rules: '否', placeholder: '', hasChildren: false, }) // 动态表单类型 const typeList = ref([ { label: "输入框", value: "text" }, { label: "数字", value: "number" }, { label: "下拉框", value: "select" }, { label: "日期", value: "date" }, { label: "年月", value: "month" }, { label: "年度", value: "year" }, { label: "起止日期", value: "datetimerange" }, // { // label:"富文本框", // value:"editor" // }, { label: "单选", value: "radio" }, { label: "多选", value: "checkbox" }, { label: "手机", value: "telephone" }, { label: "邮箱", value: "email" }, { label: "身份证", value: "IDCard" }, // { // label:"list集合", // value:"list" // }, // { // label: "封面", // value: "thumb" // }, { label: "附件", value: "file" }, { label: "多行文本", value: "textarea" }, // { // label:"视频", // value:"video" // }, // { // label: "电话", // value: "phone" // }, ]) const props = defineProps({ infoData: { default: null, type: Object, }, dialogVisible: { type: Boolean, default() { return false }, }, }) //监听方法 const emit = defineEmits(['emit-confirm', 'update:dialogVisible']) const dialogVisible = computed({ get: () => props.dialogVisible, set: (val) => emit('update:dialogVisible', val), }) watch( () => props.dialogVisible, (newVal) => { if (newVal) { dataObj.value = JSON.parse(JSON.stringify(props.infoData)) if (dataObj.value.typeName == 'add') { titleText.value = '新增字段' } if (dataObj.value.typeName == 'addChild') { formInline.value.pid = dataObj.value.id formInline.value.hasChildren = dataObj.value.hasChildren titleText.value = '新增子项' } if (dataObj.value.typeName == 'edit') { formInline.value = { ...dataObj.value } formInline.value.id = dataObj.value.id titleText.value = '编辑字段' } } }, { immediate: true } ) const changeSort = (val: any) => { const pattern = /^[1-9][0-9]*$/ if (!pattern.test(val)) { formInline.value.sort = '' } } const confirm = async () => { await formRef.value.validate((valid: any) => { if (!valid) { return } else { const loading = ElLoading.service({ lock: true, text: 'Loading', background: 'rgba(0, 0, 0, 0.7)', }) const params = { ...formInline.value } const url = dataObj.value.typeName == 'addChild' ? '/collaborate/directory/add' : '/collaborate/directory/addRoot' const urlInfo = dataObj.value.typeName == 'edit' ? '/collaborate/directory/update' : url post(constant.ieopCollaborate + urlInfo, params).then((res) => { const { code } = res.data if (code == '200') { loading.close() ElMessage.success(dataObj.value.typeName == 'edit' ? '修改成功' : '新增成功') emit('update:dialogVisible', false) formInline.value = {} emit('emit-confirm') } else { loading.close() ElMessage.error(res.message) emit('update:dialogVisible', false) } }) .catch(() => { loading.close() }) } }) } </script>
4、引用文件
src\utils\path.js
import request from "./request"; import {
getApiUrl } from "@/utils/tool"; const baseUrl = getApiUrl(); // 通用请求 export function post(url, params = {
}){
const data = request.post(baseUrl + url, params); // const data = request.post(url, params); return data } export function get(url, params = {
}){
const data = request.get(baseUrl + url); return data }
src\utils\tool.js
export function getApiUrl(v) {
return process.env.VUE_APP_API_HOST }
})
}
})
}
4、引用文件 src\utils\path.js ```js import request from "./request"; import { getApiUrl } from "@/utils/tool"; const baseUrl = getApiUrl(); // 通用请求 export function post(url, params = {}){ const data = request.post(baseUrl + url, params); // const data = request.post(url, params); return data } export function get(url, params = {}){ const data = request.get(baseUrl + url); return data }
src\utils\tool.js
export function getApiUrl(v) {
return process.env.VUE_APP_API_HOST }
到此这篇vue3中,渲染动态表单(三)——梳理动态表单的几种类型、树结构表格row-key、父子传值之props、emit和defineEmits & ElLoading组件用法和post请求动态地址的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!
版权声明:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权、违法违规、事实不符,请将相关资料发送至xkadmin@xkablog.com进行投诉反馈,一经查实,立即处理!
转载请注明出处,原文链接:https://www.xkablog.com/qdvuejs/10694.html