基于iView中后台开发(1)-根据列定义动态生成表单
博客专区 > Trivia 的博客 > 博客详情
基于iView中后台开发(1)-根据列定义动态生成表单
Trivia 发表于3个月前
基于iView中后台开发(1)-根据列定义动态生成表单
  • 发表于 3个月前
  • 阅读 214
  • 收藏 1
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

通常,中后台开发中都有大量的数据要处理,如果没有很好的业务封装和框架支持,依靠人工手动编码表单,简直不可想象。

Django xadmin为此提供了比较好的一套前端封装,通过模型定义,就可以生成表单。

var column ={
 title:'名称',
 key:'name',
 type:'text'
 readonly:false,
 searchable:true,
}
  1. title: 要显示的label标签
  2. key: 数据中的字段名称
  3. type: 要使用的表单组件,可选值为text(default),enum,textarea,code
  4. readonly:如果是新增,则不显示这个字段,如果是更新,则显示为只读字段
  5. searchable: 主要是用来在多条件面板搜索过滤时动态生成表单(本文略过)

可选的表单组件可根据需求进行封装,本文为求简单,不涉及多选(checkbox和multiple select )

text对应Input组件

enum目前选择Select

textarea选择Input[type=textarea]

code选择vue-codemirror(一个第三方组件)

代码和思路都很简单

首先遍历一个由多个column组成的columns数组

读取column的定义,然后根据type选择不同组件(这些组件应当支持v-model,双向绑定的本质vue的文档中有提到,是通过Vue.$emit('input',obj),来达到双向传递的目的)

并利用javascript动态属性的特点,将每一个表单组件双向绑定到value上。

<template>
    <Form 
        label-position="right"
        ref="advancedForm" 
        :model="value" 
        :rules="ruleValidate" 
        :label-width="80"
        @submit="advancedSearch('advancedForm')">
            <Form-item 
                v-for="column in columns"
                 v-if="!column.readonly && !/action|index|selection|expand/.test(column.key)"
                :key="column.key"
                :label="column.title"
                :prop="column.key">          
                <codemirror
                    v-if="column.type == 'code'"
                    ref="myEditor"
                    v-model="value[column.key]"
                    :options="editorOptions"
                    @change="handleSubmit('advancedForm')">
                </codemirror>
                <Select 
                    v-else-if="column.type == 'enum'"
                    v-model="value[column.key]"
                    transfer
                    @on-change="handleSubmit('advancedForm')">
                    <Option
                        v-for="option in column.enum"
                        :key="option.value"
                        :value="option.value">{{option.label}}
                    </Option>
                </Select>
                <Input 
                    v-else-if="column.type == 'textarea'"
                    type="textarea"
                    v-model.trim="value[column.key]"
                    :placeholder="column.key"
                    @on-change="handleSubmit('advancedForm')">
                </Input>
                <Input
                    v-else
                    v-model.trim="value[column.key]"
                    :placeholder="column.key" 
                    @on-change="handleSubmit('advancedForm')"></Input>
            </Form-item>
                
    </Form>
</template>
<script>
import Scripts from '../../../columns/Scripts'
import Codemirror from '../../common/CodeMirror.vue'
export default {
    components: {
        Codemirror
    },
    mixins: [Scripts],
    props: {
        value: {
            type: Object,
            default: () => {
                return {
                    confirmation: '',
                    description: ''
                }
            },
        }
    },
    data() {
        return {
            ruleValidate: {
                name: [
                    { required: true, message: '脚本名不能为空', trigger: 'blur' }
                ]
            },
            editorOptions: {
                tabSize: 4,
                mode: 'text/x-python',
                lineNumbers: true,
                line: true,
                theme: "monokai",
                keyMap: "sublime",
                foldGutter: true,
                gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter"],
                styleSelectedText: true,
                highlightSelectionMatches: { showToken: /\w/, annotateScrollbar: true },
            }
            }
    },
    methods: {
        handleSubmit(name) {

            this.$refs[name].validate((valid) => {
                if (valid) {
                    this.$emit('input', this.value);
                }
            })
        }
    }
}
</script>

 

标签: iView Vue 表单
共有 人打赏支持
粉丝 0
博文 2
码字总数 790
×
Trivia
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: