init
This commit is contained in:
parent
7fbe8d10fd
commit
834b9b0756
|
@ -0,0 +1,12 @@
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
end_of_line = lf
|
||||||
|
indent_size = 4
|
||||||
|
indent_style = tab
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
trim_trailing_whitespace = false
|
|
@ -1,18 +1,25 @@
|
||||||
# Build and Release Folders
|
.DS_Store
|
||||||
bin-debug/
|
node_modules
|
||||||
bin-release/
|
/dist
|
||||||
[Oo]bj/
|
|
||||||
[Bb]in/
|
|
||||||
|
|
||||||
# Other files and folders
|
|
||||||
.settings/
|
|
||||||
|
|
||||||
# Executables
|
# local env files
|
||||||
*.swf
|
.env.local
|
||||||
*.air
|
.env.*.local
|
||||||
*.ipa
|
|
||||||
*.apk
|
|
||||||
|
|
||||||
# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
|
# Log files
|
||||||
# should NOT be excluded as they contain compiler settings and other important
|
npm-debug.log*
|
||||||
# information for Eclipse / Flash Builder.
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
package-lock.json
|
36
README.en.md
36
README.en.md
|
@ -1,36 +0,0 @@
|
||||||
# SCUI
|
|
||||||
|
|
||||||
#### Description
|
|
||||||
SCUI
|
|
||||||
|
|
||||||
#### Software Architecture
|
|
||||||
Software architecture description
|
|
||||||
|
|
||||||
#### Installation
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Instructions
|
|
||||||
|
|
||||||
1. xxxx
|
|
||||||
2. xxxx
|
|
||||||
3. xxxx
|
|
||||||
|
|
||||||
#### Contribution
|
|
||||||
|
|
||||||
1. Fork the repository
|
|
||||||
2. Create Feat_xxx branch
|
|
||||||
3. Commit your code
|
|
||||||
4. Create Pull Request
|
|
||||||
|
|
||||||
|
|
||||||
#### Gitee Feature
|
|
||||||
|
|
||||||
1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md
|
|
||||||
2. Gitee blog [blog.gitee.com](https://blog.gitee.com)
|
|
||||||
3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore)
|
|
||||||
4. The most valuable open source project [GVP](https://gitee.com/gvp)
|
|
||||||
5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help)
|
|
||||||
6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/)
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
{
|
||||||
|
"name": "element-plus-starter",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"private": true,
|
||||||
|
"scripts": {
|
||||||
|
"serve": "vue-cli-service serve",
|
||||||
|
"build": "vue-cli-service build",
|
||||||
|
"lint": "vue-cli-service lint"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^0.21.0",
|
||||||
|
"core-js": "^3.6.5",
|
||||||
|
"element-plus": "latest",
|
||||||
|
"less": "^3.12.2",
|
||||||
|
"less-loader": "^7.1.0",
|
||||||
|
"nprogress": "^0.2.0",
|
||||||
|
"vue": "^3.0.0",
|
||||||
|
"vue-router": "^4.0.0-0",
|
||||||
|
"vuex": "^4.0.0-0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "~4.5.0",
|
||||||
|
"@vue/cli-plugin-eslint": "~4.5.0",
|
||||||
|
"@vue/cli-service": "~4.5.0",
|
||||||
|
"@vue/compiler-sfc": "^3.0.0",
|
||||||
|
"babel-eslint": "^10.1.0",
|
||||||
|
"eslint": "^6.7.2",
|
||||||
|
"eslint-plugin-vue": "^7.0.0-0"
|
||||||
|
},
|
||||||
|
"eslintConfig": {
|
||||||
|
"root": true,
|
||||||
|
"env": {
|
||||||
|
"node": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"plugin:vue/vue3-essential",
|
||||||
|
"eslint:recommended"
|
||||||
|
],
|
||||||
|
"parserOptions": {
|
||||||
|
"parser": "babel-eslint"
|
||||||
|
},
|
||||||
|
"rules": {
|
||||||
|
"indent": 0,
|
||||||
|
"no-tabs": 0,
|
||||||
|
"no-mixed-spaces-and-tabs": 0,
|
||||||
|
"vue/no-unused-components": "off"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions",
|
||||||
|
"not dead"
|
||||||
|
]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 15 KiB |
|
@ -0,0 +1,18 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title>Welcome to Element Plus</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript
|
||||||
|
enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app" class="aminui"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,68 @@
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"data": {
|
||||||
|
"userInfo" : {
|
||||||
|
"userName":"Admin"
|
||||||
|
},
|
||||||
|
"menuList" : [
|
||||||
|
{
|
||||||
|
"name": "组件",
|
||||||
|
"path": "/vab",
|
||||||
|
"meta": {
|
||||||
|
"icon":"el-icon-takeaway-box"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"path": "/vab/list",
|
||||||
|
"name": "列表",
|
||||||
|
"meta": {},
|
||||||
|
"component": "list"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/vab/show",
|
||||||
|
"name": "详情",
|
||||||
|
"meta": {},
|
||||||
|
"component": "show"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path": "/vab/lala",
|
||||||
|
"name": "404",
|
||||||
|
"meta": {},
|
||||||
|
"component": "lala"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "其他",
|
||||||
|
"path": "/other",
|
||||||
|
"meta": {
|
||||||
|
"icon":"el-icon-more"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"path": "/other/1",
|
||||||
|
"name": "other1",
|
||||||
|
"meta": {},
|
||||||
|
"component": "list"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "配置",
|
||||||
|
"path": "/setting",
|
||||||
|
"meta": {
|
||||||
|
"icon":"el-icon-setting"
|
||||||
|
},
|
||||||
|
"children": [
|
||||||
|
{
|
||||||
|
"path": "/setting/1",
|
||||||
|
"name": "setting1",
|
||||||
|
"meta": {},
|
||||||
|
"component": "lala"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"message": ""
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<template>
|
||||||
|
<router-view></router-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'App',
|
||||||
|
setup() {}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
@import '@/style/style.less';
|
||||||
|
</style>
|
|
@ -0,0 +1,13 @@
|
||||||
|
import config from "@/config";
|
||||||
|
import http from "@/utils/request";
|
||||||
|
|
||||||
|
|
||||||
|
const api = {
|
||||||
|
user: {
|
||||||
|
info: async function(){
|
||||||
|
return await http.get(`${config.apiUrl}/json/user.json`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default api;
|
Binary file not shown.
After Width: | Height: | Size: 59 KiB |
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<div class="hello">
|
||||||
|
<h1>{{ msg }}</h1>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'HelloWorld',
|
||||||
|
props: {
|
||||||
|
msg: String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||||
|
<style scoped>
|
||||||
|
h3 {
|
||||||
|
margin: 40px 0 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
li {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #42b983;
|
||||||
|
}
|
||||||
|
</style>
|
|
@ -0,0 +1,14 @@
|
||||||
|
module.exports = {
|
||||||
|
//标题
|
||||||
|
title: "VUE",
|
||||||
|
//版本号
|
||||||
|
version: "1.0",
|
||||||
|
//接口地址
|
||||||
|
apiUrl: "",
|
||||||
|
//是否开启多标签
|
||||||
|
tags: false,
|
||||||
|
//布局
|
||||||
|
layout: "default",
|
||||||
|
//主题
|
||||||
|
theme: "default",
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
<template>
|
||||||
|
<label v-for="navMenu in navMenus" v-bind:key="navMenu">
|
||||||
|
<el-menu-item v-if="!navMenu.children" :index="navMenu.path">
|
||||||
|
<i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i>
|
||||||
|
<span>{{navMenu.name}}</span>
|
||||||
|
</el-menu-item>
|
||||||
|
|
||||||
|
<el-submenu v-if="navMenu.children" :index="navMenu.path">
|
||||||
|
<template #title>
|
||||||
|
<i v-if="navMenu.meta&&navMenu.meta.icon" :class="navMenu.meta.icon || 'el-icon-menu'"></i>
|
||||||
|
<span> {{navMenu.name}}</span>
|
||||||
|
</template>
|
||||||
|
<NavMenu :navMenus="navMenu.children"></NavMenu>
|
||||||
|
</el-submenu>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'NavMenu',
|
||||||
|
props: ['navMenus'],
|
||||||
|
data() {
|
||||||
|
return {}
|
||||||
|
},
|
||||||
|
methods: {}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,14 @@
|
||||||
|
<template>
|
||||||
|
<div class="adminui-header">
|
||||||
|
header
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {},
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,80 @@
|
||||||
|
<template>
|
||||||
|
<div class="aminui-side-split">
|
||||||
|
<div class="adminui-side-split-scroll">
|
||||||
|
<ul>
|
||||||
|
<li v-for="item in menu" v-bind:key="item" :class="pmenu.path==item.path?'active':''" @click="showMenu(item)"><i :class="item.meta.icon || 'el-icon-menu'"></i>
|
||||||
|
<p>{{ item.name }}</p>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="aminui-side">
|
||||||
|
<div class="adminui-side-scroll">
|
||||||
|
<el-menu :default-active="$route.path" router>
|
||||||
|
<NavMenu :navMenus="nextMenu"></NavMenu>
|
||||||
|
</el-menu>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import NavMenu from './NavMenu.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
NavMenu
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
menu: [],
|
||||||
|
nextMenu: [],
|
||||||
|
pmenu: {}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created: function() {
|
||||||
|
var menu = this.$TOOL.data.get("user").menuList;
|
||||||
|
var home = this.$router.options.routes[0].children[0];
|
||||||
|
menu.unshift(home);
|
||||||
|
this.menu = menu;
|
||||||
|
this.showThis()
|
||||||
|
},
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route() {
|
||||||
|
this.showThis()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//路由监听高亮
|
||||||
|
showThis(){
|
||||||
|
var menu = this.$TOOL.data.get("user").menuList;
|
||||||
|
var home = this.$router.options.routes[0].children[0];
|
||||||
|
menu.unshift(home);
|
||||||
|
var pl = this.$route.path.split("/");
|
||||||
|
var p = pl.length<=2?home.path:"/" + pl[1];
|
||||||
|
this.pmenu = p==home.path ? home:this.getRoute(p, menu);
|
||||||
|
this.nextMenu = this.pmenu.children;
|
||||||
|
},
|
||||||
|
//点击显示
|
||||||
|
showMenu(route) {
|
||||||
|
this.pmenu = route;
|
||||||
|
this.nextMenu = route.children;
|
||||||
|
},
|
||||||
|
//根据path获取
|
||||||
|
getRoute(path, menu){
|
||||||
|
for (var item of menu) {
|
||||||
|
if (item.path == path) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
if (item.children) {
|
||||||
|
this.getRoute(path, item.children);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,170 @@
|
||||||
|
<template>
|
||||||
|
<div class="adminui-tags">
|
||||||
|
<ul>
|
||||||
|
<li v-for="tag in tagList" v-bind:key="tag" :class="isActive(tag) ? 'active' : '' " @contextmenu.prevent="openContextMenu($event, tag)">
|
||||||
|
<router-link :to="tag">
|
||||||
|
{{ tag.name }}
|
||||||
|
<i v-if="!tag.meta.affix" class="el-icon-close" @click.prevent.stop='closeSelectedTag(tag)'></i>
|
||||||
|
</router-link>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul v-if="contextMenuVisible" :style="{left:left+'px',top:top+'px'}" class="contextmenu" id="contextmenu">
|
||||||
|
<li @click="refreshTab()">刷新</li>
|
||||||
|
<hr>
|
||||||
|
<li @click="closeTabs()" :class="contextMenuItem.meta.affix?'disabled':''">关闭标签</li>
|
||||||
|
<li @click="closeOtherTabs()">关闭其他标签</li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.contextmenu {
|
||||||
|
position: fixed;
|
||||||
|
margin:0;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid #e4e7ed;
|
||||||
|
box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
|
||||||
|
z-index: 3000;
|
||||||
|
list-style-type: none;
|
||||||
|
padding: 10px 0;
|
||||||
|
}
|
||||||
|
.contextmenu hr {
|
||||||
|
margin:5px 0;
|
||||||
|
border: none;
|
||||||
|
height: 1px;
|
||||||
|
font-size: 0px;
|
||||||
|
background-color: #ebeef5;
|
||||||
|
}
|
||||||
|
.contextmenu li {
|
||||||
|
margin:0;
|
||||||
|
cursor: pointer;
|
||||||
|
line-height: 30px;
|
||||||
|
padding: 0 17px;
|
||||||
|
color: #606266;
|
||||||
|
}
|
||||||
|
.contextmenu li:hover {
|
||||||
|
background-color: #ecf5ff;
|
||||||
|
color: #66b1ff;
|
||||||
|
}
|
||||||
|
.contextmenu li.disabled {
|
||||||
|
cursor: not-allowed;
|
||||||
|
color: #bbb;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
contextMenuVisible: false,
|
||||||
|
contextMenuItem: null,
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
tagList: []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {},
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route(e) {
|
||||||
|
this.addViewTags(e)
|
||||||
|
},
|
||||||
|
contextMenuVisible(value) {
|
||||||
|
var _this = this;
|
||||||
|
var cm = function(e){
|
||||||
|
let sp = document.getElementById("contextmenu");
|
||||||
|
if(sp&&!sp.contains(e.target)){
|
||||||
|
_this.closeMenu()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (value) {
|
||||||
|
document.body.addEventListener('click', e=>cm(e))
|
||||||
|
}else{
|
||||||
|
document.body.removeEventListener('click', e=>cm(e))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.addViewTags(this.$router.options.routes[0].children[0].children[0]);
|
||||||
|
this.addViewTags(this.$route);
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
//增加tag
|
||||||
|
addViewTags(route) {
|
||||||
|
var ishas = this.tagList.some(item=>{
|
||||||
|
if(item.path == route.path){
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if(!ishas){
|
||||||
|
this.tagList.push(route)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//高亮tag
|
||||||
|
isActive(route) {
|
||||||
|
return route.path === this.$route.path
|
||||||
|
},
|
||||||
|
//关闭tag
|
||||||
|
closeSelectedTag(tag) {
|
||||||
|
const newtagList = this.tagList.filter(item => item.path !== tag.path)
|
||||||
|
this.tagList = newtagList;
|
||||||
|
if (this.isActive(tag)) {
|
||||||
|
const latestView = newtagList.slice(-1)[0]
|
||||||
|
if (latestView) {
|
||||||
|
this.$router.push(latestView)
|
||||||
|
} else {
|
||||||
|
this.$router.push('/')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//tag右键
|
||||||
|
openContextMenu(e, tag){
|
||||||
|
this.contextMenuItem = tag;
|
||||||
|
this.contextMenuVisible = true;
|
||||||
|
this.left = e.clientX + 1;
|
||||||
|
this.top = e.clientY + 1;
|
||||||
|
},
|
||||||
|
//关闭右键菜单
|
||||||
|
closeMenu() {
|
||||||
|
this.contextMenuItem = null;
|
||||||
|
this.contextMenuVisible = false
|
||||||
|
},
|
||||||
|
//TAB 刷新
|
||||||
|
refreshTab(){
|
||||||
|
var nowTag = this.contextMenuItem;
|
||||||
|
this.$router.push({
|
||||||
|
path: nowTag.path
|
||||||
|
})
|
||||||
|
this.contextMenuVisible = false
|
||||||
|
},
|
||||||
|
//TAB 关闭
|
||||||
|
closeTabs(){
|
||||||
|
var nowTag = this.contextMenuItem;
|
||||||
|
if(!nowTag.meta.affix){
|
||||||
|
this.closeSelectedTag(nowTag)
|
||||||
|
this.contextMenuVisible = false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
//TAB 关闭其他
|
||||||
|
closeOtherTabs(){
|
||||||
|
var nowTag = this.contextMenuItem;
|
||||||
|
var tags = this.tagList;
|
||||||
|
tags.forEach(tag => {
|
||||||
|
if(tag.meta&&tag.meta.affix || nowTag.path==tag.path){
|
||||||
|
return true
|
||||||
|
}else{
|
||||||
|
this.closeSelectedTag(tag)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.contextMenuVisible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,32 @@
|
||||||
|
<template>
|
||||||
|
<Side></Side>
|
||||||
|
|
||||||
|
<div class="aminui-body">
|
||||||
|
<Head></Head>
|
||||||
|
<Tags></Tags>
|
||||||
|
<div class="adminui-main">
|
||||||
|
<router-view v-slot="{ Component }">
|
||||||
|
<keep-alive>
|
||||||
|
<component :is="Component" />
|
||||||
|
</keep-alive>
|
||||||
|
</router-view>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import Side from './components/side.vue';
|
||||||
|
import Head from './components/head.vue';
|
||||||
|
import Tags from './components/tags.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'index',
|
||||||
|
setup() {},
|
||||||
|
components: {
|
||||||
|
Side,
|
||||||
|
Head,
|
||||||
|
Tags
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,20 @@
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import 'element-plus/lib/theme-chalk/index.css'
|
||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import config from "./config";
|
||||||
|
import router from './router'
|
||||||
|
import store from './store'
|
||||||
|
import tool from './utils/tool'
|
||||||
|
import api from './api'
|
||||||
|
|
||||||
|
const app = createApp(App);
|
||||||
|
|
||||||
|
app.config.globalProperties.$CONFIG = config;
|
||||||
|
app.config.globalProperties.$TOOL = tool;
|
||||||
|
app.config.globalProperties.$API = api;
|
||||||
|
|
||||||
|
app.use(store);
|
||||||
|
app.use(router);
|
||||||
|
app.use(ElementPlus, { size: 'small', zIndex: 3000 });
|
||||||
|
app.mount('#app');
|
|
@ -0,0 +1,126 @@
|
||||||
|
import {createRouter, createWebHashHistory} from 'vue-router';
|
||||||
|
import { ElNotification } from 'element-plus';
|
||||||
|
import NProgress from 'nprogress'
|
||||||
|
import 'nprogress/nprogress.css'
|
||||||
|
import tool from '@/utils/tool';
|
||||||
|
|
||||||
|
//系统路由
|
||||||
|
const routes = [{
|
||||||
|
path: "/",
|
||||||
|
name: "layout",
|
||||||
|
component: () => import(/* webpackChunkName: "layout" */ '@/layout'),
|
||||||
|
redirect: '/dashboard',
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/home",
|
||||||
|
name: "首页",
|
||||||
|
component: () => import(`@/views/other/empty`),
|
||||||
|
meta: {
|
||||||
|
icon: "el-icon-platform-eleme"
|
||||||
|
},
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: "/dashboard",
|
||||||
|
name: "控制台",
|
||||||
|
meta: {
|
||||||
|
affix: true
|
||||||
|
},
|
||||||
|
component: () => import(/* webpackChunkName: "home" */ '@/views/home'),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: "/login",
|
||||||
|
name: "登录",
|
||||||
|
component: () => import(/* webpackChunkName: "login" */ '@/views/login'),
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
//系统路由
|
||||||
|
const routes_404 = {
|
||||||
|
path: "/:pathMatch(.*)*",
|
||||||
|
name: "404",
|
||||||
|
hidden: true,
|
||||||
|
component: () => import(/* webpackChunkName: "404" */ '@/views/other/404'),
|
||||||
|
}
|
||||||
|
|
||||||
|
const router = createRouter({
|
||||||
|
history: createWebHashHistory(),
|
||||||
|
routes: routes
|
||||||
|
})
|
||||||
|
|
||||||
|
//判断是否已加载过API路由
|
||||||
|
var isGetApiRouter = false;
|
||||||
|
|
||||||
|
router.beforeEach(async (to, from, next) => {
|
||||||
|
NProgress.start()
|
||||||
|
|
||||||
|
let userInfo = tool.data.get("user");
|
||||||
|
|
||||||
|
if(to.path === "/login"){
|
||||||
|
next();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!userInfo){
|
||||||
|
next({
|
||||||
|
path: '/login'
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//加载API路由
|
||||||
|
if(!isGetApiRouter){
|
||||||
|
var apiRouter = filterAsyncRouter(userInfo.menuList);
|
||||||
|
apiRouter.forEach(item => {
|
||||||
|
router.addRoute("layout", item)
|
||||||
|
})
|
||||||
|
router.addRoute(routes_404)
|
||||||
|
if (to.matched.length == 0) {
|
||||||
|
router.push(to.path);
|
||||||
|
}
|
||||||
|
isGetApiRouter = true;
|
||||||
|
}
|
||||||
|
next();
|
||||||
|
});
|
||||||
|
|
||||||
|
router.afterEach(() => {
|
||||||
|
NProgress.done()
|
||||||
|
});
|
||||||
|
|
||||||
|
router.onError((error) => {
|
||||||
|
NProgress.done();
|
||||||
|
ElNotification.error({
|
||||||
|
title: '路由错误',
|
||||||
|
message: error
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
//转换
|
||||||
|
function filterAsyncRouter(routerMap) {
|
||||||
|
const accessedRouters = []
|
||||||
|
routerMap.filter(itemRouter => {
|
||||||
|
accessedRouters.push({
|
||||||
|
path: itemRouter.path,
|
||||||
|
name: itemRouter.name,
|
||||||
|
meta: itemRouter.meta,
|
||||||
|
children: filterAsyncRouter(itemRouter.children || []),
|
||||||
|
component: loadComponent(itemRouter.component)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return accessedRouters
|
||||||
|
}
|
||||||
|
function loadComponent(component){
|
||||||
|
if(component){
|
||||||
|
return () => import(/* webpackChunkName: "[request]" */ `@/views/${component}`)
|
||||||
|
}else{
|
||||||
|
return () => import(`@/views/other/empty`)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export default router
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { createStore } from 'vuex';
|
||||||
|
import tagsView from './modules/tagsView';
|
||||||
|
|
||||||
|
export default createStore({
|
||||||
|
modules: {
|
||||||
|
tagsView
|
||||||
|
}
|
||||||
|
});
|
|
@ -0,0 +1,24 @@
|
||||||
|
export default {
|
||||||
|
state: {
|
||||||
|
visitedViews: [],
|
||||||
|
cachedViews: []
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
ADD_VISITED_VIEWS: (state, view) => {
|
||||||
|
if (state.visitedViews.some(v => v.path === view.path)) return
|
||||||
|
state.visitedViews.push(Object.assign({}, view, {
|
||||||
|
title: view.meta.title || 'no-name'
|
||||||
|
}))
|
||||||
|
if (!view.meta.noCache) {
|
||||||
|
state.cachedViews.push(view.name)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
addVisitedViews({
|
||||||
|
commit
|
||||||
|
}, view) {
|
||||||
|
commit('ADD_VISITED_VIEWS', view)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
#app, body, html {width: 100%;height: 100%;background-color: #f8f8f8;font-size: 12px;}
|
||||||
|
* {margin: 0;padding: 0;box-sizing: border-box;outline: none;}
|
||||||
|
|
||||||
|
/* 全局滚动条样式 */
|
||||||
|
.scrollable {-webkit-overflow-scrolling: touch;}
|
||||||
|
::-webkit-scrollbar {width: 5px;height: 5px;}
|
||||||
|
::-webkit-scrollbar-thumb {background-color: rgba(50, 50, 50, 0.3);}
|
||||||
|
::-webkit-scrollbar-thumb:hover {background-color: rgba(50, 50, 50, 0.6);}
|
||||||
|
::-webkit-scrollbar-track {background-color: rgba(50, 50, 50, 0.1);}
|
||||||
|
::-webkit-scrollbar-track:hover {background-color: rgba(50, 50, 50, 0.2);}
|
||||||
|
|
||||||
|
.aminui-side-split {position: absolute;top:0px;left:0px;bottom:0px;width:65px;background: #333;z-index: 90;}
|
||||||
|
.adminui-side-split-scroll {position: absolute;top:0px;left:0px;bottom:0px;right:0px;overflow: auto;overflow-x:hidden;}
|
||||||
|
.aminui-side-split li {cursor: pointer;width: 65px;height: 65px;color: #fff;text-align: center;display: flex;flex-direction: column;align-items: center;justify-content: center;}
|
||||||
|
.aminui-side-split li i {font-size: 16px;}
|
||||||
|
.aminui-side-split li p {margin-top:5px;}
|
||||||
|
.aminui-side-split li:hover {background: #444;}
|
||||||
|
.aminui-side-split li.active {background: #09f;}
|
||||||
|
|
||||||
|
.adminui-side-split-scroll::-webkit-scrollbar-thumb {background-color: rgba(255, 255, 255, 0.4);border-radius:5px;}
|
||||||
|
.adminui-side-split-scroll::-webkit-scrollbar-thumb:hover {background-color: rgba(255, 255, 255, 0.5);}
|
||||||
|
.adminui-side-split-scroll::-webkit-scrollbar-track {background-color: rgba(255, 255, 255, 0);}
|
||||||
|
.adminui-side-split-scroll::-webkit-scrollbar-track:hover {background-color: rgba(255, 255, 255, 0);}
|
||||||
|
|
||||||
|
|
||||||
|
.aminui-side {position: absolute;z-index: 80;top:0px;left:65px;bottom:0px;width:210px;background: #fff;box-shadow: 2px 0 8px 0 rgba(29,35,41,.05);border-right: 1px solid #e6e6e6;}
|
||||||
|
.adminui-side-scroll {position: absolute;top:0px;left:0px;bottom:0px;right:0px;overflow: auto;overflow-x:hidden;}
|
||||||
|
|
||||||
|
|
||||||
|
.aminui-body {position: absolute;z-index: 70;top:0px;left:275px;bottom:0px;right:0px;}
|
||||||
|
|
||||||
|
.adminui-header {height: 50px;border-bottom: 1px solid #ebeef5;background: #fff;box-shadow: 0 1px 4px rgba(0,21,41,.08);}
|
||||||
|
.adminui-tags {height:35px;background: #fff;border-bottom: 1px solid #e6e6e6;box-shadow: 0 1px 4px rgba(0,21,41,.08);}
|
||||||
|
.adminui-tags li {cursor: pointer;display: inline-block;float: left;height:34px;line-height: 34px;}
|
||||||
|
.adminui-tags li a {display: inline-block;padding:0 10px;width:100%;height:100%;color: #999;text-decoration:none;}
|
||||||
|
.adminui-tags li i {margin-left:10px;padding:3px;}
|
||||||
|
.adminui-tags li i:hover {background: #ff5722;color: #fff;}
|
||||||
|
.adminui-tags li:hover {background: #ecf5ff;}
|
||||||
|
.adminui-tags li.active {background: #09f;}
|
||||||
|
.adminui-tags li.active a {color: #fff;}
|
||||||
|
|
||||||
|
|
||||||
|
.adminui-main {position: absolute;top:85px;left:0px;right:0px;bottom:0px;overflow: auto;}
|
||||||
|
|
||||||
|
|
||||||
|
.el-menu {border: none!important;}
|
||||||
|
.el-menu-item.is-active {background: #ecf5ff;}
|
|
@ -0,0 +1,78 @@
|
||||||
|
import axios from 'axios';
|
||||||
|
import { ElNotification } from 'element-plus';
|
||||||
|
|
||||||
|
axios.defaults.baseURL = ''
|
||||||
|
|
||||||
|
axios.defaults.timeout = 10000
|
||||||
|
|
||||||
|
// HTTP request 拦截器
|
||||||
|
axios.interceptors.request.use(
|
||||||
|
(config) => {
|
||||||
|
return config;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
return Promise.reject(error);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
// HTTP response 拦截器
|
||||||
|
axios.interceptors.response.use(
|
||||||
|
(response) => {
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
if(error.response.status == 404){
|
||||||
|
ElNotification.error({
|
||||||
|
title: '请求错误',
|
||||||
|
message: "Status:404,正在请求不存在的服务器记录!"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if(error.response.status == 500){
|
||||||
|
ElNotification.error({
|
||||||
|
title: '请求错误',
|
||||||
|
message: "Status:500,服务器发生错误!"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.reject(error.response);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
var http = {
|
||||||
|
|
||||||
|
/** get 请求
|
||||||
|
* @param {接口地址} url
|
||||||
|
* @param {请求参数} params
|
||||||
|
*/
|
||||||
|
get: function(url, params) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.get(url, {
|
||||||
|
params: params
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
resolve(response.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
/** post 请求
|
||||||
|
* @param {接口地址} url
|
||||||
|
* @param {请求参数} params
|
||||||
|
*/
|
||||||
|
post: function(url, params) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.post(url, params)
|
||||||
|
.then((response) => {
|
||||||
|
resolve(response.data);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(error);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default http;
|
|
@ -0,0 +1,20 @@
|
||||||
|
const tool = {
|
||||||
|
/* localStorage */
|
||||||
|
data : {
|
||||||
|
set : function(table, settings){
|
||||||
|
var _set = JSON.stringify(settings)
|
||||||
|
return localStorage.setItem(table, _set);
|
||||||
|
},
|
||||||
|
get : function(table){
|
||||||
|
return JSON.parse(localStorage.getItem(table));
|
||||||
|
},
|
||||||
|
remove : function(table){
|
||||||
|
return localStorage.removeItem(table);
|
||||||
|
},
|
||||||
|
clear : function(){
|
||||||
|
return localStorage.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default tool
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div>HOME</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
|
@ -0,0 +1,10 @@
|
||||||
|
<template>
|
||||||
|
<div>LIST</div>
|
||||||
|
<div style="height:1800px"></div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
|
@ -0,0 +1,24 @@
|
||||||
|
<template>
|
||||||
|
<h2>LOGIN</h2>
|
||||||
|
<el-button type="primary" @click='login()'>模拟登录</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created: function() {
|
||||||
|
this.$TOOL.data.remove("user")
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
login: async function() {
|
||||||
|
var userInfo = await this.$API.user.info();
|
||||||
|
this.$TOOL.data.set("user", userInfo.data);
|
||||||
|
this.$router.push({path: '/'});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,9 @@
|
||||||
|
<template>
|
||||||
|
<div>404</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
</style>
|
|
@ -0,0 +1,3 @@
|
||||||
|
<template>
|
||||||
|
<router-view></router-view>
|
||||||
|
</template>
|
|
@ -0,0 +1,20 @@
|
||||||
|
<template>
|
||||||
|
<div>SHOW</div>
|
||||||
|
<div class="main">
|
||||||
|
<el-input v-model="input" placeholder="请输入内容" clearable></el-input>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
input: ''
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.main {width:200px;}
|
||||||
|
</style>
|
Loading…
Reference in New Issue