53 | This is third tab
54 |
55 |
56 |
57 |
58 |
59 | ```
60 |
61 | The layout of layout components is based on a grid layout, with each segmented area forming a grid, and your custom content is embedded in the grid as a panel.
62 |
63 | The component provides some interfaces that allow you to quickly set the interface layout programmatically:
64 |
65 | ```ts
66 | const dockLayout = ref();
67 |
68 | onMounted(() => {
69 | nextTick(() => {
70 | //Set the interface layout here first
71 | //Here we have added a horizontal layout with three areas,
72 | //left/center/right, with a width ratio of 20%: 60%: 20%
73 | //Then the left region is divided into two regions: leftA/leftB, with a width of 50%: 50%
74 | dockLayout.value?.setData({
75 | name: 'root',
76 | size: 0,
77 | grids: [
78 | {
79 | size: 20,
80 | name: 'left',
81 | grids: [
82 | {
83 | size: 50,
84 | name: 'leftA',
85 | },
86 | {
87 | size: 50,
88 | name: 'leftB',
89 | },
90 | ]
91 | },
92 | {
93 | size: 60,
94 | name: 'center',
95 | //Here we set that the center area will not be
96 | //automatically removed when there is no panel
97 | alwaysVisible: true,
98 | },
99 | {
100 | size: 20,
101 | name: 'right',
102 | },
103 | ],
104 | });
105 | //The code below adds a content panel to the grid
106 | //Each content panel is identified by a key, which can be read from the
107 | //panel parameter in the panel render slot of DockLayout.
108 | dockLayout.value?.addPanels([
109 | {
110 | key: 'panel1',
111 | title: 'panel1',
112 | },
113 | {
114 | key: 'panel2',
115 | title: 'panel2',
116 | },
117 | ], 'leftA');
118 | dockLayout.value?.addPanels([
119 | {
120 | key: 'panel3',
121 | title: 'panel3',
122 | },
123 | ], 'leftB');
124 | })
125 | });
126 | ```
127 |
128 | The above examples can be found in [online Demo](https://imengyu.top/pages/vue-dock-layout-demo/). The first example in was found.
129 |
130 | Users can customize the drag and drop interface. Therefore, when the program leaves, if you need to save the user's custom settings, you can read the current grid layout data, set it to the component the next time the program loads.
131 |
132 | ```js
133 | onBeforeUnmount(() => {
134 | const layoutData = dockLayout.value?.getSaveData()
135 | //Save layoutData to anywhere...
136 |
137 | //Next time, load and set to dockLayout
138 | dockLayout.value?.setData(layoutData);
139 | })
140 | ```
141 |
142 | ### Customize
143 |
144 | #### Theme
145 |
146 | The component default provides two themes for you to use: `light` and `dark`. The theme can be specified using the `theme` attribute of the `DockLayout` component.
147 |
148 | ```html
149 |
150 | ...
151 |
152 | ```
153 |
154 | The two theme effects are shown in the following figure:
155 |
156 | |light|dark|
157 | |---|---|
158 | |||
159 |
160 | #### Custom rendering
161 |
162 | The component provides rendering slots in some locations that you can customize for rendering.
163 |
164 | For specific examples and source code, please see [online Dome](https://imengyu.top/pages/vue-dock-layout-demo/#/DockLayoutThemeTest).
165 |
166 | ##### tabItemRender
167 |
168 | Custom rendering for panel titles.
169 |
170 | ```vue
171 |
172 |
173 |
180 | {{ panel.title }}
181 |
182 |
183 |
184 | ```
185 |
186 | ##### emptyPanel
187 |
188 | This slot is used to render the backplane displayed when the grid has no content panel.
189 |
190 | ```vue
191 |
192 |
193 |
194 |
{{dockData.name}}
195 |
This grid won't be removed from layout even when last Tab is closed
196 |
197 |
198 |
199 | ```
200 |
201 | ## API reference
202 |
203 | DockLayout is the main container for layout components.
204 |
205 | ##### Props
206 |
207 | | Name | description | type | default value |
208 | | :----: | :----: | :----: | :----: |
209 | | tabHeight | The height of the Tab component, used for related calculations | `number` | 40 |
210 | | startVerticalDirection | Is the first layout grid vertical? | `boolean` | `false` |
211 | | allowFloatWindow | Allow floating windows? | `boolean` | `false` |
212 | | theme | Theme, can be 'light' or 'dark' | `string` | `dark` |
213 |
214 | ##### Events
215 |
216 | | Name | description | params |
217 | | :----: | :----: | :----: |
218 | | active-tab-change | Trigger event when the active content panel changes | `currentActive : DockPanel|null`,`lastActive : DockPanel|null` |
219 | | tab-closed | Trigger this event when the content panel is closed | `panel: DockPanel` |
220 |
221 | ##### Slots
222 |
223 | | Name | description | params |
224 | | :----: | :----: | :----: |
225 | | emptyPanel | This slot is used to render panel titles. | { name: string, dockData: DockData } |
226 | | tabItemRender | This slot is used to render the backplane displayed when the grid has no content panel. | DockTabItemRenderData |
227 |
228 | ##### Instance Function
229 |
230 | ```ts
231 | //When using TS, you can use DockLayoutInterface to obtain code prompts
232 | const dockLayout = ref();
233 | ```
234 |
235 | ###### `getSaveData() : IDockGrid`
236 |
237 | Explain:
238 |
239 | Obtain current interface grid layout data
240 |
241 | Return:
242 |
243 | grid layout data
244 |
245 | ###### `setData(data: IDockGrid) : void`
246 |
247 | Explain:
248 |
249 | Set interface grid layout data
250 |
251 | | params | description |
252 | | :----: | :----: |
253 | | data | grid layout data |
254 |
255 | ###### `updatePanel(panel: IDockPanel) : void`
256 |
257 | Explain:
258 |
259 | Update properties of panel instances
260 |
261 | | params | description |
262 | | :----: | :----: |
263 | | panel | Target panel |
264 |
265 | ###### `addPanel(panel: IDockPanel, insertTo?: string|DockData) : void`
266 |
267 | Explain:
268 |
269 | Insert the panel into the container.
270 |
271 | * Note: If the panel key has already been inserted into the current container and `insertTo` is not empty, the panel will be moved to the operation, and the new panel properties will not change. You need to manually call `updatePanel` to update the properties.
272 | * Note: If `insertTo` is not empty, its grid container must first exist, otherwise the addition will fail.
273 | * `panel.key` cannot be empty.
274 |
275 | | params | description |
276 | | :----: | :----: |
277 | | panel | Target panel |
278 | | insertTo | Insert the panel into the grid with the specified name. If left blank, insert it into the top-level grid |
279 |
280 | ###### `addPanels(panels: IDockPanel[], insertTo?: string|DockData) : void`
281 |
282 | Explain:
283 |
284 | Insert the panel into the container. Same as' addPanel ', but this function adds multiple panels at once.
285 |
286 | | params | description |
287 | | :----: | :----: |
288 | | panels | Panel array |
289 | | insertTo | Insert the panel into the grid with the specified name. If left blank, insert it into the top-level grid |
290 |
291 | ###### `removePanel(key: string) : void`
292 |
293 | Explain:
294 |
295 | Remove specified panel
296 |
297 | | params | description |
298 | | :----: | :----: |
299 | | key | Target panel key |
300 |
301 | ###### `removePanels(keys: string[]) : void`
302 |
303 | Explain:
304 |
305 | Remove multiple specified panels
306 |
307 | | params | description |
308 | | :----: | :----: |
309 | | keys | Target panel keys |
310 |
311 | ###### `activePanel(key: string) : void`
312 |
313 | Explain:
314 |
315 | Activate the specified panel
316 |
317 | | params | description |
318 | | :----: | :----: |
319 | | key | Target panel key |
320 |
321 | ## Changelog
322 |
323 | [Changelog](./CHANGELOG.md)
324 |
325 | ## Other projects of the author
326 |
327 | * [vue3-context-menu A very simple context menu component for Vue3](https://github.com/imengyu/vue3-context-menu/)
328 | * [vue-dynamic-form A data driven form component for vue3](https://github.com/imengyu/vue-dynamic-form)
329 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: [
3 | '@vue/cli-plugin-babel/preset'
4 | ],
5 | plugins: ['@vue/babel-plugin-jsx']
6 | }
7 |
--------------------------------------------------------------------------------
/demo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imengyu/vue-dock-layout/069910ef40cfad5c1e92178f5c8a404ca66898e1/demo.jpg
--------------------------------------------------------------------------------
/demo.light.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imengyu/vue-dock-layout/069910ef40cfad5c1e92178f5c8a404ca66898e1/demo.light.jpg
--------------------------------------------------------------------------------
/examples/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
10 |
11 |
23 |
--------------------------------------------------------------------------------
/examples/css/iconfont.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "iconfont"; /* Project id 2648583 */
3 | src: url('iconfont.woff2?t=1625231696258') format('woff2'),
4 | url('iconfont.woff?t=1625231696258') format('woff'),
5 | url('iconfont.ttf?t=1625231696258') format('truetype');
6 | }
7 |
8 | .iconfont {
9 | font-family: "iconfont" !important;
10 | font-size: 16px;
11 | font-style: normal;
12 | -webkit-font-smoothing: antialiased;
13 | -moz-osx-font-smoothing: grayscale;
14 | }
15 |
16 | .icon-reload-:before {
17 | content: "\e898";
18 | }
19 |
20 | .icon-print:before {
21 | content: "\e899";
22 | }
23 |
24 | .icon-reload-1:before {
25 | content: "\e89e";
26 | }
27 |
28 | .icon-save:before {
29 | content: "\e8a4";
30 | }
31 |
32 | .icon-settings-1:before {
33 | content: "\e8a7";
34 | }
35 |
36 | .icon-terminal:before {
37 | content: "\e8c2";
38 | }
39 |
40 | .icon-yidong:before {
41 | content: "\e68c";
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/examples/css/iconfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imengyu/vue-dock-layout/069910ef40cfad5c1e92178f5c8a404ca66898e1/examples/css/iconfont.ttf
--------------------------------------------------------------------------------
/examples/css/iconfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imengyu/vue-dock-layout/069910ef40cfad5c1e92178f5c8a404ca66898e1/examples/css/iconfont.woff
--------------------------------------------------------------------------------
/examples/css/iconfont.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/imengyu/vue-dock-layout/069910ef40cfad5c1e92178f5c8a404ca66898e1/examples/css/iconfont.woff2
--------------------------------------------------------------------------------
/examples/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | <%= htmlWebpackPlugin.options.title %>
9 |
10 |
11 |
12 |
13 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/examples/main.js:
--------------------------------------------------------------------------------
1 | import { createApp } from 'vue'
2 | import App from './App.vue'
3 | import router from './router'
4 | import './css/iconfont.css'
5 |
6 | createApp(App)
7 | .use(router)
8 | .mount('#app')
9 |
--------------------------------------------------------------------------------
/examples/router/index.ts:
--------------------------------------------------------------------------------
1 | import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
2 | import DockLayoutBaseTest from '../views/DockLayoutBaseTest.vue'
3 | import DockLayoutCustomTest from '../views/DockLayoutCustomTest.vue'
4 | import DockLayoutExtraTest from '../views/DockLayoutExtraTest.vue'
5 | import DockLayoutDataTest from '../views/DockLayoutDataTest.vue'
6 | import DockLayoutThemeTest from '../views/DockLayoutThemeTest.vue'
7 | import HomeView from '../views/DockLayoutTests.vue'
8 |
9 | const routes: Array = [
10 | {
11 | path: '/',
12 | name: 'home',
13 | component: HomeView,
14 | children: [
15 | {
16 | path: '',
17 | name: 'DockLayoutBaseTest',
18 | component: DockLayoutBaseTest
19 | },
20 | {
21 | path: 'DockLayoutCustomTest',
22 | name: 'DockLayoutCustomTest',
23 | component: DockLayoutCustomTest
24 | },
25 | {
26 | path: 'DockLayoutDataTest',
27 | name: 'DockLayoutDataTest',
28 | component: DockLayoutDataTest
29 | },
30 | {
31 | path: 'DockLayoutExtraTest',
32 | name: 'DockLayoutExtraTest',
33 | component: DockLayoutExtraTest
34 | },
35 | {
36 | path: 'DockLayoutThemeTest',
37 | name: 'DockLayoutThemeTest',
38 | component: DockLayoutThemeTest
39 | },
40 | ]
41 | },
42 | ]
43 |
44 | const router = createRouter({
45 | history: createWebHashHistory(process.env.BASE_URL),
46 | routes
47 | })
48 |
49 | export default router
50 |
--------------------------------------------------------------------------------
/examples/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | /* eslint-disable */
2 | declare module '*.vue' {
3 | import type { DefineComponent } from 'vue'
4 | const component: DefineComponent<{}, {}, any>
5 | export default component
6 | }
7 |
--------------------------------------------------------------------------------
/examples/views/DockLayoutBaseTest.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |