一个免费的驾考小程序_核心技术分享

之前做考科目一和科目四
大部分驾考软件免费的功能都是全部题目,2000道题人都做麻了
然后其他很大一部分功能:技巧讲解,精选500题,考前秘卷,真实考场模拟等功能都是收费的

就自己开发一个驾考wx小程序:愿兽驾道

核心技术点:

1.swiper无限滚动实现

问题

对于题目页面左右滑动功能,我做了很多的尝试,目前来说我论坛上常用的解决方式是只展示5张或10张图片,为啥?
因为会有1000-2000个题目展示,导致内存泄漏,页面直接卡死

但是这种方式有一个弊端,就是会出现卡顿的情况,因为每次更换,相当于重新渲染好几张图片,但是滑动的时候有卡顿,整个尤其是在老机型上尤为明显

实现方式

采用无限滚动方式:
使用原生的swiper组件,因为原生的swiper开启循环后,会自动到第一张实现循环,那么我们只需要按照算法,对接即可实现无缝的无限循环

例如:
当角标到达0时,备注组是:0.1.2
左滑动,预备组就变成了1,2,3
右滑动,预备组 就变成了3,0,1
只要保证每次滑动的时候,展示位置为中间位置,就可以实现,展示3个页面的同时,实现页面不卡顿,也就是无缝
我还顺便封装了一个组件,大家可以参考使用

<template>
	<view>
		<swiper circular :style="{height:props.height+'px'}" :current="showIndex"
			@change="scrollIssure">
			<swiper-item :item-id="index+''" v-for="(item,index) in showList" :key="index">
				<slot :item="item" :index="index">
					<!-- 默认内容,如果父组件没有提供插槽内容则显示 -->
					<text>{{ index + 1 }}.{item}</text>
				</slot>
			</swiper-item>
		</swiper>
	</view>
</template>

<script setup>
	import {
		nextTick,
		onMounted,
		ref,
		defineProps,
		watch
	} from 'vue'
	const props = defineProps({
		current: {
			type: Number,
			default: 0
		},
		height: {
			type: Number,
			default: 300
		},
		list: {
			type: Array,
			default: () => []
		}
	})

	watch(() => props.list, (newList) => {
		nextTick(() => {
			scrollIssure({
				"detail": {
					"current": showIndex.value
				}
			});
		})
	})

	watch(() => props.current, (index) => {
		if (initCurrent.value === index) {
			return;
		}
		if (index % 3 === 0) {
			showIndex.value = 0;
			beforeShowIndex.value = 0
		}
		if (index % 3 === 1) {
			showIndex.value = 1;
			beforeShowIndex.value = 1
		}
		if (index % 3 === 2) {
			showIndex.value = 2;
			beforeShowIndex.value = 2
		}
		initCurrent.value = index;
		nextTick(() => {
			scrollIssure({
				"detail": {
					"current": showIndex.value
				}
			});
		})
	})

	const initCurrent = ref(0);
	const showList = ref([]);
	const beforeShowIndex = ref(1);
	const showIndex = ref(1);

	const emit = defineEmits(['update:current']);

	const updateCurrent = (index) => {
		emit('update:current', index); // 通知父组件更新
	};

	onMounted(() => {
		initCurrent.value = props.current;
	})


	const scrollIssure = (e) => {
		let toIndex = e.detail.current;
		showIndex.value = toIndex;
		if (props.list.length < 3) {
			return;
		}
		//需要记录前上一次位置判断向后或向前滑动
		let speed = toIndex - beforeShowIndex.value;
		beforeShowIndex.value = toIndex;
		if (speed === 1 || speed === -2) { //向前
			let changeCurrent=calculateIndex(initCurrent.value,true);
			initCurrent.value=changeCurrent;
			updateCurrent(changeCurrent)
		} else if (speed === -1 || speed === 2) { //向后
			let changeCurrent=calculateIndex(initCurrent.value,false);
			initCurrent.value=changeCurrent;
			updateCurrent(changeCurrent)
		}
		//获取当前位置为核心不变,渲染页面,前后位置页面
		//有三种占位情况
		let beforeIndex=calculateIndex(initCurrent.value,false);
		let afterIndex=calculateIndex(initCurrent.value,true);
		switch (toIndex) {
			case 0:
				if (speed === 0) {
					showList.value[0] = props.list[initCurrent.value];
				}
				showList.value[1] = props.list[afterIndex];
				showList.value[2] = props.list[beforeIndex];
				break;
			case 1:
				if (speed === 0) {
					showList.value[1] = props.list[initCurrent.value];
				}
				showList.value[0] = props.list[beforeIndex];
				showList.value[2] = props.list[afterIndex];
				break;
			case 2:
				if (speed === 0) {
					showList.value[2] = props.list[initCurrent.value];
				}
				showList.value[0] = props.list[afterIndex];
				showList.value[1] = props.list[beforeIndex];
				break;
		}
	}
	
	const calculateIndex=(index,add)=>{
		if(add){
			return index+1>props.list.length-1?0:index+1	
		}
		return index-1<=0?props.list.length-1:index-1
	}
</script>

<style>
</style>

组件是可以直接使用的,注意下传参即可

2.题库的mysql数据库结构设计

问题

有人可能会说,数据库还要设计啥,当然简单的题库可能只需要记录题目即可,但是复杂的题库,需要很多功能的记录,比如说不同车型,科目题目如何记录,车型目前有10多种:包括小车,客车,货车,摩托车,无人机等等,科目四个,两者一合,会出来100来条模块题库,这还只是全部题库的情况下,加上分类,甚至能上到1000多条

然后1000多条数据每个里面又会有不同得题目,相互交融,结合起来还是比较复杂

方案


使用中间模块表,直接记录该模块下题目全部的id,那么就不用每次去题库一一查询,只需要提前跑一遍脚本,分好类,不然io大的吓人,同时加上redis的话,基本就解决了

页面的话我就不贴了,大家按需参考:wx搜:愿兽驾道

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BlackJun-初心兽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值