@truenewx/tnxvue3 3.4.5 → 3.4.6

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@truenewx/tnxvue3",
3
- "version": "3.4.5",
3
+ "version": "3.4.6",
4
4
  "description": "互联网技术解决方案:Vue3扩展支持",
5
5
  "private": false,
6
6
  "type": "module",
@@ -21,33 +21,34 @@
21
21
  "peerDependencies": {
22
22
  "@element-plus/icons-vue": "~2.3.0",
23
23
  "async-validator": "~4.2.0",
24
- "bootstrap-vue-next": "~0.40.0",
25
- "element-plus": "~2.13.0",
24
+ "bootstrap-vue-next": "~0.45.0",
25
+ "element-plus": "~2.14.0",
26
26
  "tdesign-icons-vue-next": "~0.4.0",
27
- "tdesign-mobile-vue": "~1.12.0",
28
- "tdesign-vue-next": "~1.17.0",
27
+ "tdesign-mobile-vue": "~1.15.0",
28
+ "tdesign-vue-next": "~1.20.0",
29
29
  "validator": "~13.15.0",
30
30
  "vue": "~3.5.0",
31
31
  "vue-router": "~4.6.0"
32
32
  },
33
33
  "dependencies": {
34
- "@truenewx/tnxcore": "3.4.4",
34
+ "@truenewx/tnxcore": "3.4.5",
35
35
  "bootstrap": "5.3.8",
36
36
  "cash-dom": "8.1.5",
37
37
  "mitt": "3.0.1"
38
38
  },
39
39
  "devDependencies": {
40
- "@eslint/js": "9.39.2",
41
- "@typescript-eslint/parser": "8.50.0",
42
- "@typescript-eslint/eslint-plugin": "8.50.0",
43
- "@vitejs/plugin-vue": "6.0.1",
44
- "eslint": "9.39.1",
45
- "eslint-plugin-vue": "10.5.1",
46
- "globals": "16.5.0",
47
- "tsx": "4.21.0",
48
- "typescript": "5.6.3",
49
- "vite": "7.2.2",
50
- "vue-eslint-parser": "10.2.0"
40
+ "@eslint/js": "10.0.1",
41
+ "@typescript-eslint/parser": "8.61.1",
42
+ "@typescript-eslint/eslint-plugin": "8.61.1",
43
+ "@vitejs/plugin-vue": "6.0.7",
44
+ "eslint": "10.5.0",
45
+ "eslint-plugin-vue": "10.9.2",
46
+ "globals": "17.6.0",
47
+ "less": "4.6.6",
48
+ "tsx": "4.22.4",
49
+ "typescript": "6.0.3",
50
+ "vite": "8.0.16",
51
+ "vue-eslint-parser": "10.4.1"
51
52
  },
52
53
  "browserslist": [
53
54
  "> 1%",
@@ -181,18 +181,17 @@ export default {
181
181
  },
182
182
  triggerChange(value) {
183
183
  if (this.change) {
184
- let item = undefined;
185
184
  if (this.isMulti()) {
186
- item = [];
185
+ let item = [];
187
186
  if (Array.isArray(value)) {
188
187
  for (let v of value) {
189
188
  item.push(this.getItem(v));
190
189
  }
191
190
  }
191
+ this.change(item, this.id);
192
192
  } else {
193
- item = this.getItem(value);
193
+ this.change(this.getItem(value), this.id);
194
194
  }
195
- this.change(item, this.id);
196
195
  } else {
197
196
  this.$emit('change', value);
198
197
  }
@@ -0,0 +1,69 @@
1
+ <template>
2
+ <div class="scroll-view">
3
+ <div class="scroll-view-y" :class="{'hide-scrollbar-y': !scrollY}">
4
+ <div class="scroll-view-x" :class="{'hide-scrollbar-x': !scrollX}">
5
+ <slot></slot>
6
+ </div>
7
+ </div>
8
+ </div>
9
+ </template>
10
+
11
+ <script>
12
+ export default {
13
+ name: 'ScrollView',
14
+ props: {
15
+ scrollX: {
16
+ type: Boolean,
17
+ default: false,
18
+ },
19
+ scrollY: {
20
+ type: Boolean,
21
+ default: true,
22
+ },
23
+ },
24
+ data() {
25
+ return {};
26
+ },
27
+ methods: {}
28
+ }
29
+ </script>
30
+
31
+ <style lang="less" scoped>
32
+ .scroll-view {
33
+ height: 100%;
34
+ min-height: 0;
35
+ }
36
+
37
+ .scroll-view-y {
38
+ height: 100%;
39
+ overflow-x: hidden;
40
+ overflow-y: auto;
41
+ -webkit-overflow-scrolling: touch;
42
+ }
43
+
44
+ .scroll-view-x {
45
+ width: 100%;
46
+ min-height: 100%;
47
+ overflow-x: auto;
48
+ overflow-y: visible;
49
+ -webkit-overflow-scrolling: touch;
50
+ }
51
+
52
+ .hide-scrollbar-y {
53
+ -ms-overflow-style: none;
54
+ scrollbar-width: none;
55
+ }
56
+
57
+ .hide-scrollbar-y::-webkit-scrollbar {
58
+ width: 0;
59
+ }
60
+
61
+ .hide-scrollbar-x {
62
+ -ms-overflow-style: none;
63
+ scrollbar-width: none;
64
+ }
65
+
66
+ .hide-scrollbar-x::-webkit-scrollbar {
67
+ height: 0;
68
+ }
69
+ </style>
package/src/css.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ declare module '*.css' {
2
+ const content: string;
3
+ export default content;
4
+ }
@@ -1,12 +1,12 @@
1
- import * as CryptoES from 'crypto-es';
1
+ import {AES, ECB, Pkcs7, Utf8} from 'crypto-es';
2
2
 
3
3
  /**
4
4
  * @word 要加密的内容
5
5
  * @keyWord String 服务器随机返回的关键字
6
6
  * */
7
7
  export function aesEncrypt(word, keyWord = "XwKsGlMcdPMEhR1B") {
8
- let key = CryptoES.enc.Utf8.parse(keyWord);
9
- let srcs = CryptoES.enc.Utf8.parse(word);
10
- let encrypted = CryptoES.AES.encrypt(srcs, key, {mode: CryptoES.mode.ECB, padding: CryptoES.pad.Pkcs7});
8
+ let key = Utf8.parse(keyWord);
9
+ let srcs = Utf8.parse(word);
10
+ let encrypted = AES.encrypt(srcs, key, {mode: ECB, padding: Pkcs7});
11
11
  return encrypted.toString();
12
12
  }
@@ -291,18 +291,17 @@ export default {
291
291
  },
292
292
  triggerChange(value) {
293
293
  if (this.change) {
294
- let item = undefined;
295
294
  if (this.isMulti()) {
296
- item = [];
295
+ let item = [];
297
296
  if (Array.isArray(value)) {
298
297
  for (let v of value) {
299
298
  item.push(this.getItem(v));
300
299
  }
301
300
  }
301
+ this.change(item, this.id);
302
302
  } else {
303
- item = this.getItem(value);
303
+ this.change(this.getItem(value), this.id);
304
304
  }
305
- this.change(item, this.id);
306
305
  } else {
307
306
  this.$emit('change', value);
308
307
  }
@@ -4,6 +4,7 @@
4
4
  v-model="visible"
5
5
  :placement="placement"
6
6
  :title="title"
7
+ :style="popupStyle"
7
8
  @closed="onClosed"
8
9
  >
9
10
  <template #default>
@@ -62,6 +63,20 @@ export default {
62
63
  buttonLoadings: [],
63
64
  };
64
65
  },
66
+ computed: {
67
+ popupStyle() {
68
+ const style = {};
69
+ if (this.options && this.options.width) {
70
+ style.width = this.options.width;
71
+ }
72
+ if (this.placement === 'left' || this.placement === 'right') {
73
+ style.height = '100vh';
74
+ style.maxHeight = '100vh';
75
+ style.borderRadius = '0';
76
+ }
77
+ return style;
78
+ },
79
+ },
65
80
  watch: {
66
81
  modelValue(val) {
67
82
  this.visible = val;
@@ -155,10 +170,16 @@ export default {
155
170
 
156
171
  <style>
157
172
  .tnxtdm-drawer {
173
+ width: 75%;
174
+
158
175
  .tnxtdm-drawer-body {
159
176
  flex: 1;
160
177
  overflow-y: auto;
161
- padding: 16px;
178
+ }
179
+
180
+ .tnxtdm-popup-content {
181
+ display: flex;
182
+ flex-direction: column;
162
183
  }
163
184
 
164
185
  .tnxtdm-drawer-footer {
@@ -1,21 +1,25 @@
1
1
  <template>
2
- <tnxtdm-select ref="select"
3
- v-model="model"
4
- :id="id"
5
- :selector="selector"
6
- :items="items"
7
- value-name="key" text-name="caption" index-name="searchIndex"
8
- :default-value="defaultValue"
9
- :empty="empty"
10
- :empty-value="emptyValue"
11
- :placeholder="placeholder"
12
- :width="width"
13
- :disabled="isDisabled"
14
- :filterable="filterable"
15
- :theme="theme"
16
- :size="size"
17
- :tag-click="tagClick"
18
- :change="change">
2
+ <tnxtdm-select
3
+ ref="select"
4
+ v-model="model"
5
+ :id="id"
6
+ :selector="selector"
7
+ :items="items"
8
+ value-name="key" text-name="caption" index-name="searchIndex"
9
+ :default-value="defaultValue"
10
+ :empty="empty"
11
+ :empty-value="emptyValue"
12
+ :placeholder="placeholder"
13
+ :width="width"
14
+ :disabled="isDisabled"
15
+ :filterable="filterable"
16
+ :theme="theme"
17
+ :size="size"
18
+ :tag-click="tagClick"
19
+ :change="change"
20
+ :data-type="type"
21
+ :data-subtype="subtype"
22
+ >
19
23
  <template #option="{item}" v-if="$slots.option">
20
24
  <slot name="option" :item="item"></slot>
21
25
  </template>
@@ -3,7 +3,7 @@
3
3
  :disabled="isDisabled" :key="`checkbox-${groupKey}`" v-if="selector === 'checkbox'">
4
4
  <t-checkbox v-for="item in items" :key="item[valueName]" :value="item[valueName]"
5
5
  :disabled="item.disabled === true || typeof item.disabled === 'string'"
6
- :label="item[textName]">
6
+ :label="item[textName]" :data-key="item.key">
7
7
  </t-checkbox>
8
8
  </t-checkbox-group>
9
9
 
@@ -12,8 +12,9 @@
12
12
  <template v-if="items">
13
13
  <t-tag v-for="item in items" :key="item[valueName]"
14
14
  :theme="isSelected(item[valueName]) ? 'primary' : 'default'"
15
- :variant="isSelected(item[valueName]) ? 'dark' : 'light'"
15
+ :variant="isSelected(item[valueName]) ? 'dark' : 'light-outline'"
16
16
  :disabled="isDisabled || item.disabled === true || typeof item.disabled === 'string'"
17
+ :data-key="item.key"
17
18
  @click="!isDisabled && select(item[valueName])">
18
19
  <t-icon :name="item[iconName]" v-if="item[iconName]"/>
19
20
  <span>{{ item[textName] }}</span>
@@ -30,6 +31,7 @@
30
31
  :theme="isSelected(item[valueName]) ? 'primary' : 'default'"
31
32
  size="small"
32
33
  :disabled="isDisabled || item.disabled === true || typeof item.disabled === 'string'"
34
+ :data-key="item.key"
33
35
  @click="!isDisabled && select(item[valueName], $event)">
34
36
  <t-icon :name="item[iconName]" v-if="item[iconName]"/>
35
37
  <span>{{ item[textName] }}</span>
@@ -43,7 +45,7 @@
43
45
  v-else-if="selector === 'radio-group'">
44
46
  <t-radio v-for="item in items" :key="item[valueName]" :value="item[valueName]"
45
47
  :disabled="item.disabled === true || typeof item.disabled === 'string'"
46
- :label="item[textName]">
48
+ :label="item[textName]" :data-key="item.key">
47
49
  </t-radio>
48
50
  </t-radio-group>
49
51
 
@@ -85,7 +87,7 @@
85
87
  <t-checkbox-group v-model="tempModel">
86
88
  <t-cell v-for="item in items" :key="item[valueName]" :title="item[textName]">
87
89
  <template #right-icon>
88
- <t-checkbox :value="item[valueName]"/>
90
+ <t-checkbox :value="item[valueName]" :data-key="item.key"/>
89
91
  </template>
90
92
  </t-cell>
91
93
  </t-checkbox-group>
@@ -262,18 +264,17 @@ export default {
262
264
  },
263
265
  triggerChange(value) {
264
266
  if (this.change) {
265
- let item = undefined;
266
267
  if (this.isMulti()) {
267
- item = [];
268
+ let item = [];
268
269
  if (Array.isArray(value)) {
269
270
  for (let v of value) {
270
271
  item.push(this.getItem(v));
271
272
  }
272
273
  }
274
+ this.change(item, this.id);
273
275
  } else {
274
- item = this.getItem(value);
276
+ this.change(this.getItem(value), this.id);
275
277
  }
276
- this.change(item, this.id);
277
278
  } else {
278
279
  this.$emit('change', value);
279
280
  }
@@ -5,6 +5,7 @@
5
5
  :key="item.value"
6
6
  class="tnxtdm-slide-radio-group__item"
7
7
  :class="{'is-active': modelValue === item.value}"
8
+ :data-key="item.key"
8
9
  @click="onItemClick(item.value)"
9
10
  :ref="el => { if (el) itemRefs[index] = el }">
10
11
  <t-icon class="tnxtdm-slide-radio-group__item-icon" :name="item.icon" size="1rem" v-if="item.icon"/>
@@ -278,6 +279,14 @@ export default {
278
279
  padding: 0;
279
280
  }
280
281
 
282
+ .tnxtdm-slide-radio-group--small.tnxtdm-slide-radio-group--rectangle {
283
+ border-radius: 4px;
284
+ }
285
+
286
+ .tnxtdm-slide-radio-group--small.tnxtdm-slide-radio-group--rectangle .tnxtdm-slide-radio-group__glider {
287
+ border-radius: 4px;
288
+ }
289
+
281
290
  .tnxtdm-slide-radio-group--small .tnxtdm-slide-radio-group__glider {
282
291
  top: 1px;
283
292
  bottom: 1px;
@@ -286,6 +295,22 @@ export default {
286
295
  .tnxtdm-slide-radio-group__item {
287
296
  padding: 0 12px;
288
297
  font-size: 12px;
298
+ position: relative;
299
+ display: flex;
300
+ align-items: center;
301
+ justify-content: center;
302
+ font-weight: normal;
303
+ color: var(--td-text-color-secondary);
304
+ cursor: pointer;
305
+ z-index: 1;
306
+ transition: color 0.2s;
307
+ text-align: center;
308
+ white-space: nowrap;
309
+ }
310
+
311
+ .tnxtdm-slide-radio-group__item.is-active {
312
+ color: var(--td-text-color-primary);
313
+ font-weight: normal;
289
314
  }
290
315
 
291
316
  .tnxtdm-slide-radio-group--small .tnxtdm-slide-radio-group__item {
@@ -353,26 +378,6 @@ export default {
353
378
  background-color: var(--td-error-color);
354
379
  }
355
380
 
356
- .tnxtdm-slide-radio-group__item {
357
- position: relative;
358
- display: flex;
359
- align-items: center;
360
- justify-content: center;
361
- font-weight: normal;
362
- color: var(--td-text-color-secondary);
363
- cursor: pointer;
364
- z-index: 1;
365
- padding: 0 1rem;
366
- transition: color 0.2s;
367
- text-align: center;
368
- white-space: nowrap;
369
- }
370
-
371
- .tnxtdm-slide-radio-group__item.is-active {
372
- color: var(--td-text-color-primary);
373
- font-weight: normal;
374
- }
375
-
376
381
  .tnxtdm-slide-radio-group--theme-primary .tnxtdm-slide-radio-group__item.is-active,
377
382
  .tnxtdm-slide-radio-group--theme-success .tnxtdm-slide-radio-group__item.is-active,
378
383
  .tnxtdm-slide-radio-group--theme-warning .tnxtdm-slide-radio-group__item.is-active,
@@ -7,20 +7,9 @@
7
7
  --td-tag-large-padding: 2px 10px;
8
8
  }
9
9
 
10
- .border-top-0,
11
- .border-top-0::before,
12
- .border-top-0 .t-cell-group--bordered::before {
13
- border-top: none !important;
14
- }
15
-
16
- .border-bottom-0,
17
- .border-bottom-0::after,
18
- .border-bottom-0 .t-cell-group--bordered::after {
19
- border-bottom: none !important;
20
- }
21
-
22
- .shadow {
23
- box-shadow: var(--td-shadow-1);
10
+ .t-loading__gradient-conic {
11
+ transform: none !important;
12
+ transform-origin: 50% 50% !important;
24
13
  }
25
14
 
26
15
  .t-input.border {
@@ -130,3 +119,7 @@
130
119
  .t-dialog__body {
131
120
  text-align: unset;
132
121
  }
122
+
123
+ .t-image__img {
124
+ width: auto;
125
+ }
@@ -5,6 +5,7 @@ import TDesign, {Dialog as TDialogPlugin, Toast} from 'tdesign-mobile-vue/esm';
5
5
  import 'tdesign-mobile-vue/esm/style/index.js'
6
6
  import './tnxtdm.css';
7
7
  import * as Vue from "vue";
8
+ import {EnumType, EnumItem} from '../../../../tnxcore/src/api/meta.ts';
8
9
  import {type DialogOptions, type DrawerOptions, type OpenOptions} from '../../tnxvue.ts';
9
10
  import Calendar from './calendar/Calendar.vue';
10
11
  import DateTimePicker from './date-time-picker/DateTimePicker.vue';
@@ -16,6 +17,7 @@ import RegionPicker from './region-picker/RegionPicker.vue';
16
17
  import Select from './select/Select.vue';
17
18
  import SlideRadioGroup from './slide-radio-group/SlideRadioGroup.vue';
18
19
 
20
+ export type {EnumType, EnumItem};
19
21
  export type {OpenOptions};
20
22
 
21
23
  const components = {
@@ -171,7 +173,7 @@ export default class TnxTdm extends TnxTd {
171
173
  contentProps: contentProps,
172
174
  buttons: buttons,
173
175
  theme: options.theme,
174
- placement: (options as any).placement,
176
+ placement: options.placement,
175
177
  });
176
178
  const drawer = drawerVm.mount(containerSelector) as ModalComponentInstance;
177
179
  drawer.options = Object.assign(drawer.options || {}, options);
@@ -13,6 +13,38 @@ body {
13
13
  border: var(--border);
14
14
  }
15
15
 
16
+ .border-top {
17
+ border-top: var(--border);
18
+ }
19
+
20
+ .border-bottom {
21
+ border-bottom: var(--border);
22
+ }
23
+
24
+ .border-left {
25
+ border-left: var(--border);
26
+ }
27
+
28
+ .border-right {
29
+ border-right: var(--border);
30
+ }
31
+
32
+ .border-top-0,
33
+ .border-top-0::before,
34
+ .border-top-0 .t-cell-group--bordered::before {
35
+ border-top: none !important;
36
+ }
37
+
38
+ .border-bottom-0,
39
+ .border-bottom-0::after,
40
+ .border-bottom-0 .t-cell-group--bordered::after {
41
+ border-bottom: none !important;
42
+ }
43
+
44
+ .shadow {
45
+ box-shadow: var(--td-shadow-1);
46
+ }
47
+
16
48
  .bg-page {
17
49
  background-color: var(--td-bg-color-page);
18
50
  }
@@ -169,7 +169,8 @@ export default function (items: RouteItem[], useHashHistory = true, fnImportPage
169
169
  beforeLeaveHandler = async (to: RouteLocationNormalized): Promise<boolean> => {
170
170
  let logined = await window.tnx.auth.isLogined();
171
171
  if (!logined) {
172
- window.tnx.api.toLogin(to.path);
172
+ let url = window.tnx.util.net.appendParams(to.path, to.query);
173
+ window.tnx.api.toLogin(url);
173
174
  }
174
175
  return logined;
175
176
  };
package/src/tnxvue.ts CHANGED
@@ -2,11 +2,12 @@
2
2
  * 基于Vue 3的扩展支持
3
3
  */
4
4
  import Tnx, {util} from '../../tnxcore/src/tnxcore.ts';
5
- import Text from './text/Text.vue';
6
- import Percent from './percent/Percent.vue';
5
+ import Text from './components/Text.vue';
6
+ import Percent from './components/Percent.vue';
7
+ import ScrollView from './components/ScrollView.vue';
7
8
  import * as Vue from 'vue';
8
9
  import mitt, {Emitter, EventType} from 'mitt';
9
- import {Router} from 'vue-router';
10
+ import {Router, useRoute} from 'vue-router';
10
11
  import {VueRouter} from './tnxvue-router.ts';
11
12
 
12
13
  export {util};
@@ -32,7 +33,9 @@ export type DialogOptions = {
32
33
 
33
34
  export type OpenType = 'alert' | 'confirm' | 'close' | 'none';
34
35
 
35
- export type DrawerOptions = DialogOptions
36
+ export type DrawerOptions = DialogOptions & {
37
+ placement?: 'bottom' | 'right' | 'top' | 'left';
38
+ }
36
39
 
37
40
  export type OpenOptions = DialogOptions & {
38
41
  mode?: 'dialog' | 'drawer';
@@ -50,6 +53,7 @@ export default class TnxVue extends Tnx {
50
53
  components: Record<string, Vue.Component> = {
51
54
  Text,
52
55
  Percent,
56
+ ScrollView,
53
57
  };
54
58
 
55
59
  constructor(apiBaseUrl: string, id: string = 'tnxvue') {
@@ -57,6 +61,10 @@ export default class TnxVue extends Tnx {
57
61
  this.libs.Vue = Vue;
58
62
  }
59
63
 
64
+ route(): ReturnType<typeof useRoute> {
65
+ return useRoute();
66
+ }
67
+
60
68
  install(app: Vue.App): void {
61
69
  for (let key of Object.keys(this.components)) {
62
70
  const component = this.components[key];
package/src/vue.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ declare module '*.vue' {
2
+ import type { DefineComponent } from 'vue';
3
+
4
+ const component: DefineComponent<Record<string, never>, Record<string, never>, any>;
5
+ export default component;
6
+ }
package/tsconfig.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "compilerOptions": {
3
+ "rootDir": "..",
3
4
  "target": "ES2020",
4
5
  "module": "ESNext",
5
6
  "moduleResolution": "Bundler",
@@ -18,15 +19,10 @@
18
19
  "ES2020",
19
20
  "DOM"
20
21
  ],
21
- "types": [],
22
- "baseUrl": ".",
23
- "paths": {
24
- "@/*": [
25
- "src/*"
26
- ]
27
- }
22
+ "types": []
28
23
  },
29
24
  "include": [
25
+ "src/**/*.d.ts",
30
26
  "src/**/*.ts",
31
27
  "src/**/*.vue",
32
28
  "sample/**/*.ts",
File without changes
File without changes