微信小程序中实现自定义多选效果(完整实现及问题记录)

一、原有实现步骤,抛出问题:
  1. 需求:小程序中实现自定义多选效果 | 点击高亮 / 取消还原默认样式
  2. js层:用数组保存选中 ID,点击时增删数组
  3. wxml层:循环展示 + 判断是否选中来切换样式
  4. 问题:看似实现没问题,但是初始化选中和点击选中的样式效果,完全没有
二、解决问题(切换写法):

js层把数组换成对象的方式,来存储选中状态,模型wxml层,把 includes() 换成对象属性访问 ,就好了。

三、完整代码(涵盖从使用数组,到切换成对象的完整留痕)
javascript 复制代码
Page({
	data: {
		scenes: [{
				id: 'home',
				icon: '🏠',
				name: '家庭日常'
			},
			{
				id: 'park',
				icon: '🌳',
				name: '户外公园'
			},
			{
				id: 'call',
				icon: '📞',
				name: '接打电话'
			},
			{
				id: 'tv',
				icon: '📺',
				name: '电视/广播'
			},
			{
				id: 'restaurant',
				icon: '🍽️',
				name: '嘈杂餐厅'
			}
		],

		 // 第一种:初始化选中【数组方式】
		// selectedScenes: ['home'],

		// 第二种:初始化选中【对象方式】
		selectedScenes: {  
			home: true,
			park: false,
			call: false,
			tv: false,
			restaurant: false
		},
	},

	toggleScene_A_Method(e) {
		// 1. 获取点击的场景 ID(从 data-id 传过来)
		const sceneId = e.currentTarget.dataset.id

		// 2. 复制一份当前选中数组(不直接修改原数据)
		const selectedScenes = [...this.data.selectedScenes]

		// 3. 查找这个 ID 是否已经在选中数组里
		const index = selectedScenes.indexOf(sceneId)

		if (index > -1) {
			// 已选中 → 取消选中(删除)
			selectedScenes.splice(index, 1)
		} else {
			// 未选中 → 添加选中
			selectedScenes.push(sceneId)
		}
		console.warn("当前选中",this.data.selectedScenes);

		// 4. 更新到页面数据
		this.setData({
			selectedScenes
		})
	},

	toggleScene_B_Method(e) {
		const sceneId = e.currentTarget.dataset.id
		const selectedScenes = { ...this.data.selectedScenes }
		// 直接取反
		selectedScenes[sceneId] = !selectedScenes[sceneId]  
		this.setData({ selectedScenes })
	}

})
html 复制代码
<view class="scene-section">
	<text class="section-title">选择今日聆听的生活场景(多选)</text>
	<view class="scene-options">
		<block wx:for="{{scenes}}" wx:key="id">
			<!-- 第一种,对应使用includes()方式【导致初始选中和点击选中,样式完全失效】 : 
			 class="scene-item {{selectedScenes.includes(item.id) ? 'selected' : ''}}"
			-->
			<!-- 第二种, 使用对象属性访问【多选的初始选中和点击完全生效~】 -->
			<view class="scene-item {{selectedScenes[item.id] ? 'selected' : ''}}" bindtap="toggleScene_B_Method"
				data-id="{{item.id}}">
				<text>{{item.icon}} {{item.name}}</text>
			</view>
		</block>
	</view>
</view>
css 复制代码
.scene-section {
  padding: 30rpx;
}

.section-title {
  font-size: 28rpx;
  color: #333;
  margin-bottom: 20rpx;
}

.scene-options {
  display: flex;
  flex-wrap: wrap;
  gap: 20rpx;
}

.scene-item {
  flex-grow: 1;
  padding: 24rpx 40rpx;
  background: #f8fafc;
  border-radius: 20rpx;
  text-align: center;
  font-size: 28rpx;
  color: #64748b;
  border: 2rpx solid #e2e8f0;
}

.scene-item.selected {
  background: #e0f2fe;
  border-color: #0ea5e9;
  color: #0369a1;
}
四、总结(这是找到解释,原理我没有深究为什么小程序中不行)
  1. 初始化问题 :小程序中数组初始值有时不会被正确应用,而对象可以
  2. 模板兼容 : includes() 在 WXML 模板中兼容性不好,对象属性访问 \[\] 更稳定
  3. 更新效率 :对象直接修改属性比数组的 splice/push 更直接,视图更新更及时
相关推荐
fengGer的bugs2 小时前
新生儿喂养记录微信小程序:本地存储、四套主题,以及一份可改期的疫苗体检日程
微信小程序
5G微创业5 小时前
去除抖音视频水印的Python实现
python·微信小程序·去水印
WeiXin_DZbishe5 小时前
基于微信小程序的本地闲置物品交易平台-计算机毕设 附源码【课程设计】26825
vue.js·spring boot·python·微信小程序·架构·php·课程设计
小蒜学长8 小时前
基于微信小程序的医院医疗废弃物追溯管理系统(代码+数据库+LW)
java·spring boot·后端·微信小程序·医疗废弃物
霍营_托尼8 小时前
微信小程序点餐项目实战:飞入动画、样式错位、弹窗不消失,7 个前端坑的完整排障记录
javascript·微信小程序·动效
andrsted10 小时前
练题簿在线免费刷题:选择、填空、简答与排序,多种题型练出不同的掌握程度
学习·微信小程序·小程序·学习方法·刷题
andrsted21 小时前
练题簿在线免费刷题:Word、PDF 导题与预览补全,把现成资料变成可练习题库
微信小程序·小程序·pdf·word·学习方法·刷题
计算机毕设定制辅导-无忧学长1 天前
《校园食堂在线订餐小程序的设计与实现》
java·vue.js·spring boot·微信小程序·uniapp·校园食堂在线订餐小程序
andrsted2 天前
练题簿在线免费刷题:听读练题支持暂停续播、循环播放,让自己的题库听得更方便
学习·微信小程序·小程序·刷题·在线刷题
今年下半年3 天前
【微信小程序】uni-app + Vue3 + Vite 的小程序项目实现「进入指定范围才能打卡」的考勤功能
微信小程序·uni-app·定位·考勤