首页 前端知识 element框架 el-table嵌套input 实现表单(pc端)

element框架 el-table嵌套input 实现表单(pc端)

2024-02-06 15:02:56 前端知识 前端哥 788 14 我要收藏

运用到实际项目可能有帮助的点:

  1. el-table嵌套input的实际使用

  1. 多选和单选的答案排版显示切换

  1. v-model改变了但页面没渲染的解决方式

  1. 封装组件的思想

前几天做了一个表单组件 分享一下感受(vue2)

先上图

点击新增或者编辑会进入表单组件并且触发组件内的init方法,编辑会带该题的id,新建则是空。(父组件代码就不摆上来了)

子组件代码
<template>
    <transition name="el-zoom-in-center">
        <div class="JNPF-preview-main">
            <div class="JNPF-common-page-header">
                <el-page-header @back="goBack" :content="!dataForm.id ? '新建' : '编辑'" />
                <div class="options">
                    <el-button type="primary" @click="dataFormSubmit()" :loading="btnLoading">确 定</el-button>
                    <el-button @click="goBack">取 消</el-button>
                </div>
            </div>
            <div :style="{ margin: '0 auto', width: '100%' }">
                <el-row :gutter="15" class=" main">
                    <el-form ref="elForm" :model="dataForm" size="small" label-width="100px" label-position="right"
                        :rules="rules">
                        <el-col :span="24">
                            <el-form-item label="分类" prop="Category">
                                <el-select v-model='dataForm.Category' placeholder='请选择' clearable required
                                    :style='{ "width": "100%" }'>
                                    <el-option v-for="(item, index) in CategoryOptions" :key="index" :label="item.fullName"
                                        :value="item.id"></el-option>
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="题型" prop="QuestionType">
                                <el-radio-group v-model='dataForm.QuestionType' @change="(e) => QuestionTypeIs(e)" required>
                                    <el-radio v-for="(item, index) in QuestionTypeOptions" :key="index" :label="item.id">{{
                                        item.fullName }} </el-radio>
                                </el-radio-group>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="题干" prop="QuestionStem">
                                <el-input v-model='dataForm.QuestionStem' placeholder='请输入' clearable required
                                    :style='{ "width": "100%" }'>
                                </el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label-width="0">
                                <div class="JNPF-common-title">
                                    <h2>选项内容</h2>
                                </div>
                                <el-table :data="dataForm.Options" size='mini'>
                                    <el-table-column type="index" width="50" label="序号" align="center" />
                                    <el-table-column prop="Options" label="选项内容">
                                        <template slot="header">
                                            <span class="required-sign">*</span>选项内容
                                        </template>
                                        <template slot-scope="scope">
                                            <el-input v-model="dataForm.Options[scope.$index]" :style='{ "width": "100%" }'
                                                placeholder='请输入' clearable required>
                                            </el-input>
                                        </template>
                                    </el-table-column>
                                    <el-table-column label="操作" width="50">
                                        <template slot-scope="scope">
                                            <el-button size="mini" type="text" class="JNPF-table-delBtn"
                                                @click="handleDelEmaQuestionOptionEntityList(scope.$index)">删除</el-button>
                                        </template>
                                    </el-table-column>
                                </el-table>
                                <div class="table-actions" @click="addHandleEmaQuestionOptionEntityList()">
                                    <el-button type="text" icon="el-icon-plus">新增</el-button>
                                </div>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="答案" prop="Answer" v-if="QuestionType == 1">
                                <el-select v-model='dataForm.Answer' placeholder='请选择' clearable required
                                    :style='{ "width": "100%" }'>
                                    <el-option v-for="(item, index) in dataForm.Options" :key="index" :label="index + 1"
                                        :value="index + 1"></el-option>
                                </el-select>
                            </el-form-item>
                            <el-form-item label="答案" prop="Answer" v-if="QuestionType == 2">
                                <el-select v-model="dataForm.Answer" placeholder="请选择" :style='{ "width": "100%" }'
                                    clearable required multiple>
                                    <el-option v-for="(item, index) in dataForm.Options" :key="index" :label="index + 1"
                                        :value="index + 1">
                                    </el-option>
                                </el-select>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="分值" prop="Point">
                                <el-input-number v-model='dataForm.Point' placeholder='数字文本' required :step='1'
                                    controls-position='right' :max='100' :min='1'>
                                </el-input-number>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24">
                            <el-form-item label="是否有效" prop="F_EnabledMark">
                                <el-switch v-model='dataForm.F_EnabledMark' :active-value='1' :inactive-value='0'>
                                </el-switch>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24" v-if='false'>
                            <el-form-item label="创建用户" prop="F_CreatorUserId">
                                <jnpf-open-data v-model='dataForm.F_CreatorUserId' readonly type='currUser'>
                                </jnpf-open-data>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24" v-if='false'>
                            <el-form-item label="创建时间" prop="F_CreatorTime">
                                <jnpf-open-data v-model='dataForm.F_CreatorTime' readonly type='currTime'>
                                </jnpf-open-data>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24" v-if='false'>
                            <el-form-item label="修改用户" prop="F_LastModifyUserId">
                                <el-input v-model='dataForm.F_LastModifyUserId' placeholder='系统自动生成' readonly>
                                </el-input>
                            </el-form-item>
                        </el-col>
                        <el-col :span="24" v-if='false'>
                            <el-form-item label="修改时间" prop="F_LastModifyTime">
                                <el-input :value='dataForm.f_LastModifyTime | toDate' placeholder='系统自动生成' readonly />
                            </el-form-item>
                        </el-col>
                    </el-form>
                </el-row>
            </div>
        </div>
    </transition>
</template>
<script>
import request from '@/utils/request'
import { getDictionaryDataSelector } from '@/api/systemData/dictionary'
export default {
    components: {},
    props: [],
    data() {
        return {
            btnLoading: false,
            loading: false,
            visible: false,
            dataForm: {
                id: '',
                Category: '',
                QuestionType: "1",
                QuestionStem: '',
                Answer: [],
                Point: 5,
                F_EnabledMark: 0,
                F_CreatorUserId: '',
                F_CreatorTime: '',
                F_LastModifyUserId: '',
                F_LastModifyTime: '',
            },
            QuestionType: 1,
            rules: {
                Category: [
                    {
                        required: true,
                        message: '请输入分类',
                        trigger: 'change'
                    },
                ],
                QuestionType: [
                    {
                        required: true,
                        message: '请输入题型',
                        trigger: 'change'
                    },
                ],
                QuestionStem: [
                    {
                        required: true,
                        message: '请输入题干',
                        trigger: 'blur'
                    },
                ],
                Answer: [
                    {
                        required: true,
                        message: '请输入答案',
                        trigger: 'change'
                    },
                ],
                Point: [
                    {
                        required: true,
                        message: '请输入分值',
                        trigger: [
                            "blur",
                            "change"
                        ]
                    },
                ],
            },
            CategoryOptions: [],
        }
    },
    computed: {},
    watch: {},
    created() {
        this.getcategoryOptions();
    },
    mounted() {
    },
    computed: {
    },
    watch: {
    },
    methods: {
        // 非空校验
        emaQuestionOptionExist() {
            let isOk = true;
            for (let i = 0; i < this.dataForm.Options.length; i++) {
                const e = this.dataForm.Options[i];
                if (!e) {
                    this.$message({
                        message: '选项内容不能为空',
                        type: 'error',
                        duration: 1000
                    });
                    isOk = false
                    break
                }
                if (this.QuestionType == 2) {
                    if (this.dataForm.Answer.length == 1) {
                        this.$message({
                            message: '多选题答案应为两个及以上',
                            type: 'error',
                            duration: 1000
                        });
                        isOk = false
                        break
                    }
                }
            }
            return isOk;
        },
        // 获取试题分类数据(消防安全等等..)
        getcategoryOptions() {
            getDictionaryDataSelector('397272689904988741').then(res => {
                this.CategoryOptions = res.data.list
            });
        },
        // 关闭
        goBack() {
            this.$emit('refresh')
        },
        // 点开
        init(id) {
            this.dataForm.id = id || '';
            this.visible = true;
            this.$nextTick(() => {
                this.$refs['elForm'].resetFields();
                this.dataForm.Options = [];
                // 编辑操作
                if (this.dataForm.id) {
                    request({
                        url: `api/visualdev/OnlineDev/380291022044793029/${this.dataForm.id}`,
                        method: 'get'
                    }).then(res => {
                        this.dataForm = res.data.data
                        this.dataForm.id = id || '';
                        this.dataForm.Answer = JSON.parse(this.dataForm.Answer);
                        this.QuestionType = this.dataForm.QuestionType || 1
                    })
                // 新建操作
                }else{
                    this.QuestionType = 1
                }
            });
            this.$store.commit('generator/UPDATE_RELATION_DATA', {})
        },
        // 多选单选切换
        QuestionTypeIs(e) {
            this.QuestionType = e
            if (e == 1) this.dataForm.Answer = ''
            if (e == 2) this.dataForm.Answer = []
        },
        // 提交确定
        dataFormSubmit() {
            this.$refs['elForm'].validate((valid) => {
                if (valid) {
                    if (!this.emaQuestionOptionExist()) return;
                    this.btnLoading = true;
                    this.dataForm.F_EnabledMark = parseInt(this.dataForm.F_EnabledMark)
                    this.dataForm.flowId = ''
                        // 新建提交确定
                    if (!this.dataForm.id) {
                        request({
                            url: `/api/visualdev/OnlineDev/380291022044793029/`,
                            method: 'post',
                            data: {
                                id: this.dataForm.id,
                                data: this.dataForm
                            }
                        }).then((res) => {
                            this.$message({
                                message: res.msg,
                                type: 'success',
                                duration: 1000,
                                onClose: () => {
                                    this.btnLoading = false;
                                    this.visible = false,
                                        this.$emit('refresh', true)
                                }
                            })
                        }).catch(() => {
                            this.btnLoading = false;
                        })
                    } else {
                        // 编辑提交确定
                        request({
                            url: `/api/visualdev/OnlineDev/380291022044793029/${this.dataForm.id}`,
                            method: 'PUT',
                            data: {
                                id: this.dataForm.id,
                                data: this.dataForm
                            }
                        }).then((res) => {
                            this.$message({
                                message: res.msg,
                                type: 'success',
                                duration: 1000,
                                onClose: () => {
                                    this.btnLoading = false;
                                    this.visible = false
                                    this.$emit('refresh', true)
                                }
                            })
                        }).catch(() => {
                            this.btnLoading = false;
                        })
                    }
                }
            })
        },
        // 选项新增
        addHandleEmaQuestionOptionEntityList() {
            let item = ''
            this.dataForm.Options.push(item)
            if (!this.dataForm.id) this.$forceUpdate()
        },
        // 选项删除
        handleDelEmaQuestionOptionEntityList(index) {
            this.dataForm.Options.splice(index, 1);
            if (!this.dataForm.id) this.$forceUpdate()
        },
    }
}
</script>
编辑实际图
新增实际图

代码不复杂 且都做了注释

主要是分享下el-table嵌套input项目中的实际运用(插槽的使用),还有怎么实现一个简洁可编辑响应式表单(新增 编辑 删除)的业务需求

其中需要注意的目前回忆起来有几点:
  1. el-select多选框的multiple属性(可多选)需要是一个数组,所以每次都需要切换

  1. 如果反复切换,数组和字符串的方法转化会多很多不要的标点符号,所以每次切换得清空值

  1. scope里的$index可以拿到循环里的下标

  1. 新建的时候选项的值更新了 但是没有进到dataForm.Options里面去 所以我用了this.$forceUpdate()。

第四点奇怪的是编辑时候是正常的 能同步到select去,但是新建就不行得用强制刷新,这个问题我还在疑惑,希望有大佬解惑。

转载请注明出处或者链接地址:https://www.qianduange.cn//article/1467.html
评论
发布的文章
大家推荐的文章
会员中心 联系我 留言建议 回顶部
复制成功!