当前位置: 首页 > news >正文

H5 中 van-popup 的使用以及题目的切换

H5 中 van-popup 的使用以及题目的切换

在移动端开发中,弹窗组件是一个常见的需求。vant 是一个轻量、可靠的移动端 Vue 组件库,其中的 van-popup 组件可以方便地实现弹窗效果。本文将介绍如何使用 van-popup 实现题目详情的弹窗展示,并实现题目的切换功能。

关键点总结

  1. 引入 van-popup 组件

    • 在 Vue 项目中引入 vant 组件库,并使用 van-popup 组件实现弹窗效果。
    • import { createApp } from 'vue'
      import Vant from 'vant'const app = createApp(App)
      app.use(Vant)
      app.mount('#app')
  2. 弹窗内容的条件渲染

    • 根据不同的题目类型(如互动题和练习题),在弹窗中显示不同的内容。
  3. 题目详情的展示

    • 使用 computed 属性计算当前题目的详情,并在弹窗中展示题目的相关信息。
  4. 题目的切换

    • 通过按钮实现题目的上一题和下一题的切换,并更新当前题目的索引。
代码示例

以下是实现上述功能的关键代码片段:

questions.vue---子组件

<template><van-popup v-model:show="localVisible" position="bottom" round :style="{ height: '80%' }" @close="close"><div v-if="type === 'interactive'"><div class="picker-header"><div class="picker-title">题目详情<button @click="close" class="close-button">X</button></div><div class="picker-info"><div class="left-info"><span class="number">第{{ currentQuestion.serial_number }}题</span><span class="status">{{ getStatusText(currentQuestion.status) }}</span></div><div class="right-info"><button v-if="!isFirstQuestion" @click="prevQuestion"><van-icon name="arrow-left" /></button><span>{{ currentQuestion.serial_number }}/{{ questions.length }}</span><button v-if="!isLastQuestion" @click="nextQuestion"><van-icon name="arrow" /></button></div></div></div><div class="picker-content"><div class="section-title">课件页面</div><iframe :src="currentQuestion.previewUrl" frameborder="0"></iframe><div class="use-duration">我的用时:<span class="time-number">{{ formattedDuration.minutes }}</span>分 <span class="time-number">{{formattedDuration.seconds }}</span>秒</div></div></div><div v-else-if="type === 'practice'">//  其他内容</div></van-popup>
</template><script setup>
import { defineProps, defineEmits, computed, ref, watch } from 'vue'
import { Popup } from 'vant'const props = defineProps({visible: Boolean,questions: {type: Array,required: true,},currentQuestionIndex: {type: Number,required: true,},type: {type: String,required: true,},
})const emits = defineEmits(['close', 'changeQuestion'])const localVisible = ref(props.visible)watch(() => props.visible,newVal => {localVisible.value = newVal},
)const currentQuestion = computed(() => {const question = props.questions[props.currentQuestionIndex] || {}if (props.type === 'practice' && !question.serial_number) {question.serial_number = props.currentQuestionIndex + 1}return question
})const getStatusText = status => {switch (status) {case 1:return '正确'case 2:return '错误'case 3:return '半对半错'default:return '未作答'}
}const formatDuration = duration => {const minutes = String(Math.floor(duration / 60)).padStart(2, '0')const seconds = String(duration % 60).padStart(2, '0')return { minutes, seconds }
}const formattedDuration = computed(() => formatDuration(currentQuestion.value.use_duration))const isFirstQuestion = computed(() => props.currentQuestionIndex === 0)
const isLastQuestion = computed(() => props.currentQuestionIndex === props.questions.length - 1)const prevQuestion = () => {if (!isFirstQuestion.value) {emits('changeQuestion', props.currentQuestionIndex - 1)}
}const nextQuestion = () => {if (!isLastQuestion.value) {emits('changeQuestion', props.currentQuestionIndex + 1)}
}const close = () => {emits('close')
}
</script><style lang="less" scoped>
.picker-header {padding: 10px;
}.picker-title {font-size: 18px;font-weight: bold;justify-content: space-between;align-items: center;margin-bottom: 10px;color: #000;margin-top: 10px;display: flex;width: 100%;.close-button {background: none;border: none;font-size: 16px;margin-left: auto;color: #a9aeb8;cursor: pointer;}
}.picker-info {display: flex;justify-content: space-between;align-items: center;padding: 0 10px 0 10px;
}.left-info {display: flex;flex-direction: row;.number {margin-right: 20px;font-size: 16px;font-weight: 500;}.status {font-size: 16px;font-weight: 500;color: #1f70ff;}
}.right-info {display: flex;position: absolute;right: 10px;color: #a9aeb8;.right-icon {width: 28px;height: 28px;}
}.right-info button {background: none;border: none;font-size: 16px;cursor: pointer;margin: 0 5px;
}.picker-content {padding: 10px 20px 0 20px;
}.section-title {font-size: 16px;font-family: PingFangSC-Regular, PingFang SC;font-weight: 400;color: #2b2f38;
}iframe {width: 100%;height: 300px;border: none;margin-bottom: 10px;
}.use-duration {font-size: 16px;color: #2b2f38;
}.time-number {font-weight: bold;color: #0074fc;font-size: 24px;
}.van-popup {height: 50%;z-index: 99999;
}.practice-content {padding: 0px 20px 0 20px;
}
</style>

courseDetail.vue---父组件

// template关键代码
<div v-for="(item, index) in period.interactive_performance.list" :key="index" :class="['performance-item',getStatusClass(item.status),{ selected: selectedQuestion === index },]" @click="selectQuestion(index, period.interactive_performance.list, 'interactive')"><span :class="getQuestionTextClass(item.status, selectedQuestion === index)">{{item.serial_number}}</span></div><div v-for="(item, index) in period.practice_detail.list" :key="index" :class="['practice-item',getStatusClass(item.status),{ selected: selectedPracticeQuestion === index },]" @click="selectPracticeQuestion(index, period.practice_detail.list, 'practice')"><div class="question-number"><span>{{ index + 1 }}</span></div>
</div><QuestionDetail :visible="showQuestionDetail" :questions="currentQuestions" :type="currentType":currentQuestionIndex="currentQuestionIndex" @close="closeQuestionDetail" @changeQuestion="changeQuestion" />// script关键代码
const selectQuestion = (index, questions, type) => {selectedQuestion.value = indexcurrentQuestions.value = questionscurrentType.value = typecurrentQuestionIndex.value = indexshowQuestionDetail.value = true
}const selectPracticeQuestion = (index, questions, type) => {selectedPracticeQuestion.value = indexcurrentQuestions.value = questionscurrentQuestionIndex.value = index// 设置 serial_number 属性currentQuestions.value.forEach((question, idx) => {question.serial_number = idx + 1})currentType.value = typeshowQuestionDetail.value = true
}
const changeQuestion = index => {currentQuestionIndex.value = index
}

数据结构

关键点解析
  1. 引入 van-popup 组件

    • 在模板中使用 <van-popup> 标签,并通过 v-model:show 绑定弹窗的显示状态。
    • 设置 position="bottom" 和 round 属性,使弹窗从底部弹出并带有圆角。
  2. 弹窗内容的条件渲染

    • 使用 v-if 和 v-else-if 根据 type 属性的值渲染不同的内容。
    • 当 type 为 interactive 时,显示互动题的详情;当 type 为 practice 时,显示练习题的详情。
  3. 题目详情的展示

    • 使用 computed 属性计算当前题目的详情,并在弹窗中展示题目的相关信息。
    • 通过 currentQuestion 计算属性获取当前题目的详细信息。
  4. 题目的切换

    • 通过按钮实现题目的上一题和下一题的切换,并更新当前题目的索引。
    • 使用 isFirstQuestion 和 isLastQuestion 计算属性判断当前题目是否为第一题或最后一题,以控制按钮的显示和隐藏。

大致效果

通过以上关键点的实现,我们可以在移动端应用中使用 van-popup 组件实现题目详情的弹窗展示,并实现题目的切换功能。希望本文对您有所帮助!

相关文章:

H5 中 van-popup 的使用以及题目的切换

H5 中 van-popup 的使用以及题目的切换 在移动端开发中&#xff0c;弹窗组件是一个常见的需求。vant 是一个轻量、可靠的移动端 Vue 组件库&#xff0c;其中的 van-popup 组件可以方便地实现弹窗效果。本文将介绍如何使用 van-popup 实现题目详情的弹窗展示&#xff0c;并实现…...

Liinux下VMware Workstation Pro的安装,建议安装最新版本17.61

建议安装最新版本17.61&#xff0c;否则可能有兼容性问题 下载VMware Workstation安装软件 从官网网站下载 https://support.broadcom.com/group/ecx/productdownloads?subfamilyVMwareWorkstationPro 选择所需版本 现在最新版本是17.61&#xff0c;否则可能有兼容性问题…...

WebRTC服务质量(05)- 重传机制(02) NACK判断丢包

WebRTC服务质量&#xff08;01&#xff09;- Qos概述 WebRTC服务质量&#xff08;02&#xff09;- RTP协议 WebRTC服务质量&#xff08;03&#xff09;- RTCP协议 WebRTC服务质量&#xff08;04&#xff09;- 重传机制&#xff08;01) RTX NACK概述 WebRTC服务质量&#xff08;…...

修改ubuntu apt 源及apt 使用

视频教程:修改ubuntu apt 源和apt 使用方法_哔哩哔哩_bilibili 1 修改apt源 1.1 获取阿里云ubuntu apt 源 https://developer.aliyun.com/mirror/ubuntu?spma2c6h.13651102.0.0.3e221b11mqqLBC 1.2 修改apt 源 vim /etc/apt/sources.list deb https://mirrors.aliyun.com/ub…...

深入解析 `DataFrame.groupby` 和 `agg` 的用法及使用场景

深入解析 DataFrame.groupby 和 agg 的用法及使用场景 1. groupby 的基本用法语法&#xff1a;示例&#xff1a; 2. agg 的基本用法语法&#xff1a;示例&#xff1a; 3. first、sum、lambda 的用法3.1 first示例&#xff1a; 3.2 sum示例&#xff1a; 3.3 lambda示例&#xff…...

MySQL 的锁

MySQL有哪些锁?各种锁的作用与使用场景全局锁表级锁表锁元素锁意向锁AUTO-INC 锁 行级锁记录锁间隙锁临键锁 其他共享锁排他锁乐观锁悲观锁 MySQL有哪些锁? 全局锁表级锁 a. 表锁 b. 元素锁 c. 意向锁 d. AUTO-INC 锁行级锁 a. 记录锁 b. 间隙锁 c. 临键锁 各种锁的作用与使…...

二、使用langchain搭建RAG:金融问答机器人--数据清洗和切片

选择金融领域的专业文档作为源文件 这里选择 《博金大模型挑战赛-金融千问14b数据集》&#xff0c;这个数据集包含若干公司的年报&#xff0c;我们将利用这个年报搭建金融问答机器人。 具体下载地址 这里 git clone https://www.modelscope.cn/datasets/BJQW14B/bs_challenge_…...

【Linux】-- linux 配置用户免密登录本机

比如我们要配置用户 app_tom 免密登录本机&#xff08;SSH 登录自己机器时无需输入密码&#xff09;&#xff0c;你可以按照以下步骤操作&#xff1a; 步骤 1&#xff1a;切换到 app_tom 用户 首先&#xff0c;确保你已经以 app_tom 用户登录&#xff0c;或者切换到该用户&…...

泷羽sec学习打卡-brupsuite8伪造IP和爬虫审计

声明 学习视频来自B站UP主 泷羽sec,如涉及侵权马上删除文章 笔记的只是方便各位师傅学习知识,以下网站只涉及学习内容,其他的都 与本人无关,切莫逾越法律红线,否则后果自负 关于brupsuite的那些事儿-Brup-FaskIP 伪造IP配置环境brupsuite导入配置1、扩展中先配置python环境2、安…...

【uniapp蓝牙】基于native.js链接ble和非ble蓝牙

【uniapp蓝牙】基于native.js链接ble和非ble蓝牙 uniapp不是仅支持低功耗蓝牙&#xff08;基础蓝牙通讯不支持&#xff09;&#xff0c;有些可能需要基础蓝牙。我现在同步我的手机蓝牙列表低功耗&#xff0c;基础蓝牙都支持 /*** author wzj* 通用蓝牙模块封装* 搜索 ble 和非…...

.NET Core 各版本特点、差异及适用场景详解

随着 .NET Core 的不断发展&#xff0c;微软推出了一系列版本来满足不同场景下的开发需求。这些版本随着时间的推移逐渐演变为统一的 .NET 平台&#xff08;从 .NET 5 开始&#xff09;。本文将详细说明每个版本的特点、差异以及适用场景&#xff0c;帮助开发者更好地选择和使用…...

Linux中自动检测并定时关闭KDialog程序

自动检测并关闭对话框的程序示例 创建并打开KDialog的脚本自动检测并定时关闭KDialog的脚本 创建并打开KDialog的脚本 #!/bin/bash kdialog --msgbox "demo"自动检测并定时关闭KDialog的脚本 #!/bin/bash# Continuously check for kdialog dialog while true; do# …...

CSS学习记录12

CSS浮动 CSSfloat属性规定元素如何浮动 CSSclear属性规定哪些元素可以在清除的元素旁边以及在哪一侧浮动。 float属性 float属性用于定位和格式化内容&#xff0c;例如让图像向左浮动到容器的文本那里。 float属性可以设置以下值之一&#xff1a; left - 元素浮动到其容器…...

【Java基础面试题016】JavaObject类中有什么主要方法,作用是什么?

equals() 作用&#xff1a;用于比较两个对象是否相等。默认实现比较对象的内存地址&#xff0c;即判断两个引用是否指向同一个对象 使用&#xff1a;通常会重写此方法来比较对象的内容 hashCode() 作用&#xff1a;返回对象的哈希值&#xff0c;用整数表示对象。 使用&…...

实践环境-docker安装mysql8.0.40步骤

一、docker安装mysql 8.0.40版本 1、检索镜像版本 docker search mysql:8.0.40 NAME DESCRIPTION STARS OFFICIAL mysql MySQL is a widely used, open-source relation… …...

边缘智能创新应用大赛获奖作品系列一:智能边缘计算✖软硬件一体化,开启全场景效能革命新征程

边缘智能技术快速迭代&#xff0c;并与行业深度融合。它正重塑产业格局&#xff0c;催生新产品、新体验&#xff0c;带动终端需求增长。为促进边缘智能技术的进步与发展&#xff0c;拓展开发者的思路与能力&#xff0c;挖掘边缘智能应用的创新与潜能&#xff0c;高通技术公司联…...

决策树的生成与剪枝

决策树的生成与剪枝 决策树的生成生成决策树的过程决策树的生成算法 决策树的剪枝决策树的损失函数决策树的剪枝算法 代码 决策树的生成 生成决策树的过程 为了方便分析描述&#xff0c;我们对上节课中的训练样本进行编号&#xff0c;每个样本加一个ID值&#xff0c;如图所示…...

蓝桥杯算法训练 黑色星期五

题目描述 有些西方人比较迷信&#xff0c;如果某个月的13号正好是星期五&#xff0c;他们就会觉得不太吉利&#xff0c;用古人的说法&#xff0c;就是“诸事不宜”。请你编写一个程序&#xff0c;统计出在某个特定的年份中&#xff0c;出现了多少次既是13号又是星期五的情形&am…...

MySQL存储引擎-存储结构

Innodb存储结构 Buffer Pool(缓冲池)&#xff1a;BP以Page页为单位&#xff0c;页默认大小16K&#xff0c;BP的底层采用链表数据结构管理Page。在InnoDB访问表记录和索引时会在Page页中缓存&#xff0c;以后使用可以减少磁盘IO操作&#xff0c;提升效率。 ○ Page根据状态可以分…...

理解torch函数bmm

基本信息 功能描述 torch.bmm 是 PyTorch 中的一个函数&#xff0c;用于执行批量矩阵乘法&#xff08;Batch Matrix Multiplication&#xff09;。它适用于处理一批矩阵的乘法操作&#xff0c;特别适合于深度学习任务中的场景&#xff0c;比如卷积神经网络中的某些层。 参数…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

什么是库存周转?如何用进销存系统提高库存周转率?

你可能听说过这样一句话&#xff1a; “利润不是赚出来的&#xff0c;是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业&#xff0c;很多企业看着销售不错&#xff0c;账上却没钱、利润也不见了&#xff0c;一翻库存才发现&#xff1a; 一堆卖不动的旧货…...

工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配

AI3D视觉的工业赋能者 迁移科技成立于2017年&#xff0c;作为行业领先的3D工业相机及视觉系统供应商&#xff0c;累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成&#xff0c;通过稳定、易用、高回报的AI3D视觉系统&#xff0c;为汽车、新能源、金属制造等行…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!

简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求&#xff0c;并检查收到的响应。它以以下模式之一…...