diff --git a/.editorconfig b/.editorconfig
new file mode 100644
index 00000000..4e1edd14
--- /dev/null
+++ b/.editorconfig
@@ -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
diff --git a/.gitignore b/.gitignore
index 5d947ca8..af757930 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,18 +1,25 @@
-# Build and Release Folders
-bin-debug/
-bin-release/
-[Oo]bj/
-[Bb]in/
+.DS_Store
+node_modules
+/dist
-# Other files and folders
-.settings/
-# Executables
-*.swf
-*.air
-*.ipa
-*.apk
+# local env files
+.env.local
+.env.*.local
-# Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties`
-# should NOT be excluded as they contain compiler settings and other important
-# information for Eclipse / Flash Builder.
+# Log files
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+# Editor directories and files
+.idea
+.vscode
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+package-lock.json
\ No newline at end of file
diff --git a/README.en.md b/README.en.md
deleted file mode 100644
index 2c500233..00000000
--- a/README.en.md
+++ /dev/null
@@ -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/)
diff --git a/babel.config.js b/babel.config.js
new file mode 100644
index 00000000..e9558405
--- /dev/null
+++ b/babel.config.js
@@ -0,0 +1,5 @@
+module.exports = {
+ presets: [
+ '@vue/cli-plugin-babel/preset'
+ ]
+}
diff --git a/package.json b/package.json
new file mode 100644
index 00000000..236011e9
--- /dev/null
+++ b/package.json
@@ -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"
+ ]
+}
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 00000000..2d1691e9
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/index.html b/public/index.html
new file mode 100644
index 00000000..c2ef4d60
--- /dev/null
+++ b/public/index.html
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+ Welcome to Element Plus
+
+
+
+
+
+
+
diff --git a/public/json/user.json b/public/json/user.json
new file mode 100644
index 00000000..881cb815
--- /dev/null
+++ b/public/json/user.json
@@ -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": ""
+}
diff --git a/src/App.vue b/src/App.vue
new file mode 100644
index 00000000..7aa61808
--- /dev/null
+++ b/src/App.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/api/index.js b/src/api/index.js
new file mode 100644
index 00000000..5cb2466d
--- /dev/null
+++ b/src/api/index.js
@@ -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;
diff --git a/src/assets/logo.png b/src/assets/logo.png
new file mode 100644
index 00000000..ed6cb27e
Binary files /dev/null and b/src/assets/logo.png differ
diff --git a/src/components/HelloWorld.vue b/src/components/HelloWorld.vue
new file mode 100644
index 00000000..d1674196
--- /dev/null
+++ b/src/components/HelloWorld.vue
@@ -0,0 +1,32 @@
+
+
+
{{ msg }}
+
+
+
+
+
+
+
diff --git a/src/config/index.js b/src/config/index.js
new file mode 100644
index 00000000..5b3dbdd0
--- /dev/null
+++ b/src/config/index.js
@@ -0,0 +1,14 @@
+module.exports = {
+ //标题
+ title: "VUE",
+ //版本号
+ version: "1.0",
+ //接口地址
+ apiUrl: "",
+ //是否开启多标签
+ tags: false,
+ //布局
+ layout: "default",
+ //主题
+ theme: "default",
+};
diff --git a/src/layout/components/NavMenu.vue b/src/layout/components/NavMenu.vue
new file mode 100644
index 00000000..72cb595e
--- /dev/null
+++ b/src/layout/components/NavMenu.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/layout/components/head.vue b/src/layout/components/head.vue
new file mode 100644
index 00000000..d93c5943
--- /dev/null
+++ b/src/layout/components/head.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
diff --git a/src/layout/components/side.vue b/src/layout/components/side.vue
new file mode 100644
index 00000000..98c71fa9
--- /dev/null
+++ b/src/layout/components/side.vue
@@ -0,0 +1,80 @@
+
+
+
+
+
+
+
+
diff --git a/src/layout/components/tags.vue b/src/layout/components/tags.vue
new file mode 100644
index 00000000..225413e1
--- /dev/null
+++ b/src/layout/components/tags.vue
@@ -0,0 +1,170 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/layout/index.vue b/src/layout/index.vue
new file mode 100644
index 00000000..cb2af925
--- /dev/null
+++ b/src/layout/index.vue
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
+
diff --git a/src/main.js b/src/main.js
new file mode 100644
index 00000000..a8c5a124
--- /dev/null
+++ b/src/main.js
@@ -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');
diff --git a/src/router/index.js b/src/router/index.js
new file mode 100644
index 00000000..31a33240
--- /dev/null
+++ b/src/router/index.js
@@ -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
diff --git a/src/store/index.js b/src/store/index.js
new file mode 100644
index 00000000..c5b3ede3
--- /dev/null
+++ b/src/store/index.js
@@ -0,0 +1,8 @@
+import { createStore } from 'vuex';
+import tagsView from './modules/tagsView';
+
+export default createStore({
+ modules: {
+ tagsView
+ }
+});
diff --git a/src/store/modules/tagsView.js b/src/store/modules/tagsView.js
new file mode 100644
index 00000000..3dd02ad8
--- /dev/null
+++ b/src/store/modules/tagsView.js
@@ -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)
+ },
+ }
+}
diff --git a/src/style/style.less b/src/style/style.less
new file mode 100644
index 00000000..c2c46acd
--- /dev/null
+++ b/src/style/style.less
@@ -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;}
\ No newline at end of file
diff --git a/src/utils/request.js b/src/utils/request.js
new file mode 100644
index 00000000..cea0bce4
--- /dev/null
+++ b/src/utils/request.js
@@ -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;
diff --git a/src/utils/tool.js b/src/utils/tool.js
new file mode 100644
index 00000000..5725b87f
--- /dev/null
+++ b/src/utils/tool.js
@@ -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
diff --git a/src/views/home.vue b/src/views/home.vue
new file mode 100644
index 00000000..3c8cb80b
--- /dev/null
+++ b/src/views/home.vue
@@ -0,0 +1,9 @@
+
+ HOME
+
+
+
+
+
diff --git a/src/views/list.vue b/src/views/list.vue
new file mode 100644
index 00000000..c9426247
--- /dev/null
+++ b/src/views/list.vue
@@ -0,0 +1,10 @@
+
+ LIST
+
+
+
+
+
+
diff --git a/src/views/login.vue b/src/views/login.vue
new file mode 100644
index 00000000..fd62fe1e
--- /dev/null
+++ b/src/views/login.vue
@@ -0,0 +1,24 @@
+
+ LOGIN
+ 模拟登录
+
+
+
diff --git a/src/views/other/404.vue b/src/views/other/404.vue
new file mode 100644
index 00000000..601c9249
--- /dev/null
+++ b/src/views/other/404.vue
@@ -0,0 +1,9 @@
+
+ 404
+
+
+
+
+
diff --git a/src/views/other/empty.vue b/src/views/other/empty.vue
new file mode 100644
index 00000000..9c72bc89
--- /dev/null
+++ b/src/views/other/empty.vue
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/src/views/show.vue b/src/views/show.vue
new file mode 100644
index 00000000..72fd5fd7
--- /dev/null
+++ b/src/views/show.vue
@@ -0,0 +1,20 @@
+
+ SHOW
+
+
+
+
+
+
+
+
\ No newline at end of file