diff --git a/doc.config.js b/doc.config.js index 647b0f1e..93f4887a 100644 --- a/doc.config.js +++ b/doc.config.js @@ -85,6 +85,11 @@ module.exports = { toptips: require('./packages/toptips/README.md'), loadmore: require('./packages/loadmore/README.md') } + }, + { + base: 'complexComponent', + label: '高阶组件', + include: { tree_select: require('./packages/tree-select/README.md') } } ], include: {} diff --git a/example/app.json b/example/app.json index c6a3d078..2942c672 100644 --- a/example/app.json +++ b/example/app.json @@ -24,6 +24,7 @@ "pages/tag/index", "pages/toptips/index", "pages/toast/index", + "pages/tree-select/index", "pages/select/index", "pages/datetime/index" ], diff --git a/example/pages/tree-select/config.js b/example/pages/tree-select/config.js new file mode 100644 index 00000000..8d32aa89 --- /dev/null +++ b/example/pages/tree-select/config.js @@ -0,0 +1,30 @@ +module.exports = { + pro1Name: '浙江', + pro1: [{ + text: '杭州', + id: 1001 + }, { + text: '温州', + id: 1002 + }, { + text: '宁波', + id: 1003 + }, { + text: '义乌', + id: 1004 + }], + pro2Name: '江苏', + pro2: [{ + text: '无锡', + id: 1011 + }, { + text: '常州', + id: 1012 + }, { + text: '莆田', + id: 1013 + }, { + text: '三明', + id: 1014 + }] +}; diff --git a/example/pages/tree-select/index.js b/example/pages/tree-select/index.js new file mode 100644 index 00000000..cecd3afc --- /dev/null +++ b/example/pages/tree-select/index.js @@ -0,0 +1,38 @@ +const config = require('./config'); + +Page({ + data: { + items: [ + { + // 导航名称 + text: '所有城市', + // 该导航下所有的可选项 + children: [ ...config.pro1, ...config.pro2 ] + }, { + // 导航名称 + text: config.pro1Name, + // 该导航下所有的可选项 + children: config.pro1 + }, { + text: config.pro2Name, + children: config.pro2 + } + ], + + mainActiveIndex: 0, + + activeId: 1002 + }, + + handleNavClick({ detail = {} }) { + this.setData({ + mainActiveIndex: detail.index || 0 + }); + }, + + handleItemClick({ detail = {} }) { + this.setData({ + activeId: detail.id + }); + } +}); diff --git a/example/pages/tree-select/index.json b/example/pages/tree-select/index.json new file mode 100644 index 00000000..85e7ee6a --- /dev/null +++ b/example/pages/tree-select/index.json @@ -0,0 +1,7 @@ +{ + "navigationBarTitleText": "Tree Select 分类选择", + "usingComponents": { + "zan-tree-select": "../../dist/tree-select/index", + "doc-page": "../../components/doc-page/index" + } +} diff --git a/example/pages/tree-select/index.wxml b/example/pages/tree-select/index.wxml new file mode 100644 index 00000000..3cb111c0 --- /dev/null +++ b/example/pages/tree-select/index.wxml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/packages/tree-select/README.md b/packages/tree-select/README.md new file mode 100644 index 00000000..281fbac6 --- /dev/null +++ b/packages/tree-select/README.md @@ -0,0 +1,87 @@ +## TreeSelect 分类选择 + +### 使用指南 +在 index.json 中引入组件 +```json +{ + "usingComponents": { + "zan-tree-select": "path/to/zanui-weapp/dist/tree-select/index" + } +} +``` + +### 代码演示 +可以在任意位置上使用 zan-tree-select 标签。传入对应的数据即可。 +```html + +``` +```javascript +Page({ + data: { + // ... + }, + + handleNavClick({ detail = {} }) { + this.setData({ + mainActiveIndex: detail.index || 0 + }); + }, + + handleItemClick({ detail = {} }) { + this.setData({ + activeId: detail.id + }); + } +}); +``` + +### API + +| 参数 | 说明 | 类型 | 默认值 | 必须 | +|-----------|-----------|-----------|-------------|-------------| +| items | 分类显示所需的数据,具体数据结构可看 数据结构 | Array | [] | | +| main-active-index | 左侧导航高亮的索引 | Number | 0 | | +| active-id | 右侧选择项,高亮的数据id | String | Number | 0 | | + +### Event + +| 事件名称 | 说明 | 回调参数 | +|-----------|-----------|-----------| +| navclick | 左侧导航点击时,触发的事件 | index:被点击的导航的索引 | +| itemclick | 右侧选择项被点击时,会触发的事件 | data: 该点击项的数据 | + +### 数据格式 +#### items 分类显示所需数据的数据结构 +`items` 整体为一个数组,数组内包含一系列描述分类的 object。 + +每个分类里,text表示当前分类的名称。children 表示分类里的可选项,为数组结构,id被用来唯一标识每个选项 + +```javascript +[ + { + // 导航名称 + text: '所有城市', + // 该导航下所有的可选项 + children: [ + { + // 可选项的名称 + text: '温州', + // 可选项的id,高亮的时候是根据id是否和选中的id是否相同进行判断的 + id: 1002 + }, + { + // 可选项的名称 + text: '杭州', + // 可选项的id,高亮的时候是根据id是否和选中的id是否相同进行判断的 + id: 1001 + } + ] + } +] +``` diff --git a/packages/tree-select/index.js b/packages/tree-select/index.js new file mode 100644 index 00000000..c63bbc9b --- /dev/null +++ b/packages/tree-select/index.js @@ -0,0 +1,73 @@ +const ITEM_HEIGHT = 44; + +Component({ + properties: { + items: { + type: Array, + observer() { + this.updateSubItems(); + this.updateMainHeight(); + } + }, + mainActiveIndex: { + type: Number, + value: 0, + observer() { + this.updateSubItems(); + } + }, + activeId: { + type: Number, + value: 0 + }, + maxHeight: { + type: Number, + value: 300, + observer() { + this.updateItemHeight(); + this.updateMainHeight(); + } + } + }, + + data: { + subItems: [], + mainHeight: 0, + itemHeight: 0 + }, + + methods: { + // 当一个子项被选择时 + onItemSelect({ currentTarget = {} }) { + const { dataset: data = {} } = currentTarget; + this.triggerEvent('itemclick', { ...(data.item || {}) }); + }, + + // 当一个导航被点击时 + handleNavClick({ currentTarget = {} }) { + const { dataset: data = {} } = currentTarget; + this.triggerEvent('navclick', { index: data.index }); + }, + + // 更新子项列表 + updateSubItems() { + const selectedItem = this.data.items[this.data.mainActiveIndex] || {}; + + this.setData({ subItems: selectedItem.children || [] }); + + this.updateItemHeight(); + }, + + // 更新组件整体高度,根据最大高度和当前组件需要展示的高度来决定 + updateMainHeight() { + const maxHeight = Math.max(this.data.items.length * ITEM_HEIGHT, this.data.subItems.length * ITEM_HEIGHT); + + this.setData({ mainHeight: Math.min(maxHeight, this.data.maxHeight) }) + }, + + // 更新子项列表高度,根据可展示的最大高度和当前子项列表的高度决定 + updateItemHeight() { + this.setData({ itemHeight: Math.min(this.data.subItems.length * ITEM_HEIGHT, this.data.maxHeight) }); + } + } +}); diff --git a/packages/tree-select/index.json b/packages/tree-select/index.json new file mode 100644 index 00000000..fc0d0bf9 --- /dev/null +++ b/packages/tree-select/index.json @@ -0,0 +1,6 @@ +{ + "component": true, + "usingComponents": { + "zan-icon": "../icon/index" + } +} diff --git a/packages/tree-select/index.pcss b/packages/tree-select/index.pcss new file mode 100644 index 00000000..3618d2ba --- /dev/null +++ b/packages/tree-select/index.pcss @@ -0,0 +1,55 @@ +@import "../helper/index.pcss"; + +.tree-select { + user-select: none; + position: relative; + font-size: 16px; + + &__nav { + width: 143px; + position: absolute; + left: 0; + top: 0; + bottom: 0; + overflow: scroll; + background-color: #fff; + -webkit-overflow-scrolling: touch; + } + + &__nitem { + line-height: 44px; + padding: 0 15px; + background-color: #fff; + + &--active { + background-color: #f8f8f8; + } + } + + &__content { + padding: 0 15px; + margin-left: 143px; + overflow: scroll; + -webkit-overflow-scrolling: touch; + } + + &__item { + position: relative; + line-height: 44px; + padding-left: 5px; + padding-right: 18px; + + &--active { + color: #f44; + } + } + + &__selected { + float: right; + position: absolute; + right: 0; + top: 0; + bottom: 0; + line-height: inherit; + } +} diff --git a/packages/tree-select/index.wxml b/packages/tree-select/index.wxml new file mode 100644 index 00000000..caa6d584 --- /dev/null +++ b/packages/tree-select/index.wxml @@ -0,0 +1,34 @@ + + + + {{ item.text }} + + + + + {{ item.text }} + + + +