flameresttable 1.0.11 → 1.0.13
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/.vscode/launch.json +1 -1
- package/package.json +23 -26
- package/src/App.vue +17 -13
- package/src/Table/Columns.ts +37 -0
- package/src/Table/FlameTable.ts +54 -1
- package/src/Table/Paginator.vue +2 -2
- package/src/Table/Table.vue +8 -4
- package/src/Table/TableFilters.vue +25 -5
- package/src/Table/TableLoadParams.ts +10 -0
- package/src/Table/TableOpts.ts +2 -1
- package/src/main.ts +6 -4
- package/src/router.ts +1 -27
package/.vscode/launch.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flameresttable",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.13",
|
|
4
4
|
"main": "./src/plugin.ts",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -15,38 +15,35 @@
|
|
|
15
15
|
"android": "npm run build && npx cap add android && npx cap sync && npx cap open android"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@vuepic/vue-datepicker": "^
|
|
19
|
-
"flamerest": "^1.0.
|
|
18
|
+
"@vuepic/vue-datepicker": "^7.2.0",
|
|
19
|
+
"flamerest": "^1.0.92",
|
|
20
20
|
"lodash-es": "^4.17.21",
|
|
21
|
-
"pinia": "^2.
|
|
21
|
+
"pinia": "^2.1.7",
|
|
22
22
|
"pug": "github:FlameArt/pug-tailwind-only",
|
|
23
23
|
"pug-lexer": "github:FlameArt/pug-lexer-only",
|
|
24
|
-
"sass": "^1.
|
|
25
|
-
"vue": "^3.
|
|
26
|
-
"vue-router": "^4.
|
|
24
|
+
"sass": "^1.69.5",
|
|
25
|
+
"vue": "^3.3.7",
|
|
26
|
+
"vue-router": "^4.2.5"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
|
-
"@
|
|
30
|
-
"@
|
|
31
|
-
"@
|
|
32
|
-
"@
|
|
33
|
-
"@
|
|
34
|
-
"@
|
|
35
|
-
"@
|
|
36
|
-
"@
|
|
37
|
-
"@
|
|
38
|
-
"
|
|
39
|
-
"
|
|
40
|
-
"@vue/compiler-sfc": "^3.2.45",
|
|
41
|
-
"autoprefixer": "^10.4.14",
|
|
42
|
-
"eslint": "^8.38.0",
|
|
29
|
+
"@heroicons/vue": "^2.0.18",
|
|
30
|
+
"@types/lodash-es": "^4.17.10",
|
|
31
|
+
"@types/lodash.merge": "^4.6.8",
|
|
32
|
+
"@types/node": "20.8.9",
|
|
33
|
+
"@typescript-eslint/eslint-plugin": "^6.9.0",
|
|
34
|
+
"@typescript-eslint/parser": "^6.9.0",
|
|
35
|
+
"@vitejs/plugin-vue": "^4.4.0",
|
|
36
|
+
"@volar/vue-language-plugin-pug": "^1.6.5",
|
|
37
|
+
"@vue/compiler-sfc": "^3.3.7",
|
|
38
|
+
"autoprefixer": "^10.4.16",
|
|
39
|
+
"eslint": "^8.52.0",
|
|
43
40
|
"eslint-plugin-vue": "^8.7.1",
|
|
44
|
-
"postcss": "^8.4.
|
|
41
|
+
"postcss": "^8.4.31",
|
|
45
42
|
"postcss-import": "^14.1.0",
|
|
46
|
-
"tailwindcss": "^3.3.
|
|
47
|
-
"typescript": "^
|
|
48
|
-
"vite": "^4.
|
|
49
|
-
"vue-tsc": "^1.
|
|
43
|
+
"tailwindcss": "^3.3.5",
|
|
44
|
+
"typescript": "^5.2.2",
|
|
45
|
+
"vite": "^4.5.0",
|
|
46
|
+
"vue-tsc": "^1.8.22",
|
|
50
47
|
"vue-universal-modal": "^1.1.4"
|
|
51
48
|
},
|
|
52
49
|
"rules": {}
|
package/src/App.vue
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { onMounted, reactive, defineProps } from '@vue/runtime-core'; import { storeFile } from "@/store"; import { useRoute, useRouter } from 'vue-router'; import REST from "flamerest"
|
|
3
3
|
import Table from './Table/Table.vue';
|
|
4
|
+
import { ref } from 'vue';
|
|
5
|
+
import Model from '@models/Testtable';
|
|
6
|
+
import TableOpts from './Table/TableOpts';
|
|
7
|
+
|
|
4
8
|
const store = storeFile(), router = useRouter(), route = useRoute();
|
|
5
9
|
|
|
6
10
|
let notRedirectOnAuthList = [
|
|
@@ -11,23 +15,23 @@ let notRedirectOnAuthList = [
|
|
|
11
15
|
];
|
|
12
16
|
|
|
13
17
|
onMounted(() => {
|
|
14
|
-
|
|
15
|
-
store.authUser(res);
|
|
16
|
-
store.User.isLoaded = true;
|
|
17
|
-
if (res.isAuthorized === false) {
|
|
18
|
-
if (!notRedirectOnAuthList.includes(route.name?.toString() ?? "")) {
|
|
19
|
-
router.push({ name: "Auth" });
|
|
20
|
-
}
|
|
21
|
-
} else {
|
|
22
|
-
// Load state
|
|
23
|
-
// store.projects = REST.get("projects");
|
|
24
|
-
}
|
|
25
|
-
});
|
|
18
|
+
|
|
26
19
|
});
|
|
20
|
+
|
|
21
|
+
const TableComponent = ref<InstanceType<typeof Table>>();
|
|
22
|
+
const opts = new TableOpts;
|
|
23
|
+
opts.Add.can = true;
|
|
24
|
+
opts.Remove.can = true;
|
|
25
|
+
|
|
26
|
+
// Загружаем первичные данные
|
|
27
|
+
Model.all({ sort: ['id'] }).then(r =>
|
|
28
|
+
TableComponent.value?.Table.load(r)
|
|
29
|
+
)
|
|
30
|
+
|
|
27
31
|
</script>
|
|
28
32
|
|
|
29
33
|
<template lang="pug">
|
|
30
|
-
Table
|
|
34
|
+
Table(:model="Model", :opts="opts")
|
|
31
35
|
</template>
|
|
32
36
|
|
|
33
37
|
<style>
|
package/src/Table/Columns.ts
CHANGED
|
@@ -53,6 +53,32 @@ export class Column implements IColumn {
|
|
|
53
53
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Это related данные для всех селекторов и внутри таблицы
|
|
58
|
+
*/
|
|
59
|
+
public Selector = {
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Загрузчик значений
|
|
63
|
+
* @returns Array
|
|
64
|
+
*/
|
|
65
|
+
loader: () => [],
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Здесь список готовых значений
|
|
69
|
+
*/
|
|
70
|
+
values: [],
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Здесь можно определить кастомный лоадер при поиске
|
|
74
|
+
* @param row
|
|
75
|
+
* @param col
|
|
76
|
+
* @returns
|
|
77
|
+
*/
|
|
78
|
+
value: (row: any, col: string) => row[col]
|
|
79
|
+
|
|
80
|
+
};
|
|
81
|
+
|
|
56
82
|
/**
|
|
57
83
|
* Настройки фильтра
|
|
58
84
|
*/
|
|
@@ -65,6 +91,14 @@ export class Column implements IColumn {
|
|
|
65
91
|
valueString: "",
|
|
66
92
|
valueRange: { from: '', to: '' },
|
|
67
93
|
|
|
94
|
+
// Тип фильтра
|
|
95
|
+
type: 'text' as "text" | "fixed" | "fulltext" | "number" | "date" | "daterange" | "selector",
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Список значений под выбор
|
|
99
|
+
*/
|
|
100
|
+
select: [],
|
|
101
|
+
|
|
68
102
|
// Минимальное число символов в строке фильтра, после которого будет произведён запрос
|
|
69
103
|
filterMinSymbolsRequest: 0,
|
|
70
104
|
|
|
@@ -211,6 +245,9 @@ export interface IColumn {
|
|
|
211
245
|
// Показываем ли фильтр
|
|
212
246
|
isShow?: boolean,
|
|
213
247
|
|
|
248
|
+
// Тип фильтра
|
|
249
|
+
type: "text" | "fixed" | "fulltext" | "number" | "date" | "daterange" | "selector",
|
|
250
|
+
|
|
214
251
|
// Значение
|
|
215
252
|
valueString?: string,
|
|
216
253
|
valueRange?: { from: string, to: string },
|
package/src/Table/FlameTable.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { Rows, SavedObject } from 'flamerest';
|
|
|
3
3
|
import TableOpts from "./TableOpts";
|
|
4
4
|
import { reactive, UnwrapRef } from 'vue';
|
|
5
5
|
import merge from 'lodash-es/merge'
|
|
6
|
+
import ITableLoadParams from './TableLoadParams';
|
|
6
7
|
|
|
7
8
|
// Подгрузчик типа класса
|
|
8
9
|
type Class<T> = new (...args: any[]) => T
|
|
@@ -121,12 +122,64 @@ export default class FlameTable<T> {
|
|
|
121
122
|
|
|
122
123
|
if (SaveLoadParams !== null) this.opts.LoadParams = SaveLoadParams;
|
|
123
124
|
|
|
124
|
-
|
|
125
|
+
// Дополняем загрузочные параметры фильтрами
|
|
126
|
+
const filters = this.applyFiltersParams();
|
|
127
|
+
|
|
128
|
+
const rows: Rows<T> = await (this.model as any).constructor.all(merge({}, this.opts.LoadParams, filters, { page: this.Pager.page, perPage: this.Pager.perPage }));
|
|
125
129
|
|
|
126
130
|
this.load(rows);
|
|
127
131
|
|
|
128
132
|
}
|
|
129
133
|
|
|
134
|
+
public applyFiltersParams() {
|
|
135
|
+
const customFilters: ITableLoadParams = {
|
|
136
|
+
where: {}
|
|
137
|
+
};
|
|
138
|
+
for (const key in this.columns) {
|
|
139
|
+
const el = this.columns[key].Filter;
|
|
140
|
+
switch (el.type) {
|
|
141
|
+
|
|
142
|
+
// Частичное совпадение
|
|
143
|
+
case 'text':
|
|
144
|
+
|
|
145
|
+
if (el.valueString.trim() === '') continue;
|
|
146
|
+
customFilters.where[key] = ['LIKE', key, el.valueString];
|
|
147
|
+
break;
|
|
148
|
+
|
|
149
|
+
// Фуллтекстовый поиск
|
|
150
|
+
case 'fulltext':
|
|
151
|
+
|
|
152
|
+
if (el.valueString.trim() === '') continue;
|
|
153
|
+
customFilters.where[key] = ['FULLTEXT', key, el.valueString];
|
|
154
|
+
break;
|
|
155
|
+
|
|
156
|
+
// Точное совпадение
|
|
157
|
+
case 'fixed':
|
|
158
|
+
case 'date':
|
|
159
|
+
case 'selector':
|
|
160
|
+
|
|
161
|
+
if (el.valueString.trim() === '') continue;
|
|
162
|
+
customFilters.where[key] = el.valueString;
|
|
163
|
+
|
|
164
|
+
break;
|
|
165
|
+
|
|
166
|
+
// ДИАПАЗОН
|
|
167
|
+
case 'number':
|
|
168
|
+
case 'daterange':
|
|
169
|
+
|
|
170
|
+
if (el.valueRange.from.trim() !== '')
|
|
171
|
+
customFilters.where[key] = ['>=', key, el.valueRange.from];
|
|
172
|
+
if (el.valueRange.to.trim() !== '')
|
|
173
|
+
customFilters.where[key] = ['<=', key, el.valueRange.to];
|
|
174
|
+
|
|
175
|
+
break;
|
|
176
|
+
|
|
177
|
+
default:
|
|
178
|
+
alert('Unknown table filter type');
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return customFilters;
|
|
182
|
+
}
|
|
130
183
|
|
|
131
184
|
|
|
132
185
|
public async add(): Promise<SavedObject<T> | null> {
|
package/src/Table/Paginator.vue
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
<template lang="pug">
|
|
2
|
-
nav.relative.z-0.w-full.fc.rounded-md.-space-x-px(aria-label='Pagination' @click="")
|
|
2
|
+
nav.relative.z-0.w-full.fc.flex-wrap.rounded-md.-space-x-px(aria-label='Pagination' @click="")
|
|
3
3
|
a.relative.inline-flex.items-center.px-2.py-2.rounded-l-md.border.border-gray-300.bg-white.text-sm.font-medium.text-gray-500(href='#' class='hover:bg-gray-50')
|
|
4
4
|
span.sr-only Previous
|
|
5
5
|
// Heroicon name: solid/chevron-left
|
|
6
6
|
svg.h-5.w-5(xmlns='http://www.w3.org/2000/svg' viewbox='0 0 20 20' fill='currentColor' aria-hidden='true')
|
|
7
7
|
path(fill-rule='evenodd' d='M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z' clip-rule='evenodd')
|
|
8
8
|
// Current: "z-10 bg-indigo-50 border-indigo-500 text-indigo-600", Default: "bg-white border-gray-300 text-gray-500 hover:bg-gray-50"
|
|
9
|
-
a.bg-white.border-gray-300.text-gray-500.relative.inline-flex.items-center.px-4.py-2.border.text-sm.font-medium(v-for="page in props.table.Pager.count" class="hover:bg-gray-50" :class="props.table.Pager.page === page ? 'z-10 bg-indigo-50 border-indigo-500 text-indigo-600' : ''" @click="goPage(page)")
|
|
9
|
+
a.cursor-pointer.bg-white.border-gray-300.text-gray-500.relative.inline-flex.items-center.px-4.py-2.border.text-sm.font-medium(v-for="page in props.table.Pager.count" class="hover:bg-gray-50" :class="props.table.Pager.page === page ? 'z-10 bg-indigo-50 border-indigo-500 text-indigo-600' : ''" @click="goPage(page)")
|
|
10
10
|
| {{ page }}
|
|
11
11
|
//span.relative.inline-flex.items-center.px-4.py-2.border.border-gray-300.bg-white.text-sm.font-medium.text-gray-700 ...
|
|
12
12
|
a.relative.inline-flex.items-center.px-2.py-2.rounded-r-md.border.border-gray-300.bg-white.text-sm.font-medium.text-gray-500(href='#' class='hover:bg-gray-50')
|
package/src/Table/Table.vue
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div class="mt-0">
|
|
2
|
+
<div class="mt-0 overflow-x-scroll">
|
|
3
|
+
|
|
4
|
+
<!-- ФИЛЬТРЫ -->
|
|
5
|
+
<TableFilters :columns="Table.columns" :table="Table"></TableFilters>
|
|
3
6
|
|
|
4
7
|
<!-- "ДОБАВИТЬ" И ЧИСЛО ЗАПИСЕЙ-->
|
|
5
8
|
<div class="flex items-center justify-between">
|
|
@@ -26,7 +29,7 @@
|
|
|
26
29
|
</div>
|
|
27
30
|
|
|
28
31
|
<!-- ТАБЛИЦА-->
|
|
29
|
-
<div class="mt-2 table w-full">
|
|
32
|
+
<div class="mt-2 table w-full ">
|
|
30
33
|
|
|
31
34
|
<!-- ЗАГОЛОВКИ СТОЛБЦОВ-->
|
|
32
35
|
<div class="table-header-group">
|
|
@@ -176,7 +179,7 @@
|
|
|
176
179
|
</div>
|
|
177
180
|
<div
|
|
178
181
|
class="cursor-pointer ml-2 text-lg py-2 mr-3 text-white block bg-blue-600 font-medium rounded text-sm px-4 text-center hover:bg-blue-700 focus:ring-4 focus:ring-blue-200 dark:focus:ring-blue-900"
|
|
179
|
-
@click="SaveTable()">
|
|
182
|
+
@click=" SaveTable()">
|
|
180
183
|
{{ Table.mode === 'add' ? 'Добавить' : 'Сохранить' }}
|
|
181
184
|
</div>
|
|
182
185
|
</div>
|
|
@@ -197,6 +200,7 @@ import TableOpts from './TableOpts';
|
|
|
197
200
|
import FlameTable from './FlameTable';
|
|
198
201
|
import ModalVue from './../components/default/Modal.vue';
|
|
199
202
|
import Paginator from './Paginator.vue';
|
|
203
|
+
import TableFilters from './TableFilters.vue';
|
|
200
204
|
type Class<T> = new (...args: any[]) => T;
|
|
201
205
|
|
|
202
206
|
import Datepicker from '@vuepic/vue-datepicker';
|
|
@@ -205,7 +209,7 @@ import { isNumber } from 'lodash';
|
|
|
205
209
|
|
|
206
210
|
|
|
207
211
|
export default defineComponent({
|
|
208
|
-
components: { ModalVue, Paginator, Datepicker },
|
|
212
|
+
components: { ModalVue, Paginator, Datepicker, TableFilters },
|
|
209
213
|
props: {
|
|
210
214
|
rows: {
|
|
211
215
|
default: [] as Array<any>,
|
|
@@ -1,13 +1,25 @@
|
|
|
1
|
-
<template
|
|
2
|
-
|
|
1
|
+
<template>
|
|
2
|
+
<div class="fc flex-wrap">
|
|
3
|
+
<div v-for="(col) in props.columns" :key="col.name">
|
|
4
|
+
{{ col.name }}
|
|
5
|
+
<!-- ТЕКСТ -->
|
|
6
|
+
<div v-if="col.Filter.type === 'text'">
|
|
7
|
+
<input type="text" @keyup="update()" v-model="col.Filter.valueString" />
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
</div>
|
|
11
|
+
</div>
|
|
3
12
|
</template>
|
|
4
13
|
|
|
5
|
-
<script setup lang="ts">
|
|
14
|
+
<script setup lang="ts" generic="T">
|
|
6
15
|
import { onMounted, reactive, ref, defineProps } from '@vue/runtime-core'; import type { Ref } from 'vue'; import { storeFile } from "@/store"; import { useRoute, useRouter } from 'vue-router'; import REST from "flamerest"
|
|
7
16
|
|
|
8
17
|
// Иконки
|
|
9
18
|
import { XCircleIcon } from '@icons/24/solid'
|
|
10
|
-
import
|
|
19
|
+
import TableOpts from './TableOpts';
|
|
20
|
+
import { Column } from './Columns';
|
|
21
|
+
//import { TableFilter } from './TableOpts.js';
|
|
22
|
+
import FlameTable from './FlameTable';
|
|
11
23
|
|
|
12
24
|
// Глобальное хранилище и роуты
|
|
13
25
|
const store = storeFile(), router = useRouter(), route = useRoute();
|
|
@@ -19,7 +31,8 @@ const state = reactive({
|
|
|
19
31
|
|
|
20
32
|
// Входящие данные компонента
|
|
21
33
|
const props = defineProps<{
|
|
22
|
-
|
|
34
|
+
columns: { [key: string]: Column; },
|
|
35
|
+
table: FlameTable<any>,
|
|
23
36
|
}>()
|
|
24
37
|
|
|
25
38
|
// Примонтировано
|
|
@@ -27,6 +40,13 @@ onMounted(async () => {
|
|
|
27
40
|
|
|
28
41
|
})
|
|
29
42
|
|
|
43
|
+
|
|
44
|
+
const update = () => {
|
|
45
|
+
|
|
46
|
+
props.table.update();
|
|
47
|
+
|
|
48
|
+
}
|
|
49
|
+
|
|
30
50
|
</script>
|
|
31
51
|
|
|
32
52
|
<style scoped lang="scss"></style>
|
package/src/Table/TableOpts.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { Column, IColumn } from './Columns';
|
|
|
2
2
|
|
|
3
3
|
import merge from 'lodash-es/merge'
|
|
4
4
|
import FlameTable from './FlameTable';
|
|
5
|
+
import ITableLoadParams from './TableLoadParams';
|
|
5
6
|
|
|
6
7
|
export default class TableOpts {
|
|
7
8
|
|
|
@@ -18,7 +19,7 @@ export default class TableOpts {
|
|
|
18
19
|
/**
|
|
19
20
|
* Параметры прогрузки
|
|
20
21
|
*/
|
|
21
|
-
public LoadParams = {}
|
|
22
|
+
public LoadParams: ITableLoadParams = {};
|
|
22
23
|
|
|
23
24
|
|
|
24
25
|
public set(ColumnName: string, mergingOpts: IColumn) {
|
package/src/main.ts
CHANGED
|
@@ -6,12 +6,14 @@ import router from "./router";
|
|
|
6
6
|
|
|
7
7
|
import 'vue-universal-modal/dist/index.css'
|
|
8
8
|
import VueUniversalModal from 'vue-universal-modal'
|
|
9
|
+
import REST from 'flamerest';
|
|
9
10
|
|
|
10
11
|
|
|
12
|
+
REST.SERVER = 'http://testrest';
|
|
11
13
|
|
|
12
14
|
|
|
13
15
|
createApp(App)
|
|
14
|
-
.use(createPinia())
|
|
15
|
-
.use(router)
|
|
16
|
-
.use(VueUniversalModal, {teleportTarget: '#my-modals',modalComponent: 'CustomModal'})
|
|
17
|
-
.mount('#app')
|
|
16
|
+
.use(createPinia())
|
|
17
|
+
.use(router)
|
|
18
|
+
.use(VueUniversalModal, { teleportTarget: '#my-modals', modalComponent: 'CustomModal' })
|
|
19
|
+
.mount('#app')
|
package/src/router.ts
CHANGED
|
@@ -3,34 +3,8 @@ const routes = [
|
|
|
3
3
|
{
|
|
4
4
|
path: '/',
|
|
5
5
|
name: 'Home',
|
|
6
|
-
component: ()=> import('./pages/Home.vue'),
|
|
6
|
+
component: () => import('./pages/Home.vue'),
|
|
7
7
|
},
|
|
8
|
-
{
|
|
9
|
-
path: '/in',
|
|
10
|
-
name: 'Auth',
|
|
11
|
-
component: ()=> import('./pages/user/Auth.vue'),
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
path: '/signup',
|
|
15
|
-
name: 'Signup',
|
|
16
|
-
component: ()=> import('./pages/user/Signup.vue'),
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
path: '/resetpasswordrequest',
|
|
20
|
-
name: 'ResetPasswordRequest',
|
|
21
|
-
component: ()=> import('./pages/user/ResetPasswordRequest.vue'),
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
path: '/resetpassword',
|
|
25
|
-
name: 'ResetPassword',
|
|
26
|
-
component: ()=> import('./pages/user/ResetPassword.vue'),
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
path: '/mysettings',
|
|
30
|
-
name: 'MySettings',
|
|
31
|
-
component: ()=> import('./pages/user/UserSettings.vue'),
|
|
32
|
-
},
|
|
33
|
-
|
|
34
8
|
|
|
35
9
|
]
|
|
36
10
|
const router = createRouter({
|