merge master
This commit is contained in:
		
							
								
								
									
										33
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										33
									
								
								.github/ISSUE_TEMPLATE/bug_report.md
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,33 @@ | ||||
| --- | ||||
| name: Bug report(报告问题) | ||||
| about: Create a report to help us improve | ||||
| --- | ||||
| <!-- | ||||
|     注意:为更好的解决你的问题,请参考模板提供完整信息,准确描述问题,信息不全的 issue 将被关闭。 | ||||
|  | ||||
|     Note: In order to better solve your problem, please refer to the template to provide complete information, accurately describe the problem, and the incomplete information issue will be closed. | ||||
| --> | ||||
|  | ||||
|  | ||||
| ## Bug report(问题描述) | ||||
|  | ||||
| #### Steps to reproduce(问题复现步骤) | ||||
| <!-- | ||||
| 1. [xxx] | ||||
| 2. [xxx] | ||||
| 3. [xxxx] | ||||
| --> | ||||
|  | ||||
| #### Screenshot or Gif(截图或动态图) | ||||
|  | ||||
|  | ||||
| #### Link to minimal reproduction(最小可在线还原demo) | ||||
|  | ||||
| <!-- | ||||
| Please only use Codepen, JSFiddle, CodeSandbox or a github repo | ||||
| --> | ||||
|  | ||||
| #### Other relevant information(格外信息) | ||||
| - Your OS: | ||||
| - Node.js version: | ||||
| - vue-element-admin version: | ||||
							
								
								
									
										7
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										7
									
								
								.github/ISSUE_TEMPLATE/feature_request.md
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,7 @@ | ||||
| --- | ||||
| name: Feature Request(新功能建议) | ||||
| about: Suggest an idea for this project | ||||
| --- | ||||
|  | ||||
| ## Feature request(新功能建议) | ||||
|  | ||||
							
								
								
									
										14
									
								
								.github/ISSUE_TEMPLATE/question.md
									
									
									
									
										vendored
									
									
										Executable file
									
								
							
							
						
						
									
										14
									
								
								.github/ISSUE_TEMPLATE/question.md
									
									
									
									
										vendored
									
									
										Executable file
									
								
							| @@ -0,0 +1,14 @@ | ||||
| --- | ||||
| name: Question(提问) | ||||
| about: Asking questions about use | ||||
| --- | ||||
|  | ||||
| ## Question(提问) | ||||
|  | ||||
| <!-- | ||||
|     提问之前,请确定你已经过自己的努力,尝试解决过这个问题。 | ||||
|     若是代码相关问题,请不要只截图,请提供在线 demo,以便节约彼此的时间。 | ||||
|  | ||||
|     Before asking a question, please make sure that you have tried your best to solve this problem. | ||||
|     If it's a code-related issue, please don't just take screenshots. Please provide an online demo to save each other's time. | ||||
| --> | ||||
| @@ -26,7 +26,7 @@ if (process.env.npm_config_preview || rawArgv.includes('--preview')) { | ||||
|   app.listen(port, function () { | ||||
|     console.log(chalk.green(`> Preview at  http://localhost:${port}${publicPath}`)) | ||||
|     if (report) { | ||||
|       console.log(chalk.green(`> Report at  http://localhost:${port}${publicPath}/report.html`)) | ||||
|       console.log(chalk.green(`> Report at  http://localhost:${port}${publicPath}report.html`)) | ||||
|     } | ||||
|  | ||||
|   }) | ||||
|   | ||||
| @@ -1,11 +1,23 @@ | ||||
| import Mock from 'mockjs' | ||||
| import mocks from './mocks' | ||||
| import { param2Obj } from '../src/utils' | ||||
|  | ||||
| const MOCK_API_BASE = '/mock' | ||||
| import user from './user' | ||||
| import role from './role' | ||||
| import article from './article' | ||||
| import search from './remoteSearch' | ||||
|  | ||||
| const mocks = [ | ||||
|   ...user, | ||||
|   ...role, | ||||
|   ...article, | ||||
|   ...search | ||||
| ] | ||||
|  | ||||
| // for front mock | ||||
| // please use it cautiously, it will redefine XMLHttpRequest, | ||||
| // which will cause many of your third-party libraries to be invalidated(like progress event). | ||||
| export function mockXHR() { | ||||
|   // 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题 | ||||
|   // mock patch | ||||
|   // https://github.com/nuysoft/Mock/issues/300 | ||||
|   Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send | ||||
|   Mock.XHR.prototype.send = function() { | ||||
| @@ -42,9 +54,10 @@ export function mockXHR() { | ||||
|   } | ||||
| } | ||||
|  | ||||
| // for mock server | ||||
| const responseFake = (url, type, respond) => { | ||||
|   return { | ||||
|     url: new RegExp(`${MOCK_API_BASE}${url}`), | ||||
|     url: new RegExp(`/mock${url}`), | ||||
|     type: type || 'get', | ||||
|     response(req, res) { | ||||
|       res.json(Mock.mock(respond instanceof Function ? respond(req, res) : respond)) | ||||
|   | ||||
							
								
								
									
										62
									
								
								mock/mock-server.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										62
									
								
								mock/mock-server.js
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,62 @@ | ||||
| const chokidar = require('chokidar') | ||||
| const bodyParser = require('body-parser') | ||||
| const chalk = require('chalk') | ||||
|  | ||||
| function registerRoutes(app) { | ||||
|   let mockStartIndex | ||||
|   const { default: mocks } = require('./index.js') | ||||
|   for (const mock of mocks) { | ||||
|     app[mock.type](mock.url, mock.response) | ||||
|     mockStartIndex = app._router.stack.length | ||||
|   } | ||||
|   const mockRoutesLength = Object.keys(mocks).length | ||||
|   return { | ||||
|     mockRoutesLength: mockRoutesLength, | ||||
|     mockStartIndex: mockStartIndex - mockRoutesLength | ||||
|   } | ||||
| } | ||||
|  | ||||
| function unregisterRoutes() { | ||||
|   Object.keys(require.cache).forEach(i => { | ||||
|     if (i.includes('/mock')) { | ||||
|       delete require.cache[require.resolve(i)] | ||||
|     } | ||||
|   }) | ||||
| } | ||||
|  | ||||
| module.exports = app => { | ||||
|   // es6 polyfill | ||||
|   require('@babel/register') | ||||
|  | ||||
|   // parse app.body | ||||
|   // http://expressjs.com/en/4x/api.html#req.body | ||||
|   app.use(bodyParser.json()) | ||||
|   app.use(bodyParser.urlencoded({ | ||||
|     extended: true | ||||
|   })) | ||||
|  | ||||
|   const mockRoutes = registerRoutes(app) | ||||
|   var mockRoutesLength = mockRoutes.mockRoutesLength | ||||
|   var mockStartIndex = mockRoutes.mockStartIndex | ||||
|  | ||||
|   // watch files, hot reload mock server | ||||
|   chokidar.watch(('./mock'), { | ||||
|     ignored: 'mock/mock-server.js', | ||||
|     persistent: true, | ||||
|     ignoreInitial: true | ||||
|   }).on('all', (event, path) => { | ||||
|     if (event === 'change' || event === 'add') { | ||||
|       // remove mock routes stack | ||||
|       app._router.stack.splice(mockStartIndex, mockRoutesLength) | ||||
|  | ||||
|       // clear routes cache | ||||
|       unregisterRoutes() | ||||
|  | ||||
|       const mockRoutes = registerRoutes(app) | ||||
|       mockRoutesLength = mockRoutes.mockRoutesLength | ||||
|       mockStartIndex = mockRoutes.mockStartIndex | ||||
|  | ||||
|       console.log(chalk.magentaBright(`\n > Mock Server hot reload success! changed  ${path}`)) | ||||
|     } | ||||
|   }) | ||||
| } | ||||
| @@ -1,12 +0,0 @@ | ||||
| import user from './user' | ||||
| import role from './role' | ||||
| import article from './article' | ||||
| import search from './remoteSearch' | ||||
|  | ||||
| export default [ | ||||
|   ...user, | ||||
|   ...role, | ||||
|   ...article, | ||||
|   ...search | ||||
| ] | ||||
|  | ||||
| @@ -19,7 +19,7 @@ export const constantRoutes = [ | ||||
|   }, | ||||
|   { | ||||
|     path: '/auth-redirect', | ||||
|     component: 'views/login/authredirect', | ||||
|     component: 'views/login/authRedirect', | ||||
|     hidden: true | ||||
|   }, | ||||
|   { | ||||
|   | ||||
| @@ -74,6 +74,7 @@ | ||||
|     "@babel/core": "7.0.0", | ||||
|     "@babel/register": "7.0.0", | ||||
|     "@vue/cli-plugin-babel": "3.5.3", | ||||
|     "@vue/cli-plugin-eslint": "3.5.1", | ||||
|     "@vue/cli-plugin-unit-jest": "3.5.3", | ||||
|     "@vue/cli-service": "3.5.3", | ||||
|     "@vue/test-utils": "1.0.0-beta.29", | ||||
| @@ -81,6 +82,7 @@ | ||||
|     "babel-eslint": "10.0.1", | ||||
|     "babel-jest": "23.6.0", | ||||
|     "chalk": "2.4.2", | ||||
|     "chokidar": "2.1.5", | ||||
|     "connect": "3.6.6", | ||||
|     "eslint": "5.15.3", | ||||
|     "eslint-plugin-vue": "5.2.2", | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|   <div class="dndList"> | ||||
|     <div :style="{width:width1}" class="dndList-list"> | ||||
|       <h3>{{ list1Title }}</h3> | ||||
|       <draggable :list="list1" group="article" class="dragArea"> | ||||
|       <draggable :set-data="setData" :list="list1" group="article" class="dragArea"> | ||||
|         <div v-for="element in list1" :key="element.id" class="list-complete-item"> | ||||
|           <div class="list-complete-item-handle"> | ||||
|             {{ element.id }}[{{ element.author }}] {{ element.title }} | ||||
| @@ -94,6 +94,11 @@ export default { | ||||
|       if (this.isNotInList1(ele)) { | ||||
|         this.list1.push(ele) | ||||
|       } | ||||
|     }, | ||||
|     setData(dataTransfer) { | ||||
|       // to avoid Firefox bug | ||||
|       // Detail see : https://github.com/RubaXa/Sortable/issues/1012 | ||||
|       dataTransfer.setData('Text', '') | ||||
|     } | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -6,7 +6,7 @@ | ||||
|       </el-button> | ||||
|     </el-badge> | ||||
|  | ||||
|     <el-dialog :visible.sync="dialogTableVisible" title="Error Log" width="80%"> | ||||
|     <el-dialog :visible.sync="dialogTableVisible" title="Error Log" width="80%" append-to-body> | ||||
|       <el-table :data="errorLogs" border> | ||||
|         <el-table-column label="Message"> | ||||
|           <template slot-scope="{row}"> | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|       :list="list" | ||||
|       v-bind="$attrs" | ||||
|       class="board-column-content" | ||||
|       :set-data="setData" | ||||
|     > | ||||
|       <div v-for="element in list" :key="element.id" class="board-item"> | ||||
|         {{ element.name }} {{ element.id }} | ||||
| @@ -39,6 +40,13 @@ export default { | ||||
|         return [] | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     setData(dataTransfer) { | ||||
|       // to avoid Firefox bug | ||||
|       // Detail see : https://github.com/RubaXa/Sortable/issues/1012 | ||||
|       dataTransfer.setData('Text', '') | ||||
|     } | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|   | ||||
| @@ -3,7 +3,7 @@ | ||||
|     <logo v-if="showLogo" :collapse="isCollapse" /> | ||||
|     <el-scrollbar wrap-class="scrollbar-wrapper"> | ||||
|       <el-menu | ||||
|         :default-active="$route.path" | ||||
|         :default-active="activeMenu" | ||||
|         :collapse="isCollapse" | ||||
|         :background-color="variables.menuBg" | ||||
|         :text-color="variables.menuText" | ||||
| @@ -30,6 +30,15 @@ export default { | ||||
|       'permission_routes', | ||||
|       'sidebar' | ||||
|     ]), | ||||
|     activeMenu() { | ||||
|       const route = this.$route | ||||
|       const { meta, path } = route | ||||
|       // if set path, the sidebar will highlight the path you set | ||||
|       if (meta.activeMenu) { | ||||
|         return meta.activeMenu | ||||
|       } | ||||
|       return path | ||||
|     }, | ||||
|     showLogo() { | ||||
|       return this.$store.state.settings.sidebarLogo | ||||
|     }, | ||||
|   | ||||
| @@ -134,7 +134,7 @@ export default { | ||||
|     closeSelectedTag(view) { | ||||
|       this.$store.dispatch('tagsView/delView', view).then(({ visitedViews }) => { | ||||
|         if (this.isActive(view)) { | ||||
|           this.toLastView(visitedViews) | ||||
|           this.toLastView(visitedViews, view) | ||||
|         } | ||||
|       }) | ||||
|     }, | ||||
| @@ -149,17 +149,23 @@ export default { | ||||
|         if (this.affixTags.some(tag => tag.path === view.path)) { | ||||
|           return | ||||
|         } | ||||
|         this.toLastView(visitedViews) | ||||
|         this.toLastView(visitedViews, view) | ||||
|       }) | ||||
|     }, | ||||
|     toLastView(visitedViews) { | ||||
|     toLastView(visitedViews, view) { | ||||
|       const latestView = visitedViews.slice(-1)[0] | ||||
|       if (latestView) { | ||||
|         this.$router.push(latestView) | ||||
|       } else { | ||||
|         // You can set another route | ||||
|         // now the default is to redirect to the home page if there is no tags-view, | ||||
|         // you can adjust it according to your needs. | ||||
|         if (view.name === 'Dashboard') { | ||||
|           // to reload home page | ||||
|           this.$router.replace({ path: '/redirect' + view.fullPath }) | ||||
|         } else { | ||||
|           this.$router.push('/') | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     openMenu(tag, e) { | ||||
|       const menuMinWidth = 105 | ||||
| @@ -232,7 +238,7 @@ export default { | ||||
|   .contextmenu { | ||||
|     margin: 0; | ||||
|     background: #fff; | ||||
|     z-index: 100; | ||||
|     z-index: 3000; | ||||
|     position: absolute; | ||||
|     list-style-type: none; | ||||
|     padding: 5px 0; | ||||
|   | ||||
| @@ -12,32 +12,32 @@ import chartsRouter from './modules/charts' | ||||
| import tableRouter from './modules/table' | ||||
| import nestedRouter from './modules/nested' | ||||
|  | ||||
| /** note: sub-menu only appear when children.length>=1 | ||||
|  *  detail see  https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html | ||||
|  **/ | ||||
|  | ||||
| /** | ||||
| * hidden: true                   if `hidden:true` will not show in the sidebar(default is false) | ||||
| * alwaysShow: true               if set true, will always show the root menu, whatever its child routes length | ||||
| *                                if not set alwaysShow, only more than one route under the children | ||||
|  * Note: sub-menu only appear when route children.length >= 1 | ||||
|  * Detail see: https://panjiachen.github.io/vue-element-admin-site/guide/essentials/router-and-nav.html | ||||
|  * | ||||
|  * hidden: true                   if set true, item will not show in the sidebar(default is false) | ||||
|  * alwaysShow: true               if set true, will always show the root menu | ||||
|  *                                if not set alwaysShow, when item has more than one children route, | ||||
|  *                                it will becomes nested mode, otherwise not show the root menu | ||||
|  * redirect: noredirect           if `redirect:noredirect` will no redirect in the breadcrumb | ||||
|  * name:'router-name'             the name is used by <keep-alive> (must set!!!) | ||||
|  * meta : { | ||||
|     roles: ['admin','editor']    will control the page roles (you can set multiple roles) | ||||
|     title: 'title'               the name show in sub-menu and breadcrumb (recommend set) | ||||
|     roles: ['admin','editor']    control the page roles (you can set multiple roles) | ||||
|     title: 'title'               the name show in sidebar and breadcrumb (recommend set) | ||||
|     icon: 'svg-name'             the icon show in the sidebar | ||||
|     noCache: true                if true, the page will no be cached(default is false) | ||||
|     breadcrumb: false            if false, the item will hidden in breadcrumb(default is true) | ||||
|     affix: true                  if true, the tag will affix in the tags-view | ||||
|     noCache: true                if set true, the page will no be cached(default is false) | ||||
|     affix: true                  if set true, the tag will affix in the tags-view | ||||
|     breadcrumb: false            if set false, the item will hidden in breadcrumb(default is true) | ||||
|     activeMenu: '/example/list'  if set path, the sidebar will highlight the path you set | ||||
|   } | ||||
| **/ | ||||
|  */ | ||||
|  | ||||
| /** | ||||
|  * constantRoutes | ||||
|  * a base page that does not have permission requirements | ||||
|  * all roles can be accessed | ||||
|  * */ | ||||
|  */ | ||||
| export const constantRoutes = [ | ||||
|   { | ||||
|     path: '/redirect', | ||||
| @@ -57,7 +57,7 @@ export const constantRoutes = [ | ||||
|   }, | ||||
|   { | ||||
|     path: '/auth-redirect', | ||||
|     component: () => import('@/views/login/authredirect'), | ||||
|     component: () => import('@/views/login/authRedirect'), | ||||
|     hidden: true | ||||
|   }, | ||||
|   { | ||||
| @@ -195,7 +195,7 @@ export const asyncRoutes = [ | ||||
|         path: 'edit/:id(\\d+)', | ||||
|         component: () => import('@/views/example/edit'), | ||||
|         name: 'EditArticle', | ||||
|         meta: { title: 'Edit Article', noCache: true }, | ||||
|         meta: { title: 'Edit Article', noCache: true, activeMenu: '/example/list' }, | ||||
|         hidden: true | ||||
|       }, | ||||
|       { | ||||
|   | ||||
| @@ -1,24 +1,24 @@ | ||||
| import Vue from 'vue' | ||||
| import Vuex from 'vuex' | ||||
| import app from './modules/app' | ||||
| import errorLog from './modules/errorLog' | ||||
| import permission from './modules/permission' | ||||
| import tagsView from './modules/tagsView' | ||||
| import settings from './modules/settings' | ||||
| import user from './modules/user' | ||||
| import getters from './getters' | ||||
|  | ||||
| Vue.use(Vuex) | ||||
|  | ||||
| // https://webpack.js.org/guides/dependency-management/#requirecontext | ||||
| const modulesFiles = require.context('./modules', false, /\.js$/) | ||||
|  | ||||
| // you do not need `import app from './modules/app'` | ||||
| // it will auto require all vuex module from modules file | ||||
| const modules = modulesFiles.keys().reduce((modules, modulePath) => { | ||||
|   // set './app.js' => 'app' | ||||
|   const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1') | ||||
|   const value = modulesFiles(modulePath) | ||||
|   modules[moduleName] = value.default | ||||
|   return modules | ||||
| }, {}) | ||||
|  | ||||
| const store = new Vuex.Store({ | ||||
|   modules: { | ||||
|     app, | ||||
|     errorLog, | ||||
|     permission, | ||||
|     tagsView, | ||||
|     settings, | ||||
|     user | ||||
|   }, | ||||
|   modules, | ||||
|   getters | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| const state = { | ||||
|   logs: [] | ||||
| } | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| const state = { | ||||
|   visitedViews: [], | ||||
|   cachedViews: [] | ||||
|   | ||||
| @@ -12,6 +12,7 @@ | ||||
|   .sidebar-container { | ||||
|     transition: width 0.28s; | ||||
|     width: $sideBarWidth !important; | ||||
|     background-color: $menuBg; | ||||
|     height: 100%; | ||||
|     position: fixed; | ||||
|     font-size: 0px; | ||||
| @@ -28,10 +29,6 @@ | ||||
|  | ||||
|     .scrollbar-wrapper { | ||||
|       overflow-x: hidden !important; | ||||
|  | ||||
|       .el-scrollbar__view { | ||||
|         height: 100%; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     .el-scrollbar__bar.is-vertical { | ||||
|   | ||||
| @@ -23,7 +23,7 @@ service.interceptors.request.use( | ||||
|   error => { | ||||
|     // Do something with request error | ||||
|     console.log(error) // for debug | ||||
|     Promise.reject(error) | ||||
|     return Promise.reject(error) | ||||
|   } | ||||
| ) | ||||
|  | ||||
| @@ -43,7 +43,7 @@ service.interceptors.response.use( | ||||
|     const res = response.data | ||||
|     if (res.code !== 20000) { | ||||
|       Message({ | ||||
|         message: res.message, | ||||
|         message: res.message || 'error', | ||||
|         type: 'error', | ||||
|         duration: 5 * 1000 | ||||
|       }) | ||||
| @@ -61,7 +61,7 @@ service.interceptors.response.use( | ||||
|           }) | ||||
|         }) | ||||
|       } | ||||
|       return Promise.reject('error') | ||||
|       return Promise.reject(res.message || 'error') | ||||
|     } else { | ||||
|       return res | ||||
|     } | ||||
|   | ||||
| @@ -28,7 +28,7 @@ | ||||
|               <el-row> | ||||
|                 <el-col :span="8"> | ||||
|                   <el-form-item label-width="45px" label="作者:" class="postInfo-container-item"> | ||||
|                     <el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable remote placeholder="搜索用户"> | ||||
|                     <el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable default-first-option remote placeholder="搜索用户"> | ||||
|                       <el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item" /> | ||||
|                     </el-select> | ||||
|                   </el-form-item> | ||||
|   | ||||
| @@ -1,6 +1,6 @@ | ||||
| <script> | ||||
| export default { | ||||
|   name: 'Authredirect', | ||||
|   name: 'AuthRedirect', | ||||
|   created() { | ||||
|     const hash = window.location.search.slice(1) | ||||
|     if (window.localStorage) { | ||||
| @@ -20,6 +20,7 @@ | ||||
|         /> | ||||
|       </el-form-item> | ||||
|  | ||||
|       <el-tooltip v-model="capsTooltip" content="Caps lock is On" placement="right" manual> | ||||
|         <el-form-item prop="password"> | ||||
|           <span class="svg-container"> | ||||
|             <svg-icon icon-class="password" /> | ||||
| @@ -29,15 +30,18 @@ | ||||
|             ref="password" | ||||
|             v-model="loginForm.password" | ||||
|             :type="passwordType" | ||||
|           placeholder="Password" | ||||
|             :placeholder="Password" | ||||
|             name="password" | ||||
|             auto-complete="on" | ||||
|             @keyup.native="checkCapslock" | ||||
|             @blur="capsTooltip = false" | ||||
|             @keyup.enter.native="handleLogin" | ||||
|           /> | ||||
|           <span class="show-pwd" @click="showPwd"> | ||||
|             <svg-icon :icon-class="passwordType === 'password' ? 'eye' : 'eye-open'" /> | ||||
|           </span> | ||||
|         </el-form-item> | ||||
|       </el-tooltip> | ||||
|  | ||||
|       <el-button :loading="loading" type="primary" style="width:100%;margin-bottom:30px;" @click.native.prevent="handleLogin">Login</el-button> | ||||
|  | ||||
| @@ -69,7 +73,7 @@ | ||||
|  | ||||
| <script> | ||||
| import { validUsername } from '@/utils/validate' | ||||
| import SocialSign from './socialsignin' | ||||
| import SocialSign from './socialSignin' | ||||
|  | ||||
| export default { | ||||
|   name: 'Login', | ||||
| @@ -99,6 +103,7 @@ export default { | ||||
|         password: [{ required: true, trigger: 'blur', validator: validatePassword }] | ||||
|       }, | ||||
|       passwordType: 'password', | ||||
|       capsTooltip: false, | ||||
|       loading: false, | ||||
|       showDialog: false, | ||||
|       redirect: undefined | ||||
| @@ -126,6 +131,18 @@ export default { | ||||
|     // window.removeEventListener('storage', this.afterQRScan) | ||||
|   }, | ||||
|   methods: { | ||||
|     checkCapslock({ shiftKey, key } = {}) { | ||||
|       if (key && key.length === 1) { | ||||
|         if (shiftKey && (key >= 'a' && key <= 'z') || !shiftKey && (key >= 'A' && key <= 'Z')) { | ||||
|           this.capsTooltip = true | ||||
|         } else { | ||||
|           this.capsTooltip = false | ||||
|         } | ||||
|       } | ||||
|       if (key === 'CapsLock' && this.capsTooltip === true) { | ||||
|         this.capsTooltip = false | ||||
|       } | ||||
|     }, | ||||
|     showPwd() { | ||||
|       if (this.passwordType === 'password') { | ||||
|         this.passwordType = '' | ||||
|   | ||||
							
								
								
									
										1
									
								
								src/views/svg-icons/element-icon.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/views/svg-icons/element-icon.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| ["info","error","success","warning","question","back","arrow-left","arrow-down","arrow-right","arrow-up","caret-left","caret-bottom","caret-top","caret-right","d-arrow-left","d-arrow-right","minus","plus","remove","circle-plus","remove-outline","circle-plus-outline","close","check","circle-close","circle-check","circle-close-outline","circle-check-outline","zoom-out","zoom-in","d-caret","sort","sort-down","sort-up","tickets","document","goods","sold-out","news","message","date","printer","time","bell","mobile-phone","service","view","menu","more","more-outline","star-on","star-off","location","location-outline","phone","phone-outline","picture","picture-outline","delete","search","edit","edit-outline","rank","refresh","share","setting","upload","upload2","download","loading"] | ||||
| @@ -4,7 +4,8 @@ | ||||
|       <a href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/icon.html" target="_blank">Add and use | ||||
|       </a> | ||||
|     </p> | ||||
|     <div class="icons-wrapper"> | ||||
|     <el-tabs type="border-card"> | ||||
|       <el-tab-pane label="Icons"> | ||||
|         <div v-for="item of iconsMap" :key="item" @click="handleClipboard(generateIconCode(item),$event)"> | ||||
|           <el-tooltip placement="top"> | ||||
|             <div slot="content"> | ||||
| @@ -16,25 +17,44 @@ | ||||
|             </div> | ||||
|           </el-tooltip> | ||||
|         </div> | ||||
|       </el-tab-pane> | ||||
|       <el-tab-pane label="Element-UI Icons"> | ||||
|         <div v-for="item of elementIcons" :key="item" @click="handleClipboard(generateElementIconCode(item),$event)"> | ||||
|           <el-tooltip placement="top"> | ||||
|             <div slot="content"> | ||||
|               {{ generateElementIconCode(item) }} | ||||
|             </div> | ||||
|             <div class="icon-item"> | ||||
|               <i :class="'el-icon-' + item" /> | ||||
|               <span>{{ item }}</span> | ||||
|             </div> | ||||
|           </el-tooltip> | ||||
|         </div> | ||||
|       </el-tab-pane> | ||||
|     </el-tabs> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script> | ||||
| import icons from './requireIcons' | ||||
| import clipboard from '@/utils/clipboard' | ||||
| import icons from './requireIcons' | ||||
| import elementIcons from './element-icon.json' | ||||
|  | ||||
| export default { | ||||
|   name: 'Icons', | ||||
|   data() { | ||||
|     return { | ||||
|       iconsMap: icons | ||||
|       iconsMap: icons, | ||||
|       elementIcons: elementIcons | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     generateIconCode(symbol) { | ||||
|       return `<svg-icon icon-class="${symbol}" />` | ||||
|     }, | ||||
|     generateElementIconCode(symbol) { | ||||
|       return `<i class="el-icon-${symbol}" />` | ||||
|     }, | ||||
|     handleClipboard(text, event) { | ||||
|       clipboard(text, event) | ||||
|     } | ||||
| @@ -46,24 +66,24 @@ export default { | ||||
| .icons-container { | ||||
|   margin: 10px 20px 0; | ||||
|   overflow: hidden; | ||||
|   .icons-wrapper { | ||||
|     margin: 0 auto; | ||||
|   } | ||||
|  | ||||
|   .icon-item { | ||||
|     margin: 20px; | ||||
|     height: 110px; | ||||
|     height: 85px; | ||||
|     text-align: center; | ||||
|     width: 110px; | ||||
|     width: 100px; | ||||
|     float: left; | ||||
|     font-size: 30px; | ||||
|     color: #24292e; | ||||
|     cursor: pointer; | ||||
|   } | ||||
|  | ||||
|   span { | ||||
|     display: block; | ||||
|     font-size: 24px; | ||||
|     font-size: 16px; | ||||
|     margin-top: 10px; | ||||
|   } | ||||
|  | ||||
|   .disabled { | ||||
|     pointer-events: none; | ||||
|   } | ||||
|   | ||||
| @@ -1,4 +1,3 @@ | ||||
|  | ||||
| const req = require.context('../../icons/svg', false, /\.svg$/) | ||||
| const requireAll = requireContext => requireContext.keys() | ||||
|  | ||||
|   | ||||
| @@ -112,9 +112,9 @@ export default { | ||||
|       this.sortable = Sortable.create(el, { | ||||
|         ghostClass: 'sortable-ghost', // Class name for the drop placeholder, | ||||
|         setData: function(dataTransfer) { | ||||
|           dataTransfer.setData('Text', '') | ||||
|           // to avoid Firefox bug | ||||
|           // Detail see : https://github.com/RubaXa/Sortable/issues/1012 | ||||
|           dataTransfer.setData('Text', '') | ||||
|         }, | ||||
|         onEnd: evt => { | ||||
|           const targetRow = this.list.splice(evt.oldIndex, 1)[0] | ||||
|   | ||||
| @@ -21,7 +21,7 @@ module.exports = { | ||||
|   publicPath: '/', | ||||
|   outputDir: 'dist', | ||||
|   assetsDir: 'static', | ||||
|   lintOnSave: process.env.NODE_ENV === 'development' ? 'error' : false, | ||||
|   lintOnSave: process.env.NODE_ENV === 'development', | ||||
|   productionSourceMap: false, | ||||
|   devServer: { | ||||
|     port: port, | ||||
| @@ -41,22 +41,7 @@ module.exports = { | ||||
|         } | ||||
|       } | ||||
|     }, | ||||
|     after(app) { | ||||
|       require('@babel/register') | ||||
|       const bodyParser = require('body-parser') | ||||
|  | ||||
|       // parse app.body | ||||
|       // http://expressjs.com/en/4x/api.html#req.body | ||||
|       app.use(bodyParser.json()) | ||||
|       app.use(bodyParser.urlencoded({ | ||||
|         extended: true | ||||
|       })) | ||||
|  | ||||
|       const { default: mocks } = require('./mock') | ||||
|       for (const mock of mocks) { | ||||
|         app[mock.type](mock.url, mock.response) | ||||
|       } | ||||
|     } | ||||
|     after: require('./mock/mock-server.js') | ||||
|   }, | ||||
|   configureWebpack: { | ||||
|     // provide the app's title in webpack's name field, so that | ||||
| @@ -129,7 +114,7 @@ module.exports = { | ||||
|                 elementUI: { | ||||
|                   name: 'chunk-elementUI', // split elementUI into a single package | ||||
|                   priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app | ||||
|                   test: /[\\/]node_modules[\\/]element-ui[\\/]/ | ||||
|                   test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm | ||||
|                 }, | ||||
|                 commons: { | ||||
|                   name: 'chunk-commons', | ||||
|   | ||||
		Reference in New Issue
	
	Block a user