本篇内容介绍了“element中el-form-item属性prop的坑怎么解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
最近负责前后端项目开发,有个需求是实现Djangorestframework(drf)+element实现动态渲染form表单,drf后端提供json,前端从json中获取form表单元素,并且绑定表单验证规则
在el-form-item属性prop上遇到报错或者没绑定到数据,报错如下
[Vue warn]: Error in render: "TypeError: Cannot read properties of undefined (reading 'prop')"
element官方文档解释el-form-item的prop必须是el-form属性model的直接子属性
后端返回数据如下
{
"status": "success",
"code": 200,
"data": {
"form_attributes": {
"inline": true,
"label-width": "auto",
"size": "small"
},
"form_data": {
"name": null,
"path": null,
"component": null,
"hidden": false,
"meta": {
"icon": null,
"title": null
},
"pid": null
},
"form_item_list": [
{
"type": "text",
"prop": "name",
"label": "菜单名",
"placeholder": "请输入菜单名",
"rules": [
{
"required": true,
"message": "请输入菜单名",
"trigger": "blur"
}
]
},
{
"type": "text",
"prop": "path",
"label": "链接地址",
"placeholder": "'/'开头",
"rules": [
{
"required": true,
"message": "'/'开头",
"trigger": "blur"
}
]
},
{
"type": "text",
"prop": "component",
"label": "组件",
"placeholder": "参考前端组件填写",
"rules": [
{
"required": true,
"message": "参考前端组件填写",
"trigger": "blur"
}
]
},
{
"type": "switch",
"prop": "hidden",
"label": "是否隐藏",
"value": false
},
{
"type": "json",
"prop": "meta",
"item": [
{
"type": "text",
"prop": "icon",
"label": "图标",
"placeholder": "图标名字,参考前端图标",
"rules": [
{
"required": true,
"message": "图标名字,参考前端图标",
"trigger": "blur"
}
]
},
{
"type": "text",
"prop": "title",
"label": "标题",
"placeholder": "请输入菜单名",
"rules": [
{
"required": true,
"message": "请输入菜单名",
"trigger": "blur"
}
]
}
]
},
{
"type": "select",
"prop": "pid",
"label": "父菜单",
"clearable": true,
"filterable": false,
"multiple": false,
"options": [
{
"label": "系统管理",
"value": 2
},
{
"label": "用户管理",
"value": 3
},
{
"label": "菜单管理",
"value": 4
},
{
"label": "权限管理",
"value": 5
},
{
"label": "角色管理",
"value": 6
}
]
}
]
},
"message": null
}
从上面可以看到form表单元素对应的是 form_item_list,表单提交数据是 form_data,这两个是分开,也就是el-form中model绑定是 form_data 而el-form-item遍历的是 form_item_list,注意 form_item_list 中含有嵌套类型json,对应的后端是json字段渲染表单,单独提供form_data返回字段设计是为了控制前端json内容,动态字段中过于灵活,可以随意修改json包含的字段和类型,所以返回字段由后端控制和校验
截取前端渲染表单代码如下,注意这个时候能渲染但是rules绑定是失败的
<!-- 添加菜单对话框 -->
<el-dialog title="添加菜单" :visible.sync="addDialogVisible" width="50%" :close-on-click-modal="false" @close="addDialogClosed">
<!-- 表单内容主体 -->
<el-form ref="addFormRef" :model="formData" :size="formAttributes.size" :inline="formAttributes.inline" :label-width="formAttributes.labelWidth">
<div v-for="(item, index) in formItemList" :key="index">
<el-form-item :prop="formItemList + index + item.prop" :label="item.label" :rules="item.rules">
<!-- text输入框 -->
<el-input v-if="item.type==='text'" v-model="formData[item.prop]" clearable :placeholder="item.placeholder"></el-input>
<!-- textarea输入框 -->
<el-input v-if="item.type==='textarea'" v-model="formData[item.prop]" clearable autosize :type="textarea" :placeholder="item.placeholder"></el-input>
<!-- 下拉框 -->
<el-select v-if="item.type==='select'" v-model="formData[item.prop]" clearable :multiple="item.multiple">
<el-option v-for="op in item.options" :key="op.value" :label="op.label" :value="op.value"></el-option>
</el-select>
<el-switch v-if="item.type==='switch'" v-model="formData[item.prop]" :label="item.label"></el-switch>
<template v-if="item.type==='json'">
<div v-for="(json_item, json_index) in item.item" :key="json_index">
<el-form-item :prop="item.item + json_index + json_item.prop" :label="json_item.label" :rules="json_item.rules" >
<!-- text输入框 -->
<el-input v-if="json_item.type==='text'" v-model="formData[item.prop][json_item.prop]" clearable :placeholder="json_item.placeholder"></el-input>
<!-- textarea输入框 -->
<el-input v-if="json_item.type==='textarea'" v-model="formData[json_item.prop]" clearable autosize :type="textarea" :placeholder="json_item.placeholder"></el-input>
<!-- 下拉框 -->
<!-- <el-select v-if="item.type==='select'" v-model="formData[item.prop]" clearable :placeholder="item.label" :multiple="item.multiple" @change="item.change(formData[item.prop])"> -->
<el-select v-if="json_item.type==='select'" v-model="formData[json_item.prop]" clearable :multiple="json_item.multiple">
<el-option v-for="op in json_item.options" :key="op.value" :label="op.label" :value="op.value"></el-option>
</el-select>
<el-switch v-if="json_item.type==='switch'" v-model="formData[json_item.prop]" :label="json_item.label"></el-switch>
</el-form-item>
</div>
</template>
</el-form-item>
</div>
</el-form>
<!-- 底部 -->
<el-divider></el-divider>
<span slot="footer" class="dialog-footer">
<el-button @click="addDialogVisible = false">取消</el-button>
<el-button type="primary" @click="addForm">确定</el-button>
</span>
</el-dialog>
在前端渲染无法绑定到表单规则,如下图
经过研究,从上面的数据结构可以发现,form_data 中每个元素对应是 form_item_list 中的 prop,那么有两个写法可以定位
第一种写法如下,这种写法没那么直观
<!-- 普通字段渲染 -->
<el-form-item :prop="item.prop" :label="item.label" :rules="item.rules">
<!-- json字段渲染 -->
<el-form-item :prop="item.prop + '.' + json_item.prop" :label="json_item.label" :rules="json_item.rules" >
更好的第二种写法如下
<el-form-item :prop="formItemList[index].prop" :label="item.label" :rules="item.rules">
<el-form-item :prop="formItemList[index].prop + '.' + item.item[json_index].prop" :label="json_item.label" :rules="json_item.rules" >
此时能动态渲染表单和绑定表单项验证规则,如下图
“element中el-form-item属性prop的坑怎么解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注亿速云网站,小编将为大家输出更多高质量的实用文章!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。