diff --git a/README.md b/README.md index 37f933a..63aefa5 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,43 @@ # building-table-vue -基于vue2的楼盘表组件,以二维表图形方式显示栋楼的 `逻辑区`、`单元`、`楼层`、`房屋` 信息 +基于 vue2 的楼盘表组件,以二维表图形方式显示栋楼的 `逻辑区`、`单元`、`楼层`、`房屋` 信息 ## 楼盘表基础用法 基础的楼盘表展示用法。 -``` html +```html ``` @@ -48,81 +48,83 @@ export default { 1、通过属性修改房屋单元格的显示 -``` html +```html - + ``` 2、通过自定义模板完全控制房屋单元格的显示 -``` html +```html - - - - + + + + ``` -房屋单元格的事件处理在模板外层的td,所以自定义模板不需要处理鼠标事件,仅仅控制显示, -样式可参考代码 `style/house.scss` 。 +房屋单元格的事件处理在模板外层的 td,所以自定义模板不需要处理鼠标事件,仅仅控制显示, +样式可参考代码 `style/house.scss` 。 单元格状态控制: - - 单元格被选中时外层td会增加 `td-selected` 样式 - - 单元格定位高亮时外层td会增加 `td-highlight` 样式 + +- 单元格被选中时外层 td 会增加 `td-selected` 样式 +- 单元格定位高亮时外层 td 会增加 `td-highlight` 样式 为了不处理这些状态,可以在自定义模板根元素上增加样式 `house-display-wrap` @@ -140,40 +142,40 @@ export default { 楼盘表单元固定,仅房屋、楼层区域才会滚动,所以需要设置高度,默认值为 `600px` -``` html - - +```html + ``` -## BuildingTable 组件说明 - -### BuildingTable属性 - -| 参数 | 说明 | 类型 | 默认值 | 可选值 | -| ------------- | ----------------------------------------------- | ------- | ---------- | ------------------------------- | -| className | 楼盘表自定义样式类名 | String | '' | | -| tableStyle | 楼盘表自定义样式 | Object | | | -| height | 楼盘表高度 | Number | 600 | | -| buildingData | 楼盘表数据 | Object | | | -| logicBuildId | 当前逻辑幢ID,为空时加载第一个逻辑幢 | String | '' | | -| selectionMode | 楼盘表选择模式,优先级低于buildingData的useMode | String | '' | "single", "multiple", "disable" | -| showLegends | 是否显示图例 | Boolean | true | | -| tipText | 提示信息 | String | '暂无数据' | | - -### BuildingTable方法 -| 方法 | 说明 | 参数 | -| ---------------- | ---------------------------------------------------------------------- | -------- | -| setData | 设置楼盘表数据源,同属性buildingData | Object | -| getSelections | 获取楼盘表选择的房屋(onlyId为true时仅返回房屋ID集合,否则返回房屋集合) | onlyId | -| changeLogicBuild | 切换逻辑幢(logicId:逻辑幢ID),同属性logicBuildId | logicId | -| addSelections | 增加房屋选择(houseIds:房屋ID集合) | houseIds | -| removeSelections | 移除房屋选择(houseIds:房屋ID集合) | houseIds | -| clearSelection | 移除房屋选择(houseIds:房屋ID集合) | | +## BuildingTable 组件说明 -### BuildingTable事件 +### BuildingTable 属性 + +| 参数 | 说明 | 类型 | 默认值 | 可选值 | +| ------------- | ----------------------------------------------------------- | ------- | ---------- | ----------------------------------- | +| className | 楼盘表自定义样式类名 | String | '' | | +| tableStyle | 楼盘表自定义样式 | Object | | | +| height | 楼盘表高度 | Number | 600 | | +| buildingData | 楼盘表数据 | Object | | | +| logicBuildId | 当前逻辑幢 ID,为空时加载第一个逻辑幢 | String | '' | | +| selectionMode | 楼盘表选择模式,优先级低于 buildingData 的 useMode | String | '' | "single", "multiple", "disable" | +| showTitle | 是否显示标题 | Boolean | false | | +| showLegends | 是否显示图例 | Boolean | true | | +| tools | 内置工具栏,可以是["locate", "select", "switchLogic"]的组合 | Array | 全部工具 | ["locate", "select", "switchLogic"] | +| tipText | 提示信息 | String | '暂无数据' | | + +### BuildingTable 方法 + +| 方法 | 说明 | 参数 | +| ---------------- | --------------------------------------------------------------------------- | ----------- | +| setData | 设置楼盘表数据源,同属性 buildingData | Object | +| getSelections | 获取楼盘表选择的房屋(onlyId 为 true 时仅返回房屋 ID 集合,否则返回房屋集合) | onlyId | +| changeLogicBuild | 切换逻辑幢(logicId:逻辑幢 ID),同属性 logicBuildId | logicId | +| addSelections | 增加房屋选择(houseIds:房屋 ID 集合) | houseIds | +| removeSelections | 移除房屋选择(houseIds:房屋 ID 集合) | houseIds | +| clearSelection | 移除房屋选择(houseIds:房屋 ID 集合) | | +| selectAll | 全选所有房屋(onlyEnabled 为 true,isEnabled 为 false 的房屋不会被选中) | onlyEnabled | + +### BuildingTable 事件 | 事件名 | 说明 | 参数 | | ------------------ | -------------------------- | ---------------------------- | @@ -185,21 +187,20 @@ export default { | house-contextmenu | 房屋单元格鼠标右键菜单事件 | house,MouseEvent | | logic-build-change | 逻辑幢改变事件 | logicBuildId | | select-change | 房屋单元格选择改变事件 | Array\ | -| floor-checked | 楼层checkbox点击事件 | floorInfo, unitInfo, checked | -| unit-checked | 单元checkbox点击事件 | unitInfo, checked | - -### BuildingTable插槽 +| floor-checked | 楼层 checkbox 点击事件 | floorInfo, unitInfo, checked | +| unit-checked | 单元 checkbox 点击事件 | unitInfo, checked | -| 插槽名 | 说明 | -| ----------- | ----------------------------------------------------------------- | -| default | 用来放置 UnitDefinition,FloorDefinition,HouseDefinition自定义模板 | -| headerLeft | 标题栏左侧工具栏 | -| headerRight | 标题栏右侧工具栏 | +### BuildingTable 插槽 +| 插槽名 | 说明 | +| ----------- | ------------------------------------------------------------------ | +| default | 用来放置 UnitDefinition,FloorDefinition,HouseDefinition 自定义模板 | +| headerLeft | 标题栏左侧工具栏 | +| headerRight | 标题栏右侧工具栏 | ## UnitDefinition 组件说明 -### UnitDefinition属性 +### UnitDefinition 属性 | 参数 | 说明 | 类型 | 默认值 | 可选值 | | ---------- | -------------------- | ------- | ---------- | ------ | @@ -211,19 +212,18 @@ export default { ### UnitDefinition scope 参数 -使用 `slot-scope template` 自定义模板时传入的 `scope` 参数 - -| 参数 | 说明 | 类型 | -| ------------ | ---------------------------------------------------- | ------ | -| definition | 单元配置信息,即UnitDefinition组件定义的属性,见上表 | Object | -| logicBuildId | 逻辑幢ID | String | -| unitInfo | 单元信息 | Object | -| store | 楼盘表内部使用的store对象 | Object | +使用 `slot-scope template` 自定义模板时传入的 `scope` 参数 +| 参数 | 说明 | 类型 | +| ------------ | ------------------------------------------------------ | ------ | +| definition | 单元配置信息,即 UnitDefinition 组件定义的属性,见上表 | Object | +| logicBuildId | 逻辑幢 ID | String | +| unitInfo | 单元信息 | Object | +| store | 楼盘表内部使用的 store 对象 | Object | ## FloorDefinition 组件说明 -### FloorDefinition属性 +### FloorDefinition 属性 | 参数 | 说明 | 类型 | 默认值 | 可选值 | | ---------- | -------------------- | ------- | ------- | ------ | @@ -235,41 +235,61 @@ export default { ### FloorDefinition scope 参数 -使用 `slot-scope template` 自定义模板时传入的 `scope` 参数 - -| 参数 | 说明 | 类型 | -| ------------ | ----------------------------------------------------- | ------ | -| definition | 楼层配置信息,即FloorDefinition组件定义的属性,见上表 | Object | -| logicBuildId | 逻辑幢ID | String | -| floorInfo | 楼层信息 | Object | -| unitInfo | 单元信息 | Object | -| store | 楼盘表内部使用的store对象 | Object | +使用 `slot-scope template` 自定义模板时传入的 `scope` 参数 +| 参数 | 说明 | 类型 | +| ------------ | ------------------------------------------------------- | ------ | +| definition | 楼层配置信息,即 FloorDefinition 组件定义的属性,见上表 | Object | +| logicBuildId | 逻辑幢 ID | String | +| floorInfo | 楼层信息 | Object | +| unitInfo | 单元信息 | Object | +| store | 楼盘表内部使用的 store 对象 | Object | ## HouseDefinition 组件说明 -### HouseDefinition属性 +### HouseDefinition 属性 -| 参数 | 说明 | 类型 | 默认值 | 可选值 | -| ------------- | ---------------------------------------- | -------------- | ------ | ------ | -| width | 房屋单元格宽度 | Number | 220 | | -| className | 房屋单元格自定义类名 | String | '' | | -| houseStyle | 房屋单元格自定义样式 | Object | | | -| showBlock | 是否显示房屋详细(blocks)信息 | Boolean | true | | -| includeFields | blocks中要显示的字段,不设置显示所有字段 | Array\ | null | | -| excludeFields | blocks中要排除的字段 | Array\ | null | | -| showSymbol | 是否显示房屋符号(symbols)信息 | Boolean | true | | -| symbolColumn | 每行显示几个房屋符号(symbol) | Number | 3 | | +| 参数 | 说明 | 类型 | 默认值 | 可选值 | +| ------------- | ----------------------------------------- | -------------- | ------ | ------ | +| width | 房屋单元格宽度 | Number | 220 | | +| className | 房屋单元格自定义类名 | String | '' | | +| houseStyle | 房屋单元格自定义样式 | Object | | | +| showBlock | 是否显示房屋详细(blocks)信息 | Boolean | true | | +| includeFields | blocks 中要显示的字段,不设置显示所有字段 | Array\ | null | | +| excludeFields | blocks 中要排除的字段 | Array\ | null | | +| showSymbol | 是否显示房屋符号(symbols)信息 | Boolean | true | | +| symbolColumn | 每行显示几个房屋符号(symbol) | Number | 3 | | +| simple | 是否以精简模式显示 | Boolean | false | | ### HouseDefinition scope 参数 -使用 `slot-scope template` 自定义模板时传入的 `scope` 参数 - -| 参数 | 说明 | 类型 | -| ------------ | ----------------------------------------------------- | ------ | -| definition | 房屋配置信息,即HouseDefinition组件定义的属性,见上表 | Object | -| logicBuildId | 逻辑幢ID | String | -| floorInfo | 楼层信息 | Object | -| unitInfo | 单元信息 | Object | -| houseInfo | 房屋信息 | Object | -| store | 楼盘表内部使用的store对象 | Object | \ No newline at end of file +使用 `slot-scope template` 自定义模板时传入的 `scope` 参数 + +| 参数 | 说明 | 类型 | +| ------------ | ------------------------------------------------------- | ------ | +| definition | 房屋配置信息,即 HouseDefinition 组件定义的属性,见上表 | Object | +| logicBuildId | 逻辑幢 ID | String | +| floorInfo | 楼层信息 | Object | +| unitInfo | 单元信息 | Object | +| houseInfo | 房屋信息 | Object | +| store | 楼盘表内部使用的 store 对象 | Object | + +## HouseTooltip 组件说明 + +用来显示房屋单元格的 tooltip,可以使用 `slot-scope template` 自定义模板,传入的 `scope` 参数为 house + +```html + + + + + +``` diff --git a/src/components/BuildingTable/BuildingHeader.vue b/src/components/BuildingTable/BuildingHeader.vue index 18aa81f..243ed7b 100644 --- a/src/components/BuildingTable/BuildingHeader.vue +++ b/src/components/BuildingTable/BuildingHeader.vue @@ -1,6 +1,7 @@ \ No newline at end of file + diff --git a/src/components/BuildingTable/BuildingTable.vue b/src/components/BuildingTable/BuildingTable.vue index aebafab..f606bf7 100644 --- a/src/components/BuildingTable/BuildingTable.vue +++ b/src/components/BuildingTable/BuildingTable.vue @@ -2,7 +2,7 @@
- +
@@ -58,11 +58,21 @@ export default { validator: (val) => ["single", "multiple", "disable"].includes(val), default: "multiple", }, + // 是否显示标题 + showTitle: { + type: Boolean, + default: false, + }, // 是否显示图例 showLegends: { type: Boolean, default: true, }, + // 楼盘表工具 + tools: { + type: Array, + default: () => ["locate", "select", "switchLogic"], + }, // 提示信息 tipText: { type: String, @@ -111,6 +121,10 @@ export default { removeSelections(houseIds) { this.store.commit("removeSelectHouses", houseIds); }, + // 全选(onlyEnabled为true,isEnabled为false的房屋不会被选中) + selectAll(onlyEnabled = true) { + this.store.commit("selectAll", onlyEnabled); + }, // 清空选择 clearSelection() { this.store.commit("clearSelect"); diff --git a/src/components/BuildingTable/HouseDefinition.vue b/src/components/BuildingTable/HouseDefinition.vue index 08216ea..bd2fa1b 100644 --- a/src/components/BuildingTable/HouseDefinition.vue +++ b/src/components/BuildingTable/HouseDefinition.vue @@ -18,6 +18,8 @@ const props = { showSymbol: Boolean, // 每行显示几个房屋符号(symbol),默认:3 symbolColumn: Number, + // 是否以精简模式显示 + simple: Boolean, }; /** @@ -34,6 +36,12 @@ export default { // 创建房屋配置定义 createHouseDefinition() { const definition = deepClone(this.$options.propsData); + // 精简模式 + if (definition.simple) { + definition.className = "simple-cell"; + definition.showBlock = false; + definition.width = 90; + } // 定义render函数,如果有自定义模板使用自定义模块,否则使用默认模板 if (this.$scopedSlots.default) { definition.render = (h, context) => { diff --git a/src/components/BuildingTable/HouseTooltip.vue b/src/components/BuildingTable/HouseTooltip.vue new file mode 100644 index 0000000..aeff07f --- /dev/null +++ b/src/components/BuildingTable/HouseTooltip.vue @@ -0,0 +1,64 @@ + + + diff --git a/src/components/BuildingTable/config/house-config.js b/src/components/BuildingTable/config/house-config.js index 2eaaa92..dc36222 100644 --- a/src/components/BuildingTable/config/house-config.js +++ b/src/components/BuildingTable/config/house-config.js @@ -20,9 +20,11 @@ const houseConfig = { showSymbol: true, // 每行显示几个房屋符号 symbolColumn: 3, + // 是否以精简模式显示 + simple: false, // 房屋单元格默认渲染函数 render: function (h, { definition, houseInfo }) { - const { className, houseStyle, showBlock, includeFields, excludeFields, showSymbol, symbolColumn } = definition + const { className, houseStyle, showBlock, includeFields, excludeFields, showSymbol, symbolColumn, simple } = definition const { houseName, blocks, symbols } = houseInfo const root = getBuildingTable(this) @@ -51,8 +53,8 @@ const houseConfig = { const items = [] if (index % symbolColumn == 0) { for (let i = index; i < Math.min(index + symbolColumn, symbols.length); i++) { - const { color, text } = symbols[i] - items.push() + const { name, value } = symbols[i] + items.push() } symbolVNodes.push(
{items}
) } @@ -60,14 +62,14 @@ const houseConfig = { return symbolVNodes } const clickTitle = (event) => { - event.stopPropagation() + !simple && event.stopPropagation() root && root.$emit('house-title-click', { house: houseInfo, event }) } return (
-

{houseName}

+

{houseName}

{renderBlock()}
diff --git a/src/components/BuildingTable/core/select-manager.js b/src/components/BuildingTable/core/select-manager.js index be92329..550e4bc 100644 --- a/src/components/BuildingTable/core/select-manager.js +++ b/src/components/BuildingTable/core/select-manager.js @@ -104,6 +104,18 @@ export default class SelectionManager { this.raiseEvent() } + // 全选 + selectAll(onlyEnabled) { + if (this.disabled) return + + this.query.queryAll().forEach(house => { + if (!onlyEnabled || (onlyEnabled && house.isEnabled)) { + this.setHouseCell(house, true) + } + }) + this.raiseEvent() + } + // 清空选择 clearSelect() { if (this.disabled) return diff --git a/src/components/BuildingTable/core/table-query.js b/src/components/BuildingTable/core/table-query.js index 45c1cd7..bfe1c3a 100644 --- a/src/components/BuildingTable/core/table-query.js +++ b/src/components/BuildingTable/core/table-query.js @@ -7,6 +7,17 @@ export default class TableQuery { this.currentLogic = null // 当前逻辑幢 } + // 查询所有房屋 + queryAll() { + const result = [] + for (const logic of this.logicBuilds) { + for (const house of logic.houses) { + result.push(house) + } + } + return result + } + // 切换逻辑幢,logicId为空时切换第一个逻辑幢 setLogicId(logicId) { if (!this.currentLogic || this.currentLogic.logicBuildId != logicId) { diff --git a/src/components/BuildingTable/index.js b/src/components/BuildingTable/index.js index 23cd461..737154f 100644 --- a/src/components/BuildingTable/index.js +++ b/src/components/BuildingTable/index.js @@ -1,6 +1,11 @@ export { default as UnitDefinition } from './UnitDefinition' export { default as FloorDefinition } from './FloorDefinition' export { default as HouseDefinition } from './HouseDefinition' +export { default as HouseTooltip } from './HouseTooltip.vue' + +export { default as SwitchLogicTool } from './tools/SwitchLogicTool' +export { default as SelectTool } from './tools/SelectTool' +export { default as LocateTool } from './tools/LocateTool' import BuildingTable from './BuildingTable' diff --git a/src/components/BuildingTable/store/selector.js b/src/components/BuildingTable/store/selector.js index 7dc9395..4215141 100644 --- a/src/components/BuildingTable/store/selector.js +++ b/src/components/BuildingTable/store/selector.js @@ -51,6 +51,10 @@ export default { removeSelectHouses(houseIds) { this._selector.selectHouseByIds(houseIds, false) }, + // 全选(onlyEnabled为true,isEnabled为false的房屋不会被选中) + selectAll(onlyEnabled) { + this._selector.selectAll(onlyEnabled) + }, // 清空选择 clearSelect() { this._selector.clearSelect() diff --git a/src/components/BuildingTable/style/house.scss b/src/components/BuildingTable/style/house.scss index 6531c07..3618602 100644 --- a/src/components/BuildingTable/style/house.scss +++ b/src/components/BuildingTable/style/house.scss @@ -51,6 +51,18 @@ position: relative; cursor: pointer; + &.simple-cell { + padding-top: 6px; + + .house-cell__block-title { + text-align: center; + text-decoration: initial; + display: block; + white-space: initial; + text-overflow: initial; + } + } + &::before { position: absolute; right: -2px; diff --git a/src/components/BuildingTable/style/index.scss b/src/components/BuildingTable/style/index.scss index 1e5f168..5fe1604 100644 --- a/src/components/BuildingTable/style/index.scss +++ b/src/components/BuildingTable/style/index.scss @@ -7,4 +7,5 @@ @import "./unit.scss"; @import "./house.scss"; @import "./legend.scss"; +@import "./tooltip.scss"; diff --git a/src/components/BuildingTable/style/table.scss b/src/components/BuildingTable/style/table.scss index 050a17f..d374cd8 100644 --- a/src/components/BuildingTable/style/table.scss +++ b/src/components/BuildingTable/style/table.scss @@ -1,4 +1,7 @@ .building-table-wrap { + position: relative; + overflow: visible; + .building-table__content { position: relative; diff --git a/src/components/BuildingTable/style/tool.scss b/src/components/BuildingTable/style/tool.scss index 954be6e..af63f24 100644 --- a/src/components/BuildingTable/style/tool.scss +++ b/src/components/BuildingTable/style/tool.scss @@ -1,21 +1,53 @@ /*tool common */ -.building-tool:not(:first-child) { - margin-left: 10px; -} - -.building-tool__button { - display: inline-block; - width: 20px; - height: 20px; +.building-tool { position: relative; - top: 5px; - margin-left: 3px; - background-size: 100% 100%; - cursor: pointer; - transition: opacity 0.25s ease; - &:hover { - opacity: 0.9; + &:not(:first-child) { + margin-left: 16px; + } + + &:not(:last-child):after { + content: " "; + position: absolute; + top: 10px; + bottom: 10px; + width: 1px; + margin-left: 6px; + background-color: #fff; + } + + .building-tool__button { + display: inline-block; + font-size: 13px; + cursor: pointer; + border: 1px solid #fff; + border-radius: 2px; + height: 24px; + line-height: 24px; + padding: 0 14px; + margin-right: 6px; + transition: all 0.25s ease; + + &:hover { + border: 2px solid #275cc4; + padding: 0 13px; + } + } + + .building-tool__icon { + display: inline-block; + width: 20px; + height: 20px; + position: relative; + top: 5px; + margin-left: 3px; + background-size: 100% 100%; + cursor: pointer; + transition: opacity 0.25s ease; + + &:hover { + opacity: 0.9; + } } } @@ -74,6 +106,21 @@ } } +/*select tool*/ +.select-tool-wrap { + cursor: pointer; + > input { + vertical-align: middle; + margin-right: 4px; + } + + > label { + vertical-align: middle; + font-size: 13px; + font-weight: normal; + } +} + /*locate tool*/ .locate-tool-wrap { .locate-tool__select { diff --git a/src/components/BuildingTable/style/tooltip.scss b/src/components/BuildingTable/style/tooltip.scss new file mode 100644 index 0000000..1804365 --- /dev/null +++ b/src/components/BuildingTable/style/tooltip.scss @@ -0,0 +1,30 @@ +.house-tooltip-wrap { + position: absolute; + top: 0; + left: 0; + padding: 8px 12px; + border-radius: 4px; + background: #fff; + box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.25); + z-index: 2000; + + > ul { + margin: 0; + padding: 0; + text-align: left; + list-style: none; + font-size: 13px; + color: #666; + line-height: 20px; + } +} + +.tooltip-enter-active, +.tooltip-leave-active { + transition: opacity 0.3s linear; +} + +.tooltip-enter, +.tooltip-leave-to { + opacity: 0; +} diff --git a/src/components/BuildingTable/tools/LocateTool.vue b/src/components/BuildingTable/tools/LocateTool.vue index 9b241cb..b1d1a49 100644 --- a/src/components/BuildingTable/tools/LocateTool.vue +++ b/src/components/BuildingTable/tools/LocateTool.vue @@ -1,22 +1,26 @@ @@ -58,4 +62,4 @@ export default { }, }, }; - \ No newline at end of file + diff --git a/src/components/BuildingTable/tools/SelectTool.vue b/src/components/BuildingTable/tools/SelectTool.vue new file mode 100644 index 0000000..2fdc0d6 --- /dev/null +++ b/src/components/BuildingTable/tools/SelectTool.vue @@ -0,0 +1,32 @@ + + + \ No newline at end of file diff --git a/src/components/BuildingTable/tools/SwitchLogicTool.vue b/src/components/BuildingTable/tools/SwitchLogicTool.vue index 7a89e52..f1cd442 100644 --- a/src/components/BuildingTable/tools/SwitchLogicTool.vue +++ b/src/components/BuildingTable/tools/SwitchLogicTool.vue @@ -1,5 +1,8 @@