题型编辑实时预览功能

需要实现的业务功能:问卷调查类似,左边编辑题目,右边实时实现题型可视化预览。如下:
调查问卷题型可视化:
在这里插入图片描述
考试题目题型可视化:
在这里插入图片描述

调查问卷

<template>
  <div class="created-form-text">
    <div class="content">
      <div>
        <p>从文本创建调查问卷 &nbsp;&nbsp;<el-button @click="getLeg" link type="primary">查看样例</el-button></p>
        <div class="left">
          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入内容" v-model="textarea" @input="textChange"> </el-input>
        </div>
        <p style="text-align: right; margin-top: 20px">
          <el-button>取消</el-button>
          <el-button type="primary" @click="markSure">确定</el-button>
        </p>
      </div>
      <div>
        <p>预览 &nbsp;&nbsp;<el-button link></el-button></p>
        <div class="right">
          <p v-for="(i, index) in textTitle" :key="index" class="textClass">{{ i }}</p>
          <div class="question-box" v-for="(item, index) in questionList" :key="index">
            <p style="margin-bottom: 6px">{{ index + 1 }}.{{ item.title }}</p>
            <div v-if="item.type === 'radio'">
              <el-radio-group v-model="radio">
                <el-radio :label="index + 1" v-for="(i, index) in item.ques" :key="index" disabled>{{ i }}</el-radio>
              </el-radio-group>
            </div>
            <div v-else-if="item.type === 'checkbox'">
              <el-checkbox-group v-model="checkList">
                <el-checkbox :label="i" v-for="(i, index) in item.ques" :key="index" disabled></el-checkbox>
              </el-checkbox-group>
            </div>
            <div v-else-if="item.type === 'input'">
              <el-input v-model="inputText" placeholder="请输入内容" disabled></el-input>
            </div>
            <div v-else-if="item.type === 'texteare'">
              <el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="textareaText" disabled> </el-input>
            </div>
          </div>
        </div>
      </div>
    </div>
    <el-dialog title="提示" v-model="isShowLeg" width="40%" :close-on-click-modal="false" destroy-on-close>
      <div>
        <p style="color: #79bbff; margin-bottom: 20px">格式说明:每道题之间用空白行隔开;用[单选题][多选题][单行填空题][多行填空题]来标注不同的题型</p>
        <div class="diaClass">
          《安全生产法》问卷调查<br /><br />
          问卷简介<br /><br />
          本单位安全生产第一责任人是()[单选题]<br />
          法人<br />
          主要责任人<br />
          总经理<br />
          总工程师<br /><br />
          安全生产事故调查的“四不放过”指的是[多选题]<br />
          事故原因未查清不放过<br />
          责任人未受到处理不放过<br />
          整改措施未落实不放过<br />
          有关人员未受到教育不放过<br /><br />
          请用一句话描述你对新安全生产法的认识[单行填空题]<br /><br />
          请详细描述你对新安全生产法的理解[多行填空题]<br />
        </div>
        <div class="footer">
          <el-button type="primary" @click="isShowLeg = false">确定</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import request from '@/utils/request'
import { ElMessage } from 'element-plus'
export default {
  data() {
    return {
      radio: '',
      checkList: [],
      inputText: '',
      textareaText: '',
      textarea: '',
      questionList: [],
      isShowLeg: false,
      textTitle: [],
    }
  },
  methods: {
    textChange(data) {
      if (!data) return
      const b = data.replace(new RegExp(' ', 'gm'), '\u3000') //可输入空格
      const text = b.split('\n\n') //根据换行题目与题目之间分割
      this.questionList = []
      this.textTitle = []
      text.forEach((i) => {
        const a = i.split('\n').filter(Boolean) //将题目答案分割成数组
        if (this.quesTypeFun(a[0]) === '[单选题]') {
          this.questionList.push({
            title: a[0].replace('[单选题]', ''),
            ques: a.slice(1),
            type: 'radio',
          })
        } else if (this.quesTypeFun(a[0]) === '[多选题]') {
          this.questionList.push({
            title: a[0].replace('[多选题]', ''),
            ques: a.slice(1),
            type: 'checkbox',
          })
        } else if (this.quesTypeFun(a[0]) === '[单行填空题]') {
          this.questionList.push({
            title: a[0].replace('[单行填空题]', ''),
            type: 'input',
          })
        } else if (this.quesTypeFun(a[0]) === '[多行填空题]') {
          this.questionList.push({
            title: a[0].replace('[多行填空题]', ''),
            type: 'texteare',
          })
        } else {
          this.textTitle.push(a[0])
        }
        // console.log(this.questionList)
      })
    },
    //判断题型
    quesTypeFun(str) {
      if (str) {
      //从字符串末尾截取中括号到结尾之间的字符
        return str.substring(str.lastIndexOf('['), str.length)
      }

      //   if (str.indexOf('[') != -1 && str.indexOf(']') != -1) {
      //     let a1 = /\[(.+?)\]/g
      //     let a2 = str.match(a1).toString()
      //     var a3 = a2.replace('[', '')
      //     a3 = a3.replace(']', '')
      //     // console.log(a3)
      //     return a3
      //   }
    },
    //查看示例
    getLeg() {
      this.isShowLeg = true
    },
  },
}
</script>
<style lang="less">
.created-form-text {
  padding: 0 1%;
  .content {
    display: flex;
    justify-content: space-between;
    .left {
      .el-textarea__inner {
        height: 100% !important;
        box-shadow: none;
        border-radius: 10px;
      }
    }

    .right {
      padding: 1%;
      box-sizing: border-box;
      overflow: scroll;
      .textClass {
        margin-bottom: 20px;
        text-align: center;
      }
      .question-box {
        margin-bottom: 20px;
      }
      .el-radio,
      .el-radio-group,
      .el-checkbox {
        display: block;
      }
      .el-radio__label,
      .el-checkbox__label {
        color: #777;
      }

      .el-checkbox-group {
        line-height: unset;
      }
    }
    > div {
      width: 49%;
      overflow: scroll;
      > div {
        border: 1px solid #d1dbe5;
        border-radius: 10px;
        height: 500px;
      }
      > p {
        margin-bottom: 31px;
      }
      .el-textarea {
        height: 100%;
      }
    }
  }
  .footer {
    text-align: center;
    margin: 20px;
  }
  .diaClass {
    border: 1px solid #d1dbe5;
    border-radius: 10px;
    padding: 10px;
  }
}
</style>

考试问卷

<template>
  <div class="created-form-text-ks">
    <div class="content">
      <div>
        <p>从文本创建考试问卷 &nbsp;&nbsp;<el-button link type="primary" @click="getLeg">查看样例</el-button></p>
        <div class="left">
          <el-input type="textarea" :autosize="{ minRows: 2, maxRows: 4 }" placeholder="请输入内容" v-model="textarea" @input="textChange"> </el-input>
        </div>
        <p style="text-align: right; margin-top: 20px">
          <el-button>取消</el-button>
          <el-button type="primary" @click="markSure">确定</el-button>
        </p>
      </div>
      <div>
        <p>预览 &nbsp;&nbsp;<el-button link></el-button></p>
        <div class="right">
          <p v-for="(i, index) in textTitle" :key="index" class="textClass">
            {{ i }}
          </p>
          <div class="question-box" v-for="(item, index) in questionList" :key="index">
            <p style="margin-bottom: 6px">
              {{ index + 1 }}.{{ item.title }}&nbsp;<span style="color: #409eff">分值:{{ item.score }}</span
              ></p>
            <div v-if="item.type === 'radio'">
              <el-radio-group v-model="item.value">
                <el-radio :label="index + 1" v-for="(i, index) in item.ques" :key="index" disabled>{{ i }}</el-radio>
              </el-radio-group>
            </div>
            <div v-else-if="item.type === 'judge'">
              <el-radio-group v-model="item.value" disabled>
                <el-radio :label="1"></el-radio>
                <el-radio :label="2"></el-radio>
              </el-radio-group>
            </div>
            <div v-else-if="item.type === 'checkbox'">
              <el-checkbox-group v-model="item.value">
                <el-checkbox :label="i" v-for="(i, index) in item.ques" :key="index" disabled></el-checkbox>
              </el-checkbox-group>
            </div>
            <div v-else-if="item.type === 'input'">
              <el-input v-model="item.value" placeholder="请输入内容" disabled></el-input>
            </div>
            <div v-else-if="item.type === 'texteare'">
              <el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="item.value" disabled> </el-input>
            </div>
          </div>
        </div>
      </div>
    </div>
    <el-dialog title="提示" v-model="isShowLeg" width="40%" :close-on-click-modal="false" destroy-on-close>
      <div>
        <p style="color: #79bbff; margin-bottom: 20px">格式说明:每道题之间用空白行隔开;用[单选题][判断题][多选题][填空题][简答题]来标注不同的题型,分值与答案之间用,隔开</p>
        <div class="diaClass">
          《安全生产法》考试<br /><br />
          考试问卷简介,该行可以删除<br /><br />
          本单位安全生产第一责任人是()[单选题]4分,C<br />
          法人<br />
          主要责任人<br />
          总经理<br />
          总工程师<br /><br />
          《安全生产法》不仅适用于生产经营单位,同时也适用于国家安全和社会治安方面的管理。[判断题]3分,错<br /><br />
          安全生产事故调查的“四不放过”指的是[多选题]5分,ABCD<br />
          事故原因未查清不放过<br />
          责任人未受到处理不放过<br />
          整改措施未落实不放过<br />
          有关人员未受到教育不放过<br /><br />
          请用一句话描述你对安全生产法的认识[填空题]5<br />
          答案:二十|20<br /><br />
          请详细描述你觉得新安全生产法有哪些好处[简答题]10<br />
          参考答案:我认为有这些好处:1...2...3...<br />
        </div>
        <div class="footer">
          <el-button type="primary" @click="isShowLeg = false">确定</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import request from '@/utils/request'
import { ElMessage } from 'element-plus'
export default {
  data() {
    return {
      radio: '',
      judgeValue: '',
      checkList: [],
      inputText: '',
      textareaText: '',
      textarea: '',
      questionList: [],
      isShowLeg: false,
      textTitle: [],
    }
  },
  methods: {
    textChange(data) {
      if (!data) return
      const b = data.replace(new RegExp(' ', 'gm'), '\u3000')
      const text = b.split('\n\n')
      this.questionList = []
      this.textTitle = []
      text.forEach((i) => {
        const a = i.split('\n').filter(Boolean)
        let flag = []
        if (a.length > 0) {
          //中英文逗号全部转化为英文逗号
          flag = a[0].replace(/[\uff0c]/g, ',')
        }

        if (this.quesTypeFun(a[0]) === '[单选题]') {
          this.questionList.push({
            title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
            ques: a.slice(1),
            type: 'radio',
            value: this.getAnswerFun(a),
            score: a[0].substring(a[0].lastIndexOf(']') + 1, flag.lastIndexOf(',')),
          })
        } else if (this.quesTypeFun(a[0]) === '[判断题]') {
          this.questionList.push({
            title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
            ques: a.slice(1),
            type: 'judge',
            value: this.getAnswerFun(a),
            score: a[0].substring(a[0].lastIndexOf(']') + 1, flag.lastIndexOf(',')),
          })
        } else if (this.quesTypeFun(a[0]) === '[多选题]') {
          this.questionList.push({
            title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
            ques: a.slice(1),
            type: 'checkbox',
            value: this.getAnswerFun(a),
            score: a[0].substring(a[0].lastIndexOf(']') + 1, flag.lastIndexOf(',')),
          })
        } else if (this.quesTypeFun(a[0]) === '[填空题]') {
          this.questionList.push({
            title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
            type: 'input',
            value: a[1],
            score: a[0].substring(a[0].lastIndexOf(']') + 1, a[0].length),
          })
        } else if (this.quesTypeFun(a[0]) === '[简答题]') {
          this.questionList.push({
            title: a[0].replace(a[0].substring(a[0].lastIndexOf('['), a[0].length), ''),
            type: 'texteare',
            value: a[1],
            score: a[0].substring(a[0].lastIndexOf(']') + 1, a[0].length),
          })
        } else {
          this.textTitle.push(a[0])
        }
        // console.log(this.questionList)
      })
    },
    //判断题型
    quesTypeFun(str) {
      if (str) {
        return str.substring(str.lastIndexOf('['), str.lastIndexOf(']') + 1)
      } else {
        return ''
      }
    },
    //将ABCDE...转化为12345....
    reverNum(str, a) {
      if (str.length > 1) {
        const arrStr = str.split('')
        let arr = []
        arrStr.forEach((item) => {
          arr.push(a[item.charCodeAt() - 64])
        })
        return arr
      } else {
        return str.charCodeAt() - 64
      }
    },
    //获取题目答案
    getAnswerFun(a) {
      const flag = a[0].replace(/[\uff0c]/g, ',')
      const value = a[0].substring(flag.lastIndexOf(',') + 1, a[0].length)
      if (value === '对') {
        return 1
      } else if (value === '错') {
        return 2
      } else {
        return this.reverNum(value, a)
      }
    },
    //查看示例
    getLeg() {
      this.isShowLeg = true
    },
  },
}
</script>
<style lang="less">
.created-form-text-ks {
  padding: 0 1%;
  .content {
    display: flex;
    justify-content: space-between;
    .left {
      .el-textarea__inner {
        height: 100% !important;
        box-shadow: none;
        border-radius: 10px;
      }
    }

    .right {
      padding: 1%;
      box-sizing: border-box;
      overflow: scroll;
      .textClass {
        margin-bottom: 20px;
        text-align: center;
      }
      .question-box {
        margin-bottom: 20px;
      }
      .el-radio,
      .el-radio-group,
      .el-checkbox {
        display: block;
      }
      .el-radio__label,
      .el-checkbox__label {
        color: #777;
      }
      .el-checkbox__input.is-disabled.is-checked .el-checkbox__inner {
        background: #409eff;
        color: #fff;
        &::after {
          border-color: #fff;
        }
      }
      .el-checkbox-group {
        line-height: unset;
      }
    }
    > div {
      width: 49%;
      overflow: scroll;
      > div {
        border: 1px solid #d1dbe5;
        border-radius: 10px;
        height: 500px;
      }
      > p {
        margin-bottom: 31px;
      }
      .el-textarea {
        height: 100%;
      }
    }
  }
  .footer {
    text-align: center;
    margin: 20px;
  }
  .diaClass {
    border: 1px solid #d1dbe5;
    border-radius: 10px;
    padding: 10px;
  }
}
</style>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值