Commit 1172ebb79113b8a99000521190fdd9f936ea649f
1 parent
c44ba96f68
Exists in
master
auto commit the code by alias command
Showing
29 changed files
with
1834 additions
and
243 deletions
Show diff stats
.eslintrc.js
babel.config.js
| 1 | +// module.exports = { | |
| 2 | +// presets: [ | |
| 3 | +// '@vue/app' | |
| 4 | +// ] | |
| 5 | +// } | |
| 6 | + // "@babel/preset-env", | |
| 7 | + // { | |
| 8 | + // "modules": false | |
| 9 | + // }, | |
| 1 | 10 | module.exports = { |
| 2 | - presets: [ | |
| 3 | - '@vue/app' | |
| 11 | + "presets": [ | |
| 12 | + [ | |
| 13 | + '@vue/app', | |
| 14 | + // '@babel/preset-env', | |
| 15 | + { | |
| 16 | + // "modules": false, | |
| 17 | + // "targets": { // 配置代码的运行环境 | |
| 18 | + // "chrome": 64 | |
| 19 | + // }, | |
| 20 | + // "useBuiltIns": true // 开启对 babel-polyfill 的优化 | |
| 21 | + } | |
| 22 | + ] | |
| 23 | + ], | |
| 24 | + "plugins": [ | |
| 25 | + [ | |
| 26 | + "component", | |
| 27 | + { | |
| 28 | + "libraryName": "element-ui", | |
| 29 | + "styleLibraryName": "theme-chalk" | |
| 30 | + } | |
| 31 | + ] | |
| 4 | 32 | ] |
| 5 | 33 | } | ... | ... |
mock/index.js
| 1 | 1 | import Mock from 'mockjs' |
| 2 | -import { param2Obj } from '../src/utils' | |
| 2 | +import { | |
| 3 | + param2Obj | |
| 4 | +} from '../src/utils' | |
| 3 | 5 | |
| 4 | 6 | import user from './user' |
| 5 | 7 | import table from './table' |
| ... | ... | @@ -16,7 +18,7 @@ export function mockXHR() { |
| 16 | 18 | // mock patch |
| 17 | 19 | // https://github.com/nuysoft/Mock/issues/300 |
| 18 | 20 | Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send |
| 19 | - Mock.XHR.prototype.send = function() { | |
| 21 | + Mock.XHR.prototype.send = function () { | |
| 20 | 22 | if (this.custom.xhr) { |
| 21 | 23 | this.custom.xhr.withCredentials = this.withCredentials || false |
| 22 | 24 | |
| ... | ... | @@ -28,10 +30,14 @@ export function mockXHR() { |
| 28 | 30 | } |
| 29 | 31 | |
| 30 | 32 | function XHR2ExpressReqWrap(respond) { |
| 31 | - return function(options) { | |
| 33 | + return function (options) { | |
| 32 | 34 | let result = null |
| 33 | 35 | if (respond instanceof Function) { |
| 34 | - const { body, type, url } = options | |
| 36 | + const { | |
| 37 | + body, | |
| 38 | + type, | |
| 39 | + url | |
| 40 | + } = options | |
| 35 | 41 | // https://expressjs.com/en/4x/api.html#req |
| 36 | 42 | result = respond({ |
| 37 | 43 | method: type, | ... | ... |
mock/table.js
| ... | ... | @@ -3,11 +3,13 @@ import Mock from 'mockjs' |
| 3 | 3 | const data = Mock.mock({ |
| 4 | 4 | 'items|10': [{ |
| 5 | 5 | id: '@id', |
| 6 | - title: '@sentence(3, 10)', | |
| 6 | + title: '@sentence(10, 10)', | |
| 7 | 7 | 'status|1': ['published', 'draft', 'deleted'], |
| 8 | - author: 'name@integer(300, 5000)', | |
| 9 | - display_time: '@datetime', | |
| 10 | - pageviews: '@integer(300, 5000)' | |
| 8 | + username: '@sentence(1, 2)', | |
| 9 | + create_at: '@datetime', | |
| 10 | + pageviews: '@integer(10, 500)', | |
| 11 | + openid: '@sentence(1, 1)', | |
| 12 | + avatar:'----' | |
| 11 | 13 | }] |
| 12 | 14 | }) |
| 13 | 15 | ... | ... |
package.json
| ... | ... | @@ -16,6 +16,7 @@ |
| 16 | 16 | }, |
| 17 | 17 | "dependencies": { |
| 18 | 18 | "axios": "0.18.1", |
| 19 | + "babel-polyfill": "^6.26.0", | |
| 19 | 20 | "echarts": "^4.7.0", |
| 20 | 21 | "element-ui": "2.13.0", |
| 21 | 22 | "js-cookie": "2.2.0", |
| ... | ... | @@ -29,6 +30,7 @@ |
| 29 | 30 | }, |
| 30 | 31 | "devDependencies": { |
| 31 | 32 | "@babel/core": "7.0.0", |
| 33 | + "@babel/preset-env": "^7.9.6", | |
| 32 | 34 | "@babel/register": "7.0.0", |
| 33 | 35 | "@vue/cli-plugin-babel": "3.6.0", |
| 34 | 36 | "@vue/cli-plugin-eslint": "^3.9.1", |
| ... | ... | @@ -36,9 +38,12 @@ |
| 36 | 38 | "@vue/cli-service": "3.6.0", |
| 37 | 39 | "@vue/test-utils": "1.0.0-beta.29", |
| 38 | 40 | "autoprefixer": "^9.5.1", |
| 41 | + "babel-cli": "^6.26.0", | |
| 39 | 42 | "babel-core": "7.0.0-bridge.0", |
| 40 | 43 | "babel-eslint": "10.0.1", |
| 41 | 44 | "babel-jest": "23.6.0", |
| 45 | + "babel-plugin-component": "^1.1.1", | |
| 46 | + "babel-preset-env": "^1.7.0", | |
| 42 | 47 | "chalk": "2.4.2", |
| 43 | 48 | "connect": "3.6.6", |
| 44 | 49 | "eslint": "5.15.3", |
| ... | ... | @@ -53,6 +58,7 @@ |
| 53 | 58 | "serve-static": "^1.13.2", |
| 54 | 59 | "svg-sprite-loader": "4.1.3", |
| 55 | 60 | "svgo": "1.2.2", |
| 61 | + "vue-schart": "^2.0.0", | |
| 56 | 62 | "vue-template-compiler": "2.6.10" |
| 57 | 63 | }, |
| 58 | 64 | "engines": { | ... | ... |
src/api/admin.js
| 1 | -import request from '@/utils/request' | |
| 2 | - | |
| 3 | -export function login(data) { | |
| 4 | - console.log('login....', data) | |
| 5 | - return request({ | |
| 6 | - url: '/yp/user/login', | |
| 7 | - method: 'post', | |
| 8 | - data | |
| 9 | - }) | |
| 10 | -} | |
| 11 | - | |
| 12 | -export function getInfo(token) { | |
| 13 | - console.log('getInfo....', token) | |
| 14 | - return request({ | |
| 15 | - url: '/yp/user/info', | |
| 16 | - method: 'get', | |
| 17 | - params: { token } | |
| 18 | - }) | |
| 19 | -} | |
| 20 | - | |
| 21 | -export function logout() { | |
| 22 | - console.log('logout....') | |
| 23 | - return request({ | |
| 24 | - url: '/yp/user/logout', | |
| 25 | - method: 'post' | |
| 26 | - }) | |
| 27 | -} | |
| 1 | +// import request from '@/utils/request' | ... | ... |
src/api/meta.js
| ... | ... | @@ -0,0 +1,33 @@ |
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +export function listMeta(params) { | |
| 4 | + return request({ | |
| 5 | + url: '/yp/meta/list', | |
| 6 | + method: 'get', | |
| 7 | + params | |
| 8 | + }) | |
| 9 | +} | |
| 10 | + | |
| 11 | +export function addMeta(params) { | |
| 12 | + return request({ | |
| 13 | + url: '/yp/meta/add', | |
| 14 | + method: 'get', | |
| 15 | + params | |
| 16 | + }) | |
| 17 | +} | |
| 18 | + | |
| 19 | +export function delMeta(params) { | |
| 20 | + return request({ | |
| 21 | + url: '/yp/meta/del', | |
| 22 | + method: 'get', | |
| 23 | + params | |
| 24 | + }) | |
| 25 | +} | |
| 26 | + | |
| 27 | +export function modiMeta(params) { | |
| 28 | + return request({ | |
| 29 | + url: '/yp/meta/modi', | |
| 30 | + method: 'get', | |
| 31 | + params | |
| 32 | + }) | |
| 33 | +} | ... | ... |
src/api/relation.js
| ... | ... | @@ -0,0 +1,17 @@ |
| 1 | +import request from '@/utils/request' | |
| 2 | + | |
| 3 | +export function build(params) { | |
| 4 | + return request({ | |
| 5 | + url: '/yp/relation/build', | |
| 6 | + method: 'get', | |
| 7 | + params | |
| 8 | + }) | |
| 9 | +} | |
| 10 | + | |
| 11 | +export function del(params) { | |
| 12 | + return request({ | |
| 13 | + url: '/yp/relation/del', | |
| 14 | + method: 'get', | |
| 15 | + params | |
| 16 | + }) | |
| 17 | +} | ... | ... |
src/api/user.js
| ... | ... | @@ -27,6 +27,24 @@ export function list(token) { |
| 27 | 27 | }) |
| 28 | 28 | } |
| 29 | 29 | |
| 30 | +export function add(token) { | |
| 31 | + console.log('addUser....', token) | |
| 32 | + return request({ | |
| 33 | + url: '/yp/user/add', | |
| 34 | + method: 'get', | |
| 35 | + params: { token } | |
| 36 | + }) | |
| 37 | +} | |
| 38 | + | |
| 39 | +export function modi(token) { | |
| 40 | + console.log('modiUser....', token) | |
| 41 | + return request({ | |
| 42 | + url: '/yp/user/modi', | |
| 43 | + method: 'get', | |
| 44 | + params: { token } | |
| 45 | + }) | |
| 46 | +} | |
| 47 | + | |
| 30 | 48 | export function logout() { |
| 31 | 49 | console.log('logout....') |
| 32 | 50 | return request({ | ... | ... |
src/assets/img/img.jpg
6 KB
src/assets/img/login-bg.jpg
68.9 KB
src/common/Header.vue
| ... | ... | @@ -0,0 +1,191 @@ |
| 1 | +<template> | |
| 2 | + <div class="header"> | |
| 3 | + <!-- 折叠按钮 --> | |
| 4 | + <div class="collapse-btn" @click="collapseChage"> | |
| 5 | + <i v-if="!collapse" class="el-icon-s-fold"></i> | |
| 6 | + <i v-else class="el-icon-s-unfold"></i> | |
| 7 | + </div> | |
| 8 | + <div class="logo">后台管理系统</div> | |
| 9 | + <div class="header-right"> | |
| 10 | + <div class="header-user-con"> | |
| 11 | + <!-- 全屏显示 --> | |
| 12 | + <div class="btn-fullscreen" @click="handleFullScreen"> | |
| 13 | + <el-tooltip effect="dark" :content="fullscreen?`取消全屏`:`全屏`" placement="bottom"> | |
| 14 | + <i class="el-icon-rank"></i> | |
| 15 | + </el-tooltip> | |
| 16 | + </div> | |
| 17 | + <!-- 消息中心 --> | |
| 18 | + <div class="btn-bell"> | |
| 19 | + <el-tooltip | |
| 20 | + effect="dark" | |
| 21 | + :content="message?`有${message}条未读消息`:`消息中心`" | |
| 22 | + placement="bottom" | |
| 23 | + > | |
| 24 | + <router-link to="/tabs"> | |
| 25 | + <i class="el-icon-bell"></i> | |
| 26 | + </router-link> | |
| 27 | + </el-tooltip> | |
| 28 | + <span class="btn-bell-badge" v-if="message"></span> | |
| 29 | + </div> | |
| 30 | + <!-- 用户头像 --> | |
| 31 | + <div class="user-avator"> | |
| 32 | + <img src="../assets/img/img.jpg" /> | |
| 33 | + </div> | |
| 34 | + <!-- 用户名下拉菜单 --> | |
| 35 | + <el-dropdown class="user-name" trigger="click" @command="handleCommand"> | |
| 36 | + <span class="el-dropdown-link"> | |
| 37 | + {{username}} | |
| 38 | + <i class="el-icon-caret-bottom"></i> | |
| 39 | + </span> | |
| 40 | + <el-dropdown-menu slot="dropdown"> | |
| 41 | + <a href="https://github.com/lin-xin/vue-manage-system" target="_blank"> | |
| 42 | + <el-dropdown-item>项目仓库</el-dropdown-item> | |
| 43 | + </a> | |
| 44 | + <el-dropdown-item divided command="loginout">退出登录</el-dropdown-item> | |
| 45 | + </el-dropdown-menu> | |
| 46 | + </el-dropdown> | |
| 47 | + </div> | |
| 48 | + </div> | |
| 49 | + </div> | |
| 50 | +</template> | |
| 51 | +<script> | |
| 52 | +import bus from './bus'; | |
| 53 | +export default { | |
| 54 | + data() { | |
| 55 | + return { | |
| 56 | + collapse: false, | |
| 57 | + fullscreen: false, | |
| 58 | + name: 'linxin', | |
| 59 | + message: 2 | |
| 60 | + }; | |
| 61 | + }, | |
| 62 | + computed: { | |
| 63 | + username() { | |
| 64 | + let username = localStorage.getItem('ms_username'); | |
| 65 | + return username ? username : this.name; | |
| 66 | + } | |
| 67 | + }, | |
| 68 | + methods: { | |
| 69 | + // 用户名下拉菜单选择事件 | |
| 70 | + handleCommand(command) { | |
| 71 | + if (command == 'loginout') { | |
| 72 | + localStorage.removeItem('ms_username'); | |
| 73 | + this.$router.push('/login'); | |
| 74 | + } | |
| 75 | + }, | |
| 76 | + // 侧边栏折叠 | |
| 77 | + collapseChage() { | |
| 78 | + this.collapse = !this.collapse; | |
| 79 | + bus.$emit('collapse', this.collapse); | |
| 80 | + }, | |
| 81 | + // 全屏事件 | |
| 82 | + handleFullScreen() { | |
| 83 | + let element = document.documentElement; | |
| 84 | + if (this.fullscreen) { | |
| 85 | + if (document.exitFullscreen) { | |
| 86 | + document.exitFullscreen(); | |
| 87 | + } else if (document.webkitCancelFullScreen) { | |
| 88 | + document.webkitCancelFullScreen(); | |
| 89 | + } else if (document.mozCancelFullScreen) { | |
| 90 | + document.mozCancelFullScreen(); | |
| 91 | + } else if (document.msExitFullscreen) { | |
| 92 | + document.msExitFullscreen(); | |
| 93 | + } | |
| 94 | + } else { | |
| 95 | + if (element.requestFullscreen) { | |
| 96 | + element.requestFullscreen(); | |
| 97 | + } else if (element.webkitRequestFullScreen) { | |
| 98 | + element.webkitRequestFullScreen(); | |
| 99 | + } else if (element.mozRequestFullScreen) { | |
| 100 | + element.mozRequestFullScreen(); | |
| 101 | + } else if (element.msRequestFullscreen) { | |
| 102 | + // IE11 | |
| 103 | + element.msRequestFullscreen(); | |
| 104 | + } | |
| 105 | + } | |
| 106 | + this.fullscreen = !this.fullscreen; | |
| 107 | + } | |
| 108 | + }, | |
| 109 | + mounted() { | |
| 110 | + if (document.body.clientWidth < 1500) { | |
| 111 | + this.collapseChage(); | |
| 112 | + } | |
| 113 | + } | |
| 114 | +}; | |
| 115 | +</script> | |
| 116 | +<style scoped> | |
| 117 | +.header { | |
| 118 | + position: relative; | |
| 119 | + box-sizing: border-box; | |
| 120 | + width: 100%; | |
| 121 | + height: 70px; | |
| 122 | + font-size: 22px; | |
| 123 | + color: #fff; | |
| 124 | +} | |
| 125 | +.collapse-btn { | |
| 126 | + float: left; | |
| 127 | + padding: 0 21px; | |
| 128 | + cursor: pointer; | |
| 129 | + line-height: 70px; | |
| 130 | +} | |
| 131 | +.header .logo { | |
| 132 | + float: left; | |
| 133 | + width: 250px; | |
| 134 | + line-height: 70px; | |
| 135 | +} | |
| 136 | +.header-right { | |
| 137 | + float: right; | |
| 138 | + padding-right: 50px; | |
| 139 | +} | |
| 140 | +.header-user-con { | |
| 141 | + display: flex; | |
| 142 | + height: 70px; | |
| 143 | + align-items: center; | |
| 144 | +} | |
| 145 | +.btn-fullscreen { | |
| 146 | + transform: rotate(45deg); | |
| 147 | + margin-right: 5px; | |
| 148 | + font-size: 24px; | |
| 149 | +} | |
| 150 | +.btn-bell, | |
| 151 | +.btn-fullscreen { | |
| 152 | + position: relative; | |
| 153 | + width: 30px; | |
| 154 | + height: 30px; | |
| 155 | + text-align: center; | |
| 156 | + border-radius: 15px; | |
| 157 | + cursor: pointer; | |
| 158 | +} | |
| 159 | +.btn-bell-badge { | |
| 160 | + position: absolute; | |
| 161 | + right: 0; | |
| 162 | + top: -2px; | |
| 163 | + width: 8px; | |
| 164 | + height: 8px; | |
| 165 | + border-radius: 4px; | |
| 166 | + background: #f56c6c; | |
| 167 | + color: #fff; | |
| 168 | +} | |
| 169 | +.btn-bell .el-icon-bell { | |
| 170 | + color: #fff; | |
| 171 | +} | |
| 172 | +.user-name { | |
| 173 | + margin-left: 10px; | |
| 174 | +} | |
| 175 | +.user-avator { | |
| 176 | + margin-left: 20px; | |
| 177 | +} | |
| 178 | +.user-avator img { | |
| 179 | + display: block; | |
| 180 | + width: 40px; | |
| 181 | + height: 40px; | |
| 182 | + border-radius: 50%; | |
| 183 | +} | |
| 184 | +.el-dropdown-link { | |
| 185 | + color: #fff; | |
| 186 | + cursor: pointer; | |
| 187 | +} | |
| 188 | +.el-dropdown-menu__item { | |
| 189 | + text-align: center; | |
| 190 | +} | |
| 191 | +</style> | |
| 0 | 192 | \ No newline at end of file | ... | ... |
src/common/Home.vue
| ... | ... | @@ -0,0 +1,50 @@ |
| 1 | +<template> | |
| 2 | + <div class="wrapper"> | |
| 3 | + <v-head></v-head> | |
| 4 | + <v-sidebar></v-sidebar> | |
| 5 | + <div class="content-box" :class="{'content-collapse':collapse}"> | |
| 6 | + <v-tags></v-tags> | |
| 7 | + <div class="content"> | |
| 8 | + <transition name="move" mode="out-in"> | |
| 9 | + <keep-alive :include="tagsList"> | |
| 10 | + <router-view></router-view> | |
| 11 | + </keep-alive> | |
| 12 | + </transition> | |
| 13 | + <el-backtop target=".content"></el-backtop> | |
| 14 | + </div> | |
| 15 | + </div> | |
| 16 | + </div> | |
| 17 | +</template> | |
| 18 | + | |
| 19 | +<script> | |
| 20 | +import vHead from './Header.vue'; | |
| 21 | +import vSidebar from './Sidebar.vue'; | |
| 22 | +import vTags from './Tags.vue'; | |
| 23 | +import bus from './bus'; | |
| 24 | +export default { | |
| 25 | + data() { | |
| 26 | + return { | |
| 27 | + tagsList: [], | |
| 28 | + collapse: false | |
| 29 | + }; | |
| 30 | + }, | |
| 31 | + components: { | |
| 32 | + vHead, | |
| 33 | + vSidebar, | |
| 34 | + vTags | |
| 35 | + }, | |
| 36 | + created() { | |
| 37 | + bus.$on('collapse-content', msg => { | |
| 38 | + this.collapse = msg; | |
| 39 | + }); | |
| 40 | + // 只有在标签页列表里的页面才使用keep-alive,即关闭标签之后就不保存到内存中了。 | |
| 41 | + bus.$on('tags', msg => { | |
| 42 | + let arr = []; | |
| 43 | + for (let i = 0, len = msg.length; i < len; i++) { | |
| 44 | + msg[i].name && arr.push(msg[i].name); | |
| 45 | + } | |
| 46 | + this.tagsList = arr; | |
| 47 | + }); | |
| 48 | + } | |
| 49 | +}; | |
| 50 | +</script> | |
| 0 | 51 | \ No newline at end of file | ... | ... |
src/common/Sidebar.vue
| ... | ... | @@ -0,0 +1,189 @@ |
| 1 | +<template> | |
| 2 | + <div class="sidebar"> | |
| 3 | + <el-menu | |
| 4 | + class="sidebar-el-menu" | |
| 5 | + :default-active="onRoutes" | |
| 6 | + :collapse="collapse" | |
| 7 | + background-color="#324157" | |
| 8 | + text-color="#bfcbd9" | |
| 9 | + active-text-color="#20a0ff" | |
| 10 | + unique-opened | |
| 11 | + router | |
| 12 | + > | |
| 13 | + <template v-for="item in items"> | |
| 14 | + <template v-if="item.subs"> | |
| 15 | + <el-submenu :index="item.index" :key="item.index"> | |
| 16 | + <template slot="title"> | |
| 17 | + <i :class="item.icon"></i> | |
| 18 | + <span slot="title">{{ item.title }}</span> | |
| 19 | + </template> | |
| 20 | + <template v-for="subItem in item.subs"> | |
| 21 | + <el-submenu | |
| 22 | + v-if="subItem.subs" | |
| 23 | + :index="subItem.index" | |
| 24 | + :key="subItem.index" | |
| 25 | + > | |
| 26 | + <template slot="title">{{ subItem.title }}</template> | |
| 27 | + <el-menu-item | |
| 28 | + v-for="(threeItem,i) in subItem.subs" | |
| 29 | + :key="i" | |
| 30 | + :index="threeItem.index" | |
| 31 | + >{{ threeItem.title }}</el-menu-item> | |
| 32 | + </el-submenu> | |
| 33 | + <el-menu-item | |
| 34 | + v-else | |
| 35 | + :index="subItem.index" | |
| 36 | + :key="subItem.index" | |
| 37 | + >{{ subItem.title }}</el-menu-item> | |
| 38 | + </template> | |
| 39 | + </el-submenu> | |
| 40 | + </template> | |
| 41 | + <template v-else> | |
| 42 | + <el-menu-item :index="item.index" :key="item.index"> | |
| 43 | + <i :class="item.icon"></i> | |
| 44 | + <span slot="title">{{ item.title }}</span> | |
| 45 | + </el-menu-item> | |
| 46 | + </template> | |
| 47 | + </template> | |
| 48 | + </el-menu> | |
| 49 | + </div> | |
| 50 | +</template> | |
| 51 | + | |
| 52 | +<script> | |
| 53 | +import bus from './bus'; | |
| 54 | +export default { | |
| 55 | + data() { | |
| 56 | + return { | |
| 57 | + collapse: false, | |
| 58 | + items: [ | |
| 59 | + { | |
| 60 | + icon: 'el-icon-lx-home', | |
| 61 | + index: 'dashboard', | |
| 62 | + title: '系统首页' | |
| 63 | + }, | |
| 64 | + { | |
| 65 | + icon: 'el-icon-lx-cascades', | |
| 66 | + index: 'table', | |
| 67 | + title: '基础表格' | |
| 68 | + }, | |
| 69 | + { | |
| 70 | + icon: 'el-icon-lx-copy', | |
| 71 | + index: 'tabs', | |
| 72 | + title: 'tab选项卡' | |
| 73 | + }, | |
| 74 | + { | |
| 75 | + icon: 'el-icon-lx-calendar', | |
| 76 | + index: '3', | |
| 77 | + title: '表单相关', | |
| 78 | + subs: [ | |
| 79 | + { | |
| 80 | + index: 'form', | |
| 81 | + title: '基本表单' | |
| 82 | + }, | |
| 83 | + { | |
| 84 | + index: '3-2', | |
| 85 | + title: '三级菜单', | |
| 86 | + subs: [ | |
| 87 | + { | |
| 88 | + index: 'editor', | |
| 89 | + title: '富文本编辑器' | |
| 90 | + }, | |
| 91 | + { | |
| 92 | + index: 'markdown', | |
| 93 | + title: 'markdown编辑器' | |
| 94 | + } | |
| 95 | + ] | |
| 96 | + }, | |
| 97 | + { | |
| 98 | + index: 'upload', | |
| 99 | + title: '文件上传' | |
| 100 | + } | |
| 101 | + ] | |
| 102 | + }, | |
| 103 | + { | |
| 104 | + icon: 'el-icon-lx-emoji', | |
| 105 | + index: 'icon', | |
| 106 | + title: '自定义图标' | |
| 107 | + }, | |
| 108 | + { | |
| 109 | + icon: 'el-icon-pie-chart', | |
| 110 | + index: 'charts', | |
| 111 | + title: 'schart图表' | |
| 112 | + }, | |
| 113 | + { | |
| 114 | + icon: 'el-icon-rank', | |
| 115 | + index: '6', | |
| 116 | + title: '拖拽组件', | |
| 117 | + subs: [ | |
| 118 | + { | |
| 119 | + index: 'drag', | |
| 120 | + title: '拖拽列表' | |
| 121 | + }, | |
| 122 | + { | |
| 123 | + index: 'dialog', | |
| 124 | + title: '拖拽弹框' | |
| 125 | + } | |
| 126 | + ] | |
| 127 | + }, | |
| 128 | + { | |
| 129 | + icon: 'el-icon-lx-global', | |
| 130 | + index: 'i18n', | |
| 131 | + title: '国际化功能' | |
| 132 | + }, | |
| 133 | + { | |
| 134 | + icon: 'el-icon-lx-warn', | |
| 135 | + index: '7', | |
| 136 | + title: '错误处理', | |
| 137 | + subs: [ | |
| 138 | + { | |
| 139 | + index: 'permission', | |
| 140 | + title: '权限测试' | |
| 141 | + }, | |
| 142 | + { | |
| 143 | + index: '404', | |
| 144 | + title: '404页面' | |
| 145 | + } | |
| 146 | + ] | |
| 147 | + }, | |
| 148 | + { | |
| 149 | + icon: 'el-icon-lx-redpacket_fill', | |
| 150 | + index: '/donate', | |
| 151 | + title: '支持作者' | |
| 152 | + } | |
| 153 | + ] | |
| 154 | + }; | |
| 155 | + }, | |
| 156 | + computed: { | |
| 157 | + onRoutes() { | |
| 158 | + return this.$route.path.replace('/', ''); | |
| 159 | + } | |
| 160 | + }, | |
| 161 | + created() { | |
| 162 | + // 通过 Event Bus 进行组件间通信,来折叠侧边栏 | |
| 163 | + bus.$on('collapse', msg => { | |
| 164 | + this.collapse = msg; | |
| 165 | + bus.$emit('collapse-content', msg); | |
| 166 | + }); | |
| 167 | + } | |
| 168 | +}; | |
| 169 | +</script> | |
| 170 | + | |
| 171 | +<style scoped> | |
| 172 | +.sidebar { | |
| 173 | + display: block; | |
| 174 | + position: absolute; | |
| 175 | + left: 0; | |
| 176 | + top: 70px; | |
| 177 | + bottom: 0; | |
| 178 | + overflow-y: scroll; | |
| 179 | +} | |
| 180 | +.sidebar::-webkit-scrollbar { | |
| 181 | + width: 0; | |
| 182 | +} | |
| 183 | +.sidebar-el-menu:not(.el-menu--collapse) { | |
| 184 | + width: 250px; | |
| 185 | +} | |
| 186 | +.sidebar > ul { | |
| 187 | + height: 100%; | |
| 188 | +} | |
| 189 | +</style> | |
| 0 | 190 | \ No newline at end of file | ... | ... |
src/common/Tags.vue
| ... | ... | @@ -0,0 +1,177 @@ |
| 1 | +<template> | |
| 2 | + <div class="tags" v-if="showTags"> | |
| 3 | + <ul> | |
| 4 | + <li class="tags-li" v-for="(item,index) in tagsList" :class="{'active': isActive(item.path)}" :key="index"> | |
| 5 | + <router-link :to="item.path" class="tags-li-title"> | |
| 6 | + {{item.title}} | |
| 7 | + </router-link> | |
| 8 | + <span class="tags-li-icon" @click="closeTags(index)"><i class="el-icon-close"></i></span> | |
| 9 | + </li> | |
| 10 | + </ul> | |
| 11 | + <div class="tags-close-box"> | |
| 12 | + <el-dropdown @command="handleTags"> | |
| 13 | + <el-button size="mini" type="primary"> | |
| 14 | + 标签选项<i class="el-icon-arrow-down el-icon--right"></i> | |
| 15 | + </el-button> | |
| 16 | + <el-dropdown-menu size="small" slot="dropdown"> | |
| 17 | + <el-dropdown-item command="other">关闭其他</el-dropdown-item> | |
| 18 | + <el-dropdown-item command="all">关闭所有</el-dropdown-item> | |
| 19 | + </el-dropdown-menu> | |
| 20 | + </el-dropdown> | |
| 21 | + </div> | |
| 22 | + </div> | |
| 23 | +</template> | |
| 24 | + | |
| 25 | +<script> | |
| 26 | + import bus from './bus'; | |
| 27 | + export default { | |
| 28 | + data() { | |
| 29 | + return { | |
| 30 | + tagsList: [] | |
| 31 | + } | |
| 32 | + }, | |
| 33 | + methods: { | |
| 34 | + isActive(path) { | |
| 35 | + return path === this.$route.fullPath; | |
| 36 | + }, | |
| 37 | + // 关闭单个标签 | |
| 38 | + closeTags(index) { | |
| 39 | + const delItem = this.tagsList.splice(index, 1)[0]; | |
| 40 | + const item = this.tagsList[index] ? this.tagsList[index] : this.tagsList[index - 1]; | |
| 41 | + if (item) { | |
| 42 | + delItem.path === this.$route.fullPath && this.$router.push(item.path); | |
| 43 | + }else{ | |
| 44 | + this.$router.push('/'); | |
| 45 | + } | |
| 46 | + }, | |
| 47 | + // 关闭全部标签 | |
| 48 | + closeAll(){ | |
| 49 | + this.tagsList = []; | |
| 50 | + this.$router.push('/'); | |
| 51 | + }, | |
| 52 | + // 关闭其他标签 | |
| 53 | + closeOther(){ | |
| 54 | + const curItem = this.tagsList.filter(item => { | |
| 55 | + return item.path === this.$route.fullPath; | |
| 56 | + }) | |
| 57 | + this.tagsList = curItem; | |
| 58 | + }, | |
| 59 | + // 设置标签 | |
| 60 | + setTags(route){ | |
| 61 | + const isExist = this.tagsList.some(item => { | |
| 62 | + return item.path === route.fullPath; | |
| 63 | + }) | |
| 64 | + if(!isExist){ | |
| 65 | + if(this.tagsList.length >= 8){ | |
| 66 | + this.tagsList.shift(); | |
| 67 | + } | |
| 68 | + this.tagsList.push({ | |
| 69 | + title: route.meta.title, | |
| 70 | + path: route.fullPath, | |
| 71 | + name: route.matched[1].components.default.name | |
| 72 | + }) | |
| 73 | + } | |
| 74 | + bus.$emit('tags', this.tagsList); | |
| 75 | + }, | |
| 76 | + handleTags(command){ | |
| 77 | + command === 'other' ? this.closeOther() : this.closeAll(); | |
| 78 | + } | |
| 79 | + }, | |
| 80 | + computed: { | |
| 81 | + showTags() { | |
| 82 | + return this.tagsList.length > 0; | |
| 83 | + } | |
| 84 | + }, | |
| 85 | + watch:{ | |
| 86 | + $route(newValue, oldValue){ | |
| 87 | + this.setTags(newValue); | |
| 88 | + } | |
| 89 | + }, | |
| 90 | + created(){ | |
| 91 | + this.setTags(this.$route); | |
| 92 | + // 监听关闭当前页面的标签页 | |
| 93 | + bus.$on('close_current_tags', () => { | |
| 94 | + for (let i = 0, len = this.tagsList.length; i < len; i++) { | |
| 95 | + const item = this.tagsList[i]; | |
| 96 | + if(item.path === this.$route.fullPath){ | |
| 97 | + if(i < len - 1){ | |
| 98 | + this.$router.push(this.tagsList[i+1].path); | |
| 99 | + }else if(i > 0){ | |
| 100 | + this.$router.push(this.tagsList[i-1].path); | |
| 101 | + }else{ | |
| 102 | + this.$router.push('/'); | |
| 103 | + } | |
| 104 | + this.tagsList.splice(i, 1); | |
| 105 | + break; | |
| 106 | + } | |
| 107 | + } | |
| 108 | + }) | |
| 109 | + } | |
| 110 | + } | |
| 111 | +</script> | |
| 112 | + | |
| 113 | + | |
| 114 | +<style> | |
| 115 | + .tags { | |
| 116 | + position: relative; | |
| 117 | + height: 30px; | |
| 118 | + overflow: hidden; | |
| 119 | + background: #fff; | |
| 120 | + padding-right: 120px; | |
| 121 | + box-shadow: 0 5px 10px #ddd; | |
| 122 | + } | |
| 123 | + .tags ul { | |
| 124 | + box-sizing: border-box; | |
| 125 | + width: 100%; | |
| 126 | + height: 100%; | |
| 127 | + } | |
| 128 | + .tags-li { | |
| 129 | + float: left; | |
| 130 | + margin: 3px 5px 2px 3px; | |
| 131 | + border-radius: 3px; | |
| 132 | + font-size: 12px; | |
| 133 | + overflow: hidden; | |
| 134 | + cursor: pointer; | |
| 135 | + height: 23px; | |
| 136 | + line-height: 23px; | |
| 137 | + border: 1px solid #e9eaec; | |
| 138 | + background: #fff; | |
| 139 | + padding: 0 5px 0 12px; | |
| 140 | + vertical-align: middle; | |
| 141 | + color: #666; | |
| 142 | + -webkit-transition: all .3s ease-in; | |
| 143 | + -moz-transition: all .3s ease-in; | |
| 144 | + transition: all .3s ease-in; | |
| 145 | + } | |
| 146 | + .tags-li:not(.active):hover { | |
| 147 | + background: #f8f8f8; | |
| 148 | + } | |
| 149 | + .tags-li.active { | |
| 150 | + color: #fff; | |
| 151 | + } | |
| 152 | + .tags-li-title { | |
| 153 | + float: left; | |
| 154 | + max-width: 80px; | |
| 155 | + overflow: hidden; | |
| 156 | + white-space: nowrap; | |
| 157 | + text-overflow: ellipsis; | |
| 158 | + margin-right: 5px; | |
| 159 | + color: #666; | |
| 160 | + } | |
| 161 | + .tags-li.active .tags-li-title { | |
| 162 | + color: #fff; | |
| 163 | + } | |
| 164 | + .tags-close-box { | |
| 165 | + position: absolute; | |
| 166 | + right: 0; | |
| 167 | + top: 0; | |
| 168 | + box-sizing: border-box; | |
| 169 | + padding-top: 1px; | |
| 170 | + text-align: center; | |
| 171 | + width: 110px; | |
| 172 | + height: 30px; | |
| 173 | + background: #fff; | |
| 174 | + box-shadow: -3px 0 15px 3px rgba(0, 0, 0, .1); | |
| 175 | + z-index: 10; | |
| 176 | + } | |
| 177 | +</style> | |
| 0 | 178 | \ No newline at end of file | ... | ... |
src/common/bus.js
src/common/directives.js
| ... | ... | @@ -0,0 +1,80 @@ |
| 1 | +import Vue from 'vue'; | |
| 2 | + | |
| 3 | +// v-dialogDrag: 弹窗拖拽属性 | |
| 4 | +Vue.directive('dialogDrag', { | |
| 5 | + bind(el, binding, vnode, oldVnode) { | |
| 6 | + const dialogHeaderEl = el.querySelector('.el-dialog__header'); | |
| 7 | + const dragDom = el.querySelector('.el-dialog'); | |
| 8 | + | |
| 9 | + dialogHeaderEl.style.cssText += ';cursor:move;' | |
| 10 | + dragDom.style.cssText += ';top:0px;' | |
| 11 | + | |
| 12 | + // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); | |
| 13 | + const sty = (() => { | |
| 14 | + if (window.document.currentStyle) { | |
| 15 | + return (dom, attr) => dom.currentStyle[attr]; | |
| 16 | + } else { | |
| 17 | + return (dom, attr) => getComputedStyle(dom, false)[attr]; | |
| 18 | + } | |
| 19 | + })() | |
| 20 | + | |
| 21 | + dialogHeaderEl.onmousedown = (e) => { | |
| 22 | + // 鼠标按下,计算当前元素距离可视区的距离 | |
| 23 | + const disX = e.clientX - dialogHeaderEl.offsetLeft; | |
| 24 | + const disY = e.clientY - dialogHeaderEl.offsetTop; | |
| 25 | + | |
| 26 | + const screenWidth = document.body.clientWidth; // body当前宽度 | |
| 27 | + const screenHeight = document.documentElement.clientHeight; // 可见区域高度(应为body高度,可某些环境下无法获取) | |
| 28 | + | |
| 29 | + const dragDomWidth = dragDom.offsetWidth; // 对话框宽度 | |
| 30 | + const dragDomheight = dragDom.offsetHeight; // 对话框高度 | |
| 31 | + | |
| 32 | + const minDragDomLeft = dragDom.offsetLeft; | |
| 33 | + const maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidth; | |
| 34 | + | |
| 35 | + const minDragDomTop = dragDom.offsetTop; | |
| 36 | + const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomheight; | |
| 37 | + | |
| 38 | + | |
| 39 | + // 获取到的值带px 正则匹配替换 | |
| 40 | + let styL = sty(dragDom, 'left'); | |
| 41 | + let styT = sty(dragDom, 'top'); | |
| 42 | + | |
| 43 | + // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px | |
| 44 | + if (styL.includes('%')) { | |
| 45 | + styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100); | |
| 46 | + styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100); | |
| 47 | + } else { | |
| 48 | + styL = +styL.replace(/\px/g, ''); | |
| 49 | + styT = +styT.replace(/\px/g, ''); | |
| 50 | + }; | |
| 51 | + | |
| 52 | + document.onmousemove = function (e) { | |
| 53 | + // 通过事件委托,计算移动的距离 | |
| 54 | + let left = e.clientX - disX; | |
| 55 | + let top = e.clientY - disY; | |
| 56 | + | |
| 57 | + // 边界处理 | |
| 58 | + if (-(left) > minDragDomLeft) { | |
| 59 | + left = -(minDragDomLeft); | |
| 60 | + } else if (left > maxDragDomLeft) { | |
| 61 | + left = maxDragDomLeft; | |
| 62 | + } | |
| 63 | + | |
| 64 | + if (-(top) > minDragDomTop) { | |
| 65 | + top = -(minDragDomTop); | |
| 66 | + } else if (top > maxDragDomTop) { | |
| 67 | + top = maxDragDomTop; | |
| 68 | + } | |
| 69 | + | |
| 70 | + // 移动当前元素 | |
| 71 | + dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`; | |
| 72 | + }; | |
| 73 | + | |
| 74 | + document.onmouseup = function (e) { | |
| 75 | + document.onmousemove = null; | |
| 76 | + document.onmouseup = null; | |
| 77 | + }; | |
| 78 | + } | |
| 79 | + } | |
| 80 | +}) | |
| 0 | 81 | \ No newline at end of file | ... | ... |
src/common/i18n.js
| ... | ... | @@ -0,0 +1,30 @@ |
| 1 | +export const messages = { | |
| 2 | + 'zh': { | |
| 3 | + i18n: { | |
| 4 | + breadcrumb: '国际化产品', | |
| 5 | + tips: '通过切换语言按钮,来改变当前内容的语言。', | |
| 6 | + btn: '切换英文', | |
| 7 | + title1: '常用用法', | |
| 8 | + p1: '要是你把你的秘密告诉了风,那就别怪风把它带给树。', | |
| 9 | + p2: '没有什么比信念更能支撑我们度过艰难的时光了。', | |
| 10 | + p3: '只要能把自己的事做好,并让自己快乐,你就领先于大多数人了。', | |
| 11 | + title2: '组件插值', | |
| 12 | + info: 'Element组件需要国际化,请参考 {action}。', | |
| 13 | + value: '文档' | |
| 14 | + } | |
| 15 | + }, | |
| 16 | + 'en': { | |
| 17 | + i18n: { | |
| 18 | + breadcrumb: 'International Products', | |
| 19 | + tips: 'Click on the button to change the current language. ', | |
| 20 | + btn: 'Switch Chinese', | |
| 21 | + title1: 'Common usage', | |
| 22 | + p1: "If you reveal your secrets to the wind you should not blame the wind for revealing them to the trees.", | |
| 23 | + p2: "Nothing can help us endure dark times better than our faith. ", | |
| 24 | + p3: "If you can do what you do best and be happy, you're further along in life than most people.", | |
| 25 | + title2: 'Component interpolation', | |
| 26 | + info: 'The default language of Element is Chinese. If you wish to use another language, please refer to the {action}.', | |
| 27 | + value: 'documentation' | |
| 28 | + } | |
| 29 | + } | |
| 30 | +} | |
| 0 | 31 | \ No newline at end of file | ... | ... |
src/layout/components/Navbar.vue
| 1 | 1 | <template> |
| 2 | 2 | <div class="navbar"> |
| 3 | - <hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" /> | |
| 3 | + <hamburger | |
| 4 | + :is-active="sidebar.opened" | |
| 5 | + class="hamburger-container" | |
| 6 | + @toggleClick="toggleSideBar" | |
| 7 | + /> | |
| 4 | 8 | |
| 5 | 9 | <breadcrumb class="breadcrumb-container" /> |
| 6 | 10 | |
| 7 | 11 | <div class="right-menu"> |
| 8 | - 语言设置 | |
| 9 | - <el-dropdown class="avatar-container" trigger="click"> | |
| 10 | - <div class="avatar-wrapper"> | |
| 11 | - <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar"> | |
| 12 | - <i class="el-icon-caret-bottom" /> | |
| 13 | - </div> | |
| 14 | - <el-dropdown-menu slot="dropdown" class="user-dropdown"> | |
| 15 | - <router-link to="/"> | |
| 16 | - <el-dropdown-item> | |
| 17 | - Home | |
| 18 | - </el-dropdown-item> | |
| 19 | - </router-link> | |
| 20 | - <router-link to="/seting"> | |
| 21 | - <el-dropdown-item> | |
| 22 | - 个人设置 | |
| 23 | - </el-dropdown-item> | |
| 24 | - </router-link> | |
| 25 | - <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> | |
| 12 | + <el-menu | |
| 13 | + :default-active="activeIndex" | |
| 14 | + class="el-menu-demo" | |
| 15 | + mode="horizontal" | |
| 16 | + @select="handleSelect" | |
| 17 | + > | |
| 18 | + <el-menu-item index="1"> | |
| 19 | + <i class="el-icon-bell"></i>通知中心 | |
| 20 | + <el-badge class="mark" :value="12" /> | |
| 21 | + </el-menu-item> | |
| 22 | + <el-submenu index="2"> | |
| 23 | + <template slot="title"> | |
| 24 | + <i class="el-icon-custom"></i>个人设置 | |
| 25 | + </template> | |
| 26 | + <el-menu-item index="2-1">选项1</el-menu-item> | |
| 27 | + <el-menu-item index="2-2">选项2</el-menu-item> | |
| 28 | + <el-menu-item index="2-3">选项3</el-menu-item> | |
| 29 | + </el-submenu> | |
| 30 | + <el-dropdown class="avatar-container" trigger="click"> | |
| 31 | + <div class="avatar-wrapper"> | |
| 32 | + <img :src="avatar+'?imageView2/1/w/80/h/80'" class="user-avatar" /> | |
| 33 | + <i class="el-icon-caret-bottom" /> | |
| 34 | + </div> | |
| 35 | + <el-dropdown-menu slot="dropdown" class="user-dropdown"> | |
| 36 | + <router-link to="/"> | |
| 37 | + <el-dropdown-item>Home</el-dropdown-item> | |
| 38 | + </router-link> | |
| 39 | + <router-link to="/seting"> | |
| 40 | + <el-dropdown-item>个人设置</el-dropdown-item> | |
| 41 | + </router-link> | |
| 42 | + <!-- <a target="_blank" href="https://github.com/PanJiaChen/vue-admin-template/"> | |
| 26 | 43 | <el-dropdown-item>Github</el-dropdown-item> |
| 27 | - </a> --> | |
| 28 | - <!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> | |
| 44 | + </a>--> | |
| 45 | + <!-- <a target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/#/"> | |
| 29 | 46 | <el-dropdown-item>Docs</el-dropdown-item> |
| 30 | - </a> --> | |
| 31 | - <el-dropdown-item divided @click.native="logout"> | |
| 32 | - <span style="display:block;">退出系统</span> | |
| 33 | - </el-dropdown-item> | |
| 34 | - </el-dropdown-menu> | |
| 35 | - </el-dropdown> | |
| 47 | + </a>--> | |
| 48 | + <el-dropdown-item divided @click.native="logout"> | |
| 49 | + <span style="display:block;">退出系统</span> | |
| 50 | + </el-dropdown-item> | |
| 51 | + </el-dropdown-menu> | |
| 52 | + </el-dropdown> | |
| 53 | + <el-menu-item index="3" disabled>ddd</el-menu-item> | |
| 54 | + <el-menu-item index="4"> | |
| 55 | + <a href="https://glass.xiuyetang.com" target="_blank">跳到外部链接</a> | |
| 56 | + </el-menu-item> | |
| 57 | + </el-menu> | |
| 36 | 58 | </div> |
| 37 | 59 | </div> |
| 38 | 60 | </template> |
| 39 | 61 | |
| 40 | 62 | <script> |
| 41 | -import { mapGetters } from 'vuex' | |
| 42 | -import Breadcrumb from '@/components/Breadcrumb' | |
| 43 | -import Hamburger from '@/components/Hamburger' | |
| 63 | +import { mapGetters } from "vuex"; | |
| 64 | +import Breadcrumb from "@/components/Breadcrumb"; | |
| 65 | +import Hamburger from "@/components/Hamburger"; | |
| 44 | 66 | |
| 45 | 67 | export default { |
| 46 | 68 | components: { |
| ... | ... | @@ -48,41 +70,42 @@ export default { |
| 48 | 70 | Hamburger |
| 49 | 71 | }, |
| 50 | 72 | computed: { |
| 51 | - ...mapGetters([ | |
| 52 | - 'sidebar', | |
| 53 | - 'avatar' | |
| 54 | - ]) | |
| 73 | + ...mapGetters(["sidebar", "avatar"]) | |
| 55 | 74 | }, |
| 56 | 75 | methods: { |
| 57 | 76 | toggleSideBar() { |
| 58 | - this.$store.dispatch('app/toggleSideBar') | |
| 77 | + this.$store.dispatch("app/toggleSideBar"); | |
| 59 | 78 | }, |
| 60 | 79 | async logout() { |
| 61 | - await this.$store.dispatch('user/logout') | |
| 62 | - this.$router.push(`/login?redirect=${this.$route.fullPath}`) | |
| 80 | + await this.$store.dispatch("user/logout"); | |
| 81 | + this.$router.push(`/login?redirect=${this.$route.fullPath}`); | |
| 63 | 82 | } |
| 64 | 83 | } |
| 65 | -} | |
| 84 | +}; | |
| 66 | 85 | </script> |
| 67 | 86 | |
| 68 | 87 | <style lang="scss" scoped> |
| 88 | +.item { | |
| 89 | + margin-top: 10px; | |
| 90 | + margin-right: 20px; | |
| 91 | +} | |
| 69 | 92 | .navbar { |
| 70 | 93 | height: 50px; |
| 71 | 94 | overflow: hidden; |
| 72 | 95 | position: relative; |
| 73 | 96 | background: #fff; |
| 74 | - box-shadow: 0 1px 4px rgba(0,21,41,.08); | |
| 97 | + box-shadow: 0 1px 4px rgba(0, 21, 41, 0.08); | |
| 75 | 98 | |
| 76 | 99 | .hamburger-container { |
| 77 | 100 | line-height: 46px; |
| 78 | 101 | height: 100%; |
| 79 | 102 | float: left; |
| 80 | 103 | cursor: pointer; |
| 81 | - transition: background .3s; | |
| 82 | - -webkit-tap-highlight-color:transparent; | |
| 104 | + transition: background 0.3s; | |
| 105 | + -webkit-tap-highlight-color: transparent; | |
| 83 | 106 | |
| 84 | 107 | &:hover { |
| 85 | - background: rgba(0, 0, 0, .025) | |
| 108 | + background: rgba(0, 0, 0, 0.025); | |
| 86 | 109 | } |
| 87 | 110 | } |
| 88 | 111 | |
| ... | ... | @@ -109,10 +132,10 @@ export default { |
| 109 | 132 | |
| 110 | 133 | &.hover-effect { |
| 111 | 134 | cursor: pointer; |
| 112 | - transition: background .3s; | |
| 135 | + transition: background 0.3s; | |
| 113 | 136 | |
| 114 | 137 | &:hover { |
| 115 | - background: rgba(0, 0, 0, .025) | |
| 138 | + background: rgba(0, 0, 0, 0.025); | |
| 116 | 139 | } |
| 117 | 140 | } |
| 118 | 141 | } | ... | ... |
src/layout/components/index.js
src/main.js
| ... | ... | @@ -4,7 +4,7 @@ import 'normalize.css/normalize.css' // A modern alternative to CSS resets |
| 4 | 4 | |
| 5 | 5 | import ElementUI from 'element-ui' |
| 6 | 6 | import 'element-ui/lib/theme-chalk/index.css' |
| 7 | -import locale from 'element-ui/lib/locale/lang/en' // lang i18n | |
| 7 | +// import locale from 'element-ui/lib/locale/lang/en' // lang i18n | |
| 8 | 8 | // import local_zh from 'element-ui/lib/locale/lang/zh-CN' // 在node_module里面 |
| 9 | 9 | |
| 10 | 10 | import '@/styles/index.scss' // global css |
| ... | ... | @@ -29,11 +29,11 @@ if (process.env.NODE_ENV === 'production') { |
| 29 | 29 | mockXHR() |
| 30 | 30 | } |
| 31 | 31 | |
| 32 | +Vue.use(ElementUI, { size: 'small', zIndex: 3000 }) | |
| 32 | 33 | // set ElementUI lang to EN |
| 33 | -Vue.use(ElementUI, { locale }) | |
| 34 | +// Vue.use(ElementUI, { locale }) | |
| 34 | 35 | // 如果想要中文版 element-ui,按如下方式声明 |
| 35 | 36 | // Vue.use(ElementUI, {local_zh}) |
| 36 | - | |
| 37 | 37 | Vue.config.productionTip = false |
| 38 | 38 | |
| 39 | 39 | new Vue({ | ... | ... |
src/router/index.js
| ... | ... | @@ -30,8 +30,7 @@ import Layout from '@/layout' |
| 30 | 30 | * a base page that does not have permission requirements |
| 31 | 31 | * all roles can be accessed |
| 32 | 32 | */ |
| 33 | -export const constantRoutes = [ | |
| 34 | - { | |
| 33 | +export const constantRoutes = [{ | |
| 35 | 34 | path: '/login', |
| 36 | 35 | component: () => import('@/views/login/index'), |
| 37 | 36 | hidden: true |
| ... | ... | @@ -51,7 +50,10 @@ export const constantRoutes = [ |
| 51 | 50 | path: 'dashboard', |
| 52 | 51 | name: 'Dashboard', |
| 53 | 52 | component: () => import('@/views/dashboard/index'), |
| 54 | - meta: { title: '中控台', icon: 'dashboard' } | |
| 53 | + meta: { | |
| 54 | + title: '中控台', | |
| 55 | + icon: 'dashboard' | |
| 56 | + } | |
| 55 | 57 | }] |
| 56 | 58 | }, |
| 57 | 59 | { |
| ... | ... | @@ -59,19 +61,27 @@ export const constantRoutes = [ |
| 59 | 61 | component: Layout, |
| 60 | 62 | redirect: '/user/list', |
| 61 | 63 | name: 'user', |
| 62 | - meta: { title: '用户管理', icon: 'example' }, | |
| 63 | - children: [ | |
| 64 | - { | |
| 64 | + meta: { | |
| 65 | + title: '用户管理', | |
| 66 | + icon: 'example' | |
| 67 | + }, | |
| 68 | + children: [{ | |
| 65 | 69 | path: 'user', |
| 66 | 70 | name: 'User', |
| 67 | 71 | component: () => import('@/views/table/index'), |
| 68 | - meta: { title: '用户列表', icon: 'table' } | |
| 72 | + meta: { | |
| 73 | + title: '用户列表', | |
| 74 | + icon: 'table' | |
| 75 | + } | |
| 69 | 76 | }, |
| 70 | 77 | { |
| 71 | 78 | path: 'tree', |
| 72 | 79 | name: 'Table', |
| 73 | 80 | component: () => import('@/views/tree/index'), |
| 74 | - meta: { title: 'Tree', icon: 'tree' } | |
| 81 | + meta: { | |
| 82 | + title: 'Tree', | |
| 83 | + icon: 'tree' | |
| 84 | + } | |
| 75 | 85 | } |
| 76 | 86 | ] |
| 77 | 87 | }, |
| ... | ... | @@ -80,110 +90,229 @@ export const constantRoutes = [ |
| 80 | 90 | component: Layout, |
| 81 | 91 | redirect: '/example/table', |
| 82 | 92 | name: 'Example', |
| 83 | - meta: { title: 'E1111xample', icon: 'example' }, | |
| 84 | - children: [ | |
| 85 | - { | |
| 93 | + meta: { | |
| 94 | + title: '商家管理', | |
| 95 | + icon: 'example' | |
| 96 | + }, | |
| 97 | + children: [{ | |
| 86 | 98 | path: 'table', |
| 87 | 99 | name: 'Table', |
| 88 | 100 | component: () => import('@/views/table/index'), |
| 89 | - meta: { title: 'Table', icon: 'table' } | |
| 101 | + meta: { | |
| 102 | + title: 'Table', | |
| 103 | + icon: 'table' | |
| 104 | + } | |
| 90 | 105 | }, |
| 91 | 106 | { |
| 92 | 107 | path: 'tree', |
| 93 | 108 | name: 'Tree', |
| 94 | 109 | component: () => import('@/views/tree/index'), |
| 95 | - meta: { title: 'Tree', icon: 'tree' } | |
| 110 | + meta: { | |
| 111 | + title: 'Tree', | |
| 112 | + icon: 'tree' | |
| 113 | + } | |
| 96 | 114 | } |
| 97 | 115 | ] |
| 98 | 116 | }, |
| 99 | - | |
| 100 | 117 | { |
| 101 | - path: '/form', | |
| 118 | + path: '/example', | |
| 102 | 119 | component: Layout, |
| 103 | - children: [ | |
| 120 | + redirect: '/example/table', | |
| 121 | + name: 'Example', | |
| 122 | + meta: { | |
| 123 | + title: '产品管理', | |
| 124 | + icon: 'example' | |
| 125 | + }, | |
| 126 | + children: [{ | |
| 127 | + path: 'table', | |
| 128 | + name: 'Table', | |
| 129 | + component: () => import('@/views/table/index'), | |
| 130 | + meta: { | |
| 131 | + title: 'Table', | |
| 132 | + icon: 'table' | |
| 133 | + } | |
| 134 | + }, | |
| 104 | 135 | { |
| 105 | - path: 'index', | |
| 106 | - name: 'Form', | |
| 107 | - component: () => import('@/views/form/index'), | |
| 108 | - meta: { title: 'Form', icon: 'form' } | |
| 136 | + path: 'tree', | |
| 137 | + name: 'Tree', | |
| 138 | + component: () => import('@/views/tree/index'), | |
| 139 | + meta: { | |
| 140 | + title: 'Tree', | |
| 141 | + icon: 'tree' | |
| 142 | + } | |
| 109 | 143 | } |
| 110 | 144 | ] |
| 111 | - } | |
| 112 | -] | |
| 113 | - | |
| 114 | -/** | |
| 115 | - * asyncRoutes | |
| 116 | - * the routes that need to be dynamically loaded based on user roles | |
| 117 | - */ | |
| 118 | -export const asyncRoutes = [ | |
| 145 | + }, | |
| 119 | 146 | { |
| 120 | - path: '/nested', | |
| 147 | + path: '/example', | |
| 121 | 148 | component: Layout, |
| 122 | - redirect: '/nested/menu1', | |
| 123 | - name: 'Nested', | |
| 149 | + redirect: '/example/table', | |
| 150 | + name: 'Example', | |
| 124 | 151 | meta: { |
| 125 | - title: 'Nested', | |
| 126 | - icon: 'nested' | |
| 152 | + title: '元管理', | |
| 153 | + icon: 'example' | |
| 127 | 154 | }, |
| 128 | - children: [ | |
| 129 | - { | |
| 130 | - path: 'menu1', | |
| 131 | - component: () => import('@/views/nested/menu1/index'), // Parent router-view | |
| 132 | - name: 'Menu1', | |
| 133 | - meta: { title: 'Menu1' }, | |
| 134 | - children: [ | |
| 135 | - { | |
| 136 | - path: 'menu1-1', | |
| 137 | - component: () => import('@/views/nested/menu1/menu1-1'), | |
| 138 | - name: 'Menu1-1', | |
| 139 | - meta: { title: 'Menu1-1' } | |
| 140 | - }, | |
| 141 | - { | |
| 142 | - path: 'menu1-2', | |
| 143 | - component: () => import('@/views/nested/menu1/menu1-2'), | |
| 144 | - name: 'Menu1-2', | |
| 145 | - meta: { title: 'Menu1-2' }, | |
| 146 | - children: [ | |
| 147 | - { | |
| 148 | - path: 'menu1-2-1', | |
| 149 | - component: () => import('@/views/nested/menu1/menu1-2/menu1-2-1'), | |
| 150 | - name: 'Menu1-2-1', | |
| 151 | - meta: { title: 'Menu1-2-1' } | |
| 152 | - }, | |
| 153 | - { | |
| 154 | - path: 'menu1-2-2', | |
| 155 | - component: () => import('@/views/nested/menu1/menu1-2/menu1-2-2'), | |
| 156 | - name: 'Menu1-2-2', | |
| 157 | - meta: { title: 'Menu1-2-2' } | |
| 158 | - } | |
| 159 | - ] | |
| 160 | - }, | |
| 161 | - { | |
| 162 | - path: 'menu1-3', | |
| 163 | - component: () => import('@/views/nested/menu1/menu1-3'), | |
| 164 | - name: 'Menu1-3', | |
| 165 | - meta: { title: 'Menu1-3' } | |
| 166 | - } | |
| 167 | - ] | |
| 155 | + children: [{ | |
| 156 | + path: 'table', | |
| 157 | + name: 'Table', | |
| 158 | + component: () => import('@/views/table/index'), | |
| 159 | + meta: { | |
| 160 | + title: 'Table', | |
| 161 | + icon: 'table' | |
| 162 | + } | |
| 168 | 163 | }, |
| 169 | 164 | { |
| 170 | - path: 'menu2', | |
| 171 | - component: () => import('@/views/nested/menu2/index'), | |
| 172 | - meta: { title: 'menu2' } | |
| 165 | + path: 'tree', | |
| 166 | + name: 'Tree', | |
| 167 | + component: () => import('@/views/tree/index'), | |
| 168 | + meta: { | |
| 169 | + title: 'Tree', | |
| 170 | + icon: 'tree' | |
| 171 | + } | |
| 173 | 172 | } |
| 174 | 173 | ] |
| 175 | 174 | }, |
| 176 | - | |
| 177 | 175 | { |
| 178 | - path: 'external-link', | |
| 176 | + path: '/example', | |
| 177 | + component: Layout, | |
| 178 | + redirect: '/example/table', | |
| 179 | + name: 'Example', | |
| 180 | + meta: { | |
| 181 | + title: '交易管理', | |
| 182 | + icon: 'example' | |
| 183 | + }, | |
| 184 | + children: [{ | |
| 185 | + path: 'table', | |
| 186 | + name: 'Table', | |
| 187 | + component: () => import('@/views/table/index'), | |
| 188 | + meta: { | |
| 189 | + title: 'Table', | |
| 190 | + icon: 'table' | |
| 191 | + } | |
| 192 | + }, | |
| 193 | + { | |
| 194 | + path: 'tree', | |
| 195 | + name: 'Tree', | |
| 196 | + component: () => import('@/views/tree/index'), | |
| 197 | + meta: { | |
| 198 | + title: 'Tree', | |
| 199 | + icon: 'tree' | |
| 200 | + } | |
| 201 | + } | |
| 202 | + ] | |
| 203 | + }, { | |
| 204 | + path: '/example', | |
| 179 | 205 | component: Layout, |
| 180 | - children: [ | |
| 206 | + redirect: '/example/table', | |
| 207 | + name: 'Example', | |
| 208 | + meta: { | |
| 209 | + title: '推荐系统', | |
| 210 | + icon: 'example' | |
| 211 | + }, | |
| 212 | + children: [{ | |
| 213 | + path: 'table', | |
| 214 | + name: 'Table', | |
| 215 | + component: () => import('@/views/table/index'), | |
| 216 | + meta: { | |
| 217 | + title: 'Table', | |
| 218 | + icon: 'table' | |
| 219 | + } | |
| 220 | + }, | |
| 221 | + { | |
| 222 | + path: 'tree', | |
| 223 | + name: 'Tree', | |
| 224 | + component: () => import('@/views/tree/index'), | |
| 225 | + meta: { | |
| 226 | + title: 'Tree', | |
| 227 | + icon: 'tree' | |
| 228 | + } | |
| 229 | + } | |
| 230 | + ] | |
| 231 | + }, { | |
| 232 | + path: '/system', | |
| 233 | + component: Layout, | |
| 234 | + redirect: '/system/table', | |
| 235 | + name: 'System', | |
| 236 | + meta: { | |
| 237 | + title: '系统设置', | |
| 238 | + icon: 'example' | |
| 239 | + }, | |
| 240 | + children: [{ | |
| 241 | + path: 'table', | |
| 242 | + name: 'Table', | |
| 243 | + component: () => import('@/views/table/index'), | |
| 244 | + meta: { | |
| 245 | + title: '行业设置', | |
| 246 | + icon: 'table' | |
| 247 | + } | |
| 248 | + }, | |
| 249 | + { | |
| 250 | + path: 'tree', | |
| 251 | + name: 'Tree', | |
| 252 | + component: () => import('@/views/tree/index'), | |
| 253 | + meta: { | |
| 254 | + title: '语言设置', | |
| 255 | + icon: 'tree' | |
| 256 | + } | |
| 257 | + }, | |
| 258 | + { | |
| 259 | + path: 'tree', | |
| 260 | + name: 'Tree', | |
| 261 | + component: () => import('@/views/tree/index'), | |
| 262 | + meta: { | |
| 263 | + title: '货币设置', | |
| 264 | + icon: 'tree' | |
| 265 | + } | |
| 266 | + }, | |
| 267 | + { | |
| 268 | + path: 'tree', | |
| 269 | + name: 'Tree', | |
| 270 | + component: () => import('@/views/tree/index'), | |
| 271 | + meta: { | |
| 272 | + title: '站点类型设置', | |
| 273 | + icon: 'tree' | |
| 274 | + } | |
| 275 | + }, | |
| 276 | + { | |
| 277 | + path: 'tree', | |
| 278 | + name: 'Tree', | |
| 279 | + component: () => import('@/views/tree/index'), | |
| 280 | + meta: { | |
| 281 | + title: '模版设置', | |
| 282 | + icon: 'tree' | |
| 283 | + } | |
| 284 | + }, | |
| 181 | 285 | { |
| 182 | - path: 'https://panjiachen.github.io/vue-element-admin-site/#/', | |
| 183 | - meta: { title: 'External Link', icon: 'link' } | |
| 286 | + path: 'tree', | |
| 287 | + name: 'Tree', | |
| 288 | + component: () => import('@/views/tree/index'), | |
| 289 | + meta: { | |
| 290 | + title: '权限设置', | |
| 291 | + icon: 'tree' | |
| 292 | + } | |
| 184 | 293 | } |
| 185 | 294 | ] |
| 186 | 295 | }, |
| 296 | + { | |
| 297 | + path: '/form', | |
| 298 | + component: Layout, | |
| 299 | + children: [{ | |
| 300 | + path: 'index', | |
| 301 | + name: 'Form', | |
| 302 | + component: () => import('@/views/form/index'), | |
| 303 | + meta: { | |
| 304 | + title: 'Form', | |
| 305 | + icon: 'form' | |
| 306 | + } | |
| 307 | + }] | |
| 308 | + } | |
| 309 | +] | |
| 310 | + | |
| 311 | +/** | |
| 312 | + * asyncRoutes | |
| 313 | + * the routes that need to be dynamically loaded based on user roles | |
| 314 | + */ | |
| 315 | +export const asyncRoutes = [ | |
| 187 | 316 | // 404 page must be placed at the end !!! |
| 188 | 317 | { |
| 189 | 318 | path: '*', |
| ... | ... | @@ -193,7 +322,9 @@ export const asyncRoutes = [ |
| 193 | 322 | |
| 194 | 323 | const createRouter = () => new Router({ |
| 195 | 324 | // mode: 'history', // require service support |
| 196 | - scrollBehavior: () => ({ y: 0 }), | |
| 325 | + scrollBehavior: () => ({ | |
| 326 | + y: 0 | |
| 327 | + }), | |
| 197 | 328 | routes: constantRoutes |
| 198 | 329 | }) |
| 199 | 330 | ... | ... |
src/views/403.vue
| ... | ... | @@ -0,0 +1,59 @@ |
| 1 | +<template> | |
| 2 | + <div class="error-page"> | |
| 3 | + <div class="error-code"> | |
| 4 | + 4 | |
| 5 | + <span>0</span>3 | |
| 6 | + </div> | |
| 7 | + <div class="error-desc">啊哦~ 你没有权限访问该页面哦</div> | |
| 8 | + <div class="error-handle"> | |
| 9 | + <router-link to="/"> | |
| 10 | + <el-button type="primary" size="large">返回首页</el-button> | |
| 11 | + </router-link> | |
| 12 | + <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> | |
| 13 | + </div> | |
| 14 | + </div> | |
| 15 | +</template> | |
| 16 | + | |
| 17 | +<script> | |
| 18 | +export default { | |
| 19 | + methods: { | |
| 20 | + goBack() { | |
| 21 | + this.$router.go(-1); | |
| 22 | + } | |
| 23 | + } | |
| 24 | +}; | |
| 25 | +</script> | |
| 26 | + | |
| 27 | + | |
| 28 | +<style scoped> | |
| 29 | +.error-page { | |
| 30 | + display: flex; | |
| 31 | + justify-content: center; | |
| 32 | + align-items: center; | |
| 33 | + flex-direction: column; | |
| 34 | + width: 100%; | |
| 35 | + height: 100%; | |
| 36 | + background: #f3f3f3; | |
| 37 | + box-sizing: border-box; | |
| 38 | +} | |
| 39 | +.error-code { | |
| 40 | + line-height: 1; | |
| 41 | + font-size: 250px; | |
| 42 | + font-weight: bolder; | |
| 43 | + color: #f02d2d; | |
| 44 | +} | |
| 45 | +.error-code span { | |
| 46 | + color: #00a854; | |
| 47 | +} | |
| 48 | +.error-desc { | |
| 49 | + font-size: 30px; | |
| 50 | + color: #777; | |
| 51 | +} | |
| 52 | +.error-handle { | |
| 53 | + margin-top: 30px; | |
| 54 | + padding-bottom: 200px; | |
| 55 | +} | |
| 56 | +.error-btn { | |
| 57 | + margin-left: 100px; | |
| 58 | +} | |
| 59 | +</style> | |
| 0 | 60 | \ No newline at end of file | ... | ... |
src/views/404.vue
| ... | ... | @@ -2,39 +2,45 @@ |
| 2 | 2 | <div class="wscn-http404-container"> |
| 3 | 3 | <div class="wscn-http404"> |
| 4 | 4 | <div class="pic-404"> |
| 5 | - <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404"> | |
| 6 | - <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404"> | |
| 7 | - <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404"> | |
| 8 | - <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404"> | |
| 5 | + <img class="pic-404__parent" src="@/assets/404_images/404.png" alt="404" /> | |
| 6 | + <img class="pic-404__child left" src="@/assets/404_images/404_cloud.png" alt="404" /> | |
| 7 | + <img class="pic-404__child mid" src="@/assets/404_images/404_cloud.png" alt="404" /> | |
| 8 | + <img class="pic-404__child right" src="@/assets/404_images/404_cloud.png" alt="404" /> | |
| 9 | 9 | </div> |
| 10 | 10 | <div class="bullshit"> |
| 11 | 11 | <div class="bullshit__oops">OOPS!</div> |
| 12 | - <div class="bullshit__info">All rights reserved | |
| 13 | - <a style="color:#20a0ff" href="https://wallstreetcn.com" target="_blank">wallstreetcn</a> | |
| 12 | + <div class="bullshit__info"> | |
| 13 | + All rights reserved | |
| 14 | + <a | |
| 15 | + style="color:#20a0ff" | |
| 16 | + href="https://wallstreetcn.com" | |
| 17 | + target="_blank" | |
| 18 | + >wallstreetcn</a> | |
| 14 | 19 | </div> |
| 15 | 20 | <div class="bullshit__headline">{{ message }}</div> |
| 16 | - <div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div> | |
| 17 | - <a href="" class="bullshit__return-home">Back to home</a> | |
| 21 | + <div | |
| 22 | + class="bullshit__info" | |
| 23 | + >Please check that the URL you entered is correct, or click the button below to return to the homepage.</div> | |
| 24 | + <a href class="bullshit__return-home">Back to home</a> | |
| 18 | 25 | </div> |
| 19 | 26 | </div> |
| 20 | 27 | </div> |
| 21 | 28 | </template> |
| 22 | 29 | |
| 23 | 30 | <script> |
| 24 | - | |
| 25 | 31 | export default { |
| 26 | - name: 'Page404', | |
| 32 | + name: "Page404", | |
| 27 | 33 | computed: { |
| 28 | 34 | message() { |
| 29 | - return 'The webmaster said that you can not enter this page...' | |
| 35 | + return "The webmaster said that you can not enter this page..."; | |
| 30 | 36 | } |
| 31 | 37 | } |
| 32 | -} | |
| 38 | +}; | |
| 33 | 39 | </script> |
| 34 | 40 | |
| 35 | 41 | <style lang="scss" scoped> |
| 36 | -.wscn-http404-container{ | |
| 37 | - transform: translate(-50%,-50%); | |
| 42 | +.wscn-http404-container { | |
| 43 | + transform: translate(-50%, -50%); | |
| 38 | 44 | position: absolute; |
| 39 | 45 | top: 40%; |
| 40 | 46 | left: 50%; | ... | ... |
src/views/502.vue
| ... | ... | @@ -0,0 +1,57 @@ |
| 1 | +<template> | |
| 2 | + <div class="error-page"> | |
| 3 | + <div class="error-code"> | |
| 4 | + 5 | |
| 5 | + <span>0</span>2 | |
| 6 | + </div> | |
| 7 | + <div class="error-desc">啊哦~ 系统出了故障!</div> | |
| 8 | + <div class="error-handle"> | |
| 9 | + <router-link to="/"> | |
| 10 | + <el-button type="primary" size="large">返回首页</el-button> | |
| 11 | + </router-link> | |
| 12 | + <el-button class="error-btn" type="primary" size="large" @click="goBack">返回上一页</el-button> | |
| 13 | + </div> | |
| 14 | + </div> | |
| 15 | +</template> | |
| 16 | + | |
| 17 | +<script> | |
| 18 | +export default { | |
| 19 | + methods: { | |
| 20 | + goBack() { | |
| 21 | + this.$router.go(-1); | |
| 22 | + } | |
| 23 | + } | |
| 24 | +}; | |
| 25 | +</script> | |
| 26 | +<style scoped> | |
| 27 | +.error-page { | |
| 28 | + display: flex; | |
| 29 | + justify-content: center; | |
| 30 | + align-items: center; | |
| 31 | + flex-direction: column; | |
| 32 | + width: 100%; | |
| 33 | + height: 100%; | |
| 34 | + background: #f3f3f3; | |
| 35 | + box-sizing: border-box; | |
| 36 | +} | |
| 37 | +.error-code { | |
| 38 | + line-height: 1; | |
| 39 | + font-size: 250px; | |
| 40 | + font-weight: bolder; | |
| 41 | + color: #f02d2d; | |
| 42 | +} | |
| 43 | +.error-code span { | |
| 44 | + color: #00a854; | |
| 45 | +} | |
| 46 | +.error-desc { | |
| 47 | + font-size: 30px; | |
| 48 | + color: #777; | |
| 49 | +} | |
| 50 | +.error-handle { | |
| 51 | + margin-top: 30px; | |
| 52 | + padding-bottom: 200px; | |
| 53 | +} | |
| 54 | +.error-btn { | |
| 55 | + margin-left: 100px; | |
| 56 | +} | |
| 57 | +</style> | |
| 0 | 58 | \ No newline at end of file | ... | ... |
src/views/dashboard/index.vue
| 1 | 1 | <template> |
| 2 | - <div class="dashboard-container"> | |
| 3 | - <div class="dashboard-text">用户名: {{ name }}</div> | |
| 4 | - <div class="dashboard-text">角色: <span v-for="role in roles" :key="role">{{ role }}</span></div> | |
| 2 | + <div> | |
| 3 | + <el-row :gutter="20"> | |
| 4 | + <el-col :span="8"> | |
| 5 | + <el-card shadow="hover" class="mgb20" style="height:252px;"> | |
| 6 | + <div class="user-info"> | |
| 7 | + <img src="../../assets/img/img.jpg" class="user-avator" alt /> | |
| 8 | + <div class="user-info-cont"> | |
| 9 | + <div class="user-info-name">{{name}}</div> | |
| 10 | + <div>{{role}}</div> | |
| 11 | + </div> | |
| 12 | + </div> | |
| 13 | + <div class="user-info-list"> | |
| 14 | + 上次登录时间: | |
| 15 | + <span>2019-11-01</span> | |
| 16 | + </div> | |
| 17 | + <div class="user-info-list"> | |
| 18 | + 上次登录地点: | |
| 19 | + <span>东莞</span> | |
| 20 | + </div> | |
| 21 | + </el-card> | |
| 22 | + <el-card shadow="hover" style="height:252px;"> | |
| 23 | + <div slot="header" class="clearfix"> | |
| 24 | + <span>语言详情</span> | |
| 25 | + </div>Vue | |
| 26 | + <el-progress :percentage="71.3" color="#42b983"></el-progress>JavaScript | |
| 27 | + <el-progress :percentage="24.1" color="#f1e05a"></el-progress>CSS | |
| 28 | + <el-progress :percentage="13.7"></el-progress>HTML | |
| 29 | + <el-progress :percentage="5.9" color="#f56c6c"></el-progress> | |
| 30 | + </el-card> | |
| 31 | + </el-col> | |
| 32 | + <el-col :span="16"> | |
| 33 | + <el-row :gutter="20" class="mgb20"> | |
| 34 | + <el-col :span="8"> | |
| 35 | + <el-card shadow="hover" :body-style="{padding: '0px'}"> | |
| 36 | + <div class="grid-content grid-con-1"> | |
| 37 | + <i class="el-icon-lx-people grid-con-icon"></i> | |
| 38 | + <div class="grid-cont-right"> | |
| 39 | + <div class="grid-num">1234</div> | |
| 40 | + <div>用户访问量</div> | |
| 41 | + </div> | |
| 42 | + </div> | |
| 43 | + </el-card> | |
| 44 | + </el-col> | |
| 45 | + <el-col :span="8"> | |
| 46 | + <el-card shadow="hover" :body-style="{padding: '0px'}"> | |
| 47 | + <div class="grid-content grid-con-2"> | |
| 48 | + <i class="el-icon-lx-notice grid-con-icon"></i> | |
| 49 | + <div class="grid-cont-right"> | |
| 50 | + <div class="grid-num">321</div> | |
| 51 | + <div>系统消息</div> | |
| 52 | + </div> | |
| 53 | + </div> | |
| 54 | + </el-card> | |
| 55 | + </el-col> | |
| 56 | + <el-col :span="8"> | |
| 57 | + <el-card shadow="hover" :body-style="{padding: '0px'}"> | |
| 58 | + <div class="grid-content grid-con-3"> | |
| 59 | + <i class="el-icon-lx-goods grid-con-icon"></i> | |
| 60 | + <div class="grid-cont-right"> | |
| 61 | + <div class="grid-num">5000</div> | |
| 62 | + <div>数量</div> | |
| 63 | + </div> | |
| 64 | + </div> | |
| 65 | + </el-card> | |
| 66 | + </el-col> | |
| 67 | + </el-row> | |
| 68 | + <el-card shadow="hover" style="height:403px;"> | |
| 69 | + <div slot="header" class="clearfix"> | |
| 70 | + <span>待办事项</span> | |
| 71 | + <el-button style="float: right; padding: 3px 0" type="text" @click="addAction">添加</el-button> | |
| 72 | + </div> | |
| 73 | + <el-table :show-header="false" :data="todoList" style="width:100%;"> | |
| 74 | + <el-table-column width="40"> | |
| 75 | + <template slot-scope="scope"> | |
| 76 | + <el-checkbox v-model="scope.row.status"></el-checkbox> | |
| 77 | + </template> | |
| 78 | + </el-table-column> | |
| 79 | + <el-table-column> | |
| 80 | + <template slot-scope="scope"> | |
| 81 | + <div | |
| 82 | + class="todo-item" | |
| 83 | + :class="{'todo-item-del': scope.row.status}" | |
| 84 | + >{{scope.row.title}}</div> | |
| 85 | + </template> | |
| 86 | + </el-table-column> | |
| 87 | + <el-table-column width="60"> | |
| 88 | + <template> | |
| 89 | + <i class="el-icon-edit" @click="modiAction"></i> | |
| 90 | + <i class="el-icon-delete" @click="delAction"></i> | |
| 91 | + </template> | |
| 92 | + </el-table-column> | |
| 93 | + </el-table> | |
| 94 | + </el-card> | |
| 95 | + </el-col> | |
| 96 | + </el-row> | |
| 97 | + <el-row :gutter="20"> | |
| 98 | + <el-col :span="12"> | |
| 99 | + <el-card shadow="hover"> | |
| 100 | + <schart ref="bar" class="schart" canvasId="bar" :options="options"></schart> | |
| 101 | + </el-card> | |
| 102 | + </el-col> | |
| 103 | + <el-col :span="12"> | |
| 104 | + <el-card shadow="hover"> | |
| 105 | + <schart ref="line" class="schart" canvasId="line" :options="options2"></schart> | |
| 106 | + </el-card> | |
| 107 | + </el-col> | |
| 108 | + </el-row> | |
| 5 | 109 | </div> |
| 6 | 110 | </template> |
| 7 | 111 | |
| 8 | 112 | <script> |
| 9 | -import { mapGetters } from 'vuex' | |
| 113 | +import { mapGetters } from "vuex"; | |
| 114 | +import Vue from "vue"; | |
| 115 | +import { | |
| 116 | + Pagination, | |
| 117 | + Dialog, | |
| 118 | + Autocomplete, | |
| 119 | + Dropdown, | |
| 120 | + DropdownMenu, | |
| 121 | + DropdownItem, | |
| 122 | + Menu, | |
| 123 | + Submenu, | |
| 124 | + MenuItem, | |
| 125 | + MenuItemGroup, | |
| 126 | + Input, | |
| 127 | + InputNumber, | |
| 128 | + Radio, | |
| 129 | + RadioGroup, | |
| 130 | + RadioButton, | |
| 131 | + Checkbox, | |
| 132 | + CheckboxButton, | |
| 133 | + CheckboxGroup, | |
| 134 | + Switch, | |
| 135 | + Select, | |
| 136 | + Option, | |
| 137 | + OptionGroup, | |
| 138 | + Button, | |
| 139 | + ButtonGroup, | |
| 140 | + Table, | |
| 141 | + TableColumn, | |
| 142 | + DatePicker, | |
| 143 | + TimeSelect, | |
| 144 | + TimePicker, | |
| 145 | + Popover, | |
| 146 | + Tooltip, | |
| 147 | + Breadcrumb, | |
| 148 | + BreadcrumbItem, | |
| 149 | + Form, | |
| 150 | + FormItem, | |
| 151 | + Tabs, | |
| 152 | + TabPane, | |
| 153 | + Tag, | |
| 154 | + Tree, | |
| 155 | + Alert, | |
| 156 | + Slider, | |
| 157 | + Icon, | |
| 158 | + Row, | |
| 159 | + Col, | |
| 160 | + Upload, | |
| 161 | + Progress, | |
| 162 | + Spinner, | |
| 163 | + Badge, | |
| 164 | + Card, | |
| 165 | + Rate, | |
| 166 | + Steps, | |
| 167 | + Step, | |
| 168 | + Carousel, | |
| 169 | + CarouselItem, | |
| 170 | + Collapse, | |
| 171 | + CollapseItem, | |
| 172 | + Cascader, | |
| 173 | + ColorPicker, | |
| 174 | + Transfer, | |
| 175 | + Container, | |
| 176 | + Header, | |
| 177 | + Aside, | |
| 178 | + Main, | |
| 179 | + Footer, | |
| 180 | + Timeline, | |
| 181 | + TimelineItem, | |
| 182 | + Link, | |
| 183 | + Divider, | |
| 184 | + Image, | |
| 185 | + Calendar, | |
| 186 | + Backtop, | |
| 187 | + PageHeader, | |
| 188 | + CascaderPanel, | |
| 189 | + Loading, | |
| 190 | + MessageBox, | |
| 191 | + Message, | |
| 192 | + Notification | |
| 193 | +} from "element-ui"; | |
| 10 | 194 | // import ElementUI from 'element-ui' |
| 195 | +Vue.prototype.$ELEMENT = { size: "small", zIndex: 3000 }; | |
| 196 | +Vue.use(Pagination); | |
| 197 | +Vue.use(Dialog); | |
| 198 | +Vue.use(Autocomplete); | |
| 199 | +Vue.use(Dropdown); | |
| 200 | +Vue.use(DropdownMenu); | |
| 201 | +Vue.use(DropdownItem); | |
| 202 | +Vue.use(Menu); | |
| 203 | +Vue.use(Submenu); | |
| 204 | +Vue.use(MenuItem); | |
| 205 | +Vue.use(MenuItemGroup); | |
| 206 | +Vue.use(Input); | |
| 207 | +Vue.use(InputNumber); | |
| 208 | +Vue.use(Radio); | |
| 209 | +Vue.use(RadioGroup); | |
| 210 | +Vue.use(RadioButton); | |
| 211 | +Vue.use(Checkbox); | |
| 212 | +Vue.use(CheckboxButton); | |
| 213 | +Vue.use(CheckboxGroup); | |
| 214 | +Vue.use(Switch); | |
| 215 | +Vue.use(Select); | |
| 216 | +Vue.use(Option); | |
| 217 | +Vue.use(OptionGroup); | |
| 218 | +Vue.use(Button); | |
| 219 | +Vue.use(ButtonGroup); | |
| 220 | +Vue.use(Table); | |
| 221 | +Vue.use(TableColumn); | |
| 222 | +Vue.use(DatePicker); | |
| 223 | +Vue.use(TimeSelect); | |
| 224 | +Vue.use(TimePicker); | |
| 225 | +Vue.use(Popover); | |
| 226 | +Vue.use(Tooltip); | |
| 227 | +Vue.use(Breadcrumb); | |
| 228 | +Vue.use(BreadcrumbItem); | |
| 229 | +Vue.use(Form); | |
| 230 | +Vue.use(FormItem); | |
| 231 | +Vue.use(Tabs); | |
| 232 | +Vue.use(TabPane); | |
| 233 | +Vue.use(Tag); | |
| 234 | +Vue.use(Tree); | |
| 235 | +Vue.use(Alert); | |
| 236 | +Vue.use(Slider); | |
| 237 | +Vue.use(Icon); | |
| 238 | +Vue.use(Row); | |
| 239 | +Vue.use(Col); | |
| 240 | +Vue.use(Upload); | |
| 241 | +Vue.use(Progress); | |
| 242 | +Vue.use(Spinner); | |
| 243 | +Vue.use(Badge); | |
| 244 | +Vue.use(Card); | |
| 245 | +Vue.use(Rate); | |
| 246 | +Vue.use(Steps); | |
| 247 | +Vue.use(Step); | |
| 248 | +Vue.use(Carousel); | |
| 249 | +Vue.use(CarouselItem); | |
| 250 | +Vue.use(Collapse); | |
| 251 | +Vue.use(CollapseItem); | |
| 252 | +Vue.use(Cascader); | |
| 253 | +Vue.use(ColorPicker); | |
| 254 | +Vue.use(Transfer); | |
| 255 | +Vue.use(Container); | |
| 256 | +Vue.use(Header); | |
| 257 | +Vue.use(Aside); | |
| 258 | +Vue.use(Main); | |
| 259 | +Vue.use(Footer); | |
| 260 | +Vue.use(Timeline); | |
| 261 | +Vue.use(TimelineItem); | |
| 262 | +Vue.use(Link); | |
| 263 | +Vue.use(Divider); | |
| 264 | +Vue.use(Image); | |
| 265 | +Vue.use(Calendar); | |
| 266 | +Vue.use(Backtop); | |
| 267 | +Vue.use(PageHeader); | |
| 268 | +Vue.use(CascaderPanel); | |
| 269 | +Vue.use(Loading.directive); | |
| 270 | + | |
| 271 | +import Schart from "vue-schart"; | |
| 272 | +import bus from "../../common/bus"; | |
| 273 | + | |
| 11 | 274 | // 按需引入 引入 ECharts 主模块 |
| 12 | 275 | // var echarts = require('echarts/lib/echarts') |
| 13 | 276 | // 引入柱状图 |
| ... | ... | @@ -19,24 +282,239 @@ import { mapGetters } from 'vuex' |
| 19 | 282 | // var echarts = require('echarts') |
| 20 | 283 | |
| 21 | 284 | export default { |
| 22 | - name: 'Dashboard', | |
| 285 | + name: "Dashboard", | |
| 286 | + data() { | |
| 287 | + return { | |
| 288 | + name: localStorage.getItem("ms_username"), | |
| 289 | + todoList: [ | |
| 290 | + { | |
| 291 | + title: "今天要修复100个bug", | |
| 292 | + status: true | |
| 293 | + }, | |
| 294 | + { | |
| 295 | + title: "今天要写100行代码加几个bug吧", | |
| 296 | + status: true | |
| 297 | + } | |
| 298 | + ], | |
| 299 | + data: [ | |
| 300 | + { | |
| 301 | + name: "2018/09/04", | |
| 302 | + value: 1083 | |
| 303 | + }, | |
| 304 | + { | |
| 305 | + name: "2018/09/10", | |
| 306 | + value: 1065 | |
| 307 | + } | |
| 308 | + ], | |
| 309 | + options: { | |
| 310 | + type: "bar", | |
| 311 | + title: { | |
| 312 | + text: "最近一周各品类销售图" | |
| 313 | + }, | |
| 314 | + xRorate: 25, | |
| 315 | + labels: ["周一", "周二", "周三", "周四", "周五"], | |
| 316 | + datasets: [ | |
| 317 | + { | |
| 318 | + label: "百货", | |
| 319 | + data: [164, 178, 190, 135, 160] | |
| 320 | + }, | |
| 321 | + { | |
| 322 | + label: "食品", | |
| 323 | + data: [144, 198, 150, 235, 120] | |
| 324 | + } | |
| 325 | + ] | |
| 326 | + }, | |
| 327 | + options2: { | |
| 328 | + type: "line", | |
| 329 | + title: { | |
| 330 | + text: "最近几个月各品类销售趋势图" | |
| 331 | + }, | |
| 332 | + labels: ["6月", "7月", "8月", "9月", "10月"], | |
| 333 | + datasets: [ | |
| 334 | + { | |
| 335 | + label: "百货", | |
| 336 | + data: [164, 178, 150, 135, 160] | |
| 337 | + }, | |
| 338 | + { | |
| 339 | + label: "食品", | |
| 340 | + data: [74, 118, 200, 235, 90] | |
| 341 | + } | |
| 342 | + ] | |
| 343 | + } | |
| 344 | + }; | |
| 345 | + }, | |
| 346 | + components: { | |
| 347 | + Schart | |
| 348 | + }, | |
| 23 | 349 | computed: { |
| 24 | - ...mapGetters([ | |
| 25 | - 'name', | |
| 26 | - 'roles' | |
| 27 | - ]) | |
| 350 | + // ...mapGetters(["name", "roles"]) | |
| 351 | + role() { | |
| 352 | + return this.name === "admin" ? "超级管理员" : "普通用户"; | |
| 353 | + } | |
| 354 | + }, | |
| 355 | + methods: { | |
| 356 | + addAction(){ | |
| 357 | + this.$prompt("请输入内容", "提示", { | |
| 358 | + confirmButtonText: "确定", | |
| 359 | + cancelButtonText: "取消", | |
| 360 | + inputErrorMessage: "内容不能为空" | |
| 361 | + }) | |
| 362 | + .then(({ value }) => { | |
| 363 | + this.$message({ | |
| 364 | + type: "success", | |
| 365 | + message: "你的邮箱是: " + value | |
| 366 | + }); | |
| 367 | + }) | |
| 368 | + .catch(() => { | |
| 369 | + this.$message({ | |
| 370 | + type: "info", | |
| 371 | + message: "取消输入" | |
| 372 | + }); | |
| 373 | + }); | |
| 374 | + }, | |
| 375 | + modiAction() { | |
| 376 | + // this.$prompt("请输入邮箱", "提示", { | |
| 377 | + // confirmButtonText: "确定", | |
| 378 | + // cancelButtonText: "取消", | |
| 379 | + // inputPattern: /[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?/, | |
| 380 | + // inputErrorMessage: "邮箱格式不正确" | |
| 381 | + // }) | |
| 382 | + this.$prompt("请输入内容", "提示", { | |
| 383 | + confirmButtonText: "确定", | |
| 384 | + cancelButtonText: "取消", | |
| 385 | + inputErrorMessage: "内容不能为空" | |
| 386 | + }) | |
| 387 | + .then(({ value }) => { | |
| 388 | + this.$message({ | |
| 389 | + type: "success", | |
| 390 | + message: "你的邮箱是: " + value | |
| 391 | + }); | |
| 392 | + }) | |
| 393 | + .catch(() => { | |
| 394 | + this.$message({ | |
| 395 | + type: "info", | |
| 396 | + message: "取消输入" | |
| 397 | + }); | |
| 398 | + }); | |
| 399 | + }, | |
| 400 | + delAction() { | |
| 401 | + this.$confirm("此操作将永久删除该文件, 是否继续?", "提示", { | |
| 402 | + confirmButtonText: "确定", | |
| 403 | + cancelButtonText: "取消", | |
| 404 | + type: "warning" | |
| 405 | + }) | |
| 406 | + .then(() => { | |
| 407 | + this.$message({ | |
| 408 | + type: "success", | |
| 409 | + message: "删除成功!" | |
| 410 | + }); | |
| 411 | + }) | |
| 412 | + .catch(() => { | |
| 413 | + this.$message({ | |
| 414 | + type: "info", | |
| 415 | + message: "已取消删除" | |
| 416 | + }); | |
| 417 | + }); | |
| 418 | + }, | |
| 419 | + changeDate() { | |
| 420 | + const now = new Date().getTime(); | |
| 421 | + this.data.forEach((item, index) => { | |
| 422 | + const date = new Date(now - (6 - index) * 86400000); | |
| 423 | + item.name = `${date.getFullYear()}/${date.getMonth() + | |
| 424 | + 1}/${date.getDate()}`; | |
| 425 | + }); | |
| 426 | + } | |
| 28 | 427 | } |
| 29 | -} | |
| 428 | +}; | |
| 30 | 429 | </script> |
| 31 | 430 | |
| 32 | -<style lang="scss" scoped> | |
| 33 | -.dashboard { | |
| 34 | - &-container { | |
| 35 | - margin: 30px; | |
| 36 | - } | |
| 37 | - &-text { | |
| 38 | - font-size: 30px; | |
| 39 | - line-height: 46px; | |
| 40 | - } | |
| 431 | +<style scoped> | |
| 432 | +.el-row { | |
| 433 | + margin-bottom: 20px; | |
| 434 | +} | |
| 435 | +.grid-content { | |
| 436 | + display: flex; | |
| 437 | + align-items: center; | |
| 438 | + height: 100px; | |
| 439 | +} | |
| 440 | +.grid-cont-right { | |
| 441 | + flex: 1; | |
| 442 | + text-align: center; | |
| 443 | + font-size: 14px; | |
| 444 | + color: #999; | |
| 445 | +} | |
| 446 | +.grid-num { | |
| 447 | + font-size: 30px; | |
| 448 | + font-weight: bold; | |
| 449 | +} | |
| 450 | +.grid-con-icon { | |
| 451 | + font-size: 50px; | |
| 452 | + width: 100px; | |
| 453 | + height: 100px; | |
| 454 | + text-align: center; | |
| 455 | + line-height: 100px; | |
| 456 | + color: #fff; | |
| 457 | +} | |
| 458 | +.grid-con-1 .grid-con-icon { | |
| 459 | + background: rgb(45, 140, 240); | |
| 460 | +} | |
| 461 | +.grid-con-1 .grid-num { | |
| 462 | + color: rgb(45, 140, 240); | |
| 463 | +} | |
| 464 | +.grid-con-2 .grid-con-icon { | |
| 465 | + background: rgb(100, 213, 114); | |
| 466 | +} | |
| 467 | +.grid-con-2 .grid-num { | |
| 468 | + color: rgb(45, 140, 240); | |
| 469 | +} | |
| 470 | +.grid-con-3 .grid-con-icon { | |
| 471 | + background: rgb(242, 94, 67); | |
| 472 | +} | |
| 473 | +.grid-con-3 .grid-num { | |
| 474 | + color: rgb(242, 94, 67); | |
| 475 | +} | |
| 476 | +.user-info { | |
| 477 | + display: flex; | |
| 478 | + align-items: center; | |
| 479 | + padding-bottom: 20px; | |
| 480 | + border-bottom: 2px solid #ccc; | |
| 481 | + margin-bottom: 20px; | |
| 482 | +} | |
| 483 | +.user-avator { | |
| 484 | + width: 120px; | |
| 485 | + height: 120px; | |
| 486 | + border-radius: 50%; | |
| 487 | +} | |
| 488 | +.user-info-cont { | |
| 489 | + padding-left: 50px; | |
| 490 | + flex: 1; | |
| 491 | + font-size: 14px; | |
| 492 | + color: #999; | |
| 493 | +} | |
| 494 | +.user-info-cont div:first-child { | |
| 495 | + font-size: 30px; | |
| 496 | + color: #222; | |
| 497 | +} | |
| 498 | +.user-info-list { | |
| 499 | + font-size: 14px; | |
| 500 | + color: #999; | |
| 501 | + line-height: 25px; | |
| 502 | +} | |
| 503 | +.user-info-list span { | |
| 504 | + margin-left: 70px; | |
| 505 | +} | |
| 506 | +.mgb20 { | |
| 507 | + margin-bottom: 20px; | |
| 508 | +} | |
| 509 | +.todo-item { | |
| 510 | + font-size: 14px; | |
| 511 | +} | |
| 512 | +.todo-item-del { | |
| 513 | + text-decoration: line-through; | |
| 514 | + color: #999; | |
| 515 | +} | |
| 516 | +.schart { | |
| 517 | + width: 100%; | |
| 518 | + height: 300px; | |
| 41 | 519 | } |
| 42 | 520 | </style> | ... | ... |
src/views/form/index.vue
| ... | ... | @@ -12,11 +12,21 @@ |
| 12 | 12 | </el-form-item> |
| 13 | 13 | <el-form-item label="Activity time"> |
| 14 | 14 | <el-col :span="11"> |
| 15 | - <el-date-picker v-model="form.date1" type="date" placeholder="Pick a date" style="width: 100%;" /> | |
| 15 | + <el-date-picker | |
| 16 | + v-model="form.date1" | |
| 17 | + type="date" | |
| 18 | + placeholder="Pick a date" | |
| 19 | + style="width: 100%;" | |
| 20 | + /> | |
| 16 | 21 | </el-col> |
| 17 | 22 | <el-col :span="2" class="line">-</el-col> |
| 18 | 23 | <el-col :span="11"> |
| 19 | - <el-time-picker v-model="form.date2" type="fixed-time" placeholder="Pick a time" style="width: 100%;" /> | |
| 24 | + <el-time-picker | |
| 25 | + v-model="form.date2" | |
| 26 | + type="fixed-time" | |
| 27 | + placeholder="Pick a time" | |
| 28 | + style="width: 100%;" | |
| 29 | + /> | |
| 20 | 30 | </el-col> |
| 21 | 31 | </el-form-item> |
| 22 | 32 | <el-form-item label="Instant delivery"> |
| ... | ... | @@ -52,33 +62,33 @@ export default { |
| 52 | 62 | data() { |
| 53 | 63 | return { |
| 54 | 64 | form: { |
| 55 | - name: '', | |
| 56 | - region: '', | |
| 57 | - date1: '', | |
| 58 | - date2: '', | |
| 65 | + name: "", | |
| 66 | + region: "", | |
| 67 | + date1: "", | |
| 68 | + date2: "", | |
| 59 | 69 | delivery: false, |
| 60 | 70 | type: [], |
| 61 | - resource: '', | |
| 62 | - desc: '' | |
| 71 | + resource: "", | |
| 72 | + desc: "" | |
| 63 | 73 | } |
| 64 | - } | |
| 74 | + }; | |
| 65 | 75 | }, |
| 66 | 76 | methods: { |
| 67 | 77 | onSubmit() { |
| 68 | - this.$message('submit!') | |
| 78 | + this.$message("submit!"); | |
| 69 | 79 | }, |
| 70 | 80 | onCancel() { |
| 71 | 81 | this.$message({ |
| 72 | - message: 'cancel!', | |
| 73 | - type: 'warning' | |
| 74 | - }) | |
| 82 | + message: "cancel!", | |
| 83 | + type: "warning" | |
| 84 | + }); | |
| 75 | 85 | } |
| 76 | 86 | } |
| 77 | -} | |
| 87 | +}; | |
| 78 | 88 | </script> |
| 79 | 89 | |
| 80 | 90 | <style scoped> |
| 81 | -.line{ | |
| 91 | +.line { | |
| 82 | 92 | text-align: center; |
| 83 | 93 | } |
| 84 | 94 | </style> | ... | ... |
src/views/nested/menu1/menu1-1/index.vue
src/views/table/index.vue
| ... | ... | @@ -8,73 +8,86 @@ |
| 8 | 8 | fit |
| 9 | 9 | highlight-current-row |
| 10 | 10 | > |
| 11 | - <el-table-column align="center" label="ID" width="95"> | |
| 12 | - <template slot-scope="scope"> | |
| 13 | - {{ scope.$index }} | |
| 14 | - </template> | |
| 11 | + <el-table-column align="center" label="用户id"> | |
| 12 | + <template slot-scope="scope">{{ scope.$index }}</template> | |
| 13 | + </el-table-column> | |
| 14 | + | |
| 15 | + <el-table-column label="openid"> | |
| 16 | + <template slot-scope="scope">{{ scope.row.openid }}</template> | |
| 15 | 17 | </el-table-column> |
| 16 | - <el-table-column label="Title"> | |
| 18 | + | |
| 19 | + <el-table-column label="昵称" width="110" align="center"> | |
| 17 | 20 | <template slot-scope="scope"> |
| 18 | - {{ scope.row.title }} | |
| 21 | + <span>{{ scope.row.username }}</span> | |
| 19 | 22 | </template> |
| 20 | 23 | </el-table-column> |
| 21 | - <el-table-column label="Author" width="110" align="center"> | |
| 24 | + | |
| 25 | + <el-table-column label="头像" width="110" align="center"> | |
| 26 | + <template slot-scope="scope">{{ scope.row.avatar }}</template> | |
| 27 | + </el-table-column> | |
| 28 | + | |
| 29 | + <el-table-column class-name="status-col" label="状态" align="center"> | |
| 22 | 30 | <template slot-scope="scope"> |
| 23 | - <span>{{ scope.row.author }}</span> | |
| 31 | + <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag> | |
| 24 | 32 | </template> |
| 25 | 33 | </el-table-column> |
| 26 | - <el-table-column label="Pageviews" width="110" align="center"> | |
| 34 | + | |
| 35 | + <el-table-column align="center" prop="created_at" label="注册时间"> | |
| 27 | 36 | <template slot-scope="scope"> |
| 28 | - {{ scope.row.pageviews }} | |
| 37 | + <i class="el-icon-time" /> | |
| 38 | + <span>{{ scope.row.create_at }}</span> | |
| 29 | 39 | </template> |
| 30 | 40 | </el-table-column> |
| 31 | - <el-table-column class-name="status-col" label="Status" width="110" align="center"> | |
| 41 | + <el-table-column align="center" prop="created_at" label="成交记录"> | |
| 32 | 42 | <template slot-scope="scope"> |
| 33 | - <el-tag :type="scope.row.status | statusFilter">{{ scope.row.status }}</el-tag> | |
| 43 | + <i class="el-icon-time" /> | |
| 44 | + <span>{{ scope.row.pageviews }}</span> | |
| 34 | 45 | </template> |
| 35 | 46 | </el-table-column> |
| 36 | - <el-table-column align="center" prop="created_at" label="Display_time" width="200"> | |
| 47 | + <el-table-column align="center" prop="created_at" label="引流图"> | |
| 37 | 48 | <template slot-scope="scope"> |
| 38 | - <i class="el-icon-time" /> | |
| 39 | - <span>{{ scope.row.display_time }}</span> | |
| 49 | + <span> | |
| 50 | + <el-button type="primary">子用户{{scope.row.pageviews}}</el-button> | |
| 51 | + </span> | |
| 40 | 52 | </template> |
| 41 | 53 | </el-table-column> |
| 42 | 54 | </el-table> |
| 55 | + <el-pagination background layout="prev, pager, next" :total="100"></el-pagination> | |
| 43 | 56 | </div> |
| 44 | 57 | </template> |
| 45 | 58 | |
| 46 | 59 | <script> |
| 47 | -import { getList } from '@/api/table' | |
| 60 | +import { getList } from "@/api/table"; | |
| 48 | 61 | |
| 49 | 62 | export default { |
| 50 | 63 | filters: { |
| 51 | 64 | statusFilter(status) { |
| 52 | 65 | const statusMap = { |
| 53 | - published: 'success', | |
| 54 | - draft: 'gray', | |
| 55 | - deleted: 'danger' | |
| 56 | - } | |
| 57 | - return statusMap[status] | |
| 66 | + published: "success", | |
| 67 | + draft: "gray", | |
| 68 | + deleted: "danger" | |
| 69 | + }; | |
| 70 | + return statusMap[status]; | |
| 58 | 71 | } |
| 59 | 72 | }, |
| 60 | 73 | data() { |
| 61 | 74 | return { |
| 62 | 75 | list: null, |
| 63 | 76 | listLoading: true |
| 64 | - } | |
| 77 | + }; | |
| 65 | 78 | }, |
| 66 | 79 | created() { |
| 67 | - this.fetchData() | |
| 80 | + this.fetchData(); | |
| 68 | 81 | }, |
| 69 | 82 | methods: { |
| 70 | 83 | fetchData() { |
| 71 | - this.listLoading = true | |
| 84 | + this.listLoading = true; | |
| 72 | 85 | getList().then(response => { |
| 73 | - console.log('----getList---', response) | |
| 74 | - this.list = response.data.items | |
| 75 | - this.listLoading = false | |
| 76 | - }) | |
| 86 | + console.log("----getList---", response); | |
| 87 | + this.list = response.data.items; | |
| 88 | + this.listLoading = false; | |
| 89 | + }); | |
| 77 | 90 | } |
| 78 | 91 | } |
| 79 | -} | |
| 92 | +}; | |
| 80 | 93 | </script> | ... | ... |