进度条和上下题目切换,有单选,有多选,有填空

进度条和上下题目切换,有单选,有多选,有填空,结果类似于这样,写的不好,仅供参考,数据都是后台拿的

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>

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值