feat:使用pinia替换vuex;新增markdown编辑器
parent
d28f504a80
commit
a072752609
12
README.md
12
README.md
|
@ -1,10 +1,10 @@
|
|||
# vue-manage-system
|
||||
|
||||
<a href="https://github.com/vuejs/vue">
|
||||
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue">
|
||||
<img src="https://img.shields.io/badge/vue-3.1.2-brightgreen.svg" alt="vue">
|
||||
</a>
|
||||
<a href="https://github.com/ElemeFE/element">
|
||||
<img src="https://img.shields.io/badge/element--ui-2.8.2-brightgreen.svg" alt="element-ui">
|
||||
<a href="https://github.com/vuejs/pinia">
|
||||
<img src="https://img.shields.io/badge/pinia-2.0.14-brightgreen.svg" alt="pinia">
|
||||
</a>
|
||||
<a href="https://github.com/lin-xin/vue-manage-system/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="license">
|
||||
|
@ -16,7 +16,7 @@
|
|||
<img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="donate">
|
||||
</a>
|
||||
|
||||
基于 Vue3 + Element Plus 的后台管理系统解决方案。[线上地址](https://lin-xin.gitee.io/example/work/)
|
||||
基于 Vue3 + pinia + Element Plus 的后台管理系统解决方案。[线上地址](https://lin-xin.gitee.io/example/work/)
|
||||
|
||||
> Vue2 版本请看 [tag-V4.2.0](https://github.com/lin-xin/vue-manage-system/tree/V4.2.0)
|
||||
|
||||
|
@ -48,7 +48,7 @@
|
|||
|
||||
## 前言
|
||||
|
||||
该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(Web Management System)开发。基于 Vue3,使用 vue-cli3 脚手架,引用 Element Plus 组件库,方便开发快速简洁好看的组件。分离颜色样式,支持手动切换主题色,而且很方便使用自定义主题色。
|
||||
该方案作为一套多功能的后台框架模板,适用于绝大部分的后台管理系统(Web Management System)开发。基于 Vue3 + pinia,引用 Element Plus 组件库,方便开发快速简洁好看的组件。分离颜色样式,支持手动切换主题色,而且很方便使用自定义主题色。
|
||||
|
||||
## 功能
|
||||
|
||||
|
@ -66,6 +66,8 @@
|
|||
- [x] 三级菜单
|
||||
- [x] 自定义图标
|
||||
- [x] 国际化
|
||||
- [x] vite
|
||||
- [x] pinia
|
||||
|
||||
## 安装步骤
|
||||
|
||||
|
|
|
@ -1,700 +0,0 @@
|
|||
{
|
||||
"name": "vue-manage-system",
|
||||
"version": "5.1.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@babel/helper-validator-identifier": {
|
||||
"version": "7.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz",
|
||||
"integrity": "sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg=="
|
||||
},
|
||||
"@babel/parser": {
|
||||
"version": "7.14.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.14.7.tgz",
|
||||
"integrity": "sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA=="
|
||||
},
|
||||
"@babel/runtime": {
|
||||
"version": "7.14.6",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.14.6.tgz",
|
||||
"integrity": "sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg==",
|
||||
"requires": {
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"@babel/runtime-corejs3": {
|
||||
"version": "7.14.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.14.7.tgz",
|
||||
"integrity": "sha512-Wvzcw4mBYbTagyBVZpAJWI06auSIj033T/yNE0Zn1xcup83MieCddZA7ls3kme17L4NOGBrQ09Q+nKB41RLWBA==",
|
||||
"requires": {
|
||||
"core-js-pure": "^3.15.0",
|
||||
"regenerator-runtime": "^0.13.4"
|
||||
}
|
||||
},
|
||||
"@babel/types": {
|
||||
"version": "7.14.5",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.14.5.tgz",
|
||||
"integrity": "sha512-M/NzBpEL95I5Hh4dwhin5JlE7EzO5PHMAuzjxss3tiOBD46KfQvVedN/3jEPZvdRvtsK2222XfdHogNIttFgcg==",
|
||||
"requires": {
|
||||
"@babel/helper-validator-identifier": "^7.14.5",
|
||||
"to-fast-properties": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"@intlify/core-base": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.1.6.tgz",
|
||||
"integrity": "sha512-d5GDPpsQbqPkisSJA5b6nJFEkalY/IHAd7vOLNd/Sj4YaNRzXtInu2FoqKiOv8e/lQnXGTpurdCZg5Jxq1Gsxw==",
|
||||
"requires": {
|
||||
"@intlify/devtools-if": "9.1.6",
|
||||
"@intlify/message-compiler": "9.1.6",
|
||||
"@intlify/message-resolver": "9.1.6",
|
||||
"@intlify/runtime": "9.1.6",
|
||||
"@intlify/shared": "9.1.6",
|
||||
"@intlify/vue-devtools": "9.1.6"
|
||||
}
|
||||
},
|
||||
"@intlify/devtools-if": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/devtools-if/-/devtools-if-9.1.6.tgz",
|
||||
"integrity": "sha512-m8Api+kh+BtFa2FZ/JjIdr1ibsGGqBjdKCzWo5BZecEUxBquIeOQZwpokPh/0K5j+/PZleFXkVAMC5mNt+9WdA==",
|
||||
"requires": {
|
||||
"@intlify/shared": "9.1.6"
|
||||
}
|
||||
},
|
||||
"@intlify/message-compiler": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.1.6.tgz",
|
||||
"integrity": "sha512-DR8645VOrVK6x/8tkaCpHnckMAIcoOgeNS5j0wB12RfZoXYQp7vAXMaOP511KMll2mXCREgIB0ojpajiof7yzQ==",
|
||||
"requires": {
|
||||
"@intlify/message-resolver": "9.1.6",
|
||||
"@intlify/shared": "9.1.6",
|
||||
"source-map": "0.6.1"
|
||||
}
|
||||
},
|
||||
"@intlify/message-resolver": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/message-resolver/-/message-resolver-9.1.6.tgz",
|
||||
"integrity": "sha512-UUnbawQa5U9sffd5wRIscqtyY1xWlwJbyfwCLPEWLvBhyAnCwPYlvaHGnnO0CSi0fzJTVwlV9DYzobh3agDeMA=="
|
||||
},
|
||||
"@intlify/runtime": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/runtime/-/runtime-9.1.6.tgz",
|
||||
"integrity": "sha512-U1QZ+TPf3kQQvWo4BA2mj3cHAxMRHXNTBhu2u+deh6ubTqXdZ19XGBTMSasrXG6RE+zSio9oM+ndoLja7JGtPg==",
|
||||
"requires": {
|
||||
"@intlify/message-compiler": "9.1.6",
|
||||
"@intlify/message-resolver": "9.1.6",
|
||||
"@intlify/shared": "9.1.6"
|
||||
}
|
||||
},
|
||||
"@intlify/shared": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.1.6.tgz",
|
||||
"integrity": "sha512-6MtsKulyfZxdD7OuxjaODjj8QWoHCnLFAk4wkWiHqBCa6UCTC0qXjtEeZ1MxpQihvFmmJZauBUu25EvtngW5qQ=="
|
||||
},
|
||||
"@intlify/vue-devtools": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@intlify/vue-devtools/-/vue-devtools-9.1.6.tgz",
|
||||
"integrity": "sha512-UdNovg4OML9rIr1sOGZzTfNr1nUy4UQpDf5ni4dNC93T6FIkVJz0n1Np7Vp7e6gDjcmufRYcV99tEwjQSN9+5A==",
|
||||
"requires": {
|
||||
"@intlify/message-resolver": "9.1.6",
|
||||
"@intlify/runtime": "9.1.6",
|
||||
"@intlify/shared": "9.1.6"
|
||||
}
|
||||
},
|
||||
"@popperjs/core": {
|
||||
"version": "2.9.2",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.9.2.tgz",
|
||||
"integrity": "sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q=="
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "0.0.48",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.48.tgz",
|
||||
"integrity": "sha512-LfZwXoGUDo0C3me81HXgkBg5CTQYb6xzEl+fNmbO4JdRiSKQ8A0GD1OBBvKAIsbCUgoyAty7m99GqqMQe784ew==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/lodash": {
|
||||
"version": "4.14.170",
|
||||
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.170.tgz",
|
||||
"integrity": "sha512-bpcvu/MKHHeYX+qeEN8GE7DIravODWdACVA1ctevD8CN24RhPZIKMn9ntfAsrvLfSX3cR5RrBKAbYm9bGs0A+Q=="
|
||||
},
|
||||
"@vitejs/plugin-vue": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-1.2.3.tgz",
|
||||
"integrity": "sha512-LlnLpObkGKZ+b7dcpL4T24l13nPSHLjo+6Oc7MbZiKz5PMAUzADfNJ3EKfYIQ0l0969nxf2jp/9vsfnuJ7h6fw==",
|
||||
"dev": true
|
||||
},
|
||||
"@vue/compiler-core": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.1.2.tgz",
|
||||
"integrity": "sha512-nHmq7vLjq/XM2IMbZUcKWoH5sPXa2uR/nIKZtjbK5F3TcbnYE/zKsrSUR9WZJ03unlwotNBX1OyxVt9HbWD7/Q==",
|
||||
"requires": {
|
||||
"@babel/parser": "^7.12.0",
|
||||
"@babel/types": "^7.12.0",
|
||||
"@vue/shared": "3.1.2",
|
||||
"estree-walker": "^2.0.1",
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-dom": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.1.2.tgz",
|
||||
"integrity": "sha512-k2+SWcWH0jL6WQAX7Or2ONqu5MbtTgTO0dJrvebQYzgqaKMXNI90RNeWeCxS4BnNFMDONpHBeFgbwbnDWIkmRg==",
|
||||
"requires": {
|
||||
"@vue/compiler-core": "3.1.2",
|
||||
"@vue/shared": "3.1.2"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-sfc": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.1.2.tgz",
|
||||
"integrity": "sha512-SeG/2+DvwejQ7oAiSx8BrDh5qOdqCYHGClPiTvVIHTfSIHiS2JjMbCANdDCjHkTOh/O7WZzo2JhdKm98bRBxTw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/parser": "^7.13.9",
|
||||
"@babel/types": "^7.13.0",
|
||||
"@types/estree": "^0.0.48",
|
||||
"@vue/compiler-core": "3.1.2",
|
||||
"@vue/compiler-dom": "3.1.2",
|
||||
"@vue/compiler-ssr": "3.1.2",
|
||||
"@vue/shared": "3.1.2",
|
||||
"consolidate": "^0.16.0",
|
||||
"estree-walker": "^2.0.1",
|
||||
"hash-sum": "^2.0.0",
|
||||
"lru-cache": "^5.1.1",
|
||||
"magic-string": "^0.25.7",
|
||||
"merge-source-map": "^1.1.0",
|
||||
"postcss": "^8.1.10",
|
||||
"postcss-modules": "^4.0.0",
|
||||
"postcss-selector-parser": "^6.0.4",
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"@vue/compiler-ssr": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.1.2.tgz",
|
||||
"integrity": "sha512-BwXo9LFk5OSWdMyZQ4bX1ELHX0Z/9F+ld/OaVnpUPzAZCHslBYLvyKUVDwv2C/lpLjRffpC2DOUEdl1+RP1aGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@vue/compiler-dom": "3.1.2",
|
||||
"@vue/shared": "3.1.2"
|
||||
}
|
||||
},
|
||||
"@vue/devtools-api": {
|
||||
"version": "6.0.0-beta.14",
|
||||
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.0.0-beta.14.tgz",
|
||||
"integrity": "sha512-44fPrrN1cqcs6bFkT0C+yxTM6PZXLbR+ESh1U1j8UD22yO04gXvxH62HApMjLbS3WqJO/iCNC+CYT+evPQh2EQ=="
|
||||
},
|
||||
"@vue/reactivity": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.1.2.tgz",
|
||||
"integrity": "sha512-glJzJoN2xE7I2lRvwKM5u1BHRPTd1yc8iaf//Lai/78/uYAvE5DXp5HzWRFOwMlbRvMGJHIQjOqoxj87cDAaag==",
|
||||
"requires": {
|
||||
"@vue/shared": "3.1.2"
|
||||
}
|
||||
},
|
||||
"@vue/runtime-core": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.1.2.tgz",
|
||||
"integrity": "sha512-gsPZG4dRIkixuuKmoj4P9IHgfT0yaFLcqWOM5F/bCk0nxQn1XtxH8oUehWuET726KhbukvDoJfe9G2CKviy80w==",
|
||||
"requires": {
|
||||
"@vue/reactivity": "3.1.2",
|
||||
"@vue/shared": "3.1.2"
|
||||
}
|
||||
},
|
||||
"@vue/runtime-dom": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.1.2.tgz",
|
||||
"integrity": "sha512-QvINxjLucEZFzp5f0NVu7JqWYCv5TKQfkH2FDs/N6QNE4iKcYtKrWdT0HKfABnVXG28Znqv6rIH0dH4ZAOwxpA==",
|
||||
"requires": {
|
||||
"@vue/runtime-core": "3.1.2",
|
||||
"@vue/shared": "3.1.2",
|
||||
"csstype": "^2.6.8"
|
||||
}
|
||||
},
|
||||
"@vue/shared": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.1.2.tgz",
|
||||
"integrity": "sha512-EmH/poaDWBPJaPILXNI/1fvUbArJQmmTyVCwvvyDYDFnkPoTclAbHRAtyIvqfez7jybTDn077HTNILpxlsoWhg=="
|
||||
},
|
||||
"async-validator": {
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/async-validator/-/async-validator-3.5.2.tgz",
|
||||
"integrity": "sha512-8eLCg00W9pIRZSB781UUX/H6Oskmm8xloZfr09lz5bikRpBVDlJ3hRVuxxP1SxcwsEYfJ4IU8Q19Y8/893r3rQ=="
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.21.1",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.21.1.tgz",
|
||||
"integrity": "sha512-dKQiRHxGD9PPRIUNIWvZhPTPpl1rf/OxTYKsqKUDjBwYylTvV7SjSHJb9ratfyzM6wCdLCOYLzs73qpg5c4iGA==",
|
||||
"requires": {
|
||||
"follow-redirects": "^1.10.0"
|
||||
}
|
||||
},
|
||||
"big.js": {
|
||||
"version": "5.2.2",
|
||||
"resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz",
|
||||
"integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==",
|
||||
"dev": true
|
||||
},
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz",
|
||||
"integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==",
|
||||
"dev": true
|
||||
},
|
||||
"colorette": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.2.tgz",
|
||||
"integrity": "sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==",
|
||||
"dev": true
|
||||
},
|
||||
"consolidate": {
|
||||
"version": "0.16.0",
|
||||
"resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.16.0.tgz",
|
||||
"integrity": "sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"bluebird": "^3.7.2"
|
||||
}
|
||||
},
|
||||
"core-js-pure": {
|
||||
"version": "3.15.1",
|
||||
"resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.15.1.tgz",
|
||||
"integrity": "sha512-OZuWHDlYcIda8sJLY4Ec6nWq2hRjlyCqCZ+jCflyleMkVt3tPedDVErvHslyS2nbO+SlBFMSBJYvtLMwxnrzjA=="
|
||||
},
|
||||
"cropperjs": {
|
||||
"version": "1.5.12",
|
||||
"resolved": "https://registry.npmjs.org/cropperjs/-/cropperjs-1.5.12.tgz",
|
||||
"integrity": "sha512-re7UdjE5UnwdrovyhNzZ6gathI4Rs3KGCBSc8HCIjUo5hO42CtzyblmWLj6QWVw7huHyDMfpKxhiO2II77nhDw=="
|
||||
},
|
||||
"cssesc": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz",
|
||||
"integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"csstype": {
|
||||
"version": "2.6.17",
|
||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-2.6.17.tgz",
|
||||
"integrity": "sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A=="
|
||||
},
|
||||
"dayjs": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.5.tgz",
|
||||
"integrity": "sha512-BUFis41ikLz+65iH6LHQCDm4YPMj5r1YFLdupPIyM4SGcXMmtiLQ7U37i+hGS8urIuqe7I/ou3IS1jVc4nbN4g=="
|
||||
},
|
||||
"element-plus": {
|
||||
"version": "1.0.2-beta.52",
|
||||
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-1.0.2-beta.52.tgz",
|
||||
"integrity": "sha512-oAuJHwXyvM4dsuOz7HSDPIBVPqRJ1KEzFzGqYdqbBjQ/aw79uCJxvS9Q4q9/XrPMfPire09+bPTypiIaHkNBhA==",
|
||||
"requires": {
|
||||
"@popperjs/core": "^2.4.4",
|
||||
"@types/lodash": "^4.14.161",
|
||||
"async-validator": "^3.4.0",
|
||||
"dayjs": "1.x",
|
||||
"lodash": "^4.17.20",
|
||||
"mitt": "^2.1.0",
|
||||
"normalize-wheel": "^1.0.1",
|
||||
"resize-observer-polyfill": "^1.5.1"
|
||||
}
|
||||
},
|
||||
"emojis-list": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz",
|
||||
"integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==",
|
||||
"dev": true
|
||||
},
|
||||
"esbuild": {
|
||||
"version": "0.12.9",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.12.9.tgz",
|
||||
"integrity": "sha512-MWRhAbMOJ9RJygCrt778rz/qNYgA4ZVj6aXnNPxFjs7PmIpb0fuB9Gmg5uWrr6n++XKwwm/RmSz6RR5JL2Ocsw==",
|
||||
"dev": true
|
||||
},
|
||||
"estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.1.tgz",
|
||||
"integrity": "sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg=="
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
|
||||
"dev": true
|
||||
},
|
||||
"generic-names": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz",
|
||||
"integrity": "sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"loader-utils": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"hash-sum": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-2.0.0.tgz",
|
||||
"integrity": "sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==",
|
||||
"dev": true
|
||||
},
|
||||
"icss-replace-symbols": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz",
|
||||
"integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=",
|
||||
"dev": true
|
||||
},
|
||||
"icss-utils": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz",
|
||||
"integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==",
|
||||
"dev": true
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.4.0.tgz",
|
||||
"integrity": "sha512-6A2fkfq1rfeQZjxrZJGerpLCTHRNEBiSgnu0+obeJpEPZRUooHgsizvzv0ZjJwOz3iWIHdJtVWJ/tmPr3D21/A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"json5": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
|
||||
"integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"loader-utils": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz",
|
||||
"integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"big.js": "^5.2.2",
|
||||
"emojis-list": "^3.0.0",
|
||||
"json5": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"lodash.camelcase": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
|
||||
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
|
||||
"dev": true
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
|
||||
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"yallist": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"magic-string": {
|
||||
"version": "0.25.7",
|
||||
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.7.tgz",
|
||||
"integrity": "sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sourcemap-codec": "^1.4.4"
|
||||
}
|
||||
},
|
||||
"merge-source-map": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz",
|
||||
"integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"source-map": "^0.6.1"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz",
|
||||
"integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==",
|
||||
"dev": true
|
||||
},
|
||||
"mitt": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mitt/-/mitt-2.1.0.tgz",
|
||||
"integrity": "sha512-ILj2TpLiysu2wkBbWjAmww7TkZb65aiQO+DkVdUTBpBXq+MHYiETENkKFMtsJZX1Lf4pe4QOrTSjIfUwN5lRdg=="
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.1.23",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz",
|
||||
"integrity": "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==",
|
||||
"dev": true
|
||||
},
|
||||
"normalize-wheel": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/normalize-wheel/-/normalize-wheel-1.0.1.tgz",
|
||||
"integrity": "sha1-rsiGr/2wRQcNhWRH32Ls+GFG7EU="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"dev": true
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.3.5",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.3.5.tgz",
|
||||
"integrity": "sha512-NxTuJocUhYGsMiMFHDUkmjSKT3EdH4/WbGF6GCi1NDGk+vbcUTun4fpbOqaPtD8IIsztA2ilZm2DhYCuyN58gA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"colorette": "^1.2.2",
|
||||
"nanoid": "^3.1.23",
|
||||
"source-map-js": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"postcss-modules": {
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules/-/postcss-modules-4.1.3.tgz",
|
||||
"integrity": "sha512-dBT39hrXe4OAVYJe/2ZuIZ9BzYhOe7t+IhedYeQ2OxKwDpAGlkEN/fR0fGnrbx4BvgbMReRX4hCubYK9cE/pJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"generic-names": "^2.0.1",
|
||||
"icss-replace-symbols": "^1.1.0",
|
||||
"lodash.camelcase": "^4.3.0",
|
||||
"postcss-modules-extract-imports": "^3.0.0",
|
||||
"postcss-modules-local-by-default": "^4.0.0",
|
||||
"postcss-modules-scope": "^3.0.0",
|
||||
"postcss-modules-values": "^4.0.0",
|
||||
"string-hash": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"postcss-modules-extract-imports": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz",
|
||||
"integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==",
|
||||
"dev": true
|
||||
},
|
||||
"postcss-modules-local-by-default": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz",
|
||||
"integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"icss-utils": "^5.0.0",
|
||||
"postcss-selector-parser": "^6.0.2",
|
||||
"postcss-value-parser": "^4.1.0"
|
||||
}
|
||||
},
|
||||
"postcss-modules-scope": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz",
|
||||
"integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"postcss-selector-parser": "^6.0.4"
|
||||
}
|
||||
},
|
||||
"postcss-modules-values": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz",
|
||||
"integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"icss-utils": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"postcss-selector-parser": {
|
||||
"version": "6.0.6",
|
||||
"resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz",
|
||||
"integrity": "sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"cssesc": "^3.0.0",
|
||||
"util-deprecate": "^1.0.2"
|
||||
}
|
||||
},
|
||||
"postcss-value-parser": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz",
|
||||
"integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==",
|
||||
"dev": true
|
||||
},
|
||||
"regenerator-runtime": {
|
||||
"version": "0.13.7",
|
||||
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz",
|
||||
"integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew=="
|
||||
},
|
||||
"resize-observer-polyfill": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.20.0",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.20.0.tgz",
|
||||
"integrity": "sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-core-module": "^2.2.0",
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "2.52.3",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-2.52.3.tgz",
|
||||
"integrity": "sha512-QF3Sju8Kl2z0osI4unyOLyUudyhOMK6G0AeqJWgfiyigqLAlnNrfBcDWDx+f1cqn+JU2iIYVkDrgQ6/KtwEfrg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"schart.js": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/schart.js/-/schart.js-3.0.4.tgz",
|
||||
"integrity": "sha512-uylb2u9rrHX1jyAuSAJUQON8XTfyDKI9kWj1J3fUlCQCkLVZ4HG4+IiV8qm//Z71dqvLI78QZ/fCBw0reB22Zw=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-js": {
|
||||
"version": "0.6.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-0.6.2.tgz",
|
||||
"integrity": "sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==",
|
||||
"dev": true
|
||||
},
|
||||
"sourcemap-codec": {
|
||||
"version": "1.4.8",
|
||||
"resolved": "https://registry.npmjs.org/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz",
|
||||
"integrity": "sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==",
|
||||
"dev": true
|
||||
},
|
||||
"string-hash": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/string-hash/-/string-hash-1.1.3.tgz",
|
||||
"integrity": "sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs=",
|
||||
"dev": true
|
||||
},
|
||||
"to-fast-properties": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
|
||||
"integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4="
|
||||
},
|
||||
"tslib": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.0.tgz",
|
||||
"integrity": "sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg=="
|
||||
},
|
||||
"util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
|
||||
"dev": true
|
||||
},
|
||||
"vite": {
|
||||
"version": "2.3.7",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-2.3.7.tgz",
|
||||
"integrity": "sha512-Y0xRz11MPYu/EAvzN94+FsOZHbSvO6FUvHv127CyG7mV6oDoay2bw+g5y9wW3Blf8OY3chaz3nc/DcRe1IQ3Nw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esbuild": "^0.12.5",
|
||||
"fsevents": "~2.3.1",
|
||||
"postcss": "^8.3.0",
|
||||
"resolve": "^1.19.0",
|
||||
"rollup": "^2.38.5"
|
||||
}
|
||||
},
|
||||
"vue": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vue/-/vue-3.1.2.tgz",
|
||||
"integrity": "sha512-q/rbKpb7aofax4ugqu2k/uj7BYuNPcd6Z5/qJtfkJQsE0NkwVoCyeSh7IZGH61hChwYn3CEkh4bHolvUPxlQ+w==",
|
||||
"requires": {
|
||||
"@vue/compiler-dom": "3.1.2",
|
||||
"@vue/runtime-dom": "3.1.2",
|
||||
"@vue/shared": "3.1.2"
|
||||
}
|
||||
},
|
||||
"vue-cropperjs": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-cropperjs/-/vue-cropperjs-5.0.0.tgz",
|
||||
"integrity": "sha512-RhnC8O33uRZNkn74aiHZwNHnBJOXWlS4P6gsRI0lw4cZlWjKSCywZI9oSI9POlIPI6OYv30jvnHMXGch85tw7w==",
|
||||
"requires": {
|
||||
"cropperjs": "^1.5.6"
|
||||
}
|
||||
},
|
||||
"vue-i18n": {
|
||||
"version": "9.1.6",
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.1.6.tgz",
|
||||
"integrity": "sha512-FEC4HZkTH6QRIu/A0wlo0VS/GH3w/fuCC6xfvoC8IyhhtbG9A+go9NfW+HZ1ZXdAcO4EWcVQi04M+iSwuxgixw==",
|
||||
"requires": {
|
||||
"@intlify/core-base": "9.1.6",
|
||||
"@intlify/shared": "9.1.6",
|
||||
"@intlify/vue-devtools": "9.1.6",
|
||||
"@vue/devtools-api": "^6.0.0-beta.7"
|
||||
}
|
||||
},
|
||||
"vue-router": {
|
||||
"version": "4.0.10",
|
||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.0.10.tgz",
|
||||
"integrity": "sha512-YbPf6QnZpyyWfnk7CUt2Bme+vo7TLfg1nGZNkvYqKYh4vLaFw6Gn8bPGdmt5m4qrGnKoXLqc4htAsd3dIukICA==",
|
||||
"requires": {
|
||||
"@vue/devtools-api": "^6.0.0-beta.14"
|
||||
}
|
||||
},
|
||||
"vue-schart": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-schart/-/vue-schart-2.0.0.tgz",
|
||||
"integrity": "sha512-qAu3e5wfMcq26wK1xeHExEWfGpnjfoN1R/9QXblNi+AsU/p52X7tTwhi+Fw7H/otfEufhEY2X7z7emaoF4QO+g==",
|
||||
"requires": {
|
||||
"schart.js": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"vuex": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/vuex/-/vuex-4.0.2.tgz",
|
||||
"integrity": "sha512-M6r8uxELjZIK8kTKDGgZTYX/ahzblnzC4isU1tpmEuOIIKmV+TRdc+H4s8ds2NuZ7wpUTdGRzJRtoj+lI+pc0Q==",
|
||||
"requires": {
|
||||
"@vue/devtools-api": "^6.0.0-beta.11"
|
||||
}
|
||||
},
|
||||
"wangeditor": {
|
||||
"version": "4.7.4",
|
||||
"resolved": "https://registry.npmjs.org/wangeditor/-/wangeditor-4.7.4.tgz",
|
||||
"integrity": "sha512-MVWJyFZm3SOhIGFsxDwD6Q0ahIWQTYU0/otHxq85EnfdxtJBJ8c55iKDp3zIvBZaiBawBiYCpRmbn8HOedNj5w==",
|
||||
"requires": {
|
||||
"@babel/runtime": "^7.11.2",
|
||||
"@babel/runtime-corejs3": "^7.11.2",
|
||||
"tslib": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"yallist": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vue-manage-system",
|
||||
"version": "5.1.0",
|
||||
"version": "5.2.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
|
@ -9,13 +9,14 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"axios": "^0.21.1",
|
||||
"element-plus": "1.0.2-beta.52",
|
||||
"element-plus": "^1.0.2-beta.52",
|
||||
"md-editor-v3": "^2.2.0",
|
||||
"pinia": "^2.0.14",
|
||||
"vue": "^3.1.2",
|
||||
"vue-cropperjs": "^5.0.0",
|
||||
"vue-i18n": "^9.0.0",
|
||||
"vue-router": "^4.0.10",
|
||||
"vue-schart": "^2.0.0",
|
||||
"vuex": "^4.0.2",
|
||||
"wangeditor": "^4.7.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -1,162 +1,161 @@
|
|||
<template>
|
||||
<div class="header">
|
||||
<!-- 折叠按钮 -->
|
||||
<div class="collapse-btn" @click="collapseChage">
|
||||
<i v-if="!collapse" class="el-icon-s-fold"></i>
|
||||
<i v-else class="el-icon-s-unfold"></i>
|
||||
</div>
|
||||
<div class="logo">后台管理系统</div>
|
||||
<div class="header-right">
|
||||
<div class="header-user-con">
|
||||
<!-- 消息中心 -->
|
||||
<div class="btn-bell">
|
||||
<el-tooltip effect="dark" :content="message?`有${message}条未读消息`:`消息中心`" placement="bottom">
|
||||
<router-link to="/tabs">
|
||||
<i class="el-icon-bell"></i>
|
||||
</router-link>
|
||||
</el-tooltip>
|
||||
<span class="btn-bell-badge" v-if="message"></span>
|
||||
</div>
|
||||
<!-- 用户头像 -->
|
||||
<div class="user-avator">
|
||||
<img src="../assets/img/img.jpg" />
|
||||
</div>
|
||||
<!-- 用户名下拉菜单 -->
|
||||
<el-dropdown class="user-name" trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
{{username}}
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<a href="https://github.com/lin-xin/vue-manage-system" target="_blank">
|
||||
<el-dropdown-item>项目仓库</el-dropdown-item>
|
||||
</a>
|
||||
<el-dropdown-item command="user">个人中心</el-dropdown-item>
|
||||
<el-dropdown-item divided command="loginout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, onMounted } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { useRouter } from "vue-router";
|
||||
export default {
|
||||
setup() {
|
||||
const username = localStorage.getItem("ms_username");
|
||||
const message = 2;
|
||||
|
||||
const store = useStore();
|
||||
const collapse = computed(() => store.state.collapse);
|
||||
// 侧边栏折叠
|
||||
const collapseChage = () => {
|
||||
store.commit("handleCollapse", !collapse.value);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (document.body.clientWidth < 1500) {
|
||||
collapseChage();
|
||||
}
|
||||
});
|
||||
|
||||
// 用户名下拉菜单选择事件
|
||||
const router = useRouter();
|
||||
const handleCommand = (command) => {
|
||||
if (command == "loginout") {
|
||||
localStorage.removeItem("ms_username");
|
||||
router.push("/login");
|
||||
} else if (command == "user") {
|
||||
router.push("/user");
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
username,
|
||||
message,
|
||||
collapse,
|
||||
collapseChage,
|
||||
handleCommand,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.header {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
}
|
||||
.collapse-btn {
|
||||
float: left;
|
||||
padding: 0 21px;
|
||||
cursor: pointer;
|
||||
line-height: 70px;
|
||||
}
|
||||
.header .logo {
|
||||
float: left;
|
||||
width: 250px;
|
||||
line-height: 70px;
|
||||
}
|
||||
.header-right {
|
||||
float: right;
|
||||
padding-right: 50px;
|
||||
}
|
||||
.header-user-con {
|
||||
display: flex;
|
||||
height: 70px;
|
||||
align-items: center;
|
||||
}
|
||||
.btn-fullscreen {
|
||||
transform: rotate(45deg);
|
||||
margin-right: 5px;
|
||||
font-size: 24px;
|
||||
}
|
||||
.btn-bell,
|
||||
.btn-fullscreen {
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-bell-badge {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -2px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
background: #f56c6c;
|
||||
color: #fff;
|
||||
}
|
||||
.btn-bell .el-icon-bell {
|
||||
color: #fff;
|
||||
}
|
||||
.user-name {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.user-avator {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.user-avator img {
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.el-dropdown-link {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.el-dropdown-menu__item {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="header">
|
||||
<!-- 折叠按钮 -->
|
||||
<div class="collapse-btn" @click="collapseChage">
|
||||
<i v-if="!sidebar.collapse" class="el-icon-s-fold"></i>
|
||||
<i v-else class="el-icon-s-unfold"></i>
|
||||
</div>
|
||||
<div class="logo">后台管理系统</div>
|
||||
<div class="header-right">
|
||||
<div class="header-user-con">
|
||||
<!-- 消息中心 -->
|
||||
<div class="btn-bell">
|
||||
<el-tooltip effect="dark" :content="message?`有${message}条未读消息`:`消息中心`" placement="bottom">
|
||||
<router-link to="/tabs">
|
||||
<i class="el-icon-bell"></i>
|
||||
</router-link>
|
||||
</el-tooltip>
|
||||
<span class="btn-bell-badge" v-if="message"></span>
|
||||
</div>
|
||||
<!-- 用户头像 -->
|
||||
<div class="user-avator">
|
||||
<img src="../assets/img/img.jpg" />
|
||||
</div>
|
||||
<!-- 用户名下拉菜单 -->
|
||||
<el-dropdown class="user-name" trigger="click" @command="handleCommand">
|
||||
<span class="el-dropdown-link">
|
||||
{{username}}
|
||||
<i class="el-icon-caret-bottom"></i>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<a href="https://github.com/lin-xin/vue-manage-system" target="_blank">
|
||||
<el-dropdown-item>项目仓库</el-dropdown-item>
|
||||
</a>
|
||||
<el-dropdown-item command="user">个人中心</el-dropdown-item>
|
||||
<el-dropdown-item divided command="loginout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { computed, onMounted } from "vue";
|
||||
import { useSidebarStore } from '../store/sidebar'
|
||||
import { useRouter } from "vue-router";
|
||||
export default {
|
||||
setup() {
|
||||
const username = localStorage.getItem("ms_username");
|
||||
const message = 2;
|
||||
|
||||
const sidebar = useSidebarStore();
|
||||
// 侧边栏折叠
|
||||
const collapseChage = () => {
|
||||
sidebar.handleCollapse();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
if (document.body.clientWidth < 1500) {
|
||||
collapseChage();
|
||||
}
|
||||
});
|
||||
|
||||
// 用户名下拉菜单选择事件
|
||||
const router = useRouter();
|
||||
const handleCommand = (command) => {
|
||||
if (command == "loginout") {
|
||||
localStorage.removeItem("ms_username");
|
||||
router.push("/login");
|
||||
} else if (command == "user") {
|
||||
router.push("/user");
|
||||
}
|
||||
};
|
||||
|
||||
return {
|
||||
sidebar,
|
||||
username,
|
||||
message,
|
||||
collapseChage,
|
||||
handleCommand,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
.header {
|
||||
position: relative;
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 70px;
|
||||
font-size: 22px;
|
||||
color: #fff;
|
||||
}
|
||||
.collapse-btn {
|
||||
float: left;
|
||||
padding: 0 21px;
|
||||
cursor: pointer;
|
||||
line-height: 70px;
|
||||
}
|
||||
.header .logo {
|
||||
float: left;
|
||||
width: 250px;
|
||||
line-height: 70px;
|
||||
}
|
||||
.header-right {
|
||||
float: right;
|
||||
padding-right: 50px;
|
||||
}
|
||||
.header-user-con {
|
||||
display: flex;
|
||||
height: 70px;
|
||||
align-items: center;
|
||||
}
|
||||
.btn-fullscreen {
|
||||
transform: rotate(45deg);
|
||||
margin-right: 5px;
|
||||
font-size: 24px;
|
||||
}
|
||||
.btn-bell,
|
||||
.btn-fullscreen {
|
||||
position: relative;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
text-align: center;
|
||||
border-radius: 15px;
|
||||
cursor: pointer;
|
||||
}
|
||||
.btn-bell-badge {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: -2px;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 4px;
|
||||
background: #f56c6c;
|
||||
color: #fff;
|
||||
}
|
||||
.btn-bell .el-icon-bell {
|
||||
color: #fff;
|
||||
}
|
||||
.user-name {
|
||||
margin-left: 10px;
|
||||
}
|
||||
.user-avator {
|
||||
margin-left: 20px;
|
||||
}
|
||||
.user-avator img {
|
||||
display: block;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.el-dropdown-link {
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
.el-dropdown-menu__item {
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,154 +1,156 @@
|
|||
<template>
|
||||
<div class="sidebar">
|
||||
<el-menu class="sidebar-el-menu" :default-active="onRoutes" :collapse="collapse" background-color="#324157"
|
||||
text-color="#bfcbd9" active-text-color="#20a0ff" unique-opened router>
|
||||
<template v-for="item in items">
|
||||
<template v-if="item.subs">
|
||||
<el-submenu :index="item.index" :key="item.index">
|
||||
<template #title>
|
||||
<i :class="item.icon"></i>
|
||||
<span>{{ item.title }}</span>
|
||||
</template>
|
||||
<template v-for="subItem in item.subs">
|
||||
<el-submenu v-if="subItem.subs" :index="subItem.index" :key="subItem.index">
|
||||
<template #title>{{ subItem.title }}</template>
|
||||
<el-menu-item v-for="(threeItem, i) in subItem.subs" :key="i" :index="threeItem.index">
|
||||
{{ threeItem.title }}</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item v-else :index="subItem.index" :key="subItem.index">{{ subItem.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-submenu>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-menu-item :index="item.index" :key="item.index">
|
||||
<i :class="item.icon"></i>
|
||||
<template #title>{{ item.title }}</template>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed, watch } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { useRoute } from "vue-router";
|
||||
export default {
|
||||
setup() {
|
||||
const items = [
|
||||
{
|
||||
icon: "el-icon-lx-home",
|
||||
index: "/dashboard",
|
||||
title: "系统首页",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-cascades",
|
||||
index: "/table",
|
||||
title: "基础表格",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-copy",
|
||||
index: "/tabs",
|
||||
title: "tab选项卡",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-calendar",
|
||||
index: "3",
|
||||
title: "表单相关",
|
||||
subs: [
|
||||
{
|
||||
index: "/form",
|
||||
title: "基本表单",
|
||||
},
|
||||
{
|
||||
index: "/upload",
|
||||
title: "文件上传",
|
||||
},
|
||||
{
|
||||
index: "4",
|
||||
title: "三级菜单",
|
||||
subs: [
|
||||
{
|
||||
index: "/editor",
|
||||
title: "富文本编辑器",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-emoji",
|
||||
index: "/icon",
|
||||
title: "自定义图标",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-pie-chart",
|
||||
index: "/charts",
|
||||
title: "schart图表",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-global",
|
||||
index: "/i18n",
|
||||
title: "国际化功能",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-warn",
|
||||
index: "7",
|
||||
title: "错误处理",
|
||||
subs: [
|
||||
{
|
||||
index: "/permission",
|
||||
title: "权限测试",
|
||||
},
|
||||
{
|
||||
index: "/404",
|
||||
title: "404页面",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-redpacket_fill",
|
||||
index: "/donate",
|
||||
title: "支持作者",
|
||||
},
|
||||
];
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const onRoutes = computed(() => {
|
||||
return route.path;
|
||||
});
|
||||
|
||||
const store = useStore();
|
||||
const collapse = computed(() => store.state.collapse);
|
||||
|
||||
return {
|
||||
items,
|
||||
onRoutes,
|
||||
collapse,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sidebar {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 70px;
|
||||
bottom: 0;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.sidebar::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
.sidebar-el-menu:not(.el-menu--collapse) {
|
||||
width: 250px;
|
||||
}
|
||||
.sidebar > ul {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="sidebar">
|
||||
<el-menu class="sidebar-el-menu" :default-active="onRoutes" :collapse="sidebar.collapse" background-color="#324157"
|
||||
text-color="#bfcbd9" active-text-color="#20a0ff" unique-opened router>
|
||||
<template v-for="item in items">
|
||||
<template v-if="item.subs">
|
||||
<el-submenu :index="item.index" :key="item.index">
|
||||
<template #title>
|
||||
<i :class="item.icon"></i>
|
||||
<span>{{ item.title }}</span>
|
||||
</template>
|
||||
<template v-for="subItem in item.subs">
|
||||
<el-submenu v-if="subItem.subs" :index="subItem.index" :key="subItem.index">
|
||||
<template #title>{{ subItem.title }}</template>
|
||||
<el-menu-item v-for="(threeItem, i) in subItem.subs" :key="i" :index="threeItem.index">
|
||||
{{ threeItem.title }}</el-menu-item>
|
||||
</el-submenu>
|
||||
<el-menu-item v-else :index="subItem.index" :key="subItem.index">{{ subItem.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-submenu>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-menu-item :index="item.index" :key="item.index">
|
||||
<i :class="item.icon"></i>
|
||||
<template #title>{{ item.title }}</template>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
</el-menu>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed } from "vue";
|
||||
import { useSidebarStore } from '../store/sidebar'
|
||||
import { useRoute } from "vue-router";
|
||||
export default {
|
||||
setup() {
|
||||
const items = [
|
||||
{
|
||||
icon: "el-icon-lx-home",
|
||||
index: "/dashboard",
|
||||
title: "系统首页",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-cascades",
|
||||
index: "/table",
|
||||
title: "基础表格",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-copy",
|
||||
index: "/tabs",
|
||||
title: "tab选项卡",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-calendar",
|
||||
index: "3",
|
||||
title: "表单相关",
|
||||
subs: [
|
||||
{
|
||||
index: "/form",
|
||||
title: "基本表单",
|
||||
},
|
||||
{
|
||||
index: "/upload",
|
||||
title: "文件上传",
|
||||
},
|
||||
{
|
||||
index: "4",
|
||||
title: "三级菜单",
|
||||
subs: [
|
||||
{
|
||||
index: "/editor",
|
||||
title: "富文本编辑器",
|
||||
},
|
||||
{
|
||||
index: "/markdown",
|
||||
title: "markdown编辑器",
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-emoji",
|
||||
index: "/icon",
|
||||
title: "自定义图标",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-pie-chart",
|
||||
index: "/charts",
|
||||
title: "schart图表",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-global",
|
||||
index: "/i18n",
|
||||
title: "国际化功能",
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-warn",
|
||||
index: "7",
|
||||
title: "错误处理",
|
||||
subs: [
|
||||
{
|
||||
index: "/permission",
|
||||
title: "权限测试",
|
||||
},
|
||||
{
|
||||
index: "/404",
|
||||
title: "404页面",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: "el-icon-lx-redpacket_fill",
|
||||
index: "/donate",
|
||||
title: "支持作者",
|
||||
},
|
||||
];
|
||||
|
||||
const route = useRoute();
|
||||
const onRoutes = computed(() => {
|
||||
return route.path;
|
||||
});
|
||||
|
||||
const sidebar = useSidebarStore();
|
||||
|
||||
return {
|
||||
items,
|
||||
onRoutes,
|
||||
sidebar,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.sidebar {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 70px;
|
||||
bottom: 0;
|
||||
overflow-y: scroll;
|
||||
}
|
||||
.sidebar::-webkit-scrollbar {
|
||||
width: 0;
|
||||
}
|
||||
.sidebar-el-menu:not(.el-menu--collapse) {
|
||||
width: 250px;
|
||||
}
|
||||
.sidebar > ul {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,183 +1,174 @@
|
|||
<template>
|
||||
<div class="tags" v-if="showTags">
|
||||
<ul>
|
||||
<li class="tags-li" v-for="(item,index) in tagsList" :class="{'active': isActive(item.path)}" :key="index">
|
||||
<router-link :to="item.path" class="tags-li-title">{{item.title}}</router-link>
|
||||
<span class="tags-li-icon" @click="closeTags(index)">
|
||||
<i class="el-icon-close"></i>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tags-close-box">
|
||||
<el-dropdown @command="handleTags">
|
||||
<el-button size="mini" type="primary">
|
||||
标签选项
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu size="small">
|
||||
<el-dropdown-item command="other">关闭其他</el-dropdown-item>
|
||||
<el-dropdown-item command="all">关闭所有</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { computed } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
||||
export default {
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const isActive = (path) => {
|
||||
return path === route.fullPath;
|
||||
};
|
||||
|
||||
const store = useStore();
|
||||
const tagsList = computed(() => store.state.tagsList);
|
||||
const showTags = computed(() => tagsList.value.length > 0);
|
||||
|
||||
// 关闭单个标签
|
||||
const closeTags = (index) => {
|
||||
const delItem = tagsList.value[index];
|
||||
store.commit("delTagsItem", { index });
|
||||
const item = tagsList.value[index]
|
||||
? tagsList.value[index]
|
||||
: tagsList.value[index - 1];
|
||||
if (item) {
|
||||
delItem.path === route.fullPath && router.push(item.path);
|
||||
} else {
|
||||
router.push("/");
|
||||
}
|
||||
};
|
||||
|
||||
// 设置标签
|
||||
const setTags = (route) => {
|
||||
const isExist = tagsList.value.some((item) => {
|
||||
return item.path === route.fullPath;
|
||||
});
|
||||
if (!isExist) {
|
||||
if (tagsList.value.length >= 8) {
|
||||
store.commit("delTagsItem", { index: 0 });
|
||||
}
|
||||
store.commit("setTagsItem", {
|
||||
name: route.name,
|
||||
title: route.meta.title,
|
||||
path: route.fullPath,
|
||||
});
|
||||
}
|
||||
};
|
||||
setTags(route);
|
||||
onBeforeRouteUpdate((to) => {
|
||||
setTags(to);
|
||||
});
|
||||
|
||||
// 关闭全部标签
|
||||
const closeAll = () => {
|
||||
store.commit("clearTags");
|
||||
router.push("/");
|
||||
};
|
||||
// 关闭其他标签
|
||||
const closeOther = () => {
|
||||
const curItem = tagsList.value.filter((item) => {
|
||||
return item.path === route.fullPath;
|
||||
});
|
||||
store.commit("closeTagsOther", curItem);
|
||||
};
|
||||
const handleTags = (command) => {
|
||||
command === "other" ? closeOther() : closeAll();
|
||||
};
|
||||
|
||||
// 关闭当前页面的标签页
|
||||
// store.commit("closeCurrentTag", {
|
||||
// $router: router,
|
||||
// $route: route
|
||||
// });
|
||||
|
||||
return {
|
||||
isActive,
|
||||
tagsList,
|
||||
showTags,
|
||||
closeTags,
|
||||
handleTags,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
.tags {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
padding-right: 120px;
|
||||
box-shadow: 0 5px 10px #ddd;
|
||||
}
|
||||
|
||||
.tags ul {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tags-li {
|
||||
float: left;
|
||||
margin: 3px 5px 2px 3px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
height: 23px;
|
||||
line-height: 23px;
|
||||
border: 1px solid #e9eaec;
|
||||
background: #fff;
|
||||
padding: 0 5px 0 12px;
|
||||
vertical-align: middle;
|
||||
color: #666;
|
||||
-webkit-transition: all 0.3s ease-in;
|
||||
-moz-transition: all 0.3s ease-in;
|
||||
transition: all 0.3s ease-in;
|
||||
}
|
||||
|
||||
.tags-li:not(.active):hover {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.tags-li.active {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tags-li-title {
|
||||
float: left;
|
||||
max-width: 80px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 5px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.tags-li.active .tags-li-title {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tags-close-box {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
box-sizing: border-box;
|
||||
padding-top: 1px;
|
||||
text-align: center;
|
||||
width: 110px;
|
||||
height: 30px;
|
||||
background: #fff;
|
||||
box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<div class="tags" v-if="tags.show">
|
||||
<ul>
|
||||
<li class="tags-li" v-for="(item,index) in tags.list" :class="{'active': isActive(item.path)}" :key="index">
|
||||
<router-link :to="item.path" class="tags-li-title">{{item.title}}</router-link>
|
||||
<span class="tags-li-icon" @click="closeTags(index)">
|
||||
<i class="el-icon-close"></i>
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="tags-close-box">
|
||||
<el-dropdown @command="handleTags">
|
||||
<el-button size="mini" type="primary">
|
||||
标签选项
|
||||
<i class="el-icon-arrow-down el-icon--right"></i>
|
||||
</el-button>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu size="small">
|
||||
<el-dropdown-item command="other">关闭其他</el-dropdown-item>
|
||||
<el-dropdown-item command="all">关闭所有</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useTagsStore } from '../store/tags'
|
||||
import { onBeforeRouteUpdate, useRoute, useRouter } from "vue-router";
|
||||
export default {
|
||||
setup() {
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const isActive = (path) => {
|
||||
return path === route.fullPath;
|
||||
};
|
||||
|
||||
const tags = useTagsStore();
|
||||
// 关闭单个标签
|
||||
const closeTags = (index) => {
|
||||
const delItem = tags.list[index];
|
||||
tags.delTagsItem(index);
|
||||
const item = tags.list[index] ? tags.list[index] : tags.list[index - 1];
|
||||
if (item) {
|
||||
delItem.path === route.fullPath && router.push(item.path);
|
||||
} else {
|
||||
router.push("/");
|
||||
}
|
||||
};
|
||||
|
||||
// 设置标签
|
||||
const setTags = (route) => {
|
||||
const isExist = tags.list.some((item) => {
|
||||
return item.path === route.fullPath;
|
||||
});
|
||||
if (!isExist) {
|
||||
if (tags.list.length >= 8) tags.delTagsItem(0);
|
||||
tags.setTagsItem({
|
||||
name: route.name,
|
||||
title: route.meta.title,
|
||||
path: route.fullPath,
|
||||
});
|
||||
}
|
||||
};
|
||||
setTags(route);
|
||||
onBeforeRouteUpdate((to) => {
|
||||
setTags(to);
|
||||
});
|
||||
|
||||
// 关闭全部标签
|
||||
const closeAll = () => {
|
||||
tags.clearTags();
|
||||
router.push("/");
|
||||
};
|
||||
// 关闭其他标签
|
||||
const closeOther = () => {
|
||||
const curItem = tags.list.filter((item) => {
|
||||
return item.path === route.fullPath;
|
||||
});
|
||||
tags.closeTagsOther(curItem);
|
||||
};
|
||||
const handleTags = (command) => {
|
||||
command === "other" ? closeOther() : closeAll();
|
||||
};
|
||||
|
||||
// 关闭当前页面的标签页
|
||||
// tags.closeCurrentTag({
|
||||
// $router: router,
|
||||
// $route: route
|
||||
// });
|
||||
|
||||
return {
|
||||
isActive,
|
||||
tags,
|
||||
closeTags,
|
||||
handleTags,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
.tags {
|
||||
position: relative;
|
||||
height: 30px;
|
||||
overflow: hidden;
|
||||
background: #fff;
|
||||
padding-right: 120px;
|
||||
box-shadow: 0 5px 10px #ddd;
|
||||
}
|
||||
|
||||
.tags ul {
|
||||
box-sizing: border-box;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.tags-li {
|
||||
float: left;
|
||||
margin: 3px 5px 2px 3px;
|
||||
border-radius: 3px;
|
||||
font-size: 12px;
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
height: 23px;
|
||||
line-height: 23px;
|
||||
border: 1px solid #e9eaec;
|
||||
background: #fff;
|
||||
padding: 0 5px 0 12px;
|
||||
vertical-align: middle;
|
||||
color: #666;
|
||||
-webkit-transition: all 0.3s ease-in;
|
||||
-moz-transition: all 0.3s ease-in;
|
||||
transition: all 0.3s ease-in;
|
||||
}
|
||||
|
||||
.tags-li:not(.active):hover {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.tags-li.active {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tags-li-title {
|
||||
float: left;
|
||||
max-width: 80px;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
margin-right: 5px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
.tags-li.active .tags-li-title {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.tags-close-box {
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
box-sizing: border-box;
|
||||
padding-top: 1px;
|
||||
text-align: center;
|
||||
width: 110px;
|
||||
height: 30px;
|
||||
background: #fff;
|
||||
box-shadow: -3px 0 15px 3px rgba(0, 0, 0, 0.1);
|
||||
z-index: 10;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
import {createApp} from 'vue'
|
||||
import { createPinia } from 'pinia'
|
||||
import App from './App.vue'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
import installElementPlus from './plugins/element'
|
||||
import './assets/css/icon.css'
|
||||
const app = createApp(App)
|
||||
installElementPlus(app)
|
||||
app
|
||||
.use(store)
|
||||
app.use(createPinia())
|
||||
.use(router)
|
||||
.mount('#app')
|
|
@ -1,144 +1,151 @@
|
|||
import {createRouter, createWebHashHistory} from "vue-router";
|
||||
import Home from "../views/Home.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/dashboard'
|
||||
}, {
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: Home,
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard",
|
||||
name: "dashboard",
|
||||
meta: {
|
||||
title: '系统首页'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "dashboard" */ "../views/Dashboard.vue")
|
||||
}, {
|
||||
path: "/table",
|
||||
name: "basetable",
|
||||
meta: {
|
||||
title: '表格'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "table" */ "../views/BaseTable.vue")
|
||||
}, {
|
||||
path: "/charts",
|
||||
name: "basecharts",
|
||||
meta: {
|
||||
title: '图表'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "charts" */ "../views/BaseCharts.vue")
|
||||
}, {
|
||||
path: "/form",
|
||||
name: "baseform",
|
||||
meta: {
|
||||
title: '表单'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "form" */ "../views/BaseForm.vue")
|
||||
}, {
|
||||
path: "/tabs",
|
||||
name: "tabs",
|
||||
meta: {
|
||||
title: 'tab标签'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "tabs" */ "../views/Tabs.vue")
|
||||
}, {
|
||||
path: "/donate",
|
||||
name: "donate",
|
||||
meta: {
|
||||
title: '鼓励作者'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "donate" */ "../views/Donate.vue")
|
||||
}, {
|
||||
path: "/permission",
|
||||
name: "permission",
|
||||
meta: {
|
||||
title: '权限管理',
|
||||
permission: true
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "permission" */ "../views/Permission.vue")
|
||||
}, {
|
||||
path: "/i18n",
|
||||
name: "i18n",
|
||||
meta: {
|
||||
title: '国际化语言'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "i18n" */ "../views/I18n.vue")
|
||||
}, {
|
||||
path: "/upload",
|
||||
name: "upload",
|
||||
meta: {
|
||||
title: '上传插件'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "upload" */ "../views/Upload.vue")
|
||||
}, {
|
||||
path: "/icon",
|
||||
name: "icon",
|
||||
meta: {
|
||||
title: '自定义图标'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "icon" */ "../views/Icon.vue")
|
||||
}, {
|
||||
path: '/404',
|
||||
name: '404',
|
||||
meta: {
|
||||
title: '找不到页面'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "404" */ '../views/404.vue')
|
||||
}, {
|
||||
path: '/403',
|
||||
name: '403',
|
||||
meta: {
|
||||
title: '没有权限'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "403" */ '../views/403.vue')
|
||||
}, {
|
||||
path: '/user',
|
||||
name: 'user',
|
||||
meta: {
|
||||
title: '个人中心'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "user" */ '../views/User.vue')
|
||||
}, {
|
||||
path: '/editor',
|
||||
name: 'editor',
|
||||
meta: {
|
||||
title: '富文本编辑器'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "editor" */ '../views/Editor.vue')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
meta: {
|
||||
title: '登录'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "login" */ "../views/Login.vue")
|
||||
}
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
document.title = `${to.meta.title} | vue-manage-system`;
|
||||
const role = localStorage.getItem('ms_username');
|
||||
if (!role && to.path !== '/login') {
|
||||
next('/login');
|
||||
} else if (to.meta.permission) {
|
||||
// 如果是管理员权限则可进入,这里只是简单的模拟管理员权限而已
|
||||
role === 'admin'
|
||||
? next()
|
||||
: next('/403');
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
import {createRouter, createWebHashHistory} from "vue-router";
|
||||
import Home from "../views/Home.vue";
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
redirect: '/dashboard'
|
||||
}, {
|
||||
path: "/",
|
||||
name: "Home",
|
||||
component: Home,
|
||||
children: [
|
||||
{
|
||||
path: "/dashboard",
|
||||
name: "dashboard",
|
||||
meta: {
|
||||
title: '系统首页'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "dashboard" */ "../views/Dashboard.vue")
|
||||
}, {
|
||||
path: "/table",
|
||||
name: "basetable",
|
||||
meta: {
|
||||
title: '表格'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "table" */ "../views/BaseTable.vue")
|
||||
}, {
|
||||
path: "/charts",
|
||||
name: "basecharts",
|
||||
meta: {
|
||||
title: '图表'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "charts" */ "../views/BaseCharts.vue")
|
||||
}, {
|
||||
path: "/form",
|
||||
name: "baseform",
|
||||
meta: {
|
||||
title: '表单'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "form" */ "../views/BaseForm.vue")
|
||||
}, {
|
||||
path: "/tabs",
|
||||
name: "tabs",
|
||||
meta: {
|
||||
title: 'tab标签'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "tabs" */ "../views/Tabs.vue")
|
||||
}, {
|
||||
path: "/donate",
|
||||
name: "donate",
|
||||
meta: {
|
||||
title: '鼓励作者'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "donate" */ "../views/Donate.vue")
|
||||
}, {
|
||||
path: "/permission",
|
||||
name: "permission",
|
||||
meta: {
|
||||
title: '权限管理',
|
||||
permission: true
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "permission" */ "../views/Permission.vue")
|
||||
}, {
|
||||
path: "/i18n",
|
||||
name: "i18n",
|
||||
meta: {
|
||||
title: '国际化语言'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "i18n" */ "../views/I18n.vue")
|
||||
}, {
|
||||
path: "/upload",
|
||||
name: "upload",
|
||||
meta: {
|
||||
title: '上传插件'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "upload" */ "../views/Upload.vue")
|
||||
}, {
|
||||
path: "/icon",
|
||||
name: "icon",
|
||||
meta: {
|
||||
title: '自定义图标'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "icon" */ "../views/Icon.vue")
|
||||
}, {
|
||||
path: '/404',
|
||||
name: '404',
|
||||
meta: {
|
||||
title: '找不到页面'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "404" */ '../views/404.vue')
|
||||
}, {
|
||||
path: '/403',
|
||||
name: '403',
|
||||
meta: {
|
||||
title: '没有权限'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "403" */ '../views/403.vue')
|
||||
}, {
|
||||
path: '/user',
|
||||
name: 'user',
|
||||
meta: {
|
||||
title: '个人中心'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "user" */ '../views/User.vue')
|
||||
}, {
|
||||
path: '/editor',
|
||||
name: 'editor',
|
||||
meta: {
|
||||
title: '富文本编辑器'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "editor" */ '../views/Editor.vue')
|
||||
}, {
|
||||
path: '/markdown',
|
||||
name: 'markdown',
|
||||
meta: {
|
||||
title: 'markdown编辑器'
|
||||
},
|
||||
component: () => import (/* webpackChunkName: "markdown" */ '../views/Markdown.vue')
|
||||
}
|
||||
]
|
||||
}, {
|
||||
path: "/login",
|
||||
name: "Login",
|
||||
meta: {
|
||||
title: '登录'
|
||||
},
|
||||
component: () => import ( /* webpackChunkName: "login" */ "../views/Login.vue")
|
||||
}
|
||||
];
|
||||
|
||||
const router = createRouter({
|
||||
history: createWebHashHistory(),
|
||||
routes
|
||||
});
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
document.title = `${to.meta.title} | vue-manage-system`;
|
||||
const role = localStorage.getItem('ms_username');
|
||||
if (!role && to.path !== '/login') {
|
||||
next('/login');
|
||||
} else if (to.meta.permission) {
|
||||
// 如果是管理员权限则可进入,这里只是简单的模拟管理员权限而已
|
||||
role === 'admin'
|
||||
? next()
|
||||
: next('/403');
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
});
|
||||
|
||||
export default router;
|
|
@ -1,56 +0,0 @@
|
|||
import {createStore} from 'vuex'
|
||||
|
||||
export default createStore({
|
||||
state: {
|
||||
tagsList: [],
|
||||
collapse: false
|
||||
},
|
||||
mutations: {
|
||||
delTagsItem(state, data) {
|
||||
state
|
||||
.tagsList
|
||||
.splice(data.index, 1);
|
||||
},
|
||||
setTagsItem(state, data) {
|
||||
state
|
||||
.tagsList
|
||||
.push(data)
|
||||
},
|
||||
clearTags(state) {
|
||||
state.tagsList = []
|
||||
},
|
||||
closeTagsOther(state, data) {
|
||||
state.tagsList = data;
|
||||
},
|
||||
closeCurrentTag(state, data) {
|
||||
for (let i = 0, len = state.tagsList.length; i < len; i++) {
|
||||
const item = state.tagsList[i];
|
||||
if (item.path === data.$route.fullPath) {
|
||||
if (i < len - 1) {
|
||||
data
|
||||
.$router
|
||||
.push(state.tagsList[i + 1].path);
|
||||
} else if (i > 0) {
|
||||
data
|
||||
.$router
|
||||
.push(state.tagsList[i - 1].path);
|
||||
} else {
|
||||
data
|
||||
.$router
|
||||
.push("/");
|
||||
}
|
||||
state
|
||||
.tagsList
|
||||
.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
// 侧边栏折叠
|
||||
handleCollapse(state, data) {
|
||||
state.collapse = data;
|
||||
}
|
||||
},
|
||||
actions: {},
|
||||
modules: {}
|
||||
})
|
|
@ -0,0 +1,17 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useSidebarStore = defineStore('sidebar', {
|
||||
state: () => {
|
||||
return {
|
||||
collapse: false
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
|
||||
},
|
||||
actions: {
|
||||
handleCollapse() {
|
||||
this.collapse = !this.collapse;
|
||||
}
|
||||
}
|
||||
})
|
|
@ -0,0 +1,48 @@
|
|||
import { defineStore } from 'pinia'
|
||||
|
||||
export const useTagsStore = defineStore('tags', {
|
||||
state: () => {
|
||||
return {
|
||||
list: []
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
show: (state) => {
|
||||
return state.list.length > 0;
|
||||
},
|
||||
nameList: (state) => {
|
||||
return state.list.map(item => item.name);
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
delTagsItem(index) {
|
||||
this.list.splice(index, 1);
|
||||
},
|
||||
setTagsItem(data) {
|
||||
this.list.push(data)
|
||||
},
|
||||
clearTags() {
|
||||
this.list = []
|
||||
},
|
||||
closeTagsOther(data) {
|
||||
this.list = data;
|
||||
},
|
||||
closeCurrentTag(data) {
|
||||
console.log(data)
|
||||
for (let i = 0, len = this.list.length; i < len; i++) {
|
||||
const item = this.list[i];
|
||||
if (item.path === data.$route.fullPath) {
|
||||
if (i < len - 1) {
|
||||
data.$router.push(this.list[i + 1].path);
|
||||
} else if (i > 0) {
|
||||
data.$router.push(this.list[i - 1].path);
|
||||
} else {
|
||||
data.$router.push("/");
|
||||
}
|
||||
this.list.splice(i, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
})
|
|
@ -1,44 +1,41 @@
|
|||
<template>
|
||||
<div class="about">
|
||||
<v-header />
|
||||
<v-sidebar />
|
||||
<div class="content-box" :class="{ 'content-collapse': collapse }">
|
||||
<v-tags></v-tags>
|
||||
<div class="content">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition name="move" mode="out-in">
|
||||
<keep-alive :include="tagsList">
|
||||
<component :is="Component" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
<!-- <el-backtop target=".content"></el-backtop> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { computed } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import vHeader from "../components/Header.vue";
|
||||
import vSidebar from "../components/Sidebar.vue";
|
||||
import vTags from "../components/Tags.vue";
|
||||
export default {
|
||||
components: {
|
||||
vHeader,
|
||||
vSidebar,
|
||||
vTags,
|
||||
},
|
||||
setup() {
|
||||
const store = useStore();
|
||||
const tagsList = computed(() =>
|
||||
store.state.tagsList.map((item) => item.name)
|
||||
);
|
||||
const collapse = computed(() => store.state.collapse);
|
||||
return {
|
||||
tagsList,
|
||||
collapse,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<template>
|
||||
<div class="about">
|
||||
<v-header />
|
||||
<v-sidebar />
|
||||
<div class="content-box" :class="{ 'content-collapse': sidebar.collapse }">
|
||||
<v-tags></v-tags>
|
||||
<div class="content">
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition name="move" mode="out-in">
|
||||
<keep-alive :include="tags.nameList">
|
||||
<component :is="Component" />
|
||||
</keep-alive>
|
||||
</transition>
|
||||
</router-view>
|
||||
<!-- <el-backtop target=".content"></el-backtop> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { useSidebarStore } from '../store/sidebar'
|
||||
import { useTagsStore } from '../store/tags'
|
||||
import vHeader from "../components/Header.vue";
|
||||
import vSidebar from "../components/Sidebar.vue";
|
||||
import vTags from "../components/Tags.vue";
|
||||
export default {
|
||||
components: {
|
||||
vHeader,
|
||||
vSidebar,
|
||||
vTags,
|
||||
},
|
||||
setup() {
|
||||
const sidebar = useSidebarStore();
|
||||
const tags = useTagsStore();
|
||||
return {
|
||||
tags,
|
||||
sidebar,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -1,125 +1,125 @@
|
|||
<template>
|
||||
<div class="login-wrap">
|
||||
<div class="ms-login">
|
||||
<div class="ms-title">后台管理系统</div>
|
||||
<el-form :model="param" :rules="rules" ref="login" label-width="0px" class="ms-content">
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="param.username" placeholder="username">
|
||||
<template #prepend>
|
||||
<el-button icon="el-icon-user"></el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input type="password" placeholder="password" v-model="param.password"
|
||||
@keyup.enter="submitForm()">
|
||||
<template #prepend>
|
||||
<el-button icon="el-icon-lock"></el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<div class="login-btn">
|
||||
<el-button type="primary" @click="submitForm()">登录</el-button>
|
||||
</div>
|
||||
<p class="login-tips">Tips : 用户名和密码随便填。</p>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, reactive } from "vue";
|
||||
import { useStore } from "vuex";
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const param = reactive({
|
||||
username: "admin",
|
||||
password: "123123",
|
||||
});
|
||||
|
||||
const rules = {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入用户名",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
],
|
||||
};
|
||||
const login = ref(null);
|
||||
const submitForm = () => {
|
||||
login.value.validate((valid) => {
|
||||
if (valid) {
|
||||
ElMessage.success("登录成功");
|
||||
localStorage.setItem("ms_username", param.username);
|
||||
router.push("/");
|
||||
} else {
|
||||
ElMessage.error("登录成功");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const store = useStore();
|
||||
store.commit("clearTags");
|
||||
|
||||
return {
|
||||
param,
|
||||
rules,
|
||||
login,
|
||||
submitForm,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url(../assets/img/login-bg.jpg);
|
||||
background-size: 100%;
|
||||
}
|
||||
.ms-title {
|
||||
width: 100%;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
.ms-login {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 350px;
|
||||
margin: -190px 0 0 -175px;
|
||||
border-radius: 5px;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
overflow: hidden;
|
||||
}
|
||||
.ms-content {
|
||||
padding: 30px 30px;
|
||||
}
|
||||
.login-btn {
|
||||
text-align: center;
|
||||
}
|
||||
.login-btn button {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.login-tips {
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
color: #fff;
|
||||
}
|
||||
<template>
|
||||
<div class="login-wrap">
|
||||
<div class="ms-login">
|
||||
<div class="ms-title">后台管理系统</div>
|
||||
<el-form :model="param" :rules="rules" ref="login" label-width="0px" class="ms-content">
|
||||
<el-form-item prop="username">
|
||||
<el-input v-model="param.username" placeholder="username">
|
||||
<template #prepend>
|
||||
<el-button icon="el-icon-user"></el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<el-form-item prop="password">
|
||||
<el-input type="password" placeholder="password" v-model="param.password"
|
||||
@keyup.enter="submitForm()">
|
||||
<template #prepend>
|
||||
<el-button icon="el-icon-lock"></el-button>
|
||||
</template>
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
<div class="login-btn">
|
||||
<el-button type="primary" @click="submitForm()">登录</el-button>
|
||||
</div>
|
||||
<p class="login-tips">Tips : 用户名和密码随便填。</p>
|
||||
</el-form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { ref, reactive } from "vue";
|
||||
import { useTagsStore } from '../store/tags'
|
||||
import { useRouter } from "vue-router";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
export default {
|
||||
setup() {
|
||||
const router = useRouter();
|
||||
const param = reactive({
|
||||
username: "admin",
|
||||
password: "123123",
|
||||
});
|
||||
|
||||
const rules = {
|
||||
username: [
|
||||
{
|
||||
required: true,
|
||||
message: "请输入用户名",
|
||||
trigger: "blur",
|
||||
},
|
||||
],
|
||||
password: [
|
||||
{ required: true, message: "请输入密码", trigger: "blur" },
|
||||
],
|
||||
};
|
||||
const login = ref(null);
|
||||
const submitForm = () => {
|
||||
login.value.validate((valid) => {
|
||||
if (valid) {
|
||||
ElMessage.success("登录成功");
|
||||
localStorage.setItem("ms_username", param.username);
|
||||
router.push("/");
|
||||
} else {
|
||||
ElMessage.error("登录成功");
|
||||
return false;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const tags = useTagsStore();
|
||||
tags.clearTags();
|
||||
|
||||
return {
|
||||
param,
|
||||
rules,
|
||||
login,
|
||||
submitForm,
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.login-wrap {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-image: url(../assets/img/login-bg.jpg);
|
||||
background-size: 100%;
|
||||
}
|
||||
.ms-title {
|
||||
width: 100%;
|
||||
line-height: 50px;
|
||||
text-align: center;
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
border-bottom: 1px solid #ddd;
|
||||
}
|
||||
.ms-login {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
width: 350px;
|
||||
margin: -190px 0 0 -175px;
|
||||
border-radius: 5px;
|
||||
background: rgba(255, 255, 255, 0.3);
|
||||
overflow: hidden;
|
||||
}
|
||||
.ms-content {
|
||||
padding: 30px 30px;
|
||||
}
|
||||
.login-btn {
|
||||
text-align: center;
|
||||
}
|
||||
.login-btn button {
|
||||
width: 100%;
|
||||
height: 36px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.login-tips {
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
color: #fff;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="crumbs">
|
||||
<el-breadcrumb separator="/">
|
||||
<el-breadcrumb-item>
|
||||
<i class="el-icon-lx-calendar"></i> 表单
|
||||
</el-breadcrumb-item>
|
||||
<el-breadcrumb-item>markdown编辑器</el-breadcrumb-item>
|
||||
</el-breadcrumb>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="plugins-tips">
|
||||
md-editor-v3:vue3版本的 markdown 编辑器,配置丰富,请详看文档。
|
||||
访问地址:
|
||||
<a href="https://imzbf.github.io/md-editor-v3/index" target="_blank">md-editor-v3</a>
|
||||
</div>
|
||||
<md-editor class="mgb20" v-model="text" @on-upload-img="onUploadImg"/>
|
||||
<el-button type="primary">提交</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref} from "vue";
|
||||
import MdEditor from 'md-editor-v3';
|
||||
import 'md-editor-v3/lib/style.css';
|
||||
|
||||
const text = ref('Hello Editor!');
|
||||
const onUploadImg = (files)=>{
|
||||
console.log(files)
|
||||
}
|
||||
</script>
|
Loading…
Reference in New Issue