学科
1、去发请求获取所有的学科数据,存到subjectList:【】数组中
2、获取到数据之后,遍历数组 v-for="item in subjectList"得到每一个将其中的几个值设置给el-selectel-option的label、value、key
企业
1、去发请求获取所有企业的数据,存到 enterpriseList:【】数组中
2、获取到数据之后,遍历数组 v-for="item in enterpriseList"得到每一个将其中的几个值设置给el-selectel-option的label、value、key
阶段,题型,难度
1、设置数据:stepObj: { 1: “初级”, 2: “中级”, 3: “高级” }, //题目阶段
typeObj: { 1: “单选”, 2: “多选”, 3: “简答” }, //题目类型
difficultyObj: { 1: “简单”, 2: “一般”, 3: “困难” } // 题目难度
2、获取到数据之后,遍历对象v-for="(value,name) in xxxObj"得到每一个将其中的几个值设置给el-selectel-option的label、value、key
作者、标题
: 普通的el-input框
状态
:就两个要么禁用,要么启用,在el-select下的el-option中可以写死
跟之前做的都一样啦!没啥好说的,
其中做清除功能的时候 如果要调用 form 表单的 resetFields 这个方法,需要给 el-form-item 设置 prop
question文件夹下的index.vue组件:
<template>
<div class="question">
<el-card>
<el-form inline :model="searchForm" ref="searchFormRef" label-width="80px">
<el-row>
<el-col :span="6">
<el-form-item label="学科" prop="subject">
<el-select v-model="searchForm.subject" placeholder="请选择学科">
<el-option
v-for="item in subjectList"
:key="item.id"
:label="item.name"
:value="item.id"
>el-option>
el-select>
el-form-item>
el-col>
<el-col :span="6">
<el-form-item label="阶段" prop="step">
<el-select v-model="searchForm.step" placeholder="请选择阶段">
<el-option v-for="(value,name) in stepObj" :key="name" :label="value" :value="name">el-option>
el-select>
el-form-item>
el-col>
<el-col :span="6">
<el-form-item label="企业" prop="enterprise">
<el-select v-model="searchForm.enterprise" placeholder="请选择企业">
<el-option
v-for="item in enterpriseList"
:key="item.id"
:label="item.name"
:value="item.id"
>el-option>
el-select>
el-form-item>
el-col>
<el-col :span="6">
<el-form-item label="题型" prop="type">
<el-select v-model="searchForm.type" placeholder="请选择题型">
<el-option v-for="(value,name) in typeObj" :key="name" :label="value" :value="name">el-option>
el-select>
el-form-item>
el-col>
el-row>
<el-row>
<el-col :span="6">
<el-form-item label="难度" prop="difficulty">
<el-select v-model="searchForm.difficulty" placeholder="请选择难度">
<el-option
v-for="(value,name) in difficultyObj"
:key="name"
:label="value"
:value="name"
>el-option>
el-select>
el-form-item>
el-col>
<el-col :span="6">
<el-form-item label="作者" prop="username">
<el-input style="width:217px" v-model="searchForm.username">el-input>
el-form-item>
el-col>
<el-col :span="6">
<el-form-item label="状态" prop="status">
<el-select v-model="searchForm.status" placeholder="请选择状态">
<el-option label="启用" value="1">el-option>
<el-option label="禁用" value="0">el-option>
el-select>
el-form-item>
el-col>
<el-col :span="6">
<el-form-item label="日期" prop="create_date">
<el-date-picker v-model="searchForm.create_date" type="date" placeholder="请选择日期">el-date-picker>
el-form-item>
el-col>
el-row>
<el-row>
<el-col :span="12">
<el-form-item label="标题" prop="title">
<el-input style="width:620px" v-model="searchForm.title">el-input>
el-form-item>
el-col>
<el-col :span="12">
<el-form-item>
<el-button type="primary" @click="search">搜索el-button>
<el-button @click="clear">清除el-button>
<el-button type="primary" @click="add">+新增试题el-button>
el-form-item>
el-col>
el-row>
el-form>
el-card>
<el-card style="margin-top:15px">
<el-table :data="questionList" border stripe>
<el-table-column label="序号" type="index">el-table-column>
<el-table-column label="题目" width="300">
<template slot-scope="scope">
<span v-html="scope.row.title">span>
template>
el-table-column>
<el-table-column label="学科.阶段" :formatter="formatterSubject">el-table-column>
<el-table-column label="题型" :formatter="formatterType">
el-table-column>
<el-table-column label="企业" prop="enterprise_name">el-table-column>
<el-table-column label="状态">
<template slot-scope="scope">
<span
:style="{color:scope.row.status===1?'#85ce61':'red'}"
>{{scope.row.status===1?'启用':'禁用'}}span>
template>
el-table-column>
<el-table-column label="访问量" prop="reads">el-table-column>
<el-table-column label="操作" width="280">
<template slot-scope="scope">
<el-button type="primary" @click="editQuestion(scope.row)">编辑el-button>
<el-button
@click="changeStatus('/question/status',scope.row.id)"
:type="scope.row.status===1?'info':'success'"
>{{scope.row.status===1?'禁用':'启用'}}el-button>
<el-button type="danger" @click="del('/question/remove',scope.row.id)">删除el-button>
template>
el-table-column>
el-table>
<div style="margin-top:15px;text-align:center">
<el-pagination
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page"
:page-sizes="[2, 4, 6, 8]"
:page-size="limit"
layout="total, sizes, prev, pager, next, jumper"
:total="total"
background
>el-pagination>
div>
el-card>
<qusetion-edit
ref="questionEditRef"
:subjectList="subjectList"
:enterpriseList="enterpriseList"
:stepObj="stepObj"
:typeObj="typeObj"
:difficultyObj="difficultyObj"
>qusetion-edit>
div>
template>
<script>
import QusetionEdit from "./question-add-or-update";
//1.导入混入对象
import common from "@/mixins/common";
export default {
//2. 在自身组件中进入混入
mixins: [common],
components: {
QusetionEdit
},
name: "Qusetion",
data() {
return {
page: 1, //页码 默认为1
limit: 2, //页容量
questionList: [], //题库列表
total: 0, //总条数
//模型提交给后台的
searchForm: {
title: "", //标题名称
subject: "", //学科id
enterprise: "", // 企业id
step: "", // 题目阶段:1(初级),2(中级),3(高级)
type: "", // 题目类型:1(单选),2(多选),3(简答)
difficulty: "", // 题目难度: 1(简单),2(一般),3(困难)
username: "", // 作者
status: "", //状态:0(禁用),1(启用)
create_date: "" // 创建日期
},
subjectList: [], //学科列表
enterpriseList: [], //企业列表
stepObj: { 1: "初级", 2: "中级", 3: "高级" }, //题目阶段
typeObj: { 1: "单选", 2: "多选", 3: "简答" }, //题目类型
difficultyObj: { 1: "简单", 2: "一般", 3: "困难" } // 题目难度
};
},
created() {
this.getSubjectData();
this.getEnterpriseData();
this.getListData();
},
methods: {
//获取所有的学科列表
async getSubjectData() {
const res = await this.$axios.get("/subject/list");
if (res.data.code == 200) {
this.subjectList = res.data.data.items;
}
},
//获取所有的企业列表
async getEnterpriseData() {
const res = await this.$axios.get("/enterprise/list");
if (res.data.code == 200) {
this.enterpriseList = res.data.data.items;
}
},
//获取的题库列表
async getListData() {
const res = await this.$axios.get("/question/list", {
params: {
...this.searchForm,
page: this.page,
limit: this.limit
}
});
if (res.data.code == 200) {
this.questionList = res.data.data.items;
this.total = res.data.data.pagination.total;
}
},
//搜索
search() {
this.page = 1;
this.getListData();
},
//清除
clear() {
// 如果要调用 form 表单的 resetFields 这个方法,需要给 el-form-item 设置 prop
this.$refs.searchFormRef.resetFields();
this.search();
},
// 格式化学科.阶段
formatterSubject(row) {
return `${row.subject_name}.${this.stepObj[row.step]}`;
},
// 格式化题型
formatterType(row) {
return this.typeObj[row.type];
},
//页容量发生变化
sizeChange(val) {
this.limit = val;
this.search();
},
// 当前页发生变化
currentChange(val) {
this.page = val;
this.getListData();
},
// 改变状态
// async changeStatus(id) {
// const res = await this.$axios.post("/question/status", { id });
// if (res.data.code == 200) {
// this.$message({
// type: "success",
// message: "更新状态成功"
// });
// //重新刷新当前页面
// this.geListData();
// } else {
// this.$message.error(res.data.message);
// }
// },
//删除
// del(id) {
// this.$confirm("确定删除该题目吗?", "提示", {
// confirmButtonText: "确定",
// cancelButtonText: "取消",
// type: "warning"
// })
// .then(async () => {
// const res = await this.$axios.post("/question/remove", { id });
// if (res.data.code == 200) {
// this.$message({
// type: "success",
// message: "删除成功!"
// });
// //重新刷新第一页数据
// this.search();
// }
// })
// .catch(() => {});
// },
//新增
add() {
this.$refs.questionEditRef.modal = "add";
this.$refs.questionEditRef.dialogVisible = true;
// 点击新增的时候新增&编辑组件就要清空questionForm表单
this.$refs.questionEditRef.questionForm = {
title: "", // 标题
subject: "", // 学科id标识
step: "", //阶段1、初级 2、中级 3、高级
enterprise: "", // 企业id标识
city: "", // [省、市、区县]
type: 1, // 题型 1单选 、2多选 、3简答
difficulty: 1, // 题目难度 1简单 、2一般 、3困难
single_select_answer: "", // 单选题答案
multiple_select_answer: [], //多选题答案
short_answer: "", // 简答题答案
video: "", // 解析视频地址
answer_analyze: "", // 答案解析
remark: "", // 答案备注
select_options: [
{
label: "A",
text: "splice",
image: ""
},
{
label: "B",
text: "slice",
image: ""
},
{
label: "C",
text: "pop",
image: ""
},
{
label: "D",
text: "shift",
image: ""
}
] // 选项,介绍,图片介绍
};
},
//编辑
editQuestion(row) {
this.$refs.questionEditRef.modal = "edit";
this.$refs.questionEditRef.dialogVisible = true;
//深拷贝,把点编辑的那行的数据拷贝给新增&编辑组件的questionForm,那这样一点编辑这个questionForm就有值
// 但是有几个显示不出来比如城市(要变成数组才行),题型,难度,阶段(因为编辑的那行返回的数据这是三个都是数字,所以把他们的value变成数字就好)
this.$refs.questionEditRef.questionForm = JSON.parse(JSON.stringify(row));
if (row.city) {
// 要把返回数据的变成数组
this.$refs.questionEditRef.questionForm.city = row.city.split(",");
}else{
this.$refs.questionEditRef.questionForm.city = []
}
if (row.multiple_select_answer) {
this.$refs.questionEditRef.questionForm.multiple_select_answer=row.multiple_select_answer.split(',')
}else{
this.$refs.questionEditRef.questionForm.multiple_select_answer=[]
}
}
// 好使
// formatType(val){
// return this.typeObj[val]
// }
}
// 不好使,里面的this不是指向vue实例
// filters:{
// formatType(val){
// return this.typeObj[val]
// }
// }
//不好使,不能接收参数
// computed:{
// formatType(val){
// console.log('这是',val);//这里面的val不是传来的参数是vue实例而且上面也不能写()传递参数不然会以为是方法
// return 'test'
// }
// }
};
script>
要新建一个组件写在question文件夹下的question-add-or-update.vue组件中写在el-dialog中
其中城市这个下拉框中要用到element中的el-cascader级联选择器
城市数据也要用到第三方可以在git hub上搜element-china-area-data,点赞最多的就是我们要用的包有教你怎么使用
直通车: link.
1、安装:npm install element-china-area-data -S
2、导入:import { regionData } from “element-china-area-data”;(其中那个()里面看你需要哪种效果的就导入哪种,我导的是regionData是省市区三级联动数据(不带“全部”选项))
3、使用el-cascader显示内容
两个富文本编辑器跟一个input的ui渲染,
富文本编辑器:插件 vue-quill-editor 直通车:link. 可以直接在github上搜这个 vue-quill-editor
使用步骤
1、.安装 npm i vue-quill-editor
2、导入相应的css
import ‘quill/dist/quill.core.css’
import ‘quill/dist/quill.snow.css’
import ‘quill/dist/quill.bubble.css’
3、导入组件,并且注册
4、就可以在 template 中使用了
题型子组件中
新增试题本身就是题库列表的一个子组件,然后这个地方展示题型组件又是新增试题的子组件,右边的上传到的文件图片以及下面要做的解析视频又是题型组件的子组件
其中题型子组件就是根据你上面radio题型选中的是单选、多选、简答,来决定你这里显示的是什么内容,下面三张图就是三种不同的显示情况下,(单选情况下与多选差不多的就是一个单选radio变成了checkbox),我这里说的是题型组件,孙子组件(上传组件)后面说
1、传值
:父子组件传值,有 props & emit ,还有$parent $refs
这里我们巧妙的应用引用类型来达到父子组件传值的目的
将父组件的questionForm传递给题型子组件,然后在题型子组件里面接受传来的questionForm,因为他们的引用类型地址还是同一个,那么在题型子组件中questionForm里面的数据有什么变动,在父组件question-add-or-update.vue中都也会变
2,步骤
a、新建一个名为 question-type 的子组件,写好里面的内容
b、在 新增/修改 的组件中集成它就是导入注册,并且使用它
c、在父组件中,我会把整个 questionForm 对象传递给子组件,目的是为了在子组件中操作方便
d、传值的时候,父组件中定义好属性名,把questionForm对象传递过去,然后子组件这边通过 props 来接收
e、此时question-type题型子组件中也有questionForm了,那就可以渲染题型组件并且双向绑定questionForm中的值
<template>
<div>
<div v-if="questionForm.type==1">
<div v-for="(item, index) in questionForm.select_options" :key="index" class="item">
<el-radio v-model="questionForm.single_select_answer" :label="item.label">{{item.label}}el-radio>
<el-input v-model="item.text">el-input>
div>
div>
<div v-if="questionForm.type==2">
<div v-for="(item, index) in questionForm.select_options" :key="index" class="item">
<el-checkbox v-model="questionForm.multiple_select_answer" :label="item.label">el-checkbox>
<el-input v-model="item.text" style="margin-left:15px">el-input>
div>
div>
<div v-if="questionForm.type==3">
<el-input type="textarea" :rows="5" placeholder="请输入内容" v-model="questionForm.short_answer">el-input>
div>
div>
template>
1
、先定义好一个子组件 upload-file ,并且里面写好内容2
、在 question-add-or-update 中,集成 upload-file 子组件的时候,我们给它传递了 type = video,代表只能上传视频。在 question-type 中集成它,这里没有给它传值 type,那么子组件中 type 的默认值就是image这里是question-add-or-update.vue新增&编辑组件中的,传值给子组件上传组件:
这里是question-type.vue题型组件中的,传值给子组件上传组件:
3
、子组件上传成功之后,该如何处理?
这是上传组件upload.vue子组件:
根据父组件接受过来的值(分情况有还是没有)来决定显示在页面上是文件(视频,图片)还是+号
上传之前检测上传的东西是否符合规范。上传成功之后,触发input事件,然后传值给父组件,然后给父组件中 v-model 绑定的值赋值,同时也把我们的内容(图片\视频)展示出来。
question-type 题型子组件校验
:
对题型组件中一改变就校验
:
打个比方比如我们点新增确定按钮时,提交的时候发现这些校验未通过还没选择,那我立刻去选择,当时改变就应该当时校验消失
题型组件中:
新增&编辑组件中:
监听子组件传来的事件
对富文本编辑器中一改变就校验
:
不能直接就给模型赋值,有些地方需要处理一下
question文件夹的index.vue组件中:
点击新增的时候清空内容
question-add-or-update.vue组件中:
点击新增跟编辑时清空校验,编辑时内容不用清空
后面一篇说吧