diff --git a/example/pages/checkbox/checkbox.ts b/example/pages/checkbox/checkbox.ts index cb0915010..b3e3e0dee 100644 --- a/example/pages/checkbox/checkbox.ts +++ b/example/pages/checkbox/checkbox.ts @@ -5,13 +5,15 @@ Page({ demoCheckboxMax: ['checkbox1', 'checkbox2'], demoCheckbox3: ['checkbox2', 'checkbox4'], controledData: [], + checked: true, + checked1: true, options: [ { label: '全选', checkAll: true }, '多选1', '多选2', { label: '多选3', value: '多选3' }, ], - checkAllValues: ['多选1', '多选2', '多选3'], + checkAllValues: ['多选1', '多选2', ''], activeImage: 'https://oteam-tdesign-1258344706.cos.ap-guangzhou.myqcloud.com/miniprogram/checkbox-checked.png', inActiveImage: @@ -20,21 +22,24 @@ Page({ checkAll1: ['checkbox1'], }, handleGroupChange(event) { - console.log('group', event.detail); + console.log('group', event.detail.value); + this.setData({ + demoCheckbox1: event.detail.value, + }); }, onChange(event) { - console.log('checkbox', event.detail); + console.log('checkbox', event.detail.value); }, onCheckAllChange(event) { - console.log('checkbox', event.detail); + console.log('checkbox', event.detail.value); this.setData({ checkAllValues: event.detail, }); }, toggle5(e) { - console.log('checkbox', e.detail); + console.log('checkbox', e.detail.value); this.setData({ - check5: e.detail, + check5: e.detail.value, }); }, handleControled() { @@ -45,4 +50,25 @@ Page({ controledData: data, }); }, + testControll(val) { + console.log(val.detail); + }, + // 受控 + controlledHandler(e) { + console.log(e.detail.value); + this.setData({ + checked1: e.detail.checked, + }); + }, + buttonControl() { + console.log(!this.data.checked1); + this.setData({ + checked1: !this.data.checked1, + }); + }, + changeChecked(e) { + this.setData({ + checked: e.detail.checked, + }); + }, }); diff --git a/example/pages/checkbox/checkbox.wxml b/example/pages/checkbox/checkbox.wxml index d5acd3e49..065da0b1d 100644 --- a/example/pages/checkbox/checkbox.wxml +++ b/example/pages/checkbox/checkbox.wxml @@ -1,8 +1,23 @@ Checkbox多选框 用于预设的一组选项中执行多项选择,并呈现选择结果。 + + + - + @@ -18,7 +33,7 @@ - + @@ -35,13 +50,13 @@ - + @@ -49,7 +64,7 @@ - + @@ -58,11 +73,11 @@ - + - + @@ -73,9 +88,21 @@ - + + + - diff --git a/src/checkbox-group/README.md b/src/checkbox-group/README.md index ce631dd45..1190ac424 100644 --- a/src/checkbox-group/README.md +++ b/src/checkbox-group/README.md @@ -28,12 +28,12 @@ isComponent: true ```html - - - + + + ``` - + ## API ### `` 组件 diff --git a/src/checkbox-group/checkbox-group.ts b/src/checkbox-group/checkbox-group.ts index a16f547bb..e085f4360 100644 --- a/src/checkbox-group/checkbox-group.ts +++ b/src/checkbox-group/checkbox-group.ts @@ -22,11 +22,17 @@ export default class CheckBoxGroup extends SuperComponent { checkboxOptions: [], }; - properties = Props; + properties = { + ...Props, + defaultValue: { + type: null, + value: undefined, + }, + }; observers = { value: function () { - this.updateChildren('slot'); + this.updateChildren(); }, }; @@ -36,19 +42,33 @@ export default class CheckBoxGroup extends SuperComponent { }, }; + controlledProps = [ + { + key: 'value', + event: 'change', + }, + ]; + methods = { - // slot插入选项 - updateChildren(type = 'slot') { - let items = []; - if (type === 'not-slot') { + getChilds() { + let items = this.getRelationNodes('../checkbox/checkbox'); + if (!items.length) { items = this.selectAllComponents('.t-checkbox-option'); - } else { - items = this.getRelationNodes('../checkbox/checkbox'); } + return items || []; + }, + + // slot插入选项 + updateChildren() { + const items = this.getChilds(); + const { value, disabled } = this.data; if (items.length > 0) { items.forEach((item: any) => { - !item.data.checkAll && item.changeActive(value.indexOf(item.data.value) > -1); + !item.data.checkAll && + item.setData({ + checked: value?.indexOf(item.data.value) > -1, + }); item.setDisabled(disabled); }); // 关联可全选项 @@ -56,11 +76,11 @@ export default class CheckBoxGroup extends SuperComponent { items.forEach((item) => { item.setOptionLinked(true); }); - this.handleHalfCheck(type, items.length); + this.handleHalfCheck(items.length); } } }, - updateValue({ name, checked }, type = 'slot') { + updateValue({ name, checked }) { const { value, max } = this.data; let newValue = value; if (max && checked && newValue.length === max) { @@ -72,11 +92,11 @@ export default class CheckBoxGroup extends SuperComponent { const index = newValue.findIndex((v: string) => v === name); newValue.splice(index, 1); } - this.setData({ - value: newValue, - }); - this.updateChildren(type); - this.triggerEvent('change', newValue); + // this.setData({ + // value: newValue, + // }); + // this.updateChildren(); + this._trigger('change', { value: newValue }); }, // 支持自定义options handleCreateMulCheckbox() { @@ -103,57 +123,62 @@ export default class CheckBoxGroup extends SuperComponent { this.setData({ checkboxOptions: optionsValue, }); - this.updateChildren('not-slot'); + this.updateChildren(); } catch (error) { console.error('error', error); } }, // 处理全选 handleCheckAll(e) { - const { checked, option, name, type } = e.detail || e; - let items = []; - if (type === 'not-slot') { - items = this.selectAllComponents('.t-checkbox-option'); - } else { - items = this.getRelationNodes('../checkbox/checkbox'); - } + const { checked, option, name } = e.detail || e; + const items = this.getChilds(); + if (!option) { if (!items?.length) { return; } - this.setData({ + // this.setData({ + // value: items + // .map((item) => { + // if (item.data.disabled) { + // return this.data.value.includes(item.data.value) ? item.data.value : ''; + // } + // item.changeActive(checked); + // return checked && !item.data.checkAll ? item.data.value : ''; + // }) + // .filter((val) => val), + // }); + this._trigger('change', { value: items .map((item) => { if (item.data.disabled) { - return ''; + return this.data.value.includes(item.data.value) ? item.data.value : ''; } - item.changeActive(checked); + // item.changeActive(checked); return checked && !item.data.checkAll ? item.data.value : ''; }) .filter((val) => val), }); - this.triggerEvent('change', this.data.value); - this.handleHalfCheck(type, items.length); + // this.handleHalfCheck(items.length); } else { - this.updateValue({ name, checked }, type); + this.updateValue({ name, checked }); } }, // 处理options半选 - handleHalfCheck(type: string, len: number) { - let items = []; - if (type === 'not-slot') { - items = this.selectAllComponents('.t-checkbox-option'); - } else { - items = this.getRelationNodes('../checkbox/checkbox'); - } + handleHalfCheck(len: number) { + const items = this.getChilds(); const all = items.filter((i) => !i.data.checkAll).map((item) => item.data.value); - const currentVal = Array.from(new Set(this.data.value.filter((i) => all.indexOf(i) > -1))); + const excludeDisableArr = items + .filter((i) => !i.data.checkAll && i.data.value && !i.data.disabled) + .map((item) => item.data.value); + const currentVal = Array.from(new Set(this.data.value?.filter((i) => all.indexOf(i) > -1))); const element = items.find((item) => item.data.checkAll); if (currentVal.length) { - element?.changeActive(true); + element?.setData({ checked: true }); element?.changeCheckAllHalfStatus(currentVal.length !== len - 1); + element?.setCancel(currentVal.length >= excludeDisableArr.length); } else { - element?.changeActive(false); + element?.setData({ checked: false }); } }, // 设置可全选option选项 diff --git a/src/checkbox/README.md b/src/checkbox/README.md index 91f8df87c..852c3a688 100644 --- a/src/checkbox/README.md +++ b/src/checkbox/README.md @@ -22,7 +22,7 @@ isComponent: true ```html - + @@ -35,6 +35,8 @@ isComponent: true 多选多选多选多选多选多选多选多选多选多选多选多选多选多选多选多选多选选多选多选多选选多选多选多选多选 + + ``` ```js @@ -43,52 +45,53 @@ Page({ demoCheckbox1: ['checkbox2', 'checkbox3'], }, onChange(event) { - console.log('checkbox', event.detail); + console.log('checkbox', event.detail.value); }, }); ``` ## API - ### Checkbox Props -| 名称 | 类型 | 默认值 | 说明 | 必传 | -| ---------------- | --------------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------- | ------- | -| align | String | left | 复选框和内容相对位置。可选项:left/right | N | -| check-all | Boolean | false | 用于标识是否为「全选选项」 | N | -| checked | Boolean | false | 是否选中 | N | -| color | String | #0052d9 | 复选框颜色 | N | -| content | String / Slot | - | 复选框内容 | N | -| content-disabled | Boolean | - | 是否禁用组件内容(content)触发选中 | N | -| disabled | Boolean | undefined | 是否禁用组件 | N | -| external-classes | Array | - | 组件类名,分别用于设置 组件外层、复选框图标、主文案、内容 等元素类名。`['t-class', 't-class-icon', 't-class-label', 't-class-content']` | N | -| icon | Array | - | 自定义选中图标和非选中图标。示例:[选中态图标地址,非选中态图标地址]。TS 类型:`Array` | N | -| indeterminate | Boolean | false | 是否为半选 | N | -| label | String / Slot | - | 主文案 | N | -| max-content-row | Number | 5 | 内容最大行数限制 | N | -| max-label-row | Number | 3 | 主文案最大行数限制 | N | -| name | String | - | HTML 元素原生属性 | N | -| readonly | Boolean | false | 组件是否只读 | N | -| value | String / Number | - | 复选框的值。TS 类型:`string | number` | N | +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +align | String | left | 复选框和内容相对位置。可选项:left/right | N +check-all | Boolean | false | 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 | N +checked | Boolean | false | 受控:是否选中 | N +defaultChecked | Boolean | false | 非受控,是否选中 | N +color | String | #0052d9 | 复选框颜色 | N +content | String / Slot | - | 复选框内容 | N +content-disabled | Boolean | - | 是否禁用组件内容(content)触发选中 | N +disabled | Boolean | undefined | 是否禁用组件 | N +external-classes | Array | - | 组件类名,分别用于设置 组件外层、复选框图标、主文案、内容 等元素类名。`['t-class', 't-class-icon', 't-class-label', 't-class-content']` | N +icon | Array | - | 自定义选中图标和非选中图标。示例:[选中态图标地址,非选中态图标地址]。TS 类型:`Array` | N +indeterminate | Boolean | false | 是否为半选 | N +label | String / Slot | - | 主文案 | N +max-content-row | Number | 5 | 内容最大行数限制 | N +max-label-row | Number | 3 | 主文案最大行数限制 | N +name | String | - | HTML 元素原生属性 | N +readonly | Boolean | false | 组件是否只读 | N +value | String / Number | - | 复选框的值。TS 类型:`string | number` | N ### Checkbox Events -| 名称 | 参数 | 描述 | -| ------ | -------------------- | ------------ | -| change | `(checked: boolean)` | 值变化时触发 | +名称 | 参数 | 描述 +-- | -- | -- +change | `({checked: boolean})` | 值变化时触发 ### CheckboxGroup Props -| 名称 | 类型 | 默认值 | 说明 | 必传 | -| -------- | ------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---- | -| disabled | Boolean | false | 是否禁用组件 | N | -| max | Number | undefined | 支持最多选中的数量 | N | -| name | String | - | 统一设置内部复选框 HTML 属性 | N | -| options | Array | [] | 以配置形式设置子元素。示例 1:['北京', '上海'] ,示例 2: [{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox/type.ts) | N | -| value | Array | [] | 选中值。TS 类型:`CheckboxGroupValue`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox/type.ts) | N | +名称 | 类型 | 默认值 | 说明 | 必传 +-- | -- | -- | -- | -- +disabled | Boolean | false | 是否禁用组件 | N +max | Number | undefined | 支持最多选中的数量 | N +name | String | - | 统一设置内部复选框 HTML 属性 | N +options | Array | [] | 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」。TS 类型:`Array`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox/type.ts) | N +value | Array | [] | 受控:选中值。TS 类型:`CheckboxGroupValue`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox/type.ts) | N +defaultValue | Array | [] | 非受控:选中值。TS 类型:`CheckboxGroupValue`。[详细类型定义](https://github.com/Tencent/tdesign-miniprogram/tree/develop/src/checkbox/type.ts) | N ### CheckboxGroup Events -| 名称 | 参数 | 描述 | -| ------ | ----------------------------- | ------------ | -| change | `(value: CheckboxGroupValue)` | 值变化时触发 | +名称 | 参数 | 描述 +-- | -- | -- +change | `({value: CheckboxGroupValue})` | 值变化时触发 diff --git a/src/checkbox/checkbox-group-props.ts b/src/checkbox/checkbox-group-props.ts index f3ecba1ad..b5eee76fe 100644 --- a/src/checkbox/checkbox-group-props.ts +++ b/src/checkbox/checkbox-group-props.ts @@ -2,7 +2,6 @@ /** * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC - * updated at 2021-11-24 10:58:05 * */ import { TdCheckboxGroupProps } from './type'; @@ -22,13 +21,18 @@ const props: TdCheckboxGroupProps = { type: String, value: '', }, - /** 以配置形式设置子元素。示例1:['北京', '上海'] ,示例2: [{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]。checkAll 值为 true 表示当前选项为「全选选项」 */ + /** 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」 */ options: { type: Array, value: [], }, /** 选中值 */ value: { + type: Array, + value: null, + }, + /** 选中值,非受控属性 */ + defaultValue: { type: Array, value: [], }, diff --git a/src/checkbox/checkbox.ts b/src/checkbox/checkbox.ts index 1b456e8ad..909f939ab 100644 --- a/src/checkbox/checkbox.ts +++ b/src/checkbox/checkbox.ts @@ -18,7 +18,13 @@ export default class CheckBox extends SuperComponent { multipleSlots: true, }; - properties = Props; + properties = { + ...Props, + defaultChecked: { + type: null, + value: undefined, + }, + }; // 组件的内部数据 data = { @@ -27,6 +33,7 @@ export default class CheckBox extends SuperComponent { active: false, halfChecked: false, optionLinked: false, + canCancel: false, }; lifetimes = { @@ -35,6 +42,22 @@ export default class CheckBox extends SuperComponent { }, }; + observers = { + checked: function (isChecked) { + this.initStatus(); + this.setData({ + active: isChecked, + }); + }, + }; + + controlledProps = [ + { + key: 'checked', + event: 'change', + }, + ]; + /* Methods */ methods = { onChange(e) { @@ -45,14 +68,14 @@ export default class CheckBox extends SuperComponent { if (target === 'text' && contentDisabled) { return; } - const { value, active, checkAll, optionLinked } = this.data; + const { value, active, checkAll, optionLinked, canCancel } = this.data; const item = { name: value, checked: !active, checkAll }; const [parent] = this.getRelationNodes('../checkbox-group/checkbox-group'); if (parent) { if (checkAll || optionLinked) { parent.handleCheckAll({ type: 'slot', - checked: !active, + checked: !active || (this.data.halfChecked && !canCancel), option: !checkAll, name: value, }); @@ -62,34 +85,40 @@ export default class CheckBox extends SuperComponent { } else if (checkAll || optionLinked) { this.triggerEvent('toggleAll', { type: 'not-slot', - checked: !active, + checked: !active || (this.data.halfChecked && !canCancel), option: !checkAll, name: value, }); } else { - this.triggerEvent('change', !active); - this.toggle(); + this._trigger('change', { checked: !active }); + // this.triggerEvent('change', !active); + // this.toggle(); } }, initStatus() { if (!this.data.optionLinked) { if (this.data.indeterminate) { this.setData({ - active: true, + // active: true, halfChecked: true, }); } else { this.setData({ - active: this.data.checked, + // active: this.data.checked, halfChecked: this.data.indeterminate, }); } } }, toggle() { - const { active } = this.data; + // const { active } = this.data; + // this.setData({ + // active: !active, + // }); + }, + setCancel(cancel: boolean) { this.setData({ - active: !active, + canCancel: cancel, }); }, setDisabled(disabled: Boolean) { @@ -97,11 +126,7 @@ export default class CheckBox extends SuperComponent { disabled: this.data.disabled || disabled, }); }, - changeActive(active: boolean) { - this.setData({ - active, - }); - }, + // 半选 changeCheckAllHalfStatus(active: boolean) { this.setData({ diff --git a/src/checkbox/props.ts b/src/checkbox/props.ts index 457c29276..203874776 100644 --- a/src/checkbox/props.ts +++ b/src/checkbox/props.ts @@ -2,7 +2,6 @@ /** * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC - * updated at 2021-11-24 10:58:05 * */ import { TdCheckboxProps } from './type'; @@ -12,13 +11,18 @@ const props: TdCheckboxProps = { type: String, value: 'left', }, - /** 用于标识是否为「全选选项」 */ + /** 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 */ checkAll: { type: Boolean, value: false, }, /** 是否选中 */ checked: { + type: Boolean, + value: null, + }, + /** 是否选中,非受控属性 */ + defaultChecked: { type: Boolean, value: false, }, diff --git a/src/checkbox/type.ts b/src/checkbox/type.ts index 0afe337c6..eccee5d14 100644 --- a/src/checkbox/type.ts +++ b/src/checkbox/type.ts @@ -2,7 +2,6 @@ /** * 该文件为脚本自动生成文件,请勿随意修改。如需修改请联系 PMC - * updated at 2021-11-24 10:58:05 * */ export interface TdCheckboxProps { @@ -16,7 +15,7 @@ export interface TdCheckboxProps { required?: boolean; }; /** - * 用于标识是否为「全选选项」 + * 用于标识是否为「全选选项」。单独使用无效,需在 CheckboxGroup 中使用 * @default false */ checkAll?: { @@ -33,6 +32,15 @@ export interface TdCheckboxProps { value?: boolean; required?: boolean; }; + /** + * 是否选中,非受控属性 + * @default false + */ + defaultChecked?: { + type: BooleanConstructor; + value?: boolean; + required?: boolean; + }; /** * 复选框颜色 * @default #0052d9 @@ -144,7 +152,7 @@ export interface TdCheckboxProps { value?: string | number; required?: boolean; }; -}; +} export interface TdCheckboxGroupProps { /** @@ -174,7 +182,7 @@ export interface TdCheckboxGroupProps { required?: boolean; }; /** - * 以配置形式设置子元素。示例1:['北京', '上海'] ,示例2: [{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]。checkAll 值为 true 表示当前选项为「全选选项」 + * 以配置形式设置子元素。示例1:`['北京', '上海']` ,示例2: `[{ label: '全选', checkAll: true }, { label: '上海', value: 'shanghai' }]`。checkAll 值为 true 表示当前选项为「全选选项」 * @default [] */ options?: { @@ -191,10 +199,24 @@ export interface TdCheckboxGroupProps { value?: CheckboxGroupValue; required?: boolean; }; -}; + /** + * 选中值,非受控属性 + * @default [] + */ + defaultValue?: { + type: ArrayConstructor; + value?: CheckboxGroupValue; + required?: boolean; + }; +} export type CheckboxOption = string | number | CheckboxOptionObj; -export interface CheckboxOptionObj { label?: string; value?: string | number; disabled?: boolean; checkAll?: true }; +export interface CheckboxOptionObj { + label?: string; + value?: string | number; + disabled?: boolean; + checkAll?: true; +} -export type CheckboxGroupValue = Array | string | number; +export type CheckboxGroupValue = Array;