UNPKG

wux

Version:

微信小程序 - 自定义组件

271 lines (255 loc) 11.2 kB
import Component from '../component' export default { /** * 初始化筛选栏 * @param {Object} opts 配置项 * @param {Array} opts.items 按钮的配置数组 * @param {Function} opts.onChange 选中值变化的回调函数 * @param {Function} opts.onScroll scroll-view 滚动时触发的事件 */ init(opts = {}) { const options = Object.assign({}, opts) // 实例化组件 const component = new Component({ scope: `$wux.filterbar`, data: options, methods: { /** * 隐藏 */ hide() { if (this.removed) return !1 this.removed = !0 this.setHidden() }, /** * 显示 */ show() { if (this.removed) return !1 this.setVisible() }, /** * 重置按钮 * @param {Object} e 事件对象 * @param {Object} prevState 上一个状态值 */ onReset(e, prevState) { const { index, item } = e.currentTarget.dataset const children = prevState && prevState.children || item.children.map((n) => { return Object.assign({}, n, { children: n.children.map((m) => Object.assign({}, m, { checked: false, })), selected: '', }) }) this.setData({ [`$wux.filterbar.items[${index}].children`]: children, }) }, /** * 关闭侧边栏筛选框 * @param {Object} e 事件对象 * @param {Function} callback 回调函数 */ onClose(e, callback) { const { index } = e.currentTarget.dataset this.setData({ [`$wux.filterbar.items[${index}].visible`]: false, }, () => { if (typeof callback === 'function') { callback.call(this, e) } else { this.onReset(e, this.prevState) } }) }, /** * 确认按钮 * @param {Object} e 事件对象 */ onConfirm(e) { this.onClose(e, this.onChange) }, /** * 筛选栏内单项选择触发 change 事件 * @param {Object} e 事件对象 */ onRadioChange(e) { const { value } = e.detail const { index, item, parentIndex } = e.currentTarget.dataset const children = item.children.map((n) => Object.assign({}, n, { checked: n.value === value, })) const selected = children.filter((n) => n.checked).map((n) => n.label).join(',') this.setData({ [`$wux.filterbar.items[${parentIndex}].children[${index}].children`]: children, [`$wux.filterbar.items[${parentIndex}].children[${index}].selected`]: selected, }) }, /** * 筛选栏内多项选择触发 change 事件 * @param {Object} e 事件对象 */ onCheckboxChange(e) { const { value } = e.detail const { index, item, parentIndex } = e.currentTarget.dataset const children = item.children.map((n) => Object.assign({}, n, { checked: value.includes(n.value), })) const selected = children.filter((n) => n.checked).map((n) => n.label).join(',') this.setData({ [`$wux.filterbar.items[${parentIndex}].children[${index}].children`]: children, [`$wux.filterbar.items[${parentIndex}].children[${index}].selected`]: selected, }) }, /** * 下拉框内单项选择触发 change 事件 * @param {Object} e 事件对象 */ radioChange(e) { const { value } = e.detail const { index, item } = e.currentTarget.dataset const children = item.children.map((n) => Object.assign({}, n, { checked: n.value === value, })) this.setData({ [`$wux.filterbar.items[${index}].children`]: children, }, this.onChange) }, /** * 下拉框内多项选择触发 change 事件 * @param {Object} e 事件对象 */ checkboxChange(e) { const { value } = e.detail const { index, item } = e.currentTarget.dataset const children = item.children.map((n) => Object.assign({}, n, { checked: value.includes(n.value), })) this.setData({ [`$wux.filterbar.items[${index}].children`]: children, }, this.onChange) }, /** * 点击事件 * @param {Object} e 事件对象 */ onClick(e) { const { index } = e.currentTarget.dataset this.onOpenSelect(this.page.data.$wux.filterbar.items, index) }, /** * 打开下拉框 * @param {Array} data 菜单数据 * @param {Number} index 当前索引 */ onOpenSelect(data = [], index = 0) { const current = data[index] const items = data.map((n, i) => { const params = Object.assign({}, n, { checked: index === i ? !n.checked : false, }) // 判断已选择的元素是否同组 if (n.checked) { const has = this.getDifference(n.groups, current.groups) params.checked = !!has.length // 判断非同组的元素清空选择内容 if (index !== i && !has.length) { if (typeof params.children === 'object') { if (['radio', 'checkbox'].includes(n.type)) { params.children = params.children.map((n) => Object.assign({}, n, { checked: false, })) } if (['filter'].includes(n.type)) { params.children = params.children.map((n) => { return Object.assign({}, n, { children: n.children.map((m) => Object.assign({}, m, { checked: false, })), selected: '', }) }) } } if (['sort'].includes(n.type)) { params.sort = undefined } } } // 展开或隐藏下拉框 if (['radio', 'checkbox', 'filter'].includes(n.type)) { params.visible = index === i ? !n.visible : false } // 当前点击排序做出处理 if (index === i && ['sort'].includes(n.type)) { params.sort = typeof params.sort === 'number' ? -params.sort : 1 } return params }) this.setData({ [`$wux.filterbar.items`]: items, }, () => { this.prevState = current if (!['radio', 'checkbox', 'filter'].includes(current.type)) { this.onChange() } }) }, /** * 关闭下拉框 */ onCloseSelect() { const items = this.page.data.$wux.filterbar.items const params = {} items.forEach((n, i) => { if (n.checked && n.visible) { params[`$wux.filterbar.items[${i}].visible`] = false } }) this.setData(params) }, /** * 获取两个数组相同的元素 * @param {Array} data 数组 * @param {Array} values 数组 */ getDifference(data = [], values = []) { return data.filter(v => values.includes(v)) }, /** * 重置元素 * @param {Object} item 数据对象 */ resetValue(item = {}) { items.children.map((n) => Object.assign({}, n, { checked: false, })) }, /** * 元素发生变化时的事件 */ onChange() { const items = this.page.data.$wux.filterbar.items const checkedItems = items.filter((n) => n.checked) if (typeof options.onChange === 'function') { options.onChange.call(this, checkedItems, items) } }, /** * scroll-view 滚动时触发的事件 * @param {Object} e 事件对象 */ onScroll(e) { if (typeof options.onScroll === 'function') { options.onScroll.call(this, e) } }, }, }) component.show() return component }, }