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

一、原有实现步骤,抛出问题:
  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 更直接,视图更新更及时
相关推荐
2601_9638699510 小时前
力序健身房管理系统
微信小程序·小程序
拖孩17 小时前
给小程序加「一键发公众号贴图」,我把 wx.shareToOfficialAccount 的三个坑趟了一遍
前端·后端·微信小程序
StevenLdh2 天前
第四期 · 云端同步与冲突仲裁:离线可写、多端一致的工程解法
java·微信小程序
m0_462803882 天前
会议签到如何设置手写签名?从创建签到到导出签名 PDF 的完整流程
微信小程序
AI工具人PM产品经理3 天前
零基础微信小程序入门:一个真实项目的里程碑路线图
微信小程序·云开发·学习路线·零基础入门·ai 编程
拖孩4 天前
这个小程序是 AI 帮我写的,可它里面一个 AI 功能都没有
前端·后端·微信小程序
克里斯蒂亚诺更新4 天前
小程序自定义导航栏怎么写:从配置到实战
微信小程序
liyinchi19884 天前
微信小程序支付遇到“由于小程序违规,支付功能暂时无法使用” 解决办法
java·微信小程序·go
silianpan4 天前
Office 文档预览 UTS 插件
android·微信小程序·harmonyos
微笑的曙光4 天前
第三期 · 账号体系与双 Token 鉴权:让用户「无感登录,有感安全」
微信小程序