进度条和上下题目切换,有单选,有多选,有填空,结果类似于这样,写的不好,仅供参考,数据都是后台拿的
1.组件Li-examwidght
<template>
<view>
<view class="exam-item-testing">
<view class="exam-item-inner" v-if='dataList.length > 0'>
<view class="line_under exam-item-title">
{
{currentItem.questionName?currentItem.questionName:''}}
</view>
<!-- 单选 -->
<view v-show="currentItem.questionType==1" class="padding">
<view class="exam-item-option" v-for="(item,rowIndex_1) in currentItem.list" v-bind:key='rowIndex_1'
@click="radioChange(item,rowIndex_1)">
<view class="color optionIcon" :class='{ active:rowIndex_1===currentCheck}'></view>
<text>{
{item}}</text>
</view>
</view>
<!-- 多选 -->
<checkbox-group class="padding" @change="checkboxChange" v-show="currentItem.questionType==2">
<view v-for="(item,rowIndex_2) in currentItem.list" v-bind:key='rowIndex_2'>
<view class="exam-item-option">
<view class="color posi" :class='{active:checkboxCheck(item)}' :value="setCheckboxVal(rowIndex_2)">
<checkbox class="check" style="opacity: 0;" :value="setCheckboxVal(item)" :checked="checkboxCheck(rowIndex_2)" /></view>
<text>{
{item}}</text>
</view>
</view>
</checkbox-group>
<!-- 填空题 -->
<view v-show="currentItem.questionType == 3">
<view class="">
<textarea class="textareas" @blur="bindTextAreaBlur" @input='bindTextinput' placeholder='请写下您的评论' :value='getTxtValue(currentIndex)' />
</view>
</view>
<view class="taskNext">
<view v-if="currentIndex == 0" class="nor">{
{lastText}}</view>
<view v-else-if="currentIndex != 0" @tap="lastQuestion" class="nor">{
{lastText}}</view>
<view v-show="currentIndex < dataList.length-1" @tap="nextQuestion">{
{nextText}}</view>
</view>
<view class="finish" v-show="currentIndex === dataList.length-1" >
<view @tap="finish">{
{finishText}}</view>
</view>
</view>
</view>
</view>
</template>
<script >
export default {
name: 'Li-ExamWidghtssss',
props: {
index: {
info: Number,
default: 0
},
dataList: {
type: Array,
default:function(){
return [];
}
},
finishText:{
info: String,
default: '提交'
},
lastText:{
info: String,
default: '上一题'
},
nextText:{
info: String,
default: '下一题'
},
},
data() {
return {
number:0,
windowHeight:500,
showIndexBox:false,
currentHasChange:false,
currentIndex:0,
currentItem:{}, //当前项
currentCheck: undefined, //单选选定
currentCheckBoxCheck: [] ,//多选选定
currentText:"" ,//填空题
showMask:false ,//是否显示遮罩和题号
indexboxAnimationData:[] //题号区域动画
};
},
watch: {
index: function(val, oldVal) {
this.currentIndex = val;
this.currentSelectFinish(this.currentIndex);
//console.log('new: %s, old: %s', val, oldVal)
},
dataList: function(val, oldVal) {
this.currentItem = this.getCurrentItem();
},
numBoxShow: function(val, oldVal) {
this.switchIndexBox();
}
},
computed: {
},
created(){
let that = this;
uni.getSystemInfo({
success: function (res) {
that.windowHeight = res.windowHeight;
}
});
},
methods: {
radioChange(item,index) { //单选改变
// this.number= item.fldOptionIndex;
console.log(item,index)
this.currentHasChange = true;
this.currentCheck = index;
this.dataList[this.currentIndex].fldAnswer = item;
this.$emit('select', {
question: this.getCurrentItem(),
anwser: item
});
},
checkboxChange(e) { //多选改变
console.log(e)
this.currentHasChange = true;
this.currentCheckBoxCheck = e.detail.value;
this.dataList[this.currentIndex].fldAnswer = this.currentCheckBoxCheck.join(',');
this.$emit('select', {
question: this.getCurrentItem(),
anwser: this.dataList[this.currentIndex].fldAnswer
});
},
bindTextAreaBlur(e){ //填空结束
// this.currentText = e.detail.value;
// this.currentHasChange = true;
// this.dataList[this.currentIndex].fldAnswer = this.currentText;
},
bindTextinput(e){ //填空值改变
this.currentText = e.detail.value;
this.currentHasChange = true;
this.dataList[this.currentIndex].fldAnswer = this.currentText;
},
setCheckboxVal(val) { //设置多选框的值,如果是数字,则转换成字符串
if (typeof(val) == 'number')
return val + "";
return val;
},
checkboxCheck(num) { //检查多选框是否已经选定
let that = this;
for (let i = 0; i < that.currentCheckBoxCheck.length; i++)
if (that.currentCheckBoxCheck[i] == num)
return true;
return false;
},
getTxtValue(currentIndex){
return this.currentItem.fldAnswer?this.currentItem.fldAnswer:""
},
lastQuestion() { //上一题
let newIndex = this.currentIndex - 1;
this.currentSelectFinish(newIndex);
},
nextQuestion() { //下一题
let newIndex = this.currentIndex + 1;
this.currentSelectFinish(newIndex);
},
currentSelectFinish(newIndex){ //切换题目
let that = this;
let __oldIndex = that.currentIndex;
let __newIndex = newIndex;
if(!that.dataList[__oldIndex])
return;
if(that.dataList[__oldIndex].questionType ==1){
that.$emit('selectFinish',
{
currentItem:{ //当前项
question: that.dataList[__oldIndex],
anwser: that.currentCheck,
hasChange:that.currentHasChange,
index:__oldIndex,
total:that.dataList.length
},
newItem:{ //新项
question: that.dataList[__newIndex],
index:__newIndex,
total:that.dataList.length
}
});
}
else if(that.dataList[__oldIndex].questionType == 2){
that.$emit('selectFinish',
{
currentItem:{ //当前项
question: that.dataList[__oldIndex],
anwser: that.currentCheckBoxCheck?that.currentCheckBoxCheck.join(','):'',
hasChange:that.currentHasChange,
index:__oldIndex,
total:that.dataList.length,
},
newItem:{ //新项
question: that.dataList[__newIndex],
index:__newIndex,
total:that.dataList.length
}
});
}
else if(that.dataList[__oldIndex].questionType == 3){
that.$emit('selectFinish',
{
currentItem:{ //当前项
question: that.dataList[__oldIndex],
anwser: that.currentText,
hasChange:that.currentHasChange,
index:__oldIndex,
total:that.dataList.length,
},
newItem:{ //新项
question: that.dataList[__newIndex],
index:__newIndex,
total:that.dataList.length
}
});
}
that.currentIndex = newIndex;
that.currentItem = that.getCurrentItem();
that.currentHasChange = false;
that.checkQuestionSelected();
},
checkQuestionSelected(){ //初始化选择
if(this.currentItem.questionType == 1){
this.currentCheck = this.currentItem.fldAnswer;//单选选定
}
else if(this.currentItem.questionType == 2){
this.currentCheckBoxCheck = this.currentItem.fldAnswer?this.currentItem.fldAnswer.split(','):[]; //多选选定
}
else if(this.currentItem.questionType == 3){
this.currentText = this.currentItem.fldAnswer?this.currentItem.fldAnswer:[]; //填空
}
},
finish(){ //全部选择完成
this.$emit('finish', {
questions: this.dataList
});
},
getCurrentItem(){
if(this.dataList.length == 0)
return {};
if(this.dataList[this.currentIndex])
return this.dataList[this.currentIndex];
else
return {};
},
}
}
</script>
<style lang="scss">
page{
}
.exam-item-testing {
}
.exam-item-inner {
margin-top: 57rpx;
}
.exam-item-title {
padding: 0 20rpx;
// border: 1px solid black;
font-size: 36rpx;
font-weight: bold;
}
.padding{
padding: 0 20rpx;
}
.exam-item-option {
/* border: 1rpx solid black; */
display: flex;
align-items: center;
height: 77rpx;
margin-top: 47rpx;
border: 1rpx solid #F4F4F4;
font-size: 36rpx;
/* padding: 10rpx 0; */
}
.optionIcon{
margin-right:27rpx;
margin-left:27rpx;
width: 20rpx !important;
height: 20rpx !important;
border: 1rpx solid #AAAAAA;
border-radius: 20rpx;
}
.exam-item-option textarea{
border:1px solid gainsboro;
border-radius: 10rpx;
height:300rpx;
width: 100%;
}
.exam-button-row {
text-align: center;
}
.exam-indexbox{
padding-bottom: 20rpx;
}
.exam-indexbox:before, .exam-indexbox:after{
display: table;
content: ' ';
}
.exam-indexbox:after{
clear: both;
}
.exam-indexbox-item{
text-align: center;
vertical-align: middle;
line-height: 56rpx;
float: left;
border:1rpx solid gainsboro;
height: 56rpx;
width: 56rpx;
margin: 5rpx;
padding: 10rpx;
border-radius: 10rpx;
background-color: #fff;
-moz-box-shadow: 0px 1px 1px #ABABAB;
-webkit-box-shadow: 0px 1px 1px #ABABAB;
box-shadow: 0px 1px 1px #ABABAB;
}
.exam-indexbox-item-selected{
color: #007AFF;
}
/* 以下为实现0.5px底部边界 */
.line_under {
// position: relative;
/* .line_under:before{顶部top: 0;background: #000;} */
}
.line_under:before,
.line_under:after {
position: absolute;
content: " ";
height: 1px;
width: 100%;
left: 0;
transform-origin: 0 0;
-webkit-transform-origin: 0 0;
}
.line_under:after {
bottom: 0;
border-bottom: 1px solid gainsboro;
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
.line_under:after,
.line_under:before {
-webkit-transform: scaleY(0.667);
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2) {
.line_under:after,
.line_under:before {
-webkit-transform: scaleY(0.5);
}
}
.exam-mask{
position: absolute;
z-index: 1;
width: 100%;
height: 100%;
background-color: #999999;
opacity:0.5;
left: 0;
top:0;
}
.exam-mask-content{
position: absolute;
z-index: 1;
width: 100%;
height: 50%;
background-color: white;
left: 0;
bottom:0;
padding: 15rpx 5rpx;
}
.exam-indexbox-item-mask{
text-align: center;
vertical-align: middle;
line-height: 63rpx;
float: left;
border:1rpx solid gainsboro;
height: 63rpx;
width: 63rpx;
margin: 5rpx;
padding: 10rpx;
border-radius: 10rpx;
background-color: #fff;
-moz-box-shadow: 0px 1px 1px #ABABAB;
-webkit-box-shadow: 0px 1px 1px #ABABAB;
box-shadow: 0px 1px 1px #ABABAB;
}
.taskNext{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 20rpx 0;
height: 60rpx;
background:linear-gradient(to left, #FE0000, #FF5033) ;
display: flex;
view{
width: 50%;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
}
}
.nor{
border-right: 1rpx solid #FFFFFF;
}
.finish{
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 20rpx 0;
height: 60rpx;
background:linear-gradient(to left, #FE0000, #FF5033) ;
color: #FFFFFF;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
}
.textareas{
border: 1px solid #F4F4F4;
width: 99%;
padding: 20rpx;
margin-top: 27rpx;
}
.color{
width: 20rpx !important;
height: 20rpx !important;
border: 1rpx solid #AAAAAA;
border-radius: 20rpx;
}
.active{
background-color: #FE0000;
border: 1rpx solid #FE0000;
}
.posi{
z-index:44 ;
position: relative;
margin-left: 26rpx;
margin-right: 26rpx;
}
.check{
border: 1px solid black;
top: -20rpx;
left: -2rpx;
position: absolute;
}
</style>
2.进度条组件
<template>
<view>
<view class="uni-progress-box">
<view class="progress-bottom"><view class="progress" :style="{ width: percentage + '%', background: percentBackground }"></view></view>
</view>
</view>
</template>
<script>
export default {
props: {
// 进度条占比
percentage: {
type: Number,
default: 0
},
// 进度条占比的颜色设置
percentBackground: {
type: String,
default: null
}
}
};
</script>
<style lang="scss">
.uni-progress-box {
width:100%;
display: flex;
.progress-bottom {
margin-top: 20rpx;
height: 16rpx;
width: 100%;
background-color:#CCCCCC;
border-radius: 20rpx;
.progress {
width: 100%;
height: 16rpx;
border-radius: 20rpx;
}
}
.percentage {
margin: 0 4%;
}
}
</style>
3.页面
<template>
<view>
<view class="taskProgess">
<view class="taskNum">
<label class="nowNum">{
{ nowNum }}</label>
/
<label>{
{ totals }}</label>
</view>
<view style="width: 100%;"><uniProgress :percentage="shortPro" percentBackground="#FE0000"></uniProgress></view>
</view>
<view class="taskTit">已完成{
{ nowNum }}个,还差{
{ shortNum }}个可领取积分</view>
<exam-widght
:dataList="QuestionList"
:index="index"
@select="selectItem"
@selectFinish="selectFinish"
@finish="finish"
:numBoxType="0"
:showIndexText="showIndexText"
:numBoxShow="numBoxShow"
></exam-widght>
</view>
</template>
<script>
import uniProgress from '@/components/uni-progress.vue';
import examWidght from '@/components/Li-ExamWidght/Li-ExamWidght.vue';
import { mapGetters } from 'vuex';
var _this;
export default {
components: {
examWidght,
uniProgress
},
data() {
return {
totals: 10,
shortPro: 10,
shortNum: 10,
nowNum: 1,
fldTestPaperID: undefined,
fldTestRecordID: undefined,
showIndexText: true, //题号文字是否显示
numBoxShow: false,
items: [],
index: 0,
QuestionList: [],
radio: '1',
allAnswer:[],
all:'',
id:0,
};
},
onLoad(params) {
this.id=parseInt(params.id)
this.init(params);
console.log(111);
_this = this;
setTimeout(function() {
_this.getTestPaper();
}, 1000);
},
computed: {
...mapGetters({
taskContent: 'task/GetTaskContent'
}),
questlist() {
let arr = [];
if (this.taskContent != '') {
for (var index in this.taskContent) {
var item = this.taskContent[index];
arr.push(item);
}
return arr;
} else {
return arr;
}
},
},
methods: {
init(params) {
const reportId = {
reportId: params.reportId
};
this.$store.dispatch('task/getTaskContent', reportId);
},
check(index) {
// 先取消所有选中项
this.radios.forEach(item => {
item.isChecked = false;
});
//再设置当前点击项选中
this.radio = this.radios[index].value;
// 设置值,以供传递
this.radios[index].isChecked = true;
console.log(this.radio);
},
jump() {
this.index = 9;
},
switchIndexBox() {
this.numBoxShow = !this.numBoxShow;
},
//提交
finish(item) {
let items=item
if(items.questions!=null){
for (var index in items.questions) {
var answera = items.questions[index].fldAnswer;
this.allAnswer.push(answera);
}
this.all=this.allAnswer
console.log(this.all)
}
const paramess={
poolId:this.id,
answer:this.all
}
this.$store.dispatch('task/getTaskSubmits',paramess);
// uni.showToast({
// title:'提交成功',
// })
uni.switchTab({
url:'taskSucess'
})
},
selectItem(item) {
console.log('selectItem');
},
selectFinish(item) {
console.log('selectFinish');
// console.log('3' + JSON.stringify(item));
let index = item.newItem.index + 1;
let title = index + '/' + item.newItem.total;
this.nowNum = index;
if (this.nowNum == 1) {
this.shortPro = 10;
} else if (this.nowNum == 2) {
this.shortPro = 20;
} else if (this.nowNum == 3) {
this.shortPro = 30;
} else if (this.nowNum == 4) {
this.shortPro = 40;
} else if (this.nowNum == 5) {
this.shortPro = 50;
} else if (this.nowNum == 6) {
this.shortPro = 60;
} else if (this.nowNum == 7) {
this.shortPro = 70;
} else if (this.nowNum == 8) {
this.shortPro = 80;
} else if (this.nowNum == 9) {
this.shortPro = 90;
} else if (this.nowNum == 10) {
this.shortPro = 100;
}
this.shortNum = this.totals - this.nowNum;
},
getTestPaper() {
console.log(_this.questlist)
_this.QuestionList = _this.questlist;
}
}
};
</script>
<style lang="scss">
page {
position: relative;
height: 100%;
overflow-x: hidden;
}
.taskProgess {
// border: 1px solid black;
display: flex;
flex-shrink: 1;
align-content: center;
padding: 20rpx;
font-size: 30rpx;
.taskNum {
margin-right: 34rpx;
.nowNum {
font-size: 36rpx;
}
}
}
.taskTit {
color: #fe0000;
font-size: 20rpx;
display: flex;
align-items: center;
justify-content: center;
margin-top: 3rpx;
}
.taskContent {
// border: 1px solid black;
margin-top: 55rpx;
padding: 0 20rpx;
.itemTitle {
color: #212121;
font-size: 36rpx;
font-weight: bold;
flex-wrap: wrap;
margin-bottom: 47rpx;
}
.radioTitle {
// border: 1px solid black;
.radio-box {
border: 1rpx solid #f4f4f4;
display: flex;
align-items: center;
height: 77rpx;
margin-bottom: 32rpx;
}
.radio {
border: 1rpx solid #aaaaaa;
display: inline-block;
width: 20rpx;
height: 20rpx;
vertical-align: middle;
cursor: pointer;
border-radius: 10rpx;
margin-left: 27px;
margin-right: 27px;
}
.input-radio {
border-radius: 10rpx;
position: absolute;
opacity: 0;
width: 20px;
height: 20px;
cursor: pointer;
left: 0px;
outline: none;
-webkit-appearance: none;
}
.on {
border: 1rpx solid #fe0000;
background-color: #fe0000;
}
}
}
.taskNext {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
padding: 20rpx 0;
height: 60rpx;
background: linear-gradient(to left, #fe0000, #ff5033);
display: flex;
view {
width: 50%;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
font-size: 36rpx;
}
.nor {
border-right: 1rpx solid #ffffff;
}
}
</style>