@xilonglab/vue-main 0.7.8

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 (53) hide show
  1. package/dist/page/app.vue +86 -0
  2. package/dist/page/login.vue +185 -0
  3. package/dist/page/setting.vue +72 -0
  4. package/dist/style/app.less +58 -0
  5. package/dist/style/reset.css +32 -0
  6. package/package.json +15 -0
  7. package/packages/XlBreadcrumb.vue +85 -0
  8. package/packages/XlControlBar.vue +64 -0
  9. package/packages/XlSideBar.vue +135 -0
  10. package/packages/button/XlAsyncButton.vue +67 -0
  11. package/packages/button/XlButton.vue +25 -0
  12. package/packages/button/XlDeleteButton.vue +22 -0
  13. package/packages/button/XlEditButton.vue +22 -0
  14. package/packages/button/XlIconButton.vue +22 -0
  15. package/packages/button/XlUploadButton.vue +109 -0
  16. package/packages/dialog/XlDialog.vue +116 -0
  17. package/packages/dialog/XlEditReviewDialog.vue +81 -0
  18. package/packages/dialog/XlFormDialog.vue +79 -0
  19. package/packages/dialog/XlImagePreviewDialog.vue +40 -0
  20. package/packages/dialog/XlMessageDialog.vue +74 -0
  21. package/packages/dialog/XlReviewDialog.vue +115 -0
  22. package/packages/dialog/XlStateDialog.vue +21 -0
  23. package/packages/form/XlCascader.vue +46 -0
  24. package/packages/form/XlCheckbox.vue +45 -0
  25. package/packages/form/XlDate.vue +54 -0
  26. package/packages/form/XlFormCol.vue +19 -0
  27. package/packages/form/XlFormRow.vue +20 -0
  28. package/packages/form/XlImageInput.vue +127 -0
  29. package/packages/form/XlInput.vue +53 -0
  30. package/packages/form/XlMapSelect.vue +72 -0
  31. package/packages/form/XlNumber.vue +11 -0
  32. package/packages/form/XlRadio.vue +42 -0
  33. package/packages/form/XlRawSelect.vue +71 -0
  34. package/packages/form/XlRegion.vue +51 -0
  35. package/packages/form/XlSearchSelect.vue +85 -0
  36. package/packages/form/XlSelect.vue +77 -0
  37. package/packages/form/XlSwitch.vue +33 -0
  38. package/packages/form/XlTabRadio.vue +43 -0
  39. package/packages/form/XlTags.vue +105 -0
  40. package/packages/form/XlTextarea.vue +48 -0
  41. package/packages/form/XlTime.vue +50 -0
  42. package/packages/form/data/areas.json +1 -0
  43. package/packages/index.js +130 -0
  44. package/packages/main/XlAutoSaver.vue +75 -0
  45. package/packages/main/XlDataView.vue +212 -0
  46. package/packages/main/XlFormDialog2.vue +80 -0
  47. package/packages/main/XlLoginForm.vue +192 -0
  48. package/packages/main/XlNavBar.vue +89 -0
  49. package/packages/main/XlStatusIndicator.vue +36 -0
  50. package/packages/main/XlTabView.vue +81 -0
  51. package/packages/main/XlToolBar.vue +132 -0
  52. package/packages/main/XlUpdateIndicator.vue +40 -0
  53. package/packages/main/XlVerticalMenu.vue +72 -0
@@ -0,0 +1,135 @@
1
+ <script setup>
2
+ defineOptions({
3
+ name: 'XlSideBar',
4
+ });
5
+
6
+ const props = defineProps({
7
+ logo: {
8
+ type: String,
9
+ },
10
+ menuItems: {
11
+ type: Array,
12
+ default: () => [],
13
+ },
14
+ defaultOpeneds: {
15
+ type: Array,
16
+ default: () => [],
17
+ },
18
+ });
19
+
20
+ const emits = defineEmits(["select"]);
21
+
22
+ const triggers = {
23
+ select(val) {
24
+ let path;
25
+ let [submenuIndex, itemIndex] = val.split("-");
26
+ if (itemIndex) {
27
+ path = props.menuItems[submenuIndex].children[itemIndex].path;
28
+ } else {
29
+ path = props.menuItems[submenuIndex].path;
30
+ }
31
+ emits("select", path);
32
+ }
33
+ }
34
+ </script>
35
+
36
+
37
+ <template>
38
+ <div class="xl-side-bar">
39
+ <el-menu class="side-bar-menu" :default-openeds="defaultOpeneds" @select="triggers.select" text-color="#BCD1C7"
40
+ active-text-color="#F0F0F0">
41
+ <slot />
42
+ <template v-for="(item, index) in menuItems">
43
+
44
+ <el-sub-menu class="sub-menu" v-if="item.children" :key="index" :index="String(index)">
45
+ <template #title>
46
+ <i class="iconfont" v-html="item.iconCode"></i>
47
+ <span>{{ item.name }}</span>
48
+ </template>
49
+ <el-menu-item-group>
50
+ <el-menu-item v-for="(child, childIndex) in item.children" :index="index + '-' + childIndex"
51
+ :key="childIndex">
52
+ <span>{{ child.name }}</span>
53
+ </el-menu-item>
54
+ </el-menu-item-group>
55
+ </el-sub-menu>
56
+ <el-menu-item v-else :index="String(index)" :key="`${index}1`">
57
+ <template #title>
58
+ <i class="iconfont" v-html="item.iconCode"></i>
59
+ <span>{{ item.name }}</span>
60
+ </template>
61
+ </el-menu-item>
62
+ </template>
63
+ </el-menu>
64
+ </div>
65
+
66
+ </template>
67
+
68
+
69
+ <style lang="less">
70
+ @sidebar-background: rgb(0 0 0 / 40%);
71
+ @sidebar-color: #f0f0f0;
72
+ @sidebar-active-background: rgb(0 0 0 / 30%);
73
+ @transition-function: width 0.7s cubic-bezier(0.17, 0.67, 0.84, 0.66);
74
+
75
+ .xl-side-bar {
76
+ overflow-y: scroll;
77
+ scrollbar-width: none;
78
+ border-right: 0 !important;
79
+ height: 100%;
80
+
81
+ .side-bar-menu {
82
+ margin: 5px;
83
+ background: @sidebar-background;
84
+ height: calc(~"100% - 10px");
85
+ border-radius: 7px;
86
+ border: 0;
87
+ overflow: hidden;
88
+
89
+ overflow: auto;
90
+ scrollbar-width: none;
91
+ -ms-overflow-style: none;
92
+
93
+ &::-webkit-scrollbar {
94
+ display: none;
95
+ }
96
+
97
+ .el-menu {
98
+ background: transparent;
99
+ }
100
+ }
101
+
102
+ .el-sub-menu__title,
103
+ .el-menu-item {
104
+ background: @sidebar-background;
105
+ }
106
+
107
+ .el-menu-item {
108
+ transition: @transition-function;
109
+ -moz-transition: @transition-function;
110
+ -webkit-transition: @transition-function;
111
+ -o-transition: @transition-function;
112
+ background: transparent;
113
+
114
+ &:hover {
115
+ color: @sidebar-color !important;
116
+
117
+ i {
118
+ color: @sidebar-color !important;
119
+ }
120
+ }
121
+
122
+ &.is-active {
123
+ background: @sidebar-active-background !important;
124
+ }
125
+ }
126
+
127
+ .el-menu-item-group__title {
128
+ display: none;
129
+ }
130
+
131
+ &::-webkit-scrollbar {
132
+ display: none;
133
+ }
134
+ }
135
+ </style>
@@ -0,0 +1,67 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlAsyncButton" })
3
+
4
+ import { ref } from 'vue'
5
+
6
+ const props = defineProps({
7
+ api: {
8
+ type: Function,
9
+ default: () => ({}),
10
+ },
11
+ l: {
12
+ type: String,
13
+ default: ''
14
+ },
15
+ disabled: {
16
+ type: Boolean,
17
+ default: false
18
+ },
19
+ type: {
20
+ type: String,
21
+ },
22
+ width: {
23
+ type: Number,
24
+ },
25
+ icon: {
26
+ type: String,
27
+ default: "",
28
+ },
29
+ });
30
+
31
+
32
+ const btnRef = ref(null)
33
+ const loading = ref(false)
34
+
35
+ async function handleClick() {
36
+ loading.value = true;
37
+ try {
38
+ await props.api();
39
+ loading.value = false;
40
+ setTimeout(() => {
41
+ loading.value = false;
42
+ }, 450);
43
+ } catch (e) {
44
+ loading.value = false;
45
+ }
46
+ }
47
+
48
+ function click() {
49
+ btnRef.value.$el.click()
50
+ }
51
+
52
+ defineExpose({ click })
53
+ </script>
54
+
55
+
56
+ <template>
57
+ <el-button class="xl-button xl-async-button" ref="btnRef" :type="type" :disabled="disabled" :loading="loading"
58
+ :icon="icon" @click="handleClick">
59
+ <span v-if="!loading">
60
+ {{ l }}
61
+ <slot />
62
+ </span>
63
+ </el-button>
64
+ </template>
65
+
66
+
67
+ <style></style>
@@ -0,0 +1,25 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlButton" })
3
+
4
+ const props = defineProps({
5
+ type: {},
6
+ l: {
7
+ type: String,
8
+ default: ''
9
+ },
10
+ disabled: {},
11
+ loading: {},
12
+ icon: {},
13
+ });
14
+ </script>
15
+
16
+
17
+ <template>
18
+ <el-button class="xl-button" :type="type" :disabled="disabled" :loading="loading" :icon="icon">
19
+ <span>{{ l }}</span>
20
+ <slot />
21
+ </el-button>
22
+ </template>
23
+
24
+
25
+ <style lang="less"></style>
@@ -0,0 +1,22 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlDeleteButton" })
3
+
4
+ const emits = defineEmits('click')
5
+
6
+ const props = defineProps({
7
+ disabled: {},
8
+ loading: {},
9
+ icon: {},
10
+ l: {}
11
+ });
12
+ </script>
13
+
14
+ <template>
15
+ <xl-button type="danger" v-bind="$props" @click="() => emits('click')">
16
+ <el-icon>
17
+ <Delete />
18
+ </el-icon>
19
+ </xl-button>
20
+ </template>
21
+
22
+ <style lang="less"></style>
@@ -0,0 +1,22 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlEditButton" })
3
+
4
+ const emits = defineEmits('click')
5
+
6
+ const props = defineProps({
7
+ disabled: {},
8
+ loading: {},
9
+ icon: {},
10
+ l: {}
11
+ });
12
+ </script>
13
+
14
+ <template>
15
+ <xl-button type="primary" v-bind="$props" @click="() => emits('click')">
16
+ <el-icon>
17
+ <Edit />
18
+ </el-icon>
19
+ </xl-button>
20
+ </template>
21
+
22
+ <style lang="less"></style>
@@ -0,0 +1,22 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlIconButton" })
3
+
4
+ const emits = defineEmits('click')
5
+
6
+ const props = defineProps({
7
+ type: {},
8
+ code: {},
9
+ disabled: {},
10
+ loading: {},
11
+ icon: {},
12
+ l: {}
13
+ });
14
+ </script>
15
+
16
+ <template>
17
+ <xl-button v-bind="$props" @click="() => emits('click')">
18
+ <i class="iconfont" v-html="code"/>
19
+ </xl-button>
20
+ </template>
21
+
22
+ <style lang="less"></style>
@@ -0,0 +1,109 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlUploadButton" })
3
+
4
+ import { ref } from 'vue';
5
+ import { ElMessage } from 'element-plus'
6
+
7
+
8
+ const emits = defineEmits(['uploaded'])
9
+
10
+ const props = defineProps({
11
+ api: {
12
+ type: Function,
13
+ default: () => { },
14
+ },
15
+ l: {
16
+ type: String,
17
+ default: ''
18
+ },
19
+ params: {
20
+ type: Object,
21
+ default() {
22
+ return {};
23
+ },
24
+ },
25
+ text: {
26
+ type: String,
27
+ default: "上传",
28
+ },
29
+ allowedTypes: {
30
+ type: Array,
31
+ default() {
32
+ return [];
33
+ },
34
+ },
35
+ disabled: {
36
+ type: Boolean,
37
+ default: false,
38
+ },
39
+ type: {
40
+ type: String,
41
+ default: "",
42
+ },
43
+ })
44
+
45
+ const headers = { token: localStorage.getItem("accessToken") }
46
+ const loading = ref(false)
47
+
48
+ const handlers = {
49
+ validateFileType(fileType) {
50
+ const { allowedTypes } = props;
51
+ if (allowedTypes.length == 0) {
52
+ return true;
53
+ } else {
54
+ if (allowedTypes.indexOf(fileType) < 0) {
55
+ return false;
56
+ } else {
57
+ return true;
58
+ }
59
+ }
60
+ },
61
+ beforeUpload(file) {
62
+ loading.value = true;
63
+ },
64
+ upload(option) {
65
+ const { params } = props
66
+ let formData = new FormData();
67
+ const file = option.file;
68
+ const filename = file.name;
69
+ const fileType = file.type;
70
+ if (!handlers.validateFileType(fileType)) {
71
+ ElMessage.error(`文件类型错误`)
72
+ loading.value = false;
73
+ return;
74
+ }
75
+ formData.append("file", file);
76
+ formData.append("file_name", filename);
77
+ for (let key in params) {
78
+ formData.append(key, params[key]);
79
+ }
80
+ return props.api(formData);
81
+ },
82
+ onSuccess(data, file, filelist) {
83
+ loading.value = false;
84
+ emits("uploaded", data);
85
+ },
86
+ }
87
+ </script>
88
+
89
+
90
+ <template>
91
+ <el-upload class="xl-upload-button" ref="uploader" action="" :headers="headers" :http-request="handlers.upload"
92
+ :before-upload="handlers.beforeUpload" :on-success="handlers.onSuccess" :show-file-list="false"
93
+ :disabled="disabled">
94
+ <xl-button :loading="loading" :l="l" :type="type">
95
+ <slot />
96
+ </xl-button>
97
+ </el-upload>
98
+ </template>
99
+
100
+
101
+ <style lang="less">
102
+ .xl-upload-button {
103
+ display: inline-block;
104
+
105
+ .el-upload {
106
+ display: inline-block;
107
+ }
108
+ }
109
+ </style>
@@ -0,0 +1,116 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlDialog" })
3
+
4
+ import { ref } from 'vue';
5
+
6
+
7
+ const emits = defineEmits(['confirm', 'finish', 'cancel', 'close'])
8
+
9
+ const props = defineProps({
10
+ title: {
11
+ type: String,
12
+ default: "提示",
13
+ },
14
+ width: {
15
+ default: 30,
16
+ },
17
+ draggable: {
18
+ type: Boolean,
19
+ default: false
20
+ },
21
+ validate: {
22
+ type: Function,
23
+ default() {
24
+ return true
25
+ }
26
+ },
27
+ callback: {
28
+ type: Function,
29
+ default: async () => 0
30
+ }
31
+ });
32
+
33
+ const visible = ref(false);
34
+
35
+ const onConfirm = async () => {
36
+ const validation = await props.validate()
37
+ if (validation) {
38
+ emits('confirm');
39
+ const code = await props.callback()
40
+ if (code) {
41
+ hide();
42
+ emits('finish');
43
+ }
44
+ }
45
+ };
46
+
47
+ const onCancel = () => {
48
+ hide();
49
+ emits('cancel');
50
+ };
51
+
52
+ const onClose = () => {
53
+ emits('close');
54
+ };
55
+
56
+ const show = () => {
57
+ visible.value = true;
58
+ };
59
+
60
+ const hide = () => {
61
+ console.log('before hide')
62
+ visible.value = false;
63
+ console.log('after hide')
64
+ console.log(visible.value)
65
+ };
66
+
67
+ defineExpose({ show })
68
+ </script>
69
+
70
+
71
+ <template>
72
+ <el-dialog class="xl-dialog" :title="title" :draggable="draggable" v-model="visible" @close="onClose" :width="width + '%'">
73
+ <slot />
74
+ <div style="text-align: center; padding: 10px; margin-top: 20px">
75
+ <span slot="footer" class="dialog-footer">
76
+ <el-button type="primary" @click="onConfirm">确定</el-button>
77
+ <el-button @click="onCancel">取消</el-button>
78
+ </span>
79
+ </div>
80
+ </el-dialog>
81
+ </template>
82
+
83
+
84
+ <style lang="less">
85
+ .xl-dialog {
86
+ text-align: left;
87
+
88
+ border-radius: 10px 10px 7px 7px !important;
89
+ padding: 0;
90
+
91
+ .el-dialog__header {
92
+ border-radius: 7px 7px 0 0;
93
+ padding: 14px 20px 10px;
94
+ margin: 0!important;
95
+ background: transparent linear-gradient(90deg, #073052 0%, rgb(100, 100, 100) 100%) 0% 0% no-repeat padding-box !important;
96
+
97
+ .el-dialog__headerbtn {
98
+ top: 14px;
99
+ }
100
+
101
+ .el-dialog__title,
102
+ .el-dialog__close {
103
+ color: rgb(245, 245, 245) !important;
104
+ }
105
+
106
+ .el-dialog__headerbtn {
107
+ top: 3px !important;
108
+ }
109
+
110
+ }
111
+
112
+ .el-dialog__body {
113
+ padding: 10px 10px 5px 10px;
114
+ }
115
+ }
116
+ </style>
@@ -0,0 +1,81 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlEditReviewDialog" })
3
+
4
+ import { ref, computed } from 'vue'
5
+
6
+
7
+ const emits = defineEmits(['confirm', 'pass', 'reject'])
8
+
9
+ const props = defineProps({
10
+ title: {},
11
+ width: {},
12
+ data: {},
13
+ ruleMap: {
14
+ default() {
15
+ return {}
16
+ }
17
+ },
18
+ labelWidth: {
19
+ default: 70
20
+ },
21
+ passCallback: {
22
+ type: Function,
23
+ default: () => { },
24
+ },
25
+ rejectCallback: {
26
+ type: Function,
27
+ default: () => { },
28
+ }
29
+ })
30
+
31
+ const refs = {
32
+ dialog: ref(null),
33
+ form: ref(null),
34
+ }
35
+
36
+ function convertRuleMapToRules(ruleMap) {
37
+ const rules = {};
38
+
39
+ for (const key in ruleMap) {
40
+ rules[key] = [{ required: true, message: `请输�?{ruleMap[key]}`, trigger: "blur" }];
41
+ }
42
+
43
+ return rules;
44
+ }
45
+
46
+ const rules = computed(() => convertRuleMapToRules(props.ruleMap));
47
+
48
+ async function validate() {
49
+ let flag = 0
50
+ await refs.form.value.validate(function (valid) {
51
+ flag = valid
52
+ })
53
+ return flag
54
+ }
55
+
56
+ defineExpose({
57
+ show() {
58
+ refs.dialog.value.show()
59
+ }
60
+ })
61
+ </script>
62
+
63
+
64
+ <template>
65
+ <xl-review-dialog class="xl-edit-review-dialog xl-dialog" :ref="refs.dialog" :title="title" :width="width"
66
+ :validate="validate" :pass-callback="passCallback" :reject-callback="rejectCallback" @pass="emits('pass')"
67
+ @reject="emits('reject')">
68
+ <el-form :ref="refs.form" :model="data" :rules="rules" :label-width="`${labelWidth}px`">
69
+ <slot />
70
+ </el-form>
71
+ </xl-review-dialog>
72
+ </template>
73
+
74
+
75
+ <style lang="less">
76
+ .xl-edit-review-dialog {
77
+ .xl-form-item {
78
+ width: 100% !important;
79
+ }
80
+ }
81
+ </style>
@@ -0,0 +1,79 @@
1
+ <script setup>
2
+ defineOptions({ name: "XlFormDialog" })
3
+
4
+ import { ref, computed } from 'vue'
5
+
6
+ const emits = defineEmits(['confirm', 'finish'])
7
+
8
+ const props = defineProps({
9
+ title: {},
10
+ draggable: {
11
+ type: Boolean,
12
+ default: false
13
+ },
14
+ width: {},
15
+ data: {},
16
+ ruleMap: {
17
+ default() {
18
+ return {}
19
+ }
20
+ },
21
+ labelWidth: {
22
+ default: 70
23
+ },
24
+ callback: {
25
+ type: Function,
26
+ default: () => { },
27
+ }
28
+ })
29
+
30
+ const refs = {
31
+ dialog: ref(null),
32
+ form: ref(null),
33
+ }
34
+
35
+ function convertRuleMapToRules(ruleMap) {
36
+ const rules = {};
37
+
38
+ for (const key in ruleMap) {
39
+ rules[key] = [{ required: true, message: `请输入${ruleMap[key]}`, trigger: "blur" }];
40
+ }
41
+
42
+ return rules;
43
+ }
44
+
45
+ const rules = computed(() => convertRuleMapToRules(props.ruleMap));
46
+
47
+ async function validate() {
48
+ let flag = 0
49
+ await refs.form.value.validate(function (valid) {
50
+ flag = valid
51
+ })
52
+ return flag
53
+ }
54
+
55
+ defineExpose({
56
+ show() {
57
+ refs.dialog.value.show()
58
+ }
59
+ })
60
+ </script>
61
+
62
+
63
+ <template>
64
+ <xl-dialog class="xl-form-dialog xl-dialog" :ref="refs.dialog" :title="title" :draggable="draggable" :width="width" :validate="validate"
65
+ :callback="callback" @finish="emits('finish')">
66
+ <el-form :ref="refs.form" :model="data" :rules="rules" :label-width="`${labelWidth}px`">
67
+ <slot />
68
+ </el-form>
69
+ </xl-dialog>
70
+ </template>
71
+
72
+
73
+ <style lang="less">
74
+ .xl-form-dialog {
75
+ .xl-form-item {
76
+ width: 100% !important;
77
+ }
78
+ }
79
+ </style>