@@ -0,0 +1,377 @@
|
||||
<template>
|
||||
|
||||
<view class="container p-4">
|
||||
<!-- 新增悬浮导航 -->
|
||||
<view class="floating-nav">
|
||||
<button class="nav-toggle" @click="showNav = !showNav">
|
||||
<text class="icon">📖</text>
|
||||
</button>
|
||||
|
||||
<view v-if="showNav" class="nav-panel">
|
||||
<view class="panel-header">
|
||||
<text>题目导航</text>
|
||||
<button @click="showNav = false" class="close-btn">×</button>
|
||||
</view>
|
||||
<view class="question-grid">
|
||||
<view
|
||||
v-for="(q, index) in questions"
|
||||
:key="index"
|
||||
class="grid-item"
|
||||
:class="{
|
||||
'current': current === index,
|
||||
'answered': answers[index] !== undefined
|
||||
}"
|
||||
@click="jumpTo(index)"
|
||||
>
|
||||
{{ index + 1 }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 进度条 -->
|
||||
<view class="card mb-4">
|
||||
<view class="card-body">
|
||||
<view class="d-flex align-items-center">
|
||||
<view class="flex-grow-1 me-3 position-relative">
|
||||
<progress
|
||||
class="progress w-100"
|
||||
:value="current + 1"
|
||||
:max="questions.length"
|
||||
style="height: 8px;"
|
||||
></progress>
|
||||
</view>
|
||||
<text class="text-muted">{{ current + 1 }}/{{ questions.length }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 题目区域 -->
|
||||
<view class="card mb-4">
|
||||
<view class="card-body">
|
||||
<h2 class="card-title mb-4 text-primary">{{ currentQuestion.question }}</h2>
|
||||
|
||||
<view class="list-group list-group-flush">
|
||||
<view
|
||||
v-for="(option, index) in currentQuestion.options"
|
||||
:key="index"
|
||||
class="list-group-item list-group-item-action cursor-pointer"
|
||||
:class="{ 'active': selectedAnswer === index }"
|
||||
@click="handleAnswer(index)"
|
||||
>
|
||||
<view class="form-check">
|
||||
<view class="form-check-input" :class="{ 'checked': selectedAnswer === index }"></view>
|
||||
<span class="form-check-label">{{ option }}</span>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 操作按钮 -->
|
||||
<view class="row g-2">
|
||||
<view class="col">
|
||||
<button
|
||||
class="btn btn-outline-primary w-100"
|
||||
@click="prevQuestion"
|
||||
:disabled="current === 0"
|
||||
>
|
||||
← 上一题
|
||||
</button>
|
||||
</view>
|
||||
<view class="col">
|
||||
<button
|
||||
v-if="current < questions.length - 1"
|
||||
class="btn btn-primary w-100"
|
||||
@click="nextQuestion"
|
||||
:disabled="selectedAnswer === null"
|
||||
>
|
||||
下一题 →
|
||||
</button>
|
||||
<button
|
||||
v-else
|
||||
class="btn btn-success w-100"
|
||||
@click="submit"
|
||||
>
|
||||
提交答卷
|
||||
</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
showNav: false,
|
||||
current: 0,
|
||||
selectedAnswer: null,
|
||||
answers: [],
|
||||
questions: [
|
||||
{
|
||||
question: "uniapp的全局样式文件是?",
|
||||
options: ["App.vue", "main.js", "uni.css", "global.sass"],
|
||||
correct: 0
|
||||
},
|
||||
{
|
||||
question: "下列哪个API可以跳转页面?",
|
||||
options: ["uni.request", "uni.navigateTo", "uni.showToast", "uni.getStorage"],
|
||||
correct: 1
|
||||
},
|
||||
{
|
||||
question: "uniapp支持哪种小程序语法?",
|
||||
options: ["微信小程序", "支付宝小程序", "百度小程序", "全部支持"],
|
||||
correct: 3
|
||||
},
|
||||
{
|
||||
question: "如何获取设备信息?",
|
||||
options: ["uni.getSystemInfo", "wx.getDeviceInfo", "device.platform", "navigator.userAgent"],
|
||||
correct: 0
|
||||
},
|
||||
{
|
||||
question: "下列哪个不是uniapp项目类型?",
|
||||
options: ["HBuilderX", "微信开发者工具", "Visual Studio Code", "Android Studio"],
|
||||
correct: 3
|
||||
}
|
||||
],
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
currentQuestion() {
|
||||
return this.questions[this.current];
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
jumpTo(index) {
|
||||
if(index >=0 && index < this.questions.length) {
|
||||
this.current = index
|
||||
this.selectedAnswer = this.answers[index] ?? null
|
||||
this.showNav = false
|
||||
}
|
||||
},
|
||||
handleAnswer(index) {
|
||||
this.selectedAnswer = index;
|
||||
// 震动反馈(真机生效)
|
||||
uni.vibrateShort();
|
||||
},
|
||||
prevQuestion() {
|
||||
if (this.current > 0) {
|
||||
this.current--;
|
||||
this.selectedAnswer = this.answers[this.current] ?? null;
|
||||
}
|
||||
},
|
||||
nextQuestion() {
|
||||
if (this.selectedAnswer !== null) {
|
||||
this.answers[this.current] = this.selectedAnswer;
|
||||
this.current++;
|
||||
this.selectedAnswer = this.answers[this.current] ?? null;
|
||||
}
|
||||
},
|
||||
submit() {
|
||||
const score = this.questions.reduce((acc, q, index) => {
|
||||
return acc + (this.answers[index] === q.correct ? 1 : 0);
|
||||
}, 0);
|
||||
|
||||
uni.showModal({
|
||||
title: '答题完成',
|
||||
content: `正确率:${ ((score / this.questions.length) * 100).toFixed(0) }%`,
|
||||
showCancel: false
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
/* 引入Tabler核心样式 */
|
||||
|
||||
|
||||
.container {
|
||||
background-color: var(--tblr-bg-surface);
|
||||
min-height: 100vh;
|
||||
}
|
||||
|
||||
.card {
|
||||
box-shadow: var(--tblr-box-shadow-sm);
|
||||
border-radius: var(--tblr-border-radius);
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
transition: all 0.2s ease;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
cursor: pointer;
|
||||
-webkit-tap-highlight-color: transparent;
|
||||
}
|
||||
|
||||
.list-group-item.active {
|
||||
background-color: var(--tblr-primary-bg-subtle);
|
||||
border-color: var(--tblr-primary);
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.form-check {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.form-check-input {
|
||||
position: relative;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
border: 2px solid var(--tblr-border-color);
|
||||
border-radius: 50%;
|
||||
margin-right: 0.5em;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.form-check-input.checked {
|
||||
border-color: var(--tblr-primary);
|
||||
}
|
||||
|
||||
.form-check-input.checked::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0.6em;
|
||||
height: 0.6em;
|
||||
background: var(--tblr-primary);
|
||||
border-radius: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.btn-success {
|
||||
background-color: var(--tblr-success);
|
||||
border-color: var(--tblr-success);
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.25rem;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 添加进度条样式 */
|
||||
progress {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
overflow: hidden;
|
||||
background: var(--tblr-bg-surface-secondary);
|
||||
}
|
||||
|
||||
progress::-webkit-progress-bar {
|
||||
background: var(--tblr-bg-surface-secondary);
|
||||
}
|
||||
|
||||
progress::-webkit-progress-value {
|
||||
background: var(--tblr-primary);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
progress::-moz-progress-bar {
|
||||
background: var(--tblr-primary);
|
||||
}
|
||||
/* 新增的进度条样式 */
|
||||
progress {
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
appearance: none;
|
||||
border-radius: 8px;
|
||||
height: 8px !important;
|
||||
}
|
||||
|
||||
progress::-webkit-progress-bar {
|
||||
background: #f3f3f3;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
progress::-webkit-progress-value {
|
||||
background: var(--tblr-primary);
|
||||
border-radius: 8px;
|
||||
transition: width 0.3s ease;
|
||||
}
|
||||
|
||||
progress::-moz-progress-bar {
|
||||
background: var(--tblr-primary);
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
/* 悬浮导航样式 */
|
||||
.floating-nav {
|
||||
position: fixed;
|
||||
right: 20rpx;
|
||||
bottom: 120rpx;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.nav-toggle {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 50%;
|
||||
background: #007AFF;
|
||||
box-shadow: 0 5rpx 20rpx rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.icon {
|
||||
font-size: 50rpx;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.nav-panel {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
bottom: 120rpx;
|
||||
width: 600rpx;
|
||||
background: white;
|
||||
border-radius: 20rpx;
|
||||
box-shadow: 0 10rpx 40rpx rgba(0,0,0,0.15);
|
||||
padding: 20rpx;
|
||||
}
|
||||
|
||||
.panel-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding-bottom: 20rpx;
|
||||
border-bottom: 1rpx solid #eee;
|
||||
}
|
||||
|
||||
.close-btn {
|
||||
font-size: 40rpx;
|
||||
color: #999;
|
||||
padding: 0 20rpx;
|
||||
}
|
||||
|
||||
.question-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(5, 1fr);
|
||||
gap: 15rpx;
|
||||
margin-top: 20rpx;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
width: 100rpx;
|
||||
height: 100rpx;
|
||||
border-radius: 15rpx;
|
||||
background: #f5f5f5;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 34rpx;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.grid-item.answered {
|
||||
background: #e3f2fd;
|
||||
color: #007AFF;
|
||||
}
|
||||
|
||||
.grid-item.current {
|
||||
transform: scale(1.1);
|
||||
border: 2rpx solid #007AFF;
|
||||
box-shadow: 0 5rpx 15rpx rgba(0,122,255,0.3);
|
||||
}
|
||||
|
||||
</style>
|
||||
Reference in New Issue
Block a user