@truenewx/tnxvue3 2.6.0

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 (60) hide show
  1. package/README.md +3 -0
  2. package/package.json +76 -0
  3. package/sample/App.vue +19 -0
  4. package/sample/main.js +11 -0
  5. package/sample/pages/index.vue +79 -0
  6. package/sample/pages/info.vue +28 -0
  7. package/sample/tnx.js +31 -0
  8. package/src/aj-captcha/Verify/VerifyPoints.vue +258 -0
  9. package/src/aj-captcha/Verify/VerifySlide.vue +379 -0
  10. package/src/aj-captcha/Verify.vue +375 -0
  11. package/src/aj-captcha/api/index.js +19 -0
  12. package/src/aj-captcha/utils/ase.js +11 -0
  13. package/src/aj-captcha/utils/util.js +35 -0
  14. package/src/ant-design/tnxad-theme.css +5 -0
  15. package/src/ant-design/tnxad.css +8 -0
  16. package/src/ant-design/tnxad.js +23 -0
  17. package/src/element-plus/alert/Alert.vue +112 -0
  18. package/src/element-plus/avatar/Avatar.vue +124 -0
  19. package/src/element-plus/button/Button.vue +184 -0
  20. package/src/element-plus/check-icon/CheckIcon.vue +61 -0
  21. package/src/element-plus/close-error-button/CloseErrorButton.vue +45 -0
  22. package/src/element-plus/curd/Curd.vue +224 -0
  23. package/src/element-plus/date-picker/DatePicker.vue +206 -0
  24. package/src/element-plus/date-range/DateRange.vue +78 -0
  25. package/src/element-plus/datetime-picker/DateTimePicker.vue +129 -0
  26. package/src/element-plus/detail-form/DetailForm.vue +88 -0
  27. package/src/element-plus/dialog/Dialog.vue +259 -0
  28. package/src/element-plus/dialog/DialogContent.vue +13 -0
  29. package/src/element-plus/drawer/Drawer.vue +175 -0
  30. package/src/element-plus/dropdown-item/DropdownItem.vue +30 -0
  31. package/src/element-plus/enum-select/EnumSelect.vue +125 -0
  32. package/src/element-plus/fetch-cascader/FetchCascader.vue +138 -0
  33. package/src/element-plus/fetch-select/FetchSelect.vue +166 -0
  34. package/src/element-plus/fetch-tags/FetchTags.vue +122 -0
  35. package/src/element-plus/fss-upload/FssUpload.vue +306 -0
  36. package/src/element-plus/fss-view/FssView.vue +163 -0
  37. package/src/element-plus/icon/Icon.vue +221 -0
  38. package/src/element-plus/input-number/InputNumber.vue +150 -0
  39. package/src/element-plus/paged/Paged.vue +76 -0
  40. package/src/element-plus/permission-tree/PermissionTree.vue +184 -0
  41. package/src/element-plus/query-form/QueryForm.vue +138 -0
  42. package/src/element-plus/query-table/QueryTable.vue +402 -0
  43. package/src/element-plus/region-cascader/RegionCascader.vue +108 -0
  44. package/src/element-plus/select/Select.vue +446 -0
  45. package/src/element-plus/slider/Slider.vue +88 -0
  46. package/src/element-plus/steps-nav/StepsNav.vue +57 -0
  47. package/src/element-plus/submit-form/SubmitForm.vue +236 -0
  48. package/src/element-plus/table-column/TableColumn.vue +32 -0
  49. package/src/element-plus/tabs/Tabs.vue +93 -0
  50. package/src/element-plus/tnxel.css +890 -0
  51. package/src/element-plus/tnxel.js +528 -0
  52. package/src/element-plus/transfer/Transfer.vue +117 -0
  53. package/src/element-plus/upload/Upload.vue +856 -0
  54. package/src/percent/Percent.vue +12 -0
  55. package/src/text/Text.vue +33 -0
  56. package/src/tnxvue-cli.js +64 -0
  57. package/src/tnxvue-router.js +161 -0
  58. package/src/tnxvue-validator.js +365 -0
  59. package/src/tnxvue.css +12 -0
  60. package/src/tnxvue.js +343 -0
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <el-cascader v-model="model" class="ignore-feedback" :options="items" :props="options"
3
+ :placeholder="placeholder" :show-all-levels="showAllLevels" :clearable="empty" :disabled="disabled"
4
+ :filterable="filterable" :filter-method="filter" v-if="items"/>
5
+ </template>
6
+
7
+ <script>
8
+ export default {
9
+ name: 'TnxelFetchCascader',
10
+ props: {
11
+ modelValue: String,
12
+ url: {
13
+ type: String,
14
+ required: true,
15
+ },
16
+ params: Object,
17
+ valueName: {
18
+ type: String,
19
+ default: () => 'id',
20
+ },
21
+ textName: {
22
+ type: String,
23
+ default: () => 'name',
24
+ },
25
+ indexName: {
26
+ type: String,
27
+ default: 'index',
28
+ },
29
+ childrenName: {
30
+ type: String,
31
+ default: () => 'children',
32
+ },
33
+ leafName: {
34
+ type: String,
35
+ default: () => 'leaf',
36
+ },
37
+ showAllLevels: {
38
+ type: Boolean,
39
+ default: true,
40
+ },
41
+ empty: Boolean,
42
+ placeholder: {
43
+ type: String,
44
+ default: '请选择',
45
+ },
46
+ disabled: Boolean,
47
+ change: Function, // 选中值变化后的事件处理函数,由于比element的change事件传递更多参数,所以以prop的形式指定,以尽量节省性能
48
+ transferItems: {
49
+ type: Function,
50
+ default: function(items) {
51
+ return items;
52
+ }
53
+ },
54
+ filterable: Boolean,
55
+ },
56
+ emits: ['update:modelValue'],
57
+ data() {
58
+ return {
59
+ options: {
60
+ expandTrigger: 'hover',
61
+ emitPath: false,
62
+ value: this.valueName,
63
+ label: this.textName,
64
+ children: this.childrenName,
65
+ leaf: this.leafName,
66
+ },
67
+ items: null,
68
+ model: null,
69
+ };
70
+ },
71
+ watch: {
72
+ model(value) {
73
+ this.$emit('update:modelValue', value);
74
+ this.triggerChange(value);
75
+ },
76
+ modelValue() {
77
+ this.model = this.getModel();
78
+ }
79
+ },
80
+ created() {
81
+ this.load();
82
+ },
83
+ methods: {
84
+ triggerChange(value) {
85
+ if (this.change) {
86
+ let item = this.getItem(this.items, value);
87
+ this.change(item);
88
+ }
89
+ },
90
+ getItem(items, value) {
91
+ if (items && value !== undefined) {
92
+ for (let item of items) {
93
+ let children = item[this.childrenName];
94
+ if (children && children.length) {
95
+ let child = this.getItem(children, value);
96
+ if (child) {
97
+ return child;
98
+ }
99
+ } else if (item[this.valueName] + '' === value + '') {
100
+ return item;
101
+ }
102
+ }
103
+ }
104
+ return undefined;
105
+ },
106
+ getModel() {
107
+ if (this.items && this.items.length) {
108
+ let item = this.getItem(this.items, this.modelValue);
109
+ if (item) {
110
+ return item[this.valueName];
111
+ } else { // 如果当前值找不到匹配的选项,则需要考虑是设置为空还是默认选项
112
+ if (!this.empty) { // 如果不能为空,则默认选中第一个选项
113
+ let firstItem = this.items[0];
114
+ while (firstItem[this.childrenName] && firstItem[this.childrenName].length) {
115
+ firstItem = firstItem[this.childrenName][0];
116
+ }
117
+ return firstItem ? firstItem[this.valueName] : null;
118
+ }
119
+ }
120
+ }
121
+ return null;
122
+ },
123
+ load() {
124
+ let vm = this;
125
+ window.tnx.app.rpc.get(this.url, this.params, function(result) {
126
+ vm.items = vm.transferItems(result);
127
+ vm.model = vm.getModel();
128
+ });
129
+ },
130
+ filter(node, keyword) {
131
+ let data = node.data;
132
+ return !keyword || window.tnx.util.string.matchesForEach(data[this.valueName], keyword)
133
+ || window.tnx.util.string.matchesForEach(data[this.textName], keyword)
134
+ || window.tnx.util.string.matchesForEach(data[this.indexName], keyword)
135
+ }
136
+ }
137
+ }
138
+ </script>
@@ -0,0 +1,166 @@
1
+ <template>
2
+ <el-select v-model="model" :loading="loading" :filterable="filterable" remote :remote-method="load"
3
+ :placeholder="finalPlaceholder" :disabled="disabled" :title="title" default-first-option>
4
+ <el-option class="text-secondary" :value="null" :label="emptyText" v-if="empty"/>
5
+ <el-option v-for="item in items" :key="item[valueName]" :value="item[valueName]" :label="label(item)"/>
6
+ <el-option label="还有更多结果..." disabled v-if="more"/>
7
+ </el-select>
8
+ </template>
9
+
10
+ <script>
11
+ export default {
12
+ name: 'TnxelFetchSelect',
13
+ props: {
14
+ modelValue: [String, Number],
15
+ url: String,
16
+ params: { // 构建远程检索请求参数集的函数
17
+ type: Function,
18
+ default: function(keyword) {
19
+ return keyword ? {keyword} : undefined;
20
+ }
21
+ },
22
+ resultName: { // 从返回结果中取结果清单的字段名称,常用于从分页查询结果中获取记录清单,仅当返回结果不是数组而是对象时有效
23
+ type: String,
24
+ default: () => 'records',
25
+ },
26
+ valueName: {
27
+ type: String,
28
+ default: () => 'id',
29
+ },
30
+ textName: {
31
+ type: String,
32
+ default: () => 'name',
33
+ },
34
+ descName: String,
35
+ empty: {
36
+ type: [Boolean, String],
37
+ default: false,
38
+ },
39
+ filterable: Boolean,
40
+ placeholder: [String, Array],
41
+ disabled: Boolean,
42
+ change: Function, // 选中值变化后的事件处理函数,由于比element的change事件传递更多参数,所以以prop的形式指定,以尽量节省性能
43
+ },
44
+ emits: ['update:modelValue', 'items'],
45
+ data() {
46
+ return {
47
+ items: null,
48
+ model: null, // 初始情况下,items为空,model必然为空
49
+ loading: false,
50
+ more: false,
51
+ };
52
+ },
53
+ computed: {
54
+ finalPlaceholder() {
55
+ let defaultPlaceholder;
56
+ let noItemsPlaceholder;
57
+ if (Array.isArray(this.placeholder)) {
58
+ defaultPlaceholder = this.placeholder[0];
59
+ noItemsPlaceholder = this.placeholder[1];
60
+ } else {
61
+ defaultPlaceholder = this.placeholder;
62
+ noItemsPlaceholder = '没有可选项';
63
+ }
64
+ if (this.items && this.items.length === 0) {
65
+ return noItemsPlaceholder;
66
+ }
67
+ if (defaultPlaceholder) {
68
+ return defaultPlaceholder;
69
+ }
70
+ return this.filterable ? '输入关键字进行检索' : '请选择';
71
+ },
72
+ title() {
73
+ return this.model ? undefined : this.finalPlaceholder;
74
+ },
75
+ emptyText() {
76
+ return typeof this.empty === 'string' ? this.empty : '';
77
+ },
78
+ },
79
+ watch: {
80
+ model(value) {
81
+ this.$emit('update:modelValue', value);
82
+ this.triggerChange(value);
83
+ },
84
+ modelValue() {
85
+ this.model = this.getModel();
86
+ },
87
+ url() {
88
+ this.load();
89
+ },
90
+ params() {
91
+ this.load();
92
+ }
93
+ },
94
+ created() {
95
+ this.load();
96
+ },
97
+ methods: {
98
+ label(item) {
99
+ let label = item[this.textName];
100
+ if (this.descName && item[this.descName]) {
101
+ label += ' (' + item[this.descName] + ')';
102
+ }
103
+ return label;
104
+ },
105
+ triggerChange(value) {
106
+ if (this.change) {
107
+ let item = this.getItem(value);
108
+ this.change(item);
109
+ }
110
+ },
111
+ getItem(value) {
112
+ if (value !== undefined && value !== null && this.items) {
113
+ for (let item of this.items) {
114
+ if ((item[this.valueName] + '') === (value + '')) { // 确保一致的字符串值比较
115
+ return item;
116
+ }
117
+ }
118
+ }
119
+ return undefined;
120
+ },
121
+ load(keyword) {
122
+ if (this.url && this.params) { // 当url或参数函数被设置为null时,不进行取数操作,用于初始条件不满足的情况
123
+ this.loading = true;
124
+ let params = this.params(keyword);
125
+ let vm = this;
126
+ window.tnx.app.rpc.get(this.url, params, function(result) {
127
+ vm.loading = false;
128
+ if (Array.isArray(result)) {
129
+ vm.items = result;
130
+ } else if (typeof result === 'object') {
131
+ vm.items = result[vm.resultName];
132
+ if (result.paged) {
133
+ vm.more = result.paged.morePage;
134
+ }
135
+ }
136
+ // 确保选项的值均为字符串,以保证比较时的一致性
137
+ if (Array.isArray(vm.items)) {
138
+ vm.items.forEach(item => {
139
+ item[vm.valueName] += '';
140
+ });
141
+ }
142
+ vm.$emit('items', params, vm.items, vm.more);
143
+ vm.model = vm.getModel();
144
+ });
145
+ }
146
+ },
147
+ getModel() {
148
+ if (this.items && this.items.length) {
149
+ let item = this.getItem(this.modelValue);
150
+ if (item) {
151
+ return item[this.valueName];
152
+ } else { // 如果当前值找不到匹配的选项,则需要考虑是设置为空还是默认选项
153
+ if (!this.filterable && !this.empty) { // 如果不可检索且不能为空,则默认选中第一个选项
154
+ let firstItem = this.items[0];
155
+ return firstItem ? firstItem[this.valueName] : null;
156
+ } else { // 否则设置为空
157
+ return null;
158
+ }
159
+ }
160
+ } else {
161
+ return null;
162
+ }
163
+ },
164
+ }
165
+ }
166
+ </script>
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <div class="tnxel-tag-select" v-if="items">
3
+ <el-input v-model="keyword" prefix-icon="el-icon-search" :placeholder="placheholder" clearable
4
+ v-if="filterable"/>
5
+ <tnxel-select v-model="model" :selector="multi ? 'tags' : 'tag'" :items="items" :value-name="valueName"
6
+ :text-name="textName" :change="change" :empty="empty" :theme="theme" :size="size">
7
+ <template #empty>
8
+ <slot name="empty"></slot>
9
+ </template>
10
+ </tnxel-select>
11
+ <div class="d-flex justify-content-between" v-if="paged && paged.pageCount > 1">
12
+ <div class="el-pagination" v-if="multi">
13
+ <span class="el-pagination__total">已选择 {{ value.length }} 个</span>
14
+ </div>
15
+ <el-pagination layout="prev, pager, next" background @current-change="query"
16
+ :total="paged.total" :page-size="paged.pageSize" :current-page="paged.pageNo"/>
17
+ </div>
18
+ </div>
19
+ </template>
20
+
21
+ <script>
22
+ import Select from '../select/Select.vue';
23
+
24
+ export default {
25
+ name: 'TnxelFetchTags',
26
+ components: {
27
+ 'tnxel-select': Select,
28
+ },
29
+ props: {
30
+ modelValue: [String, Number, Boolean, Array],
31
+ url: {
32
+ type: String,
33
+ required: true,
34
+ },
35
+ params: [Object, Function],
36
+ valueName: {
37
+ type: String,
38
+ default: 'id',
39
+ },
40
+ textName: {
41
+ type: String,
42
+ default: 'name',
43
+ },
44
+ keywordName: {
45
+ type: String,
46
+ default: 'keyword',
47
+ },
48
+ multi: Boolean,
49
+ empty: String,
50
+ filterable: Boolean,
51
+ placheholder: String,
52
+ change: Function,
53
+ theme: String,
54
+ size: String,
55
+ formatter: Function,
56
+ },
57
+ emits: ['update:modelValue'],
58
+ data() {
59
+ return {
60
+ model: this.modelValue,
61
+ items: null,
62
+ paged: null,
63
+ keyword: '',
64
+ }
65
+ },
66
+ watch: {
67
+ model(value) {
68
+ this.$emit('update:modelValue', value);
69
+ },
70
+ modelValue(value) {
71
+ this.model = value;
72
+ },
73
+ url() {
74
+ this.query();
75
+ },
76
+ keyword() {
77
+ this.query();
78
+ },
79
+ },
80
+ created() {
81
+ this.query();
82
+ },
83
+ methods: {
84
+ query(pageNo) {
85
+ let params;
86
+ if (typeof this.params === 'function') {
87
+ params = this.params(pageNo);
88
+ } else {
89
+ params = Object.assign({}, this.params);
90
+ if (pageNo) {
91
+ params.pageNo = pageNo;
92
+ }
93
+ }
94
+ if (this.keyword) {
95
+ params[this.keywordName] = this.keyword;
96
+ }
97
+ let vm = this;
98
+ window.tnx.app.rpc.get(this.url, params, result => {
99
+ if (result instanceof Array) {
100
+ vm.items = vm.format(result);
101
+ } else if (result.records && result.paged) {
102
+ vm.items = vm.format(result.records);
103
+ vm.paged = result.paged;
104
+ }
105
+ });
106
+ },
107
+ format(items) {
108
+ let result = items;
109
+ if (items && this.formatter) {
110
+ result = [];
111
+ for (let item of items) {
112
+ item = this.formatter(item);
113
+ if (item) {
114
+ result.push(item);
115
+ }
116
+ }
117
+ }
118
+ return result;
119
+ }
120
+ }
121
+ }
122
+ </script>