赞
踩
运用到实际项目可能有帮助的点:
el-table嵌套input的实际使用
多选和单选的答案排版显示切换
v-model改变了但页面没渲染的解决方式
封装组件的思想
前几天做了一个表单组件 分享一下感受(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项目中的实际运用(插槽的使用),还有怎么实现一个简洁可编辑响应式表单(新增 编辑 删除)的业务需求
el-select多选框的multiple属性(可多选)需要是一个数组,所以每次都需要切换
如果反复切换,数组和字符串的方法转化会多很多不要的标点符号,所以每次切换得清空值
scope里的$index可以拿到循环里的下标
新建的时候选项的值更新了 但是没有进到dataForm.Options里面去 所以我用了this.$forceUpdate()。
第四点奇怪的是编辑时候是正常的 能同步到select去,但是新建就不行得用强制刷新,这个问题我还在疑惑,希望有大佬解惑。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。