Commit 53e7aa9670892fff70999c30a69d4d83c63923e7
1 parent
ecfadea2
业务线 小程序不用写死,从后端接口获取
Showing
1 changed file
with
33 additions
and
21 deletions
components/grouped-picker/grouped-picker.vue
| @@ -4,8 +4,10 @@ | @@ -4,8 +4,10 @@ | ||
| 4 | path 只有 1 层 → 只有侧栏(原型「植物」屏:乔木/灌木/竹类… 纯侧栏,没有 tab); | 4 | path 只有 1 层 → 只有侧栏(原型「植物」屏:乔木/灌木/竹类… 纯侧栏,没有 tab); |
| 5 | path 有 2 层 → tab + 侧栏 + 平铺列表(原型「工具」屏:手工工具/电动工具/机械工具 → 剪切工具… → 太平剪); | 5 | path 有 2 层 → tab + 侧栏 + 平铺列表(原型「工具」屏:手工工具/电动工具/机械工具 → 剪切工具… → 太平剪); |
| 6 | 配到 g3 → 再多一层吸顶分组标题(物料 类型→类别→明细→物料 折出来的形态)。 | 6 | 配到 g3 → 再多一层吸顶分组标题(物料 类型→类别→明细→物料 折出来的形态)。 |
| 7 | - 选择控件按原型:多选+数量时右侧是步进器(未选一个「+」,已选「− n +」,减到 1 再减即取消), | ||
| 8 | - 不放勾选框;按钮是小白底圆角方框 + 浅灰描边(加减同款,不是圆形、不是灰底)。 | 7 | + 选择控件:**多选行左侧一律保留勾选框**(勾选框只管选中/取消), |
| 8 | + 带数量的字段右侧再加步进器管件数(未选一个「+」,已选「− n +」,减到 1 再减即取消), | ||
| 9 | + 按钮是小圆角方框 + 浅灰描边 + 白底,「+」「−」同款。 | ||
| 10 | + ⚠️ 原型弹层里没有勾选框(只有步进器),勾选框是按要求保留的、属于刻意覆盖原型。 | ||
| 9 | 行的勾选态由本组件的 draft 数据派生,不用 u-checkbox: | 11 | 行的勾选态由本组件的 draft 数据派生,不用 u-checkbox: |
| 10 | u-checkbox 的勾选态是组件内部状态(u-checkbox.vue:199-221 只在 init 时从父组派生), | 12 | u-checkbox 的勾选态是组件内部状态(u-checkbox.vue:199-221 只在 init 时从父组派生), |
| 11 | 而 u-checkbox-group 是把每个子实例的内部 isChecked 回读成数组(u-checkbox-group.vue:95-112), | 13 | 而 u-checkbox-group 是把每个子实例的内部 isChecked 回读成数组(u-checkbox-group.vue:95-112), |
| @@ -42,14 +44,20 @@ | @@ -42,14 +44,20 @@ | ||
| 42 | <view v-if="group.label" class="gp-group-title">{{ group.label }}</view> | 44 | <view v-if="group.label" class="gp-group-title">{{ group.label }}</view> |
| 43 | <view v-for="row in group.rows" :key="row.value" class="gp-row" | 45 | <view v-for="row in group.rows" :key="row.value" class="gp-row" |
| 44 | :class="{ 'is-selected': isSelected(row), 'is-locked': isLocked(row) }" @click="onRowClick(row)"> | 46 | :class="{ 'is-selected': isSelected(row), 'is-locked': isLocked(row) }" @click="onRowClick(row)"> |
| 47 | + <!-- 多选:左侧勾选框(原型弹层里没有,按要求保留)。 | ||
| 48 | + 带数量的字段勾选框与步进器并存:勾选框只表达选中/取消,件数由右侧步进器调 --> | ||
| 49 | + <view v-if="multiple" class="gp-check" :class="{ 'is-checked': isSelected(row) }" | ||
| 50 | + @click.stop="onToggle(row)"> | ||
| 51 | + <text v-if="isSelected(row)" class="gp-check-mark">✓</text> | ||
| 52 | + </view> | ||
| 45 | <view class="gp-row-main"> | 53 | <view class="gp-row-main"> |
| 46 | <text class="gp-row-label">{{ row.label }}</text> | 54 | <text class="gp-row-label">{{ row.label }}</text> |
| 47 | <!-- 搜索态下补层级面包屑,否则不知道命中的项属于哪个分组 --> | 55 | <!-- 搜索态下补层级面包屑,否则不知道命中的项属于哪个分组 --> |
| 48 | <text v-if="breadcrumb(row)" class="gp-row-crumb">{{ breadcrumb(row) }}</text> | 56 | <text v-if="breadcrumb(row)" class="gp-row-crumb">{{ breadcrumb(row) }}</text> |
| 49 | </view> | 57 | </view> |
| 50 | - <!-- 多选 + 数量(原型形态):右侧步进器表达选中态 —— 未选只有一个「+」, | 58 | + <!-- 多选 + 数量(原型形态):右侧步进器 —— 未选只有一个「+」, |
| 51 | 点了就选中并置 1;已选是「− n +」,减到 1 再减即取消选择 --> | 59 | 点了就选中并置 1;已选是「− n +」,减到 1 再减即取消选择 --> |
| 52 | - <view v-if="needQuantity" class="gp-qty" @click.stop> | 60 | + <view v-if="multiple && needQuantity" class="gp-qty" @click.stop> |
| 53 | <view v-if="!isSelected(row)" class="gp-qty-btn is-plus" | 61 | <view v-if="!isSelected(row)" class="gp-qty-btn is-plus" |
| 54 | :class="{ 'is-disabled': isLocked(row) }" @click="onPlus(row)"> | 62 | :class="{ 'is-disabled': isLocked(row) }" @click="onPlus(row)"> |
| 55 | <up-icon name="plus" size="12" color="#606266"></up-icon> | 63 | <up-icon name="plus" size="12" color="#606266"></up-icon> |
| @@ -64,12 +72,8 @@ | @@ -64,12 +72,8 @@ | ||
| 64 | </view> | 72 | </view> |
| 65 | </template> | 73 | </template> |
| 66 | </view> | 74 | </view> |
| 67 | - <!-- 多选无数值:原型没覆盖这种,保留自绘勾选框 --> | ||
| 68 | - <view v-else-if="multiple" class="gp-check" :class="{ 'is-checked': isSelected(row) }"> | ||
| 69 | - <text v-if="isSelected(row)" class="gp-check-mark">✓</text> | ||
| 70 | - </view> | ||
| 71 | <!-- 单选:原型没覆盖,右侧给一个选中标记 --> | 75 | <!-- 单选:原型没覆盖,右侧给一个选中标记 --> |
| 72 | - <view v-else class="gp-radio"> | 76 | + <view v-else-if="!multiple" class="gp-radio"> |
| 73 | <up-icon v-if="isSelected(row)" name="checkmark" size="16" color="#2979ff"></up-icon> | 77 | <up-icon v-if="isSelected(row)" name="checkmark" size="16" color="#2979ff"></up-icon> |
| 74 | </view> | 78 | </view> |
| 75 | </view> | 79 | </view> |
| @@ -271,6 +275,20 @@ const deselect = (v) => { | @@ -271,6 +275,20 @@ const deselect = (v) => { | ||
| 271 | if (i > -1) draftSelected.value.splice(i, 1) | 275 | if (i > -1) draftSelected.value.splice(i, 1) |
| 272 | delete draftQty[v] | 276 | delete draftQty[v] |
| 273 | } | 277 | } |
| 278 | +// 勾选框:只切选中态。取消会把该项的数量一起删掉,重新勾上从 1 起 | ||
| 279 | +const onToggle = (row) => { | ||
| 280 | + const v = String(row.value) | ||
| 281 | + if (isSelected(row)) { | ||
| 282 | + deselect(v) | ||
| 283 | + return | ||
| 284 | + } | ||
| 285 | + if (isLocked(row)) { | ||
| 286 | + uni.showToast({ title: `最多选择 ${props.maxCount} 项`, icon: 'none' }) | ||
| 287 | + return | ||
| 288 | + } | ||
| 289 | + draftSelected.value.push(v) | ||
| 290 | + if (props.needQuantity && !draftQty[v]) draftQty[v] = 1 | ||
| 291 | +} | ||
| 274 | // 「+」:未选先选中并置 1,已选则 +1 | 292 | // 「+」:未选先选中并置 1,已选则 +1 |
| 275 | const onPlus = (row) => { | 293 | const onPlus = (row) => { |
| 276 | if (isLocked(row)) { | 294 | if (isLocked(row)) { |
| @@ -316,18 +334,10 @@ const switchSide = (idx) => { | @@ -316,18 +334,10 @@ const switchSide = (idx) => { | ||
| 316 | const onRowClick = (row) => { | 334 | const onRowClick = (row) => { |
| 317 | const v = String(row.value) | 335 | const v = String(row.value) |
| 318 | if (props.multiple) { | 336 | if (props.multiple) { |
| 319 | - // 整行点击也能选(不必非要点中那个「+」),选中就默认数量 1。 | ||
| 320 | - // 带数量的字段点整行「取消」要禁用:取消统一走「−」,否则误点一下就把加好的数量清了 | ||
| 321 | - if (isSelected(row)) { | ||
| 322 | - if (!props.needQuantity) deselect(v) | ||
| 323 | - return | ||
| 324 | - } | ||
| 325 | - if (isLocked(row)) { | ||
| 326 | - uni.showToast({ title: `最多选择 ${props.maxCount} 项`, icon: 'none' }) | ||
| 327 | - return | ||
| 328 | - } | ||
| 329 | - draftSelected.value.push(v) | ||
| 330 | - if (props.needQuantity && !draftQty[v]) draftQty[v] = 1 | 337 | + // 整行点击也能选(不必非要点中勾选框),选中就默认数量 1。 |
| 338 | + // 带数量的字段点整行「取消」要禁用:取消统一走勾选框或「−」,否则误点一下就把加好的数量清了 | ||
| 339 | + if (isSelected(row) && props.needQuantity) return | ||
| 340 | + onToggle(row) | ||
| 331 | return | 341 | return |
| 332 | } | 342 | } |
| 333 | // 单选:点行即确认并关闭,与底部 actionSheet 的即时选中语义一致 | 343 | // 单选:点行即确认并关闭,与底部 actionSheet 的即时选中语义一致 |
| @@ -490,6 +500,8 @@ watch( | @@ -490,6 +500,8 @@ watch( | ||
| 490 | } | 500 | } |
| 491 | } | 501 | } |
| 492 | 502 | ||
| 503 | +/* 多选勾选框(自绘,不用 u-checkbox —— 见文件头注释的幽灵勾选坑)。 | ||
| 504 | + 原型弹层里没有勾选框,是按要求保留的,不要照着原型删掉 */ | ||
| 493 | .gp-check { | 505 | .gp-check { |
| 494 | flex-shrink: 0; | 506 | flex-shrink: 0; |
| 495 | width: 36rpx; | 507 | width: 36rpx; |