@netang/quasar 0.1.32 → 0.1.34

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/.editorconfig +12 -12
  2. package/_docs/docs/components/field-table.md +58 -58
  3. package/_docs/docs/components/field-tree.md +21 -21
  4. package/_docs/docs/components/table.md +24 -24
  5. package/_docs/docs/utils/table.md +196 -196
  6. package/components/editor-code/index.vue +325 -325
  7. package/components/field-table/index.vue +1227 -1227
  8. package/components/field-tree/index.vue +757 -757
  9. package/components/mixed-table/index.vue +473 -473
  10. package/components/mixed-table-splitter/index.vue +377 -377
  11. package/components/private/components/move-to-tree/index.vue +154 -154
  12. package/components/private/edit-power-data/index.vue +846 -846
  13. package/components/private/table-visible-columns-button/index.vue +109 -109
  14. package/components/render/index.vue +127 -127
  15. package/components/search/index.vue +224 -224
  16. package/components/search-item/index.vue +212 -212
  17. package/components/select/index.vue +177 -177
  18. package/components/table/index.vue +513 -513
  19. package/components/table-column-fixed/index.vue +110 -110
  20. package/components/table-summary/index.vue +107 -107
  21. package/components/tree/index.vue +22 -4
  22. package/docs/404.html +33 -33
  23. package/docs/assets/404.html-60b35caa.js +1 -1
  24. package/docs/assets/404.html-d1e63d77.js +1 -1
  25. package/docs/assets/alert.html-b2a2a72f.js +5 -5
  26. package/docs/assets/alert.html-ba46d137.js +1 -1
  27. package/docs/assets/app-9f30aa4b.js +6 -6
  28. package/docs/assets/area.html-01b9b58d.js +42 -42
  29. package/docs/assets/area.html-9a4fce6a.js +1 -1
  30. package/docs/assets/arr.html-145d27e7.js +1 -1
  31. package/docs/assets/arr.html-674e65ab.js +11 -11
  32. package/docs/assets/auth.html-579fa830.js +1 -1
  33. package/docs/assets/auth.html-8544ed95.js +8 -8
  34. package/docs/assets/bus.html-c71254aa.js +1 -1
  35. package/docs/assets/bus.html-dc7d3d19.js +6 -6
  36. package/docs/assets/column-title.html-c735cb5a.js +3 -3
  37. package/docs/assets/column-title.html-e9316762.js +1 -1
  38. package/docs/assets/confirm.html-ddfdc27f.js +10 -10
  39. package/docs/assets/confirm.html-ef3e2bef.js +1 -1
  40. package/docs/assets/copy.html-d20345b6.js +1 -1
  41. package/docs/assets/copy.html-ef8c8571.js +13 -13
  42. package/docs/assets/data.html-6432175d.js +30 -30
  43. package/docs/assets/data.html-a3b05d5b.js +1 -1
  44. package/docs/assets/dialog.html-1f698e5a.js +1 -1
  45. package/docs/assets/dialog.html-62902b83.js +68 -68
  46. package/docs/assets/dialog.html-baea77c9.js +1 -1
  47. package/docs/assets/dialog.html-bb082fc4.js +1 -1
  48. package/docs/assets/dict.html-1311da3d.js +23 -23
  49. package/docs/assets/dict.html-b96fbf0c.js +1 -1
  50. package/docs/assets/dictOptions.html-7c4f40a5.js +1 -1
  51. package/docs/assets/dictOptions.html-fb99d175.js +5 -5
  52. package/docs/assets/dragger.html-668d3efa.js +1 -1
  53. package/docs/assets/dragger.html-749d585a.js +1 -1
  54. package/docs/assets/editor-code.html-6ab26ea9.js +1 -1
  55. package/docs/assets/editor-code.html-d196205d.js +1 -1
  56. package/docs/assets/empty.html-1c139131.js +1 -1
  57. package/docs/assets/empty.html-1e9c441d.js +1 -1
  58. package/docs/assets/field-date.html-069fdb13.js +1 -1
  59. package/docs/assets/field-date.html-ad204aa9.js +1 -1
  60. package/docs/assets/field-table.html-ce480f03.js +1 -1
  61. package/docs/assets/field-table.html-d9236160.js +1 -1
  62. package/docs/assets/field-text.html-7277c62f.js +1 -1
  63. package/docs/assets/field-text.html-ccb4cecf.js +1 -1
  64. package/docs/assets/field-tree.html-519bfb45.js +1 -1
  65. package/docs/assets/field-tree.html-fdc748d6.js +1 -1
  66. package/docs/assets/form.html-2b562c37.js +2 -2
  67. package/docs/assets/form.html-75104cd5.js +1 -1
  68. package/docs/assets/framework-204010b2.js +5 -5
  69. package/docs/assets/getData.html-990e3787.js +1 -1
  70. package/docs/assets/getData.html-bb72025f.js +34 -34
  71. package/docs/assets/getFile.html-42368004.js +1 -1
  72. package/docs/assets/getFile.html-99abd054.js +3 -3
  73. package/docs/assets/getImage.html-3429c5a1.js +1 -1
  74. package/docs/assets/getImage.html-4d886d83.js +3 -3
  75. package/docs/assets/getTime.html-7435f922.js +1 -1
  76. package/docs/assets/getTime.html-b37f49eb.js +20 -20
  77. package/docs/assets/img.html-7d1da657.js +1 -1
  78. package/docs/assets/img.html-fbea1105.js +1 -1
  79. package/docs/assets/index.html-1695dd7c.js +1 -1
  80. package/docs/assets/index.html-65a4aa67.js +1 -1
  81. package/docs/assets/index.html-7b98d5bd.js +1 -1
  82. package/docs/assets/index.html-c01f2648.js +1 -1
  83. package/docs/assets/input-number.html-0b250d2a.js +1 -1
  84. package/docs/assets/input-number.html-a8eb0378.js +1 -1
  85. package/docs/assets/list-menu-item.html-7f1b4611.js +1 -1
  86. package/docs/assets/list-menu-item.html-84ed5ab8.js +1 -1
  87. package/docs/assets/list-menu.html-28b4163f.js +1 -1
  88. package/docs/assets/list-menu.html-cb6ba95b.js +1 -1
  89. package/docs/assets/loading.html-dae9e39d.js +6 -6
  90. package/docs/assets/loading.html-dc74c9e6.js +1 -1
  91. package/docs/assets/notify.html-e6c4c514.js +1 -1
  92. package/docs/assets/notify.html-f2c4d914.js +8 -8
  93. package/docs/assets/power-page.html-32e02f82.js +1 -1
  94. package/docs/assets/power-page.html-485e77da.js +1 -1
  95. package/docs/assets/power.html-d258cc19.js +93 -93
  96. package/docs/assets/power.html-e490bd32.js +1 -1
  97. package/docs/assets/previewImage.html-6a6b4245.js +1 -1
  98. package/docs/assets/previewImage.html-c5b7e945.js +2 -2
  99. package/docs/assets/price.html-1882c548.js +19 -19
  100. package/docs/assets/price.html-94d3f5be.js +1 -1
  101. package/docs/assets/price.html-d213df0f.js +1 -1
  102. package/docs/assets/price.html-deaf880f.js +1 -1
  103. package/docs/assets/render.html-8efcbdd4.js +1 -1
  104. package/docs/assets/render.html-df228e38.js +1 -1
  105. package/docs/assets/rule.html-2cd57fc2.js +13 -13
  106. package/docs/assets/rule.html-61662001.js +1 -1
  107. package/docs/assets/ruleValid.html-04fe2552.js +1 -1
  108. package/docs/assets/ruleValid.html-e0a776af.js +14 -14
  109. package/docs/assets/search-0782d0d1.svg +1 -1
  110. package/docs/assets/search-item.html-3f75394c.js +1 -1
  111. package/docs/assets/search-item.html-4e942ecd.js +1 -1
  112. package/docs/assets/search.html-2807043e.js +1 -1
  113. package/docs/assets/search.html-c24f8806.js +1 -1
  114. package/docs/assets/select.html-00d0607c.js +1 -1
  115. package/docs/assets/select.html-de7731f5.js +1 -1
  116. package/docs/assets/splitter.html-56f51a70.js +1 -1
  117. package/docs/assets/splitter.html-f5c836d7.js +1 -1
  118. package/docs/assets/style-161e43ab.css +1 -1
  119. package/docs/assets/symbols.html-a6aea4bf.js +1 -1
  120. package/docs/assets/symbols.html-b1f65bad.js +21 -21
  121. package/docs/assets/table-column-fixed.html-3a69e7b2.js +1 -1
  122. package/docs/assets/table-column-fixed.html-e763c38b.js +1 -1
  123. package/docs/assets/table-pagination.html-236934d3.js +1 -1
  124. package/docs/assets/table-pagination.html-c37ee2ac.js +1 -1
  125. package/docs/assets/table-splitter.html-07eab15c.js +1 -1
  126. package/docs/assets/table-splitter.html-7670ee65.js +1 -1
  127. package/docs/assets/table-summary.html-04db434f.js +1 -1
  128. package/docs/assets/table-summary.html-943c65a0.js +1 -1
  129. package/docs/assets/table.html-36253ad7.js +1 -1
  130. package/docs/assets/table.html-7f9c5d1b.js +38 -38
  131. package/docs/assets/table.html-93d53dc8.js +1 -1
  132. package/docs/assets/table.html-ac99b9cb.js +1 -1
  133. package/docs/assets/thumbnail.html-bab1976b.js +1 -1
  134. package/docs/assets/thumbnail.html-eb64e5e8.js +1 -1
  135. package/docs/assets/timestamp.html-4e54f79b.js +13 -13
  136. package/docs/assets/timestamp.html-d0e1b88a.js +1 -1
  137. package/docs/assets/toast.html-58ecbe21.js +1 -1
  138. package/docs/assets/toast.html-c9b9d36b.js +6 -6
  139. package/docs/assets/toolbar.html-83d9f97c.js +1 -1
  140. package/docs/assets/toolbar.html-ff7b8c92.js +1 -1
  141. package/docs/assets/tree.html-d07cbe79.js +23 -23
  142. package/docs/assets/tree.html-ea04193e.js +1 -1
  143. package/docs/assets/uploader-query.html-05590718.js +1 -1
  144. package/docs/assets/uploader-query.html-3175bac5.js +1 -1
  145. package/docs/assets/uploader.html-36da4394.js +2 -2
  146. package/docs/assets/uploader.html-6b5f3079.js +1 -1
  147. package/docs/assets/uploader.html-b9340b57.js +1 -1
  148. package/docs/assets/uploader.html-bc1c22e3.js +1 -1
  149. package/docs/assets/value-format.html-8ae3d47d.js +1 -1
  150. package/docs/assets/value-format.html-afa99b3d.js +1 -1
  151. package/docs/components/column-title.html +35 -35
  152. package/docs/components/data.html +62 -62
  153. package/docs/components/dialog.html +33 -33
  154. package/docs/components/dragger.html +33 -33
  155. package/docs/components/editor-code.html +33 -33
  156. package/docs/components/empty.html +33 -33
  157. package/docs/components/field-date.html +33 -33
  158. package/docs/components/field-table.html +33 -33
  159. package/docs/components/field-text.html +33 -33
  160. package/docs/components/field-tree.html +33 -33
  161. package/docs/components/img.html +33 -33
  162. package/docs/components/input-number.html +33 -33
  163. package/docs/components/list-menu-item.html +33 -33
  164. package/docs/components/list-menu.html +33 -33
  165. package/docs/components/power-page.html +33 -33
  166. package/docs/components/price.html +33 -33
  167. package/docs/components/render.html +33 -33
  168. package/docs/components/search-item.html +33 -33
  169. package/docs/components/search.html +33 -33
  170. package/docs/components/select.html +33 -33
  171. package/docs/components/splitter.html +33 -33
  172. package/docs/components/table-column-fixed.html +33 -33
  173. package/docs/components/table-pagination.html +33 -33
  174. package/docs/components/table-splitter.html +33 -33
  175. package/docs/components/table-summary.html +33 -33
  176. package/docs/components/table.html +33 -33
  177. package/docs/components/thumbnail.html +33 -33
  178. package/docs/components/toolbar.html +33 -33
  179. package/docs/components/uploader-query.html +33 -33
  180. package/docs/components/uploader.html +33 -33
  181. package/docs/components/value-format.html +33 -33
  182. package/docs/index.html +33 -33
  183. package/docs/utils/alert.html +37 -37
  184. package/docs/utils/area.html +74 -74
  185. package/docs/utils/arr.html +43 -43
  186. package/docs/utils/auth.html +40 -40
  187. package/docs/utils/bus.html +38 -38
  188. package/docs/utils/confirm.html +42 -42
  189. package/docs/utils/copy.html +45 -45
  190. package/docs/utils/dialog.html +100 -100
  191. package/docs/utils/dict.html +55 -55
  192. package/docs/utils/dictOptions.html +37 -37
  193. package/docs/utils/form.html +34 -34
  194. package/docs/utils/getData.html +66 -66
  195. package/docs/utils/getFile.html +35 -35
  196. package/docs/utils/getImage.html +35 -35
  197. package/docs/utils/getTime.html +52 -52
  198. package/docs/utils/index.html +33 -33
  199. package/docs/utils/loading.html +38 -38
  200. package/docs/utils/notify.html +40 -40
  201. package/docs/utils/power.html +125 -125
  202. package/docs/utils/previewImage.html +34 -34
  203. package/docs/utils/price.html +51 -51
  204. package/docs/utils/rule.html +45 -45
  205. package/docs/utils/ruleValid.html +46 -46
  206. package/docs/utils/symbols.html +53 -53
  207. package/docs/utils/table.html +70 -70
  208. package/docs/utils/timestamp.html +45 -45
  209. package/docs/utils/toast.html +38 -38
  210. package/docs/utils/tree.html +55 -55
  211. package/docs/utils/uploader.html +34 -34
  212. package/package.json +1 -1
  213. package/sass/common.scss +179 -179
  214. package/sass/quasar/field.scss +250 -250
  215. package/sass/quasar/table.scss +161 -161
  216. package/sass/variables.scss +138 -138
  217. package/utils/$form.js +72 -72
  218. package/utils/$power.js +1233 -1233
  219. package/utils/$render.js +75 -75
  220. package/utils/$table.js +1171 -1171
  221. package/utils/$tree.js +664 -664
  222. package/utils/index.js +62 -62
  223. package/utils/timestamp.js +18 -18
  224. package/utils/useSearch.js +496 -496
@@ -1,473 +1,473 @@
1
- <template>
2
- <q-layout
3
- class="absolute-full"
4
- :class="{
5
- 'n-table--grid': tableGrid,
6
- }"
7
- view="lHr LpR lff"
8
- container
9
- >
10
- <!-- 头部 -->
11
- <n-toolbar
12
- :dense="dense"
13
- header
14
- >
15
- <!-- 插槽 -->
16
- <template
17
- v-for="slotName in slotNames.toolbar"
18
- v-slot:[slotName]
19
- >
20
- <slot :name="`toolbar-${slotName}`"/>
21
- </template>
22
- </n-toolbar>
23
-
24
- <!-- 左侧分类 -->
25
- <slot name="left-drawer" v-if="slotNames.leftDrawer" />
26
- <n-drawer
27
- :model-value="! hideLeftDrawer"
28
- :side="treeSide"
29
- :width="200"
30
- :min-width="150"
31
- bordered
32
- drag
33
- cache
34
- v-bind="leftDrawerProps"
35
- v-else-if="treeNodes.length"
36
- >
37
- <q-scroll-area class="absolute-full">
38
-
39
- <!-- 树筛选 -->
40
- <div class="q-pa-sm q-gutter-sm" v-if="treeFilter">
41
- <q-input
42
- v-model="treeFilterValue"
43
- placeholder="搜索"
44
- dense
45
- outlined
46
- clearable
47
-
48
- />
49
- </div>
50
-
51
- <!-- 分类树 -->
52
- <!--selected-color="primary"-->
53
- <n-tree
54
- color="grey-5"
55
- ref="treeRef"
56
- :nodes="treeNodes"
57
- :filter="treeFilterValue"
58
- :node-key="treeNodeKey"
59
- :label-key="treeLabelKey"
60
- v-model:selected="treeSelected"
61
- no-selection-unset
62
- default-expand-all
63
- v-bind="treeProps"
64
- />
65
-
66
- </q-scroll-area>
67
- </n-drawer>
68
-
69
- <!-- 列表 -->
70
- <q-page-container>
71
- <q-page>
72
- <n-table
73
- ref="tableRef"
74
- class="n-table absolute-full"
75
- :class="{
76
- 'n-table--last-fixed': showTableFixed,
77
- }"
78
- v-model:pagination="tablePagination"
79
- v-model:selected="tableSelected"
80
- :row-key="tableRowKey"
81
- :rows="tableRows"
82
- :columns="tableColumns"
83
- :visible-columns="tableVisibleColumns"
84
- :selection="tableSelection"
85
- :separator="tableSeparator"
86
- :loading="tableLoading"
87
- :rows-per-page-options="tableRowsPerPageOptions"
88
- :grid="tableGrid"
89
- @row-click="tableRowClick"
90
- @row-dblclick="currentTableRowDblclick"
91
- @request="tableRequest"
92
- flat
93
- virtual-scroll
94
- :virtual-scroll-slice-ratio-before="20"
95
- :virtual-scroll-slice-size="50"
96
- :virtual-scroll-slice-ratio-after="20"
97
- :dense="dense"
98
- v-bind="$attrs"
99
- >
100
- <!-- 图片 -->
101
- <template
102
- v-for="imgName in tableImgNames"
103
- v-slot:[`body-cell-${imgName}`]="props"
104
- >
105
- <!-- 缩略图 -->
106
- <n-thumbnail
107
- :src="props.row[imgName]"
108
- preview
109
- />
110
- </template>
111
-
112
- <!-- 插槽 -->
113
- <template
114
- v-for="slotName in slotNames.table"
115
- v-slot:[slotName]="props"
116
- >
117
- <slot
118
- :name="slotName"
119
- v-bind="props"
120
- />
121
- </template>
122
-
123
- <!-- 操作 -->
124
- <template v-slot:body-cell-settings="props">
125
- <n-table-column-fixed
126
- :props="props"
127
- />
128
- </template>
129
-
130
- <!-- 合计 -->
131
- <template v-slot:bottom-row="props" v-if="tableSummary">
132
- <n-table-summary
133
- :props="props"
134
- />
135
- </template>
136
-
137
- <!-- 翻页 -->
138
- <template v-slot:pagination="props">
139
- <n-table-pagination
140
- :props="props"
141
- />
142
- </template>
143
- </n-table>
144
- </q-page>
145
- </q-page-container>
146
-
147
- <!-- 右侧搜索 -->
148
- <slot name="right-drawer" v-if="slotNames.rightDrawer" />
149
- <n-drawer
150
- :model-value="! hideRightDrawer"
151
- :side="searchSide"
152
- :min-width="320"
153
- bordered
154
- drag
155
- cache
156
- v-bind="rightDrawerProps"
157
- v-else-if="! noSearch && tableSearchValue.length"
158
- >
159
- <!-- 搜索 -->
160
- <n-search
161
- v-model="tableSearchValue"
162
- :options="tableSearchOptions"
163
- :on-search="tableReload"
164
- :on-reset="tableSearchReset"
165
- v-if="showSearch"
166
- >
167
- <!-- 插槽 -->
168
- <template
169
- v-for="slotName in slotNames.search"
170
- v-slot:[slotName]
171
- >
172
- <slot :name="`search-${slotName}`"/>
173
- </template>
174
- </n-search>
175
- </n-drawer>
176
-
177
- </q-layout>
178
- </template>
179
-
180
- <script>
181
- import { ref, watch, computed, inject, onMounted } from 'vue'
182
-
183
- import $n_isFunction from 'lodash/isFunction'
184
- import $n_isNil from 'lodash/isNil'
185
-
186
- import $n_isValidObject from '@netang/utils/isValidObject'
187
- import $n_isValidValue from '@netang/utils/isValidValue'
188
- import $n_collection from '@netang/utils/collection'
189
-
190
- import { NDialogKey, NTableKey } from '../../utils/symbols'
191
-
192
- import NToolbar from '../toolbar'
193
- import NDrawer from '../drawer'
194
- import NThumbnail from '../thumbnail'
195
- import NTableColumnFixed from '../table-column-fixed'
196
- import NTableSummary from '../table-summary'
197
- import NTablePagination from '../table-pagination'
198
- import NSearch from '../search'
199
-
200
- export default {
201
-
202
- /**
203
- * 标识
204
- */
205
- name: 'NMixedTable',
206
-
207
- /**
208
- * 关闭组件 attribute 透传行为
209
- */
210
- inheritAttrs: false,
211
-
212
- /**
213
- * 组件
214
- */
215
- components: {
216
- NToolbar,
217
- NDrawer,
218
- NThumbnail,
219
- NTableColumnFixed,
220
- NTableSummary,
221
- NTablePagination,
222
- NSearch,
223
- },
224
-
225
- /**
226
- * 声明属性
227
- */
228
- props: {
229
- // 树声明属性
230
- treeProps: Object,
231
- // 树节点唯一键值
232
- treeNodeKey: {
233
- type: String,
234
- default: 'id',
235
- },
236
- // 树标签键值
237
- treeLabelKey: {
238
- type: String,
239
- default: 'title',
240
- },
241
- // 树节点列表
242
- treeNodes: {
243
- type: Array,
244
- default: ()=>[],
245
- },
246
- // 默认树已选节点 v-model:tree-selected
247
- treeSelected: [ String, Number ],
248
- // 树节点点击
249
- treeNodeClick: Function,
250
- // 是否选中第一个树节点
251
- treeSelectFirstNode: {
252
- type: Boolean,
253
- default: true,
254
- },
255
- // 显示树筛选
256
- treeFilter: Boolean,
257
- // 树位置, 可选值: left / right
258
- treeSide: {
259
- type: String,
260
- default: 'left',
261
- },
262
- // 不显示搜索
263
- noSearch: Boolean,
264
- // 搜索位置
265
- searchSide: {
266
- type: String,
267
- default: 'right',
268
- },
269
- // 紧凑模式
270
- dense: {
271
- type: Boolean,
272
- default: true,
273
- },
274
- // 隐藏左边侧滑菜单
275
- hideLeftDrawer: Boolean,
276
- // 左边侧滑菜单声明属性
277
- leftDrawerProps: Object,
278
- // 隐藏右边侧滑菜单
279
- hideRightDrawer: Boolean,
280
- // 右边侧滑菜单声明属性
281
- rightDrawerProps: Object,
282
- },
283
-
284
- /**
285
- * 组合式
286
- */
287
- setup(props, { slots, emit }) {
288
-
289
- // ==========【数据】============================================================================================
290
-
291
- // 获取表格注入
292
- const $table = inject(NTableKey)
293
-
294
- // 获取对话框注入
295
- const $dialog = inject(NDialogKey)
296
- const inDialog = !! $dialog
297
-
298
- // 当前双击表格行
299
- let currentTableRowDblclick
300
-
301
- // 如果在对话框内部
302
- if (inDialog) {
303
- // 提交表格已选数据给对话框
304
- $dialog.submit(() => $table.tableSelected.value)
305
-
306
- // 对话框中的表格双击表格行
307
- currentTableRowDblclick = function (e, row) {
308
- // 如果不是多选
309
- if ($table.tableSelection.value !== 'multiple') {
310
- $table.tableSelected.value = [ row ]
311
- $dialog.confirm()
312
- }
313
- }
314
-
315
- } else {
316
- // 表格实例中的双击表格行
317
- currentTableRowDblclick = $table.tableRowDblclick
318
- }
319
-
320
- // 表格节点
321
- const tableRef = ref(null)
322
-
323
- // 树节点
324
- const treeRef = ref(null)
325
-
326
- // 树筛选值
327
- const treeFilterValue = ref('')
328
-
329
- // 树选择数据
330
- const treeSelected = ref(props.treeSelected)
331
-
332
- // 是否显示搜索
333
- const showSearch = ref(false)
334
-
335
- // ==========【计算属性】==========================================================================================
336
-
337
- /**
338
- * 插槽标识
339
- */
340
- const slotNames = computed(function() {
341
-
342
- const toolbar = []
343
- const search = []
344
- const table = []
345
- let leftDrawer = false
346
- let rightDrawer = false
347
-
348
- // 如果有插槽
349
- if ($n_isValidObject(slots)) {
350
- for (const key in slots) {
351
- if (key.startsWith('toolbar-')) {
352
- toolbar.push(key.replace('toolbar-', ''))
353
- } else if (key.startsWith('search-')) {
354
- search.push(key.replace('search-', ''))
355
- } else if (key === 'left-drawer') {
356
- leftDrawer = true
357
- } else if (key === 'right-drawer') {
358
- rightDrawer = true
359
- } else {
360
- table.push(key)
361
- }
362
- }
363
- }
364
-
365
- return {
366
- toolbar,
367
- search,
368
- table,
369
- leftDrawer,
370
- rightDrawer,
371
- }
372
- })
373
-
374
- // ==========【监听数据】=========================================================================================
375
-
376
- // 如果有树节点点击方法
377
- if ($n_isFunction(props.treeNodeClick)) {
378
-
379
- /**
380
- * 树节点 all
381
- */
382
- const treeNodesAll = computed(function () {
383
- return $n_collection(props.treeNodes)
384
- .keyBy(props.treeNodeKey)
385
- .toObject()
386
- })
387
-
388
- /**
389
- * 监听树选择数据
390
- */
391
- watch(treeSelected, function(nodeKey) {
392
-
393
- // 触发更新已选树节点
394
- emit('update:treeSelected', nodeKey)
395
-
396
- // 如果节点值不是有效值
397
- if (! $n_isValidValue(nodeKey)) {
398
- // 则无任何操作
399
- return
400
- }
401
-
402
- // 树节点点击
403
- const res = props.treeNodeClick(nodeKey, treeNodesAll.value[nodeKey])
404
-
405
- if ($n_isValidObject(res)) {
406
-
407
- // 设置表格传参
408
- $table.setQuery(res)
409
-
410
- // 表格重新加载
411
- $table.tableReload()
412
- }
413
- })
414
-
415
- /**
416
- * 监听树节点数据
417
- */
418
- watch(() => props.treeNodes, function (val) {
419
-
420
- if (
421
- // 如果关闭选中第一个树节点
422
- ! props.treeSelectFirstNode
423
- || ! $n_isNil(treeSelected.value)
424
- ) {
425
- // 则无任何操作
426
- return
427
- }
428
-
429
- // 选中第一个节点的值
430
- treeSelected.value = val[0][props.treeNodeKey]
431
- }, {
432
- // 立即执行
433
- immediate: true,
434
- })
435
- }
436
-
437
- // ==========【生命周期】=========================================================================================
438
-
439
- /**
440
- * 实例被挂载后调用
441
- */
442
- onMounted( async function() {
443
-
444
- // 显示搜索
445
- showSearch.value = true
446
- })
447
-
448
- // ==========【返回】=============================================================================================
449
-
450
- return {
451
- // 解构表格实例
452
- ...$table,
453
-
454
- // 表格节点
455
- tableRef,
456
- // 树节点
457
- treeRef,
458
- // 树筛选值
459
- treeFilterValue,
460
- // 树选择数据
461
- treeSelected,
462
- // 是否显示搜索
463
- showSearch,
464
-
465
- // 插槽 body 单元格标识
466
- slotNames,
467
-
468
- // 当前双击表格行
469
- currentTableRowDblclick,
470
- }
471
- },
472
- }
473
- </script>
1
+ <template>
2
+ <q-layout
3
+ class="absolute-full"
4
+ :class="{
5
+ 'n-table--grid': tableGrid,
6
+ }"
7
+ view="lHr LpR lff"
8
+ container
9
+ >
10
+ <!-- 头部 -->
11
+ <n-toolbar
12
+ :dense="dense"
13
+ header
14
+ >
15
+ <!-- 插槽 -->
16
+ <template
17
+ v-for="slotName in slotNames.toolbar"
18
+ v-slot:[slotName]
19
+ >
20
+ <slot :name="`toolbar-${slotName}`"/>
21
+ </template>
22
+ </n-toolbar>
23
+
24
+ <!-- 左侧分类 -->
25
+ <slot name="left-drawer" v-if="slotNames.leftDrawer" />
26
+ <n-drawer
27
+ :model-value="! hideLeftDrawer"
28
+ :side="treeSide"
29
+ :width="200"
30
+ :min-width="150"
31
+ bordered
32
+ drag
33
+ cache
34
+ v-bind="leftDrawerProps"
35
+ v-else-if="treeNodes.length"
36
+ >
37
+ <q-scroll-area class="absolute-full">
38
+
39
+ <!-- 树筛选 -->
40
+ <div class="q-pa-sm q-gutter-sm" v-if="treeFilter">
41
+ <q-input
42
+ v-model="treeFilterValue"
43
+ placeholder="搜索"
44
+ dense
45
+ outlined
46
+ clearable
47
+
48
+ />
49
+ </div>
50
+
51
+ <!-- 分类树 -->
52
+ <!--selected-color="primary"-->
53
+ <n-tree
54
+ color="grey-5"
55
+ ref="treeRef"
56
+ :nodes="treeNodes"
57
+ :filter="treeFilterValue"
58
+ :node-key="treeNodeKey"
59
+ :label-key="treeLabelKey"
60
+ v-model:selected="treeSelected"
61
+ no-selection-unset
62
+ default-expand-all
63
+ v-bind="treeProps"
64
+ />
65
+
66
+ </q-scroll-area>
67
+ </n-drawer>
68
+
69
+ <!-- 列表 -->
70
+ <q-page-container>
71
+ <q-page>
72
+ <n-table
73
+ ref="tableRef"
74
+ class="n-table absolute-full"
75
+ :class="{
76
+ 'n-table--last-fixed': showTableFixed,
77
+ }"
78
+ v-model:pagination="tablePagination"
79
+ v-model:selected="tableSelected"
80
+ :row-key="tableRowKey"
81
+ :rows="tableRows"
82
+ :columns="tableColumns"
83
+ :visible-columns="tableVisibleColumns"
84
+ :selection="tableSelection"
85
+ :separator="tableSeparator"
86
+ :loading="tableLoading"
87
+ :rows-per-page-options="tableRowsPerPageOptions"
88
+ :grid="tableGrid"
89
+ @row-click="tableRowClick"
90
+ @row-dblclick="currentTableRowDblclick"
91
+ @request="tableRequest"
92
+ flat
93
+ virtual-scroll
94
+ :virtual-scroll-slice-ratio-before="20"
95
+ :virtual-scroll-slice-size="50"
96
+ :virtual-scroll-slice-ratio-after="20"
97
+ :dense="dense"
98
+ v-bind="$attrs"
99
+ >
100
+ <!-- 图片 -->
101
+ <template
102
+ v-for="imgName in tableImgNames"
103
+ v-slot:[`body-cell-${imgName}`]="props"
104
+ >
105
+ <!-- 缩略图 -->
106
+ <n-thumbnail
107
+ :src="props.row[imgName]"
108
+ preview
109
+ />
110
+ </template>
111
+
112
+ <!-- 插槽 -->
113
+ <template
114
+ v-for="slotName in slotNames.table"
115
+ v-slot:[slotName]="props"
116
+ >
117
+ <slot
118
+ :name="slotName"
119
+ v-bind="props"
120
+ />
121
+ </template>
122
+
123
+ <!-- 操作 -->
124
+ <template v-slot:body-cell-settings="props">
125
+ <n-table-column-fixed
126
+ :props="props"
127
+ />
128
+ </template>
129
+
130
+ <!-- 合计 -->
131
+ <template v-slot:bottom-row="props" v-if="tableSummary">
132
+ <n-table-summary
133
+ :props="props"
134
+ />
135
+ </template>
136
+
137
+ <!-- 翻页 -->
138
+ <template v-slot:pagination="props">
139
+ <n-table-pagination
140
+ :props="props"
141
+ />
142
+ </template>
143
+ </n-table>
144
+ </q-page>
145
+ </q-page-container>
146
+
147
+ <!-- 右侧搜索 -->
148
+ <slot name="right-drawer" v-if="slotNames.rightDrawer" />
149
+ <n-drawer
150
+ :model-value="! hideRightDrawer"
151
+ :side="searchSide"
152
+ :min-width="320"
153
+ bordered
154
+ drag
155
+ cache
156
+ v-bind="rightDrawerProps"
157
+ v-else-if="! noSearch && tableSearchValue.length"
158
+ >
159
+ <!-- 搜索 -->
160
+ <n-search
161
+ v-model="tableSearchValue"
162
+ :options="tableSearchOptions"
163
+ :on-search="tableReload"
164
+ :on-reset="tableSearchReset"
165
+ v-if="showSearch"
166
+ >
167
+ <!-- 插槽 -->
168
+ <template
169
+ v-for="slotName in slotNames.search"
170
+ v-slot:[slotName]
171
+ >
172
+ <slot :name="`search-${slotName}`"/>
173
+ </template>
174
+ </n-search>
175
+ </n-drawer>
176
+
177
+ </q-layout>
178
+ </template>
179
+
180
+ <script>
181
+ import { ref, watch, computed, inject, onMounted } from 'vue'
182
+
183
+ import $n_isFunction from 'lodash/isFunction'
184
+ import $n_isNil from 'lodash/isNil'
185
+
186
+ import $n_isValidObject from '@netang/utils/isValidObject'
187
+ import $n_isValidValue from '@netang/utils/isValidValue'
188
+ import $n_collection from '@netang/utils/collection'
189
+
190
+ import { NDialogKey, NTableKey } from '../../utils/symbols'
191
+
192
+ import NToolbar from '../toolbar'
193
+ import NDrawer from '../drawer'
194
+ import NThumbnail from '../thumbnail'
195
+ import NTableColumnFixed from '../table-column-fixed'
196
+ import NTableSummary from '../table-summary'
197
+ import NTablePagination from '../table-pagination'
198
+ import NSearch from '../search'
199
+
200
+ export default {
201
+
202
+ /**
203
+ * 标识
204
+ */
205
+ name: 'NMixedTable',
206
+
207
+ /**
208
+ * 关闭组件 attribute 透传行为
209
+ */
210
+ inheritAttrs: false,
211
+
212
+ /**
213
+ * 组件
214
+ */
215
+ components: {
216
+ NToolbar,
217
+ NDrawer,
218
+ NThumbnail,
219
+ NTableColumnFixed,
220
+ NTableSummary,
221
+ NTablePagination,
222
+ NSearch,
223
+ },
224
+
225
+ /**
226
+ * 声明属性
227
+ */
228
+ props: {
229
+ // 树声明属性
230
+ treeProps: Object,
231
+ // 树节点唯一键值
232
+ treeNodeKey: {
233
+ type: String,
234
+ default: 'id',
235
+ },
236
+ // 树标签键值
237
+ treeLabelKey: {
238
+ type: String,
239
+ default: 'title',
240
+ },
241
+ // 树节点列表
242
+ treeNodes: {
243
+ type: Array,
244
+ default: ()=>[],
245
+ },
246
+ // 默认树已选节点 v-model:tree-selected
247
+ treeSelected: [ String, Number ],
248
+ // 树节点点击
249
+ treeNodeClick: Function,
250
+ // 是否选中第一个树节点
251
+ treeSelectFirstNode: {
252
+ type: Boolean,
253
+ default: true,
254
+ },
255
+ // 显示树筛选
256
+ treeFilter: Boolean,
257
+ // 树位置, 可选值: left / right
258
+ treeSide: {
259
+ type: String,
260
+ default: 'left',
261
+ },
262
+ // 不显示搜索
263
+ noSearch: Boolean,
264
+ // 搜索位置
265
+ searchSide: {
266
+ type: String,
267
+ default: 'right',
268
+ },
269
+ // 紧凑模式
270
+ dense: {
271
+ type: Boolean,
272
+ default: true,
273
+ },
274
+ // 隐藏左边侧滑菜单
275
+ hideLeftDrawer: Boolean,
276
+ // 左边侧滑菜单声明属性
277
+ leftDrawerProps: Object,
278
+ // 隐藏右边侧滑菜单
279
+ hideRightDrawer: Boolean,
280
+ // 右边侧滑菜单声明属性
281
+ rightDrawerProps: Object,
282
+ },
283
+
284
+ /**
285
+ * 组合式
286
+ */
287
+ setup(props, { slots, emit }) {
288
+
289
+ // ==========【数据】============================================================================================
290
+
291
+ // 获取表格注入
292
+ const $table = inject(NTableKey)
293
+
294
+ // 获取对话框注入
295
+ const $dialog = inject(NDialogKey)
296
+ const inDialog = !! $dialog
297
+
298
+ // 当前双击表格行
299
+ let currentTableRowDblclick
300
+
301
+ // 如果在对话框内部
302
+ if (inDialog) {
303
+ // 提交表格已选数据给对话框
304
+ $dialog.submit(() => $table.tableSelected.value)
305
+
306
+ // 对话框中的表格双击表格行
307
+ currentTableRowDblclick = function (e, row) {
308
+ // 如果不是多选
309
+ if ($table.tableSelection.value !== 'multiple') {
310
+ $table.tableSelected.value = [ row ]
311
+ $dialog.confirm()
312
+ }
313
+ }
314
+
315
+ } else {
316
+ // 表格实例中的双击表格行
317
+ currentTableRowDblclick = $table.tableRowDblclick
318
+ }
319
+
320
+ // 表格节点
321
+ const tableRef = ref(null)
322
+
323
+ // 树节点
324
+ const treeRef = ref(null)
325
+
326
+ // 树筛选值
327
+ const treeFilterValue = ref('')
328
+
329
+ // 树选择数据
330
+ const treeSelected = ref(props.treeSelected)
331
+
332
+ // 是否显示搜索
333
+ const showSearch = ref(false)
334
+
335
+ // ==========【计算属性】==========================================================================================
336
+
337
+ /**
338
+ * 插槽标识
339
+ */
340
+ const slotNames = computed(function() {
341
+
342
+ const toolbar = []
343
+ const search = []
344
+ const table = []
345
+ let leftDrawer = false
346
+ let rightDrawer = false
347
+
348
+ // 如果有插槽
349
+ if ($n_isValidObject(slots)) {
350
+ for (const key in slots) {
351
+ if (key.startsWith('toolbar-')) {
352
+ toolbar.push(key.replace('toolbar-', ''))
353
+ } else if (key.startsWith('search-')) {
354
+ search.push(key.replace('search-', ''))
355
+ } else if (key === 'left-drawer') {
356
+ leftDrawer = true
357
+ } else if (key === 'right-drawer') {
358
+ rightDrawer = true
359
+ } else {
360
+ table.push(key)
361
+ }
362
+ }
363
+ }
364
+
365
+ return {
366
+ toolbar,
367
+ search,
368
+ table,
369
+ leftDrawer,
370
+ rightDrawer,
371
+ }
372
+ })
373
+
374
+ // ==========【监听数据】=========================================================================================
375
+
376
+ // 如果有树节点点击方法
377
+ if ($n_isFunction(props.treeNodeClick)) {
378
+
379
+ /**
380
+ * 树节点 all
381
+ */
382
+ const treeNodesAll = computed(function () {
383
+ return $n_collection(props.treeNodes)
384
+ .keyBy(props.treeNodeKey)
385
+ .toObject()
386
+ })
387
+
388
+ /**
389
+ * 监听树选择数据
390
+ */
391
+ watch(treeSelected, function(nodeKey) {
392
+
393
+ // 触发更新已选树节点
394
+ emit('update:treeSelected', nodeKey)
395
+
396
+ // 如果节点值不是有效值
397
+ if (! $n_isValidValue(nodeKey)) {
398
+ // 则无任何操作
399
+ return
400
+ }
401
+
402
+ // 树节点点击
403
+ const res = props.treeNodeClick(nodeKey, treeNodesAll.value[nodeKey])
404
+
405
+ if ($n_isValidObject(res)) {
406
+
407
+ // 设置表格传参
408
+ $table.setQuery(res)
409
+
410
+ // 表格重新加载
411
+ $table.tableReload()
412
+ }
413
+ })
414
+
415
+ /**
416
+ * 监听树节点数据
417
+ */
418
+ watch(() => props.treeNodes, function (val) {
419
+
420
+ if (
421
+ // 如果关闭选中第一个树节点
422
+ ! props.treeSelectFirstNode
423
+ || ! $n_isNil(treeSelected.value)
424
+ ) {
425
+ // 则无任何操作
426
+ return
427
+ }
428
+
429
+ // 选中第一个节点的值
430
+ treeSelected.value = val[0][props.treeNodeKey]
431
+ }, {
432
+ // 立即执行
433
+ immediate: true,
434
+ })
435
+ }
436
+
437
+ // ==========【生命周期】=========================================================================================
438
+
439
+ /**
440
+ * 实例被挂载后调用
441
+ */
442
+ onMounted( async function() {
443
+
444
+ // 显示搜索
445
+ showSearch.value = true
446
+ })
447
+
448
+ // ==========【返回】=============================================================================================
449
+
450
+ return {
451
+ // 解构表格实例
452
+ ...$table,
453
+
454
+ // 表格节点
455
+ tableRef,
456
+ // 树节点
457
+ treeRef,
458
+ // 树筛选值
459
+ treeFilterValue,
460
+ // 树选择数据
461
+ treeSelected,
462
+ // 是否显示搜索
463
+ showSearch,
464
+
465
+ // 插槽 body 单元格标识
466
+ slotNames,
467
+
468
+ // 当前双击表格行
469
+ currentTableRowDblclick,
470
+ }
471
+ },
472
+ }
473
+ </script>