2026-01-29 11:12:19 +08:00
|
|
|
|
# JoyD Vue3 CubeLib 组件库
|
|
|
|
|
|
|
|
|
|
|
|
## 简介
|
|
|
|
|
|
|
|
|
|
|
|
JoyD Vue3 CubeLib 是一个基于 Vue 3 开发的组件库,提供了一系列可复用的 UI 组件,旨在简化 Web 应用程序的开发流程。
|
|
|
|
|
|
|
|
|
|
|
|
## 特性
|
|
|
|
|
|
|
|
|
|
|
|
- 基于 Vue 3 构建
|
|
|
|
|
|
- TypeScript 支持
|
|
|
|
|
|
- 模块化设计
|
|
|
|
|
|
- 易于定制和扩展
|
|
|
|
|
|
- 丰富的组件库
|
|
|
|
|
|
|
|
|
|
|
|
## 安装
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
npm install joyd.web.vue.cubelib
|
|
|
|
|
|
# 或者
|
|
|
|
|
|
yarn add joyd.web.vue.cubelib
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 使用
|
|
|
|
|
|
|
2026-01-29 16:29:09 +08:00
|
|
|
|
### 全局注册
|
2026-01-29 11:12:19 +08:00
|
|
|
|
|
2026-01-29 16:29:09 +08:00
|
|
|
|
```javascript
|
|
|
|
|
|
import { createApp } from 'vue'
|
|
|
|
|
|
import App from './App.vue'
|
|
|
|
|
|
import CubeLib from 'joyd.web.vue.cubelib'
|
|
|
|
|
|
|
|
|
|
|
|
const app = createApp(App)
|
|
|
|
|
|
app.use(CubeLib)
|
|
|
|
|
|
app.mount('#app')
|
2026-01-29 11:12:19 +08:00
|
|
|
|
```
|
|
|
|
|
|
|
2026-01-29 16:29:09 +08:00
|
|
|
|
### 按需导入
|
2026-01-29 11:12:19 +08:00
|
|
|
|
|
2026-01-29 16:29:09 +08:00
|
|
|
|
```javascript
|
2026-01-29 16:50:40 +08:00
|
|
|
|
import { CubeSplitter } from 'joyd.web.vue.cubelib'
|
2026-01-29 16:29:09 +08:00
|
|
|
|
|
|
|
|
|
|
// 在组件中使用
|
|
|
|
|
|
export default {
|
|
|
|
|
|
components: {
|
|
|
|
|
|
CubeSplitter
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 组件文档
|
|
|
|
|
|
|
|
|
|
|
|
### CubeSplitter
|
|
|
|
|
|
|
|
|
|
|
|
可调整大小的分隔条组件,用于在布局中创建可调整大小的面板。
|
|
|
|
|
|
|
|
|
|
|
|
#### Props
|
|
|
|
|
|
|
|
|
|
|
|
- `direction`: 分隔条方向,可选值:`vertical` (垂直), `horizontal` (水平)
|
|
|
|
|
|
- `position`: 分隔条位置,可选值:`left`, `right`, `top`, `bottom`
|
|
|
|
|
|
- `initialSize`: 初始尺寸
|
|
|
|
|
|
- `minSize`: 最小尺寸
|
|
|
|
|
|
- `maxSize`: 最大尺寸
|
|
|
|
|
|
|
|
|
|
|
|
#### Events
|
|
|
|
|
|
|
|
|
|
|
|
- `resize`: 调整大小时触发
|
|
|
|
|
|
- `resizeEnd`: 调整大小结束时触发
|
|
|
|
|
|
- `collapse`: 折叠面板时触发
|
|
|
|
|
|
- `expand`: 展开面板时触发
|
|
|
|
|
|
|
|
|
|
|
|
#### 使用示例
|
|
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="container">
|
|
|
|
|
|
<div class="left-panel" :style="{ width: leftPanelWidth + 'px' }"></div>
|
|
|
|
|
|
<CubeSplitter
|
|
|
|
|
|
direction="vertical"
|
|
|
|
|
|
position="left"
|
|
|
|
|
|
:min-size="50"
|
|
|
|
|
|
:max-size="500"
|
|
|
|
|
|
:initial-size="200"
|
|
|
|
|
|
@resize="onLeftResize"
|
|
|
|
|
|
@resize-end="onLeftResizeEnd"
|
|
|
|
|
|
@collapse="onLeftCollapse"
|
|
|
|
|
|
@expand="onLeftExpand"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div class="middle-panel"></div>
|
|
|
|
|
|
<CubeSplitter
|
|
|
|
|
|
direction="vertical"
|
|
|
|
|
|
position="right"
|
|
|
|
|
|
:min-size="0"
|
|
|
|
|
|
:max-size="500"
|
|
|
|
|
|
:initial-size="200"
|
|
|
|
|
|
@resize="onRightResize"
|
|
|
|
|
|
@resize-end="onRightResizeEnd"
|
|
|
|
|
|
@collapse="onRightCollapse"
|
|
|
|
|
|
@expand="onRightExpand"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div class="right-panel" :style="{ width: rightPanelWidth + 'px' }"></div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { ref, onMounted } from 'vue'
|
|
|
|
|
|
|
|
|
|
|
|
const leftPanelWidth = ref(200)
|
|
|
|
|
|
const rightPanelWidth = ref(200)
|
|
|
|
|
|
|
|
|
|
|
|
// 从 localStorage 加载保存的尺寸
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
|
|
const savedLeftWidth = localStorage.getItem('leftPanelWidth')
|
2026-01-30 15:38:48 +08:00
|
|
|
|
const savedRightWidth = localStorage.getItem('rightPanelWidth')
|
2026-01-29 16:29:09 +08:00
|
|
|
|
if (savedLeftWidth) {
|
|
|
|
|
|
leftPanelWidth.value = parseInt(savedLeftWidth)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (savedRightWidth) {
|
|
|
|
|
|
rightPanelWidth.value = parseInt(savedRightWidth)
|
|
|
|
|
|
}
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
// 左侧分隔条调整
|
|
|
|
|
|
const onLeftResize = (newWidth) => {
|
|
|
|
|
|
leftPanelWidth.value = newWidth
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onLeftResizeEnd = (finalWidth) => {
|
|
|
|
|
|
// 只保存正常尺寸,不保存折叠状态
|
|
|
|
|
|
if (finalWidth > 50) {
|
|
|
|
|
|
localStorage.setItem('leftPanelWidth', finalWidth.toString())
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onLeftCollapse = (newSize) => {
|
|
|
|
|
|
leftPanelWidth.value = newSize
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onLeftExpand = (newSize) => {
|
|
|
|
|
|
leftPanelWidth.value = newSize
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 右侧分隔条调整
|
|
|
|
|
|
const onRightResize = (newWidth) => {
|
|
|
|
|
|
rightPanelWidth.value = newWidth
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onRightResizeEnd = (finalWidth) => {
|
|
|
|
|
|
// 只保存正常尺寸,不保存折叠状态
|
|
|
|
|
|
if (finalWidth > 0) {
|
|
|
|
|
|
localStorage.setItem('rightPanelWidth', finalWidth.toString())
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onRightCollapse = (newSize) => {
|
|
|
|
|
|
rightPanelWidth.value = newSize
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const onRightExpand = (newSize) => {
|
|
|
|
|
|
rightPanelWidth.value = newSize
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.container {
|
|
|
|
|
|
display: flex;
|
|
|
|
|
|
width: 100%;
|
|
|
|
|
|
height: 100vh;
|
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.left-panel {
|
|
|
|
|
|
background-color: #f0f0f0;
|
|
|
|
|
|
min-width: 50px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.middle-panel {
|
|
|
|
|
|
flex: 1;
|
|
|
|
|
|
background-color: #ffffff;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.right-panel {
|
|
|
|
|
|
background-color: #f0f0f0;
|
|
|
|
|
|
min-width: 0;
|
|
|
|
|
|
border-left: 1px solid #e0e0e0;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### CSS 变量
|
|
|
|
|
|
|
|
|
|
|
|
CubeSplitter 组件支持通过 CSS 变量进行定制:
|
|
|
|
|
|
|
|
|
|
|
|
```css
|
|
|
|
|
|
:root {
|
|
|
|
|
|
--cube-splitter-color: #e0e0e0;
|
|
|
|
|
|
--cube-splitter-hover-color: #667eea;
|
|
|
|
|
|
--cube-splitter-active-color: #5568d3;
|
|
|
|
|
|
--cube-splitter-handle-color: #fff;
|
|
|
|
|
|
--cube-splitter-handle-shadow: 0 0 4px rgba(0, 0, 0, 0.2);
|
|
|
|
|
|
--cube-splitter-collapsing-color: #667eea;
|
|
|
|
|
|
--cube-splitter-collapsing-shadow: 0 0 10px rgba(102, 126, 234, 0.5);
|
|
|
|
|
|
--cube-splitter-transition-speed: 0.3s;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-01-30 15:38:48 +08:00
|
|
|
|
### CubeWebSocket
|
|
|
|
|
|
|
|
|
|
|
|
一个功能完善的 WebSocket 组件,支持自动连接、重连、消息队列、心跳机制等功能。
|
|
|
|
|
|
|
|
|
|
|
|
#### Props
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 说明 | 类型 | 默认值 |
|
|
|
|
|
|
|------|------|------|---------|
|
|
|
|
|
|
| wsUrl | WebSocket 服务器地址 | String | '' |
|
|
|
|
|
|
| autoConnect | 是否自动连接 | Boolean | true |
|
|
|
|
|
|
| reconnect | 是否自动重连 | Boolean | true |
|
|
|
|
|
|
| maxReconnectDelay | 最大重连延迟(毫秒) | Number | 30000 |
|
|
|
|
|
|
| debugMode | 是否开启调试模式 | Boolean | false |
|
|
|
|
|
|
| heartbeatInterval | 心跳间隔(毫秒) | Number | 30000 |
|
|
|
|
|
|
| connectTimeout | 连接超时(毫秒) | Number | 10000 |
|
|
|
|
|
|
| maxQueueSize | 消息队列最大长度 | Number | 100 |
|
|
|
|
|
|
|
|
|
|
|
|
#### Events
|
|
|
|
|
|
|
|
|
|
|
|
| 事件名 | 说明 | 参数 |
|
|
|
|
|
|
|--------|------|------|
|
|
|
|
|
|
| connected | 连接成功 | - |
|
|
|
|
|
|
| disconnected | 连接断开 | (code, reason) |
|
|
|
|
|
|
| error | 连接错误 | error |
|
|
|
|
|
|
| message | 收到消息 | message |
|
|
|
|
|
|
| status-changed | 状态变化 | status |
|
|
|
|
|
|
| connecting | 开始连接 | - |
|
|
|
|
|
|
| reconnecting | 开始重连 | - |
|
|
|
|
|
|
| message-sent | 消息已发送 | message |
|
|
|
|
|
|
| message-queued | 消息已加入队列 | message |
|
|
|
|
|
|
| message-failed | 消息发送失败 | { message, reason, error? } |
|
|
|
|
|
|
|
|
|
|
|
|
#### Methods
|
|
|
|
|
|
|
|
|
|
|
|
| 方法名 | 说明 | 参数 | 返回值 |
|
|
|
|
|
|
|--------|------|------|--------|
|
|
|
|
|
|
| connect | 连接 WebSocket | - | void |
|
|
|
|
|
|
| disconnect | 断开连接 | - | void |
|
|
|
|
|
|
| send | 发送消息 | (type, data) | void |
|
|
|
|
|
|
| reconnect | 手动触发重连 | - | void |
|
|
|
|
|
|
| getStatus | 获取当前状态 | - | string |
|
|
|
|
|
|
| isConnected | 是否已连接 | - | boolean |
|
|
|
|
|
|
| getQueueSize | 获取队列长度 | - | number |
|
|
|
|
|
|
|
|
|
|
|
|
#### 使用示例
|
|
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div>状态: {{ status }}</div>
|
|
|
|
|
|
<div>消息数量: {{ messages.length }}</div>
|
|
|
|
|
|
<CubeWebSocket
|
|
|
|
|
|
ws-url="ws://localhost:8086/ws"
|
|
|
|
|
|
:auto-connect="true"
|
|
|
|
|
|
:reconnect="true"
|
|
|
|
|
|
:debug-mode="true"
|
|
|
|
|
|
@connected="handleConnected"
|
|
|
|
|
|
@disconnected="handleDisconnected"
|
|
|
|
|
|
@message="handleMessage"
|
|
|
|
|
|
@status-changed="handleStatusChanged"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { ref } from 'vue'
|
|
|
|
|
|
import CubeWebSocket from 'joyd.web.vue.cubelib'
|
|
|
|
|
|
|
|
|
|
|
|
const status = ref('disconnected')
|
|
|
|
|
|
const messages = ref([])
|
|
|
|
|
|
|
|
|
|
|
|
const handleConnected = () => {
|
|
|
|
|
|
console.log('WebSocket 已连接')
|
|
|
|
|
|
status.value = 'connected'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleDisconnected = (code, reason) => {
|
|
|
|
|
|
console.log('WebSocket 已断开:', code, reason)
|
|
|
|
|
|
status.value = 'disconnected'
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleMessage = (message) => {
|
|
|
|
|
|
console.log('收到消息:', message)
|
|
|
|
|
|
messages.value.push(message)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleStatusChanged = (newStatus) => {
|
|
|
|
|
|
console.log('状态变化:', newStatus)
|
|
|
|
|
|
status.value = newStatus
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
详细文档请查看 [CubeWebSocket.md](docs/CubeWebSocket.md)
|
|
|
|
|
|
|
|
|
|
|
|
#### 示例代码
|
|
|
|
|
|
|
|
|
|
|
|
- [基础使用示例](examples/CubeWebSocket/BasicExample.vue)
|
|
|
|
|
|
- [自动重连示例](examples/CubeWebSocket/AutoReconnectExample.vue)
|
|
|
|
|
|
- [消息队列示例](examples/CubeWebSocket/MessageQueueExample.vue)
|
|
|
|
|
|
|
2026-02-02 13:46:36 +08:00
|
|
|
|
### CubeTreeView
|
|
|
|
|
|
|
|
|
|
|
|
树形视图组件,用于展示层级数据结构,支持展开/折叠、键盘导航、自定义样式等功能。
|
|
|
|
|
|
|
|
|
|
|
|
#### Props
|
|
|
|
|
|
|
|
|
|
|
|
| 参数 | 说明 | 类型 | 默认值 |
|
|
|
|
|
|
|------|------|------|---------|
|
|
|
|
|
|
| data | 树形数据数组 | Array | [] |
|
|
|
|
|
|
| selectedId | 当前选中的节点ID | String | '' |
|
|
|
|
|
|
| config | 组件配置对象 | Object | 见下方配置说明 |
|
|
|
|
|
|
| iconMap | 自定义图标映射 | Object | - |
|
|
|
|
|
|
|
|
|
|
|
|
#### Config 配置对象
|
|
|
|
|
|
|
|
|
|
|
|
| 配置项 | 说明 | 类型 | 默认值 |
|
|
|
|
|
|
|--------|------|------|---------|
|
|
|
|
|
|
| defaultExpandAll | 是否默认展开所有节点 | Boolean | false |
|
|
|
|
|
|
| showExpandIcon | 是否显示展开/折叠图标 | Boolean | true |
|
|
|
|
|
|
| indentSize | 缩进大小(像素) | Number | 16 |
|
|
|
|
|
|
| expandable | 是否允许展开/折叠 | Boolean | true |
|
|
|
|
|
|
| iconType | 图标类型:'custom'、'file'、'heading' | String | 'custom' |
|
|
|
|
|
|
| showLevel | 是否显示层级前缀 | Boolean | false |
|
|
|
|
|
|
| levelPrefix | 层级前缀文本 | String | 'H' |
|
|
|
|
|
|
| levelKey | 层级字段名 | String | 'level' |
|
|
|
|
|
|
| autoExpand | 选中节点时是否自动展开路径 | Boolean | false |
|
|
|
|
|
|
| highlightPath | 是否高亮选中节点的路径 | Boolean | false |
|
|
|
|
|
|
|
|
|
|
|
|
#### Events
|
|
|
|
|
|
|
|
|
|
|
|
| 事件名 | 说明 | 参数 |
|
|
|
|
|
|
|--------|------|------|
|
|
|
|
|
|
| node-click | 节点被点击 | item |
|
|
|
|
|
|
| toggle-expand | 节点展开/折叠状态变化 | itemId |
|
|
|
|
|
|
|
|
|
|
|
|
#### Methods
|
|
|
|
|
|
|
|
|
|
|
|
| 方法名 | 说明 | 参数 | 返回值 |
|
|
|
|
|
|
|--------|------|------|--------|
|
|
|
|
|
|
| expandAll | 展开所有节点 | - | void |
|
|
|
|
|
|
| collapseAll | 折叠所有节点 | - | void |
|
|
|
|
|
|
| expandNode | 展开指定节点 | id | void |
|
|
|
|
|
|
| collapseNode | 折叠指定节点 | id | void |
|
|
|
|
|
|
| toggleNode | 切换节点展开/折叠状态 | id | void |
|
|
|
|
|
|
| expandPath | 展开到指定节点的路径 | id | void |
|
|
|
|
|
|
| collapsePath | 折叠到指定节点的路径 | id | void |
|
|
|
|
|
|
| getNodeById | 根据ID获取节点 | id | Object |
|
|
|
|
|
|
| getSelectedNode | 获取当前选中的节点 | - | Object |
|
|
|
|
|
|
| selectNode | 选中指定节点 | id | void |
|
|
|
|
|
|
|
|
|
|
|
|
#### Slots
|
|
|
|
|
|
|
|
|
|
|
|
| 插槽名 | 说明 | 作用域参数 |
|
|
|
|
|
|
|--------|------|-----------|
|
|
|
|
|
|
| icon | 自定义节点图标 | { item } |
|
|
|
|
|
|
| title | 自定义节点标题 | { item } |
|
|
|
|
|
|
| prefix | 自定义节点前缀 | { item } |
|
|
|
|
|
|
| suffix | 自定义节点后缀 | { item } |
|
|
|
|
|
|
|
|
|
|
|
|
#### 使用示例
|
|
|
|
|
|
|
|
|
|
|
|
```vue
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<div class="tree-container">
|
|
|
|
|
|
<CubeTreeView
|
|
|
|
|
|
ref="treeViewRef"
|
|
|
|
|
|
:data="treeData"
|
|
|
|
|
|
:selected-id="selectedId"
|
|
|
|
|
|
:config="treeConfig"
|
|
|
|
|
|
@node-click="handleNodeClick"
|
|
|
|
|
|
@toggle-expand="handleToggleExpand"
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #icon="{ item }">
|
|
|
|
|
|
<span class="custom-icon">{{ item.icon }}</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
<template #title="{ item }">
|
|
|
|
|
|
<span class="custom-title">{{ item.title }}</span>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</CubeTreeView>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup>
|
|
|
|
|
|
import { ref } from 'vue'
|
|
|
|
|
|
import { CubeTreeView } from 'joyd.web.vue.cubelib'
|
|
|
|
|
|
|
|
|
|
|
|
const treeViewRef = ref(null)
|
|
|
|
|
|
const selectedId = ref('')
|
|
|
|
|
|
|
|
|
|
|
|
const treeData = ref([
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '1',
|
|
|
|
|
|
title: '根节点1',
|
|
|
|
|
|
level: 1,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '1-1',
|
|
|
|
|
|
title: '子节点1-1',
|
|
|
|
|
|
level: 2,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ id: '1-1-1', title: '叶子节点1-1-1', level: 3 },
|
|
|
|
|
|
{ id: '1-1-2', title: '叶子节点1-1-2', level: 3 }
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '1-2',
|
|
|
|
|
|
title: '子节点1-2',
|
|
|
|
|
|
level: 2,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ id: '1-2-1', title: '叶子节点1-2-1', level: 3 }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
id: '2',
|
|
|
|
|
|
title: '根节点2',
|
|
|
|
|
|
level: 1,
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ id: '2-1', title: '子节点2-1', level: 2 }
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
])
|
|
|
|
|
|
|
|
|
|
|
|
const treeConfig = {
|
|
|
|
|
|
defaultExpandAll: false,
|
|
|
|
|
|
showExpandIcon: true,
|
|
|
|
|
|
indentSize: 16,
|
|
|
|
|
|
expandable: true,
|
|
|
|
|
|
iconType: 'custom',
|
|
|
|
|
|
showLevel: false,
|
|
|
|
|
|
autoExpand: true,
|
|
|
|
|
|
highlightPath: true
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleNodeClick = (item) => {
|
|
|
|
|
|
console.log('节点被点击:', item)
|
|
|
|
|
|
selectedId.value = item.id
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const handleToggleExpand = (itemId) => {
|
|
|
|
|
|
console.log('节点展开/折叠:', itemId)
|
|
|
|
|
|
}
|
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
|
|
.tree-container {
|
|
|
|
|
|
width: 300px;
|
|
|
|
|
|
padding: 16px;
|
|
|
|
|
|
border: 1px solid #e0e0e0;
|
|
|
|
|
|
border-radius: 4px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.custom-icon {
|
|
|
|
|
|
margin-right: 8px;
|
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
.custom-title {
|
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
|
}
|
|
|
|
|
|
</style>
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
#### 键盘导航
|
|
|
|
|
|
|
|
|
|
|
|
CubeTreeView 支持以下键盘操作:
|
|
|
|
|
|
|
|
|
|
|
|
- `↑` - 向上移动选择
|
|
|
|
|
|
- `↓` - 向下移动选择
|
|
|
|
|
|
- `←` - 折叠当前节点或选择父节点
|
|
|
|
|
|
- `→` - 展开当前节点或选择第一个子节点
|
|
|
|
|
|
- `Enter` / `Space` - 触发节点点击事件
|
|
|
|
|
|
|
|
|
|
|
|
#### CSS 变量
|
|
|
|
|
|
|
|
|
|
|
|
CubeTreeView 组件支持通过 CSS 变量进行定制:
|
|
|
|
|
|
|
|
|
|
|
|
```css
|
|
|
|
|
|
:root {
|
|
|
|
|
|
--cube-tree-item-hover-bg: rgba(0, 0, 0, 0.05);
|
|
|
|
|
|
--cube-tree-item-selected-bg: #1890ff;
|
|
|
|
|
|
--cube-tree-item-selected-color: #ffffff;
|
|
|
|
|
|
--cube-tree-item-path-bg: rgba(24, 144, 255, 0.1);
|
|
|
|
|
|
--cube-tree-item-icon-color: rgba(0, 0, 0, 0.45);
|
|
|
|
|
|
--cube-tree-item-level-color: rgba(0, 0, 0, 0.45);
|
|
|
|
|
|
--cube-tree-item-title-color: inherit;
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
2026-01-29 16:29:09 +08:00
|
|
|
|
## 常见问题解答
|
|
|
|
|
|
|
|
|
|
|
|
### Q: 如何保存分隔条的位置?
|
|
|
|
|
|
|
|
|
|
|
|
A: 可以使用 `@resize-end` 事件来保存最终的尺寸到 localStorage 或其他存储中,然后在组件挂载时从存储中加载。
|
|
|
|
|
|
|
|
|
|
|
|
### Q: 如何在最小尺寸和当前尺寸之间切换?
|
|
|
|
|
|
|
|
|
|
|
|
A: 单击分隔条的句柄即可在最小尺寸和当前尺寸之间切换。
|
|
|
|
|
|
|
|
|
|
|
|
### Q: 为什么右侧分隔条的拖拽方向与左侧不同?
|
|
|
|
|
|
|
|
|
|
|
|
A: CubeSplitter 组件统一了拖拽方向逻辑:向左/上拖动减小尺寸,向右/下拖动增大尺寸,无论分隔条位置是左还是右。
|
2026-01-29 11:12:19 +08:00
|
|
|
|
|
|
|
|
|
|
## 贡献
|
|
|
|
|
|
|
|
|
|
|
|
我们欢迎社区贡献!请阅读 [贡献指南](CONTRIBUTING.md) 了解如何参与。
|
|
|
|
|
|
|
|
|
|
|
|
## 许可证
|
|
|
|
|
|
|
|
|
|
|
|
MIT License
|
|
|
|
|
|
|
|
|
|
|
|
## 联系我们
|
|
|
|
|
|
|
|
|
|
|
|
- 邮箱:support@joyd.com
|
|
|
|
|
|
- 网站:https://www.joyd.com
|
|
|
|
|
|
|
|
|
|
|
|
## 版本历史
|
|
|
|
|
|
|
|
|
|
|
|
请查看 [CHANGELOG.md](CHANGELOG.md) 了解版本更新历史。
|