merge master

This commit is contained in:
Pan 2019-04-16 15:49:12 +08:00
commit 8835c5b48f
117 changed files with 731 additions and 444 deletions

View File

@ -1,4 +1,4 @@
# http://editorconfig.org # https://editorconfig.org
root = true root = true
[*] [*]

View File

@ -30,11 +30,11 @@ English | [简体中文](./README.zh-CN.md)
## Introduction ## Introduction
[vue-element-admin](http://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It based on [vue](https://github.com/vuejs/vue) and use the UI Toolkit [element-ui](https://github.com/ElemeFE/element). [vue-element-admin](https://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It based on [vue](https://github.com/vuejs/vue) and use the UI Toolkit [element-ui](https://github.com/ElemeFE/element).
It is a magical vue admin based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you. It is a magical vue admin based on the newest development stack of vue, built-in i18n solution, typical templates for enterprise applications, lots of awesome features. It helps you build a large complex Single-Page Applications. I believe whatever your needs are, this project will help you.
- [Preview](http://panjiachen.github.io/vue-element-admin) - [Preview](https://panjiachen.github.io/vue-element-admin)
- [Documentation](https://panjiachen.github.io/vue-element-admin-site/) - [Documentation](https://panjiachen.github.io/vue-element-admin-site/)
@ -50,13 +50,13 @@ It is a magical vue admin based on the newest development stack of vue, built-in
- Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) - Desktop: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour)) - Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Credits: [@Armour](https://github.com/Armour))
**The current version is `4.0-beta`. If you find a problem, please put [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). If you want to use the old version - stable version, you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)** **The current version is `v4.0+` build on `vue-cli`. If you find a problem, please put [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). If you want to use the old version , you can switch branch to [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), it does not rely on `vue-cli'**
**This project does not support low version browsers (e.g. IE). Please add polyfill by yourself.** **This project does not support low version browsers (e.g. IE). Please add polyfill by yourself.**
## Preparation ## Preparation
You need to install [node](http://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](http://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock). You need to install [node](https://nodejs.org/) and [git](https://git-scm.com/) locally. The project is based on [ES2015+](https://es6.ruanyifeng.com/), [vue](https://cn.vuejs.org/index.html), [vuex](https://vuex.vuejs.org/zh-cn/), [vue-router](https://router.vuejs.org/zh-cn/), [vue-cli](https://github.com/vuejs/vue-cli) , [axios](https://github.com/axios/axios) and [element-ui](https://github.com/ElemeFE/element), all request data is simulated using [Mock.js](https://github.com/nuysoft/Mock).
Understanding and learning this knowledge in advance will greatly help the use of this project. Understanding and learning this knowledge in advance will greatly help the use of this project.
<p align="center"> <p align="center">
@ -187,7 +187,7 @@ Detailed changes for each release are documented in the [release notes](https://
## Online Demo ## Online Demo
[Preview](http://panjiachen.github.io/vue-element-admin) [Preview](https://panjiachen.github.io/vue-element-admin)
## Donate ## Donate
@ -203,7 +203,7 @@ If you find this project useful, you can buy author a glass of juice :tropical_d
Modern browsers and Internet Explorer 10+. Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- | | --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions | IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions

View File

@ -30,9 +30,9 @@
## 简介 ## 简介
[vue-element-admin](http://panjiachen.github.io/vue-element-admin) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)实现。它使用了最新的前端技术栈,内置了 i18n 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。 [vue-element-admin](https://panjiachen.github.io/vue-element-admin) 是一个后台前端解决方案,它基于 [vue](https://github.com/vuejs/vue) 和 [element-ui](https://github.com/ElemeFE/element)实现。它使用了最新的前端技术栈,内置了 i18n 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。
- [在线预览](http://panjiachen.github.io/vue-element-admin) - [在线预览](https://panjiachen.github.io/vue-element-admin)
- [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/) - [使用文档](https://panjiachen.github.io/vue-element-admin-site/zh/)
@ -50,7 +50,7 @@
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin) - 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
- Typescript 版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour)) - Typescript 版: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (鸣谢: [@Armour](https://github.com/Armour))
**目前版本为 `4.0-beta`,若发现问题,欢迎提[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)。若你想使用旧版本-稳定版,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0)** **目前版本为 `v4.0+` 基于 `vue-cli` 进行构建,若发现问题,欢迎提[issue](https://github.com/PanJiaChen/vue-element-admin/issues/new)。若你想使用旧版本,可以切换分支到[tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0),它不依赖 `vue-cli`**
**该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)** **该项目不支持低版本浏览器(如 ie),有需求请自行添加 polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
@ -204,7 +204,7 @@ Detailed changes for each release are documented in the [release notes](https://
## Online Demo ## Online Demo
[在线 Demo](http://panjiachen.github.io/vue-element-admin) [在线 Demo](https://panjiachen.github.io/vue-element-admin)
## Donate ## Donate
@ -221,7 +221,7 @@ Detailed changes for each release are documented in the [release notes](https://
Modern browsers and Internet Explorer 10+. Modern browsers and Internet Explorer 10+.
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari | | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](https://godban.github.io/browsers-support-badges/)</br>Safari |
| --------- | --------- | --------- | --------- | | --------- | --------- | --------- | --------- |
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions | IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions

View File

@ -3,7 +3,7 @@ import Mock from 'mockjs'
const List = [] const List = []
const count = 100 const count = 100
const baseContent = '<p>我是测试数据我是测试数据</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>' const baseContent = '<p>I am testing data, I am testing data.</p><p><img src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>'
const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3' const image_uri = 'https://wpimg.wallstcn.com/e4558086-631c-425c-9430-56ffb46e70b3'
for (let i = 0; i < count; i++) { for (let i = 0; i < count; i++) {

View File

@ -4,7 +4,7 @@ import { param2Obj } from '../src/utils'
import user from './user' import user from './user'
import role from './role' import role from './role'
import article from './article' import article from './article'
import search from './remoteSearch' import search from './remote-search'
const mocks = [ const mocks = [
...user, ...user,

View File

@ -3,16 +3,16 @@ const bodyParser = require('body-parser')
const chalk = require('chalk') const chalk = require('chalk')
function registerRoutes(app) { function registerRoutes(app) {
let mockStartIndex let mockLastIndex
const { default: mocks } = require('./index.js') const { default: mocks } = require('./index.js')
for (const mock of mocks) { for (const mock of mocks) {
app[mock.type](mock.url, mock.response) app[mock.type](mock.url, mock.response)
mockStartIndex = app._router.stack.length mockLastIndex = app._router.stack.length
} }
const mockRoutesLength = Object.keys(mocks).length const mockRoutesLength = Object.keys(mocks).length
return { return {
mockRoutesLength: mockRoutesLength, mockRoutesLength: mockRoutesLength,
mockStartIndex: mockStartIndex - mockRoutesLength mockStartIndex: mockLastIndex - mockRoutesLength
} }
} }
@ -29,7 +29,7 @@ module.exports = app => {
require('@babel/register') require('@babel/register')
// parse app.body // parse app.body
// http://expressjs.com/en/4x/api.html#req.body // https://expressjs.com/en/4x/api.html#req.body
app.use(bodyParser.json()) app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ app.use(bodyParser.urlencoded({
extended: true extended: true

View File

@ -19,17 +19,17 @@ export const constantRoutes = [
}, },
{ {
path: '/auth-redirect', path: '/auth-redirect',
component: 'views/login/authRedirect', component: 'views/login/auth-redirect',
hidden: true hidden: true
}, },
{ {
path: '/404', path: '/404',
component: 'views/errorPage/404', component: 'views/error-page/404',
hidden: true hidden: true
}, },
{ {
path: '/401', path: '/401',
component: 'views/errorPage/401', component: 'views/error-page/401',
hidden: true hidden: true
}, },
{ {
@ -129,7 +129,7 @@ export const asyncRoutes = [
{ {
path: '/components', path: '/components',
component: 'layout/Layout', component: 'layout/Layout',
redirect: 'noredirect', redirect: 'noRedirect',
name: 'ComponentDemo', name: 'ComponentDemo',
meta: { meta: {
title: 'components', title: 'components',
@ -150,19 +150,19 @@ export const asyncRoutes = [
}, },
{ {
path: 'json-editor', path: 'json-editor',
component: 'views/components-demo/jsonEditor', component: 'views/components-demo/json-editor',
name: 'JsonEditorDemo', name: 'JsonEditorDemo',
meta: { title: 'jsonEditor' } meta: { title: 'jsonEditor' }
}, },
{ {
path: 'splitpane', path: 'split-pane',
component: 'views/components-demo/splitpane', component: 'views/components-demo/split-pane',
name: 'SplitpaneDemo', name: 'SplitpaneDemo',
meta: { title: 'splitPane' } meta: { title: 'splitPane' }
}, },
{ {
path: 'avatar-upload', path: 'avatar-upload',
component: 'views/components-demo/avatarUpload', component: 'views/components-demo/avatar-upload',
name: 'AvatarUploadDemo', name: 'AvatarUploadDemo',
meta: { title: 'avatarUpload' } meta: { title: 'avatarUpload' }
}, },
@ -180,7 +180,7 @@ export const asyncRoutes = [
}, },
{ {
path: 'count-to', path: 'count-to',
component: 'views/components-demo/countTo', component: 'views/components-demo/count-to',
name: 'CountToDemo', name: 'CountToDemo',
meta: { title: 'countTo' } meta: { title: 'countTo' }
}, },
@ -192,31 +192,31 @@ export const asyncRoutes = [
}, },
{ {
path: 'back-to-top', path: 'back-to-top',
component: 'views/components-demo/backToTop', component: 'views/components-demo/back-to-top',
name: 'BackToTopDemo', name: 'BackToTopDemo',
meta: { title: 'backToTop' } meta: { title: 'backToTop' }
}, },
{ {
path: 'drag-dialog', path: 'drag-dialog',
component: 'views/components-demo/dragDialog', component: 'views/components-demo/drag-dialog',
name: 'DragDialogDemo', name: 'DragDialogDemo',
meta: { title: 'dragDialog' } meta: { title: 'dragDialog' }
}, },
{ {
path: 'drag-select', path: 'drag-select',
component: 'views/components-demo/dragSelect', component: 'views/components-demo/drag-select',
name: 'DragSelectDemo', name: 'DragSelectDemo',
meta: { title: 'dragSelect' } meta: { title: 'dragSelect' }
}, },
{ {
path: 'dnd-list', path: 'dnd-list',
component: 'views/components-demo/dndList', component: 'views/components-demo/dnd-list',
name: 'DndListDemo', name: 'DndListDemo',
meta: { title: 'dndList' } meta: { title: 'dndList' }
}, },
{ {
path: 'drag-kanban', path: 'drag-kanban',
component: 'views/components-demo/dragKanban', component: 'views/components-demo/drag-kanban',
name: 'DragKanbanDemo', name: 'DragKanbanDemo',
meta: { title: 'dragKanban' } meta: { title: 'dragKanban' }
} }
@ -225,7 +225,7 @@ export const asyncRoutes = [
{ {
path: '/charts', path: '/charts',
component: 'layout/Layout', component: 'layout/Layout',
redirect: 'noredirect', redirect: 'noRedirect',
name: 'Charts', name: 'Charts',
meta: { meta: {
title: 'charts', title: 'charts',
@ -361,7 +361,7 @@ export const asyncRoutes = [
{ {
path: '/error', path: '/error',
component: 'layout/Layout', component: 'layout/Layout',
redirect: 'noredirect', redirect: 'noRedirect',
name: 'ErrorPages', name: 'ErrorPages',
meta: { meta: {
title: 'errorPages', title: 'errorPages',
@ -370,13 +370,13 @@ export const asyncRoutes = [
children: [ children: [
{ {
path: '401', path: '401',
component: 'views/errorPage/401', component: 'views/error-page/401',
name: 'Page401', name: 'Page401',
meta: { title: 'page401', noCache: true } meta: { title: 'page401', noCache: true }
}, },
{ {
path: '404', path: '404',
component: 'views/errorPage/404', component: 'views/error-page/404',
name: 'Page404', name: 'Page404',
meta: { title: 'page404', noCache: true } meta: { title: 'page404', noCache: true }
} }
@ -386,11 +386,11 @@ export const asyncRoutes = [
{ {
path: '/error-log', path: '/error-log',
component: 'layout/Layout', component: 'layout/Layout',
redirect: 'noredirect', redirect: 'noRedirect',
children: [ children: [
{ {
path: 'log', path: 'log',
component: 'views/errorLog/index', component: 'views/error-log/index',
name: 'ErrorLog', name: 'ErrorLog',
meta: { title: 'errorLog', icon: 'bug' } meta: { title: 'errorLog', icon: 'bug' }
} }
@ -409,25 +409,25 @@ export const asyncRoutes = [
children: [ children: [
{ {
path: 'export-excel', path: 'export-excel',
component: 'views/excel/exportExcel', component: 'views/excel/export-excel',
name: 'ExportExcel', name: 'ExportExcel',
meta: { title: 'exportExcel' } meta: { title: 'exportExcel' }
}, },
{ {
path: 'export-selected-excel', path: 'export-selected-excel',
component: 'views/excel/selectExcel', component: 'views/excel/select-excel',
name: 'SelectExcel', name: 'SelectExcel',
meta: { title: 'selectExcel' } meta: { title: 'selectExcel' }
}, },
{ {
path: 'export-merge-header', path: 'export-merge-header',
component: 'views/excel/mergeHeader', component: 'views/excel/merge-header',
name: 'MergeHeader', name: 'MergeHeader',
meta: { title: 'mergeHeader' } meta: { title: 'mergeHeader' }
}, },
{ {
path: 'upload-excel', path: 'upload-excel',
component: 'views/excel/uploadExcel', component: 'views/excel/upload-excel',
name: 'UploadExcel', name: 'UploadExcel',
meta: { title: 'uploadExcel' } meta: { title: 'uploadExcel' }
} }
@ -472,7 +472,7 @@ export const asyncRoutes = [
{ {
path: '/theme', path: '/theme',
component: 'layout/Layout', component: 'layout/Layout',
redirect: 'noredirect', redirect: 'noRedirect',
children: [ children: [
{ {
path: 'index', path: 'index',
@ -486,7 +486,7 @@ export const asyncRoutes = [
{ {
path: '/clipboard', path: '/clipboard',
component: 'layout/Layout', component: 'layout/Layout',
redirect: 'noredirect', redirect: 'noRedirect',
children: [ children: [
{ {
path: 'index', path: 'index',

View File

@ -1,6 +1,6 @@
{ {
"name": "vue-element-admin", "name": "vue-element-admin",
"version": "4.0.0", "version": "4.0.1",
"description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features", "description": "A magical vue admin. An out-of-box UI solution for enterprise applications. Newest development stack of vue. Lots of awesome features",
"author": "Pan <panfree23@gmail.com>", "author": "Pan <panfree23@gmail.com>",
"license": "MIT", "license": "MIT",

View File

@ -1,12 +1,7 @@
<template> <template>
<transition :name="transitionName"> <transition :name="transitionName">
<div v-show="visible" :style="customStyle" class="back-to-ceiling" @click="backToTop"> <div v-show="visible" :style="customStyle" class="back-to-ceiling" @click="backToTop">
<svg width="16" height="16" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg" class="Icon Icon--backToTopArrow" aria-hidden="true" style="height: 16px; width: 16px;"> <svg width="16" height="16" viewBox="0 0 17 17" xmlns="http://www.w3.org/2000/svg" class="Icon Icon--backToTopArrow" aria-hidden="true" style="height:16px;width:16px"><path d="M12.036 15.59a1 1 0 0 1-.997.995H5.032a.996.996 0 0 1-.997-.996V8.584H1.03c-1.1 0-1.36-.633-.578-1.416L7.33.29a1.003 1.003 0 0 1 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.004z" /></svg>
<title>回到顶部</title>
<g>
<path d="M12.036 15.59c0 .55-.453.995-.997.995H5.032c-.55 0-.997-.445-.997-.996V8.584H1.03c-1.1 0-1.36-.633-.578-1.416L7.33.29c.39-.39 1.026-.385 1.412 0l6.878 6.88c.782.78.523 1.415-.58 1.415h-3.004v7.004z" fill-rule="evenodd" />
</g>
</svg>
</div> </div>
</transition> </transition>
</template> </template>

View File

@ -2,7 +2,7 @@
<el-breadcrumb class="app-breadcrumb" separator="/"> <el-breadcrumb class="app-breadcrumb" separator="/">
<transition-group name="breadcrumb"> <transition-group name="breadcrumb">
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path"> <el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
<span v-if="item.redirect==='noredirect'||index==levelList.length-1" class="no-redirect">{{ <span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{
generateTitle(item.meta.title) }}</span> generateTitle(item.meta.title) }}</span>
<a v-else @click.prevent="handleLink(item)">{{ generateTitle(item.meta.title) }}</a> <a v-else @click.prevent="handleLink(item)">{{ generateTitle(item.meta.title) }}</a>
</el-breadcrumb-item> </el-breadcrumb-item>
@ -31,15 +31,23 @@ export default {
methods: { methods: {
generateTitle, generateTitle,
getBreadcrumb() { getBreadcrumb() {
let matched = this.$route.matched.filter(item => item.name) // only show routes with meta.title
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
const first = matched[0] const first = matched[0]
if (first && first.name.trim().toLocaleLowerCase() !== 'Dashboard'.toLocaleLowerCase()) {
if (!this.isDashboard(first)) {
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched) matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
} }
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false) this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
}, },
isDashboard(route) {
const name = route && route.name
if (!name) {
return false
}
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
},
pathCompile(path) { pathCompile(path) {
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561 // To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
const { params } = this.$route const { params } = this.$route

View File

@ -0,0 +1,155 @@
<template>
<div :id="id" :class="className" :style="{height:height,width:width}" />
</template>
<script>
import echarts from 'echarts'
import resize from './mixins/resize'
export default {
mixins: [resize],
props: {
className: {
type: String,
default: 'chart'
},
id: {
type: String,
default: 'chart'
},
width: {
type: String,
default: '200px'
},
height: {
type: String,
default: '200px'
}
},
data() {
return {
chart: null
}
},
mounted() {
this.initChart()
},
beforeDestroy() {
if (!this.chart) {
return
}
this.chart.dispose()
this.chart = null
},
methods: {
initChart() {
this.chart = echarts.init(document.getElementById(this.id))
const xAxisData = []
const data = []
const data2 = []
for (let i = 0; i < 50; i++) {
xAxisData.push(i)
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
}
this.chart.setOption({
backgroundColor: '#08263a',
grid: {
left: '5%',
right: '5%'
},
xAxis: [{
show: false,
data: xAxisData
}, {
show: false,
data: xAxisData
}],
visualMap: {
show: false,
min: 0,
max: 50,
dimension: 0,
inRange: {
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
}
},
yAxis: {
axisLine: {
show: false
},
axisLabel: {
textStyle: {
color: '#4a657a'
}
},
splitLine: {
show: true,
lineStyle: {
color: '#08263f'
}
},
axisTick: {
show: false
}
},
series: [{
name: 'back',
type: 'bar',
data: data2,
z: 1,
itemStyle: {
normal: {
opacity: 0.4,
barBorderRadius: 5,
shadowBlur: 3,
shadowColor: '#111'
}
}
}, {
name: 'Simulate Shadow',
type: 'line',
data,
z: 2,
showSymbol: false,
animationDelay: 0,
animationEasing: 'linear',
animationDuration: 1200,
lineStyle: {
normal: {
color: 'transparent'
}
},
areaStyle: {
normal: {
color: '#08263a',
shadowBlur: 50,
shadowColor: '#000'
}
}
}, {
name: 'front',
type: 'bar',
data,
xAxisIndex: 1,
z: 3,
itemStyle: {
normal: {
barBorderRadius: 5
}
}
}],
animationEasing: 'elasticOut',
animationEasingUpdate: 'elasticOut',
animationDelay(idx) {
return idx * 20
},
animationDelayUpdate(idx) {
return idx * 20
}
})
}
}
}
</script>

View File

@ -53,8 +53,7 @@ export default {
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5) data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3) data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
} }
this.chart.setOption( this.chart.setOption({
{
backgroundColor: '#08263a', backgroundColor: '#08263a',
grid: { grid: {
left: '5%', left: '5%',

View File

@ -3,7 +3,7 @@ import { debounce } from '@/utils'
export default { export default {
data() { data() {
return { return {
sidebarElm: null $_sidebarElm: null
} }
}, },
mounted() { mounted() {
@ -14,16 +14,18 @@ export default {
}, 100) }, 100)
window.addEventListener('resize', this.__resizeHandler) window.addEventListener('resize', this.__resizeHandler)
this.sidebarElm = document.getElementsByClassName('sidebar-container')[0] this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler) this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
}, },
beforeDestroy() { beforeDestroy() {
window.removeEventListener('resize', this.__resizeHandler) window.removeEventListener('resize', this.__resizeHandler)
this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler) this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
}, },
methods: { methods: {
sidebarResizeHandler(e) { // use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') { if (e.propertyName === 'width') {
this.__resizeHandler() this.__resizeHandler()
} }

View File

@ -121,7 +121,7 @@ export default {
data.title = [...data.title, i18ntitle] data.title = [...data.title, i18ntitle]
if (router.redirect !== 'noredirect') { if (router.redirect !== 'noRedirect') {
// only push the routes with title // only push the routes with title
// special case: need to exclude parent router without redirect // special case: need to exclude parent router without redirect
res.push(data) res.push(data)

View File

@ -25,8 +25,8 @@ export default {
}, },
watch: { watch: {
value(value) { value(value) {
const editor_value = this.jsonEditor.getValue() const editorValue = this.jsonEditor.getValue()
if (value !== editor_value) { if (value !== editorValue) {
this.jsonEditor.setValue(JSON.stringify(this.value, null, 2)) this.jsonEditor.setValue(JSON.stringify(this.value, null, 2))
} }
} }

View File

@ -15,6 +15,7 @@
</draggable> </draggable>
</div> </div>
</template> </template>
<script> <script>
import draggable from 'vuedraggable' import draggable from 'vuedraggable'

View File

@ -9,7 +9,7 @@ import 'tui-editor/dist/tui-editor.css' // editor ui
import 'tui-editor/dist/tui-editor-contents.css' // editor content import 'tui-editor/dist/tui-editor-contents.css' // editor content
import Editor from 'tui-editor' import Editor from 'tui-editor'
import defaultOptions from './defaultOptions' import defaultOptions from './default-options'
export default { export default {
name: 'MarddownEditor', name: 'MarddownEditor',

View File

@ -15,7 +15,7 @@
</template> </template>
<script> <script>
import { scrollTo } from '@/utils/scrollTo' import { scrollTo } from '@/utils/scroll-to'
export default { export default {
name: 'Pagination', name: 'Pagination',

View File

@ -8,19 +8,28 @@
</template> </template>
<script> <script>
const version = require('element-ui/package.json').version // element-ui version from node_modules const version = require('element-ui/package.json').version // element-ui version from node_modules
const ORIGINAL_THEME = '#409EFF' // default color const ORIGINAL_THEME = '#409EFF' // default color
import defaultSettings from '@/settings'
export default { export default {
data() { data() {
return { return {
chalk: '', // content of theme-chalk css chalk: '', // content of theme-chalk css
theme: defaultSettings.theme theme: ''
}
},
computed: {
defaultTheme() {
return this.$store.state.settings.theme
} }
}, },
watch: { watch: {
defaultTheme: {
handler: function(val, oldVal) {
this.theme = val
},
immediate: true
},
async theme(val) { async theme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return if (typeof val !== 'string') return

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="upload-container"> <div class="upload-container">
<el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true"> <el-button :style="{background:color,borderColor:color}" icon="el-icon-upload" size="mini" type="primary" @click=" dialogVisible=true">
上传图片 upload
</el-button> </el-button>
<el-dialog :visible.sync="dialogVisible"> <el-dialog :visible.sync="dialogVisible">
<el-upload <el-upload
@ -16,14 +16,14 @@
list-type="picture-card" list-type="picture-card"
> >
<el-button size="small" type="primary"> <el-button size="small" type="primary">
点击上传 Click upload
</el-button> </el-button>
</el-upload> </el-upload>
<el-button @click="dialogVisible = false"> <el-button @click="dialogVisible = false">
Cancel
</el-button> </el-button>
<el-button type="primary" @click="handleSubmit"> <el-button type="primary" @click="handleSubmit">
Confirm
</el-button> </el-button>
</el-dialog> </el-dialog>
</div> </div>
@ -54,7 +54,7 @@ export default {
handleSubmit() { handleSubmit() {
const arr = Object.keys(this.listObj).map(v => this.listObj[v]) const arr = Object.keys(this.listObj).map(v => this.listObj[v])
if (!this.checkAllSuccess()) { if (!this.checkAllSuccess()) {
this.$message('请等待所有图片上传成功 或 出现了网络问题,请刷新页面重新上传!') this.$message('Please wait for all images to be uploaded successfully. If there is a network problem, please refresh the page and upload again!')
return return
} }
this.$emit('successCBK', arr) this.$emit('successCBK', arr)

View File

@ -8,7 +8,7 @@
</template> </template>
<script> <script>
import editorImage from './components/editorImage' import editorImage from './components/EditorImage'
import plugins from './plugins' import plugins from './plugins'
import toolbar from './toolbar' import toolbar from './toolbar'

View File

@ -26,7 +26,6 @@
</template> </template>
<script> <script>
//
import { getToken } from '@/api/qiniu' import { getToken } from '@/api/qiniu'
export default { export default {

View File

@ -1,4 +1,3 @@
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event' import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event'
/** /**
@ -30,13 +29,13 @@ export default {
el.resizeListener = () => { el.resizeListener = () => {
doResize(el, binding, vnode) doResize(el, binding, vnode)
} }
// parameter 1 is must be "Element" type
addResizeListener(el, el.resizeListener) addResizeListener(window.document.body, el.resizeListener)
}, },
inserted(el, binding, vnode) { inserted(el, binding, vnode) {
doResize(el, binding, vnode) doResize(el, binding, vnode)
}, },
unbind(el) { unbind(el) {
removeResizeListener(el, el.resizeListener) removeResizeListener(window.document.body, el.resizeListener)
} }
} }

View File

@ -1,4 +1,3 @@
import adaptive from './adaptive' import adaptive from './adaptive'
const install = function(Vue) { const install = function(Vue) {

View File

@ -1,4 +1,3 @@
import store from '@/store' import store from '@/store'
export default { export default {

View File

@ -1,6 +1,12 @@
// set function parseTime,formatTime to filter // import parseTime, formatTime and set to filter
export { parseTime, formatTime } from '@/utils' export { parseTime, formatTime } from '@/utils'
/**
* Show plural label if time is plural number
* @param {number} time
* @param {string} label
* @return {string}
*/
function pluralize(time, label) { function pluralize(time, label) {
if (time === 1) { if (time === 1) {
return time + label return time + label
@ -8,6 +14,9 @@ function pluralize(time, label) {
return time + label + 's' return time + label + 's'
} }
/**
* @param {number} time
*/
export function timeAgo(time) { export function timeAgo(time) {
const between = Date.now() / 1000 - Number(time) const between = Date.now() / 1000 - Number(time)
if (between < 3600) { if (between < 3600) {
@ -19,7 +28,12 @@ export function timeAgo(time) {
} }
} }
/* 数字 格式化*/ /**
* Number formatting
* like 10000 => 10k
* @param {number} num
* @param {number} digits
*/
export function numberFormatter(num, digits) { export function numberFormatter(num, digits) {
const si = [ const si = [
{ value: 1E18, symbol: 'E' }, { value: 1E18, symbol: 'E' },
@ -37,6 +51,10 @@ export function numberFormatter(num, digits) {
return num.toString() return num.toString()
} }
/**
* 10000 => "10,000"
* @param {number} num
*/
export function toThousandFilter(num) { export function toThousandFilter(num) {
return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ',')) return (+num || 0).toString().replace(/^-?\d+/g, m => m.replace(/(?=(?!\b)(\d{3})+$)/g, ','))
} }

View File

@ -133,6 +133,9 @@ export default {
cancel: 'Cancel', cancel: 'Cancel',
confirm: 'Confirm' confirm: 'Confirm'
}, },
example: {
warning: 'Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all pages directly. See details'
},
errorLog: { errorLog: {
tips: 'Please click the bug icon in the upper right corner', tips: 'Please click the bug icon in the upper right corner',
description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.', description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',

View File

@ -133,6 +133,9 @@ export default {
cancel: 'Cancelar', cancel: 'Cancelar',
confirm: 'Confirmar' confirm: 'Confirmar'
}, },
example: {
warning: 'Creating and editing pages cannot be cached by keep-alive because keep-alive include does not currently support caching based on routes, so it is currently cached based on component name. If you want to achieve a similar caching effect, you can use a browser caching scheme such as localStorage. Or do not use keep-alive include to cache all pages directly. See details'
},
errorLog: { errorLog: {
tips: 'Please click the bug icon in the upper right corner', tips: 'Please click the bug icon in the upper right corner',
description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.', description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',

View File

@ -133,6 +133,9 @@ export default {
cancel: '取 消', cancel: '取 消',
confirm: '确 定' confirm: '确 定'
}, },
example: {
warning: '创建和编辑页面是不能被 keep-alive 缓存的因为keep-alive 的 include 目前不支持根据路由来缓存,所以目前都是基于 component name 来进行缓存的。如果你想类似的实现缓存效果,可以使用 localStorage 等浏览器缓存方案。或者不要使用 keep-alive 的 include直接缓存所有页面。详情见'
},
errorLog: { errorLog: {
tips: '请点击右上角bug小图标', tips: '请点击右上角bug小图标',
description: '现在的管理后台基本都是spa的形式了它增强了用户体验但同时也会增加页面出问题的可能性可能一个小小的疏忽就导致整个页面的死锁。好在 Vue 官网提供了一个方法来捕获处理异常,你可以在其中进行错误处理或者异常上报。', description: '现在的管理后台基本都是spa的形式了它增强了用户体验但同时也会增加页面出问题的可能性可能一个小小的疏忽就导致整个页面的死锁。好在 Vue 官网提供了一个方法来捕获处理异常,你可以在其中进行错误处理或者异常上报。',

View File

@ -1,5 +1,5 @@
export { default as AppMain } from './AppMain'
export { default as Navbar } from './Navbar' export { default as Navbar } from './Navbar'
export { default as Settings } from './Settings'
export { default as Sidebar } from './Sidebar/index.vue' export { default as Sidebar } from './Sidebar/index.vue'
export { default as TagsView } from './TagsView/index.vue' export { default as TagsView } from './TagsView/index.vue'
export { default as AppMain } from './AppMain'
export { default as Settings } from './Settings'

View File

@ -18,7 +18,7 @@
<script> <script>
import RightPanel from '@/components/RightPanel' import RightPanel from '@/components/RightPanel'
import { Navbar, Sidebar, AppMain, TagsView, Settings } from './components' import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
import ResizeMixin from './mixin/ResizeHandler' import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex' import { mapState } from 'vuex'
import AD from '@/components/AD' import AD from '@/components/AD'
@ -26,13 +26,13 @@ import AD from '@/components/AD'
export default { export default {
name: 'Layout', name: 'Layout',
components: { components: {
RightPanel, AD,
Navbar,
Sidebar,
AppMain, AppMain,
TagsView, Navbar,
RightPanel,
Settings, Settings,
AD Sidebar,
TagsView
}, },
mixins: [ResizeMixin], mixins: [ResizeMixin],
computed: { computed: {

View File

@ -12,26 +12,28 @@ export default {
} }
}, },
beforeMount() { beforeMount() {
window.addEventListener('resize', this.resizeHandler) window.addEventListener('resize', this.$_resizeHandler)
}, },
beforeDestroy() { beforeDestroy() {
window.removeEventListener('resize', this.resizeHandler) window.removeEventListener('resize', this.$_resizeHandler)
}, },
mounted() { mounted() {
const isMobile = this.isMobile() const isMobile = this.$_isMobile()
if (isMobile) { if (isMobile) {
store.dispatch('app/toggleDevice', 'mobile') store.dispatch('app/toggleDevice', 'mobile')
store.dispatch('app/closeSideBar', { withoutAnimation: true }) store.dispatch('app/closeSideBar', { withoutAnimation: true })
} }
}, },
methods: { methods: {
isMobile() { // use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_isMobile() {
const rect = body.getBoundingClientRect() const rect = body.getBoundingClientRect()
return rect.width - 1 < WIDTH return rect.width - 1 < WIDTH
}, },
resizeHandler() { $_resizeHandler() {
if (!document.hidden) { if (!document.hidden) {
const isMobile = this.isMobile() const isMobile = this.$_isMobile()
store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop')
if (isMobile) { if (isMobile) {

View File

@ -2,7 +2,7 @@ import Vue from 'vue'
import Cookies from 'js-cookie' import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // A modern alternative to CSS resets import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui' import Element from 'element-ui'
import './styles/element-variables.scss' import './styles/element-variables.scss'
@ -13,10 +13,10 @@ import App from './App'
import store from './store' import store from './store'
import router from './router' import router from './router'
import i18n from './lang' // Internationalization import i18n from './lang' // internationalization
import './icons' // icon import './icons' // icon
import './permission' // permission control import './permission' // permission control
import './utils/errorLog' // error log import './utils/error-log' // error log
import * as filters from './filters' // global filters import * as filters from './filters' // global filters
@ -36,7 +36,7 @@ Vue.use(Element, {
i18n: (key, value) => i18n.t(key, value) i18n: (key, value) => i18n.t(key, value)
}) })
// register global utility filters. // register global utility filters
Object.keys(filters).forEach(key => { Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key]) Vue.filter(key, filters[key])
}) })

View File

@ -4,6 +4,7 @@ import { Message } from 'element-ui'
import NProgress from 'nprogress' // progress bar import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration NProgress.configure({ showSpinner: false }) // NProgress Configuration
@ -13,6 +14,9 @@ router.beforeEach(async(to, from, next) => {
// start progress bar // start progress bar
NProgress.start() NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
// determine whether the user has logged in // determine whether the user has logged in
const hasToken = getToken() const hasToken = getToken()

View File

@ -20,7 +20,7 @@ import nestedRouter from './modules/nested'
* alwaysShow: true if set true, will always show the root menu * alwaysShow: true if set true, will always show the root menu
* if not set alwaysShow, when item has more than one children route, * if not set alwaysShow, when item has more than one children route,
* it will becomes nested mode, otherwise not show the root menu * it will becomes nested mode, otherwise not show the root menu
* redirect: noredirect if `redirect:noredirect` will no redirect in the breadcrumb * redirect: noRedirect if set noRedirect will no redirect in the breadcrumb
* name:'router-name' the name is used by <keep-alive> (must set!!!) * name:'router-name' the name is used by <keep-alive> (must set!!!)
* meta : { * meta : {
roles: ['admin','editor'] control the page roles (you can set multiple roles) roles: ['admin','editor'] control the page roles (you can set multiple roles)
@ -57,17 +57,17 @@ export const constantRoutes = [
}, },
{ {
path: '/auth-redirect', path: '/auth-redirect',
component: () => import('@/views/login/authRedirect'), component: () => import('@/views/login/auth-redirect'),
hidden: true hidden: true
}, },
{ {
path: '/404', path: '/404',
component: () => import('@/views/errorPage/404'), component: () => import('@/views/error-page/404'),
hidden: true hidden: true
}, },
{ {
path: '/401', path: '/401',
component: () => import('@/views/errorPage/401'), component: () => import('@/views/error-page/401'),
hidden: true hidden: true
}, },
{ {
@ -118,8 +118,9 @@ export const asyncRoutes = [
{ {
path: '/permission', path: '/permission',
component: Layout, component: Layout,
redirect: '/permission/index', redirect: '/permission/page',
alwaysShow: true, // will always show the root menu alwaysShow: true, // will always show the root menu
name: 'Permission',
meta: { meta: {
title: 'permission', title: 'permission',
icon: 'lock', icon: 'lock',
@ -223,7 +224,7 @@ export const asyncRoutes = [
{ {
path: '/error', path: '/error',
component: Layout, component: Layout,
redirect: 'noredirect', redirect: 'noRedirect',
name: 'ErrorPages', name: 'ErrorPages',
meta: { meta: {
title: 'errorPages', title: 'errorPages',
@ -232,13 +233,13 @@ export const asyncRoutes = [
children: [ children: [
{ {
path: '401', path: '401',
component: () => import('@/views/errorPage/401'), component: () => import('@/views/error-page/401'),
name: 'Page401', name: 'Page401',
meta: { title: 'page401', noCache: true } meta: { title: 'page401', noCache: true }
}, },
{ {
path: '404', path: '404',
component: () => import('@/views/errorPage/404'), component: () => import('@/views/error-page/404'),
name: 'Page404', name: 'Page404',
meta: { title: 'page404', noCache: true } meta: { title: 'page404', noCache: true }
} }
@ -248,11 +249,10 @@ export const asyncRoutes = [
{ {
path: '/error-log', path: '/error-log',
component: Layout, component: Layout,
redirect: 'noredirect',
children: [ children: [
{ {
path: 'log', path: 'log',
component: () => import('@/views/errorLog/index'), component: () => import('@/views/error-log/index'),
name: 'ErrorLog', name: 'ErrorLog',
meta: { title: 'errorLog', icon: 'bug' } meta: { title: 'errorLog', icon: 'bug' }
} }
@ -271,25 +271,25 @@ export const asyncRoutes = [
children: [ children: [
{ {
path: 'export-excel', path: 'export-excel',
component: () => import('@/views/excel/exportExcel'), component: () => import('@/views/excel/export-excel'),
name: 'ExportExcel', name: 'ExportExcel',
meta: { title: 'exportExcel' } meta: { title: 'exportExcel' }
}, },
{ {
path: 'export-selected-excel', path: 'export-selected-excel',
component: () => import('@/views/excel/selectExcel'), component: () => import('@/views/excel/select-excel'),
name: 'SelectExcel', name: 'SelectExcel',
meta: { title: 'selectExcel' } meta: { title: 'selectExcel' }
}, },
{ {
path: 'export-merge-header', path: 'export-merge-header',
component: () => import('@/views/excel/mergeHeader'), component: () => import('@/views/excel/merge-header'),
name: 'MergeHeader', name: 'MergeHeader',
meta: { title: 'mergeHeader' } meta: { title: 'mergeHeader' }
}, },
{ {
path: 'upload-excel', path: 'upload-excel',
component: () => import('@/views/excel/uploadExcel'), component: () => import('@/views/excel/upload-excel'),
name: 'UploadExcel', name: 'UploadExcel',
meta: { title: 'uploadExcel' } meta: { title: 'uploadExcel' }
} }
@ -301,6 +301,7 @@ export const asyncRoutes = [
component: Layout, component: Layout,
redirect: '/zip/download', redirect: '/zip/download',
alwaysShow: true, alwaysShow: true,
name: 'Zip',
meta: { title: 'zip', icon: 'zip' }, meta: { title: 'zip', icon: 'zip' },
children: [ children: [
{ {
@ -334,7 +335,6 @@ export const asyncRoutes = [
{ {
path: '/theme', path: '/theme',
component: Layout, component: Layout,
redirect: 'noredirect',
children: [ children: [
{ {
path: 'index', path: 'index',
@ -348,7 +348,6 @@ export const asyncRoutes = [
{ {
path: '/clipboard', path: '/clipboard',
component: Layout, component: Layout,
redirect: 'noredirect',
children: [ children: [
{ {
path: 'index', path: 'index',

View File

@ -5,7 +5,7 @@ import Layout from '@/layout'
const chartsRouter = { const chartsRouter = {
path: '/charts', path: '/charts',
component: Layout, component: Layout,
redirect: 'noredirect', redirect: 'noRedirect',
name: 'Charts', name: 'Charts',
meta: { meta: {
title: 'charts', title: 'charts',
@ -25,8 +25,8 @@ const chartsRouter = {
meta: { title: 'lineChart', noCache: true } meta: { title: 'lineChart', noCache: true }
}, },
{ {
path: 'mixchart', path: 'mix-chart',
component: () => import('@/views/charts/mixChart'), component: () => import('@/views/charts/mix-chart'),
name: 'MixChart', name: 'MixChart',
meta: { title: 'mixChart', noCache: true } meta: { title: 'mixChart', noCache: true }
} }

View File

@ -5,7 +5,7 @@ import Layout from '@/layout'
const componentsRouter = { const componentsRouter = {
path: '/components', path: '/components',
component: Layout, component: Layout,
redirect: 'noredirect', redirect: 'noRedirect',
name: 'ComponentDemo', name: 'ComponentDemo',
meta: { meta: {
title: 'components', title: 'components',
@ -26,19 +26,19 @@ const componentsRouter = {
}, },
{ {
path: 'json-editor', path: 'json-editor',
component: () => import('@/views/components-demo/jsonEditor'), component: () => import('@/views/components-demo/json-editor'),
name: 'JsonEditorDemo', name: 'JsonEditorDemo',
meta: { title: 'jsonEditor' } meta: { title: 'jsonEditor' }
}, },
{ {
path: 'splitpane', path: 'split-pane',
component: () => import('@/views/components-demo/splitpane'), component: () => import('@/views/components-demo/split-pane'),
name: 'SplitpaneDemo', name: 'SplitpaneDemo',
meta: { title: 'splitPane' } meta: { title: 'splitPane' }
}, },
{ {
path: 'avatar-upload', path: 'avatar-upload',
component: () => import('@/views/components-demo/avatarUpload'), component: () => import('@/views/components-demo/avatar-upload'),
name: 'AvatarUploadDemo', name: 'AvatarUploadDemo',
meta: { title: 'avatarUpload' } meta: { title: 'avatarUpload' }
}, },
@ -56,7 +56,7 @@ const componentsRouter = {
}, },
{ {
path: 'count-to', path: 'count-to',
component: () => import('@/views/components-demo/countTo'), component: () => import('@/views/components-demo/count-to'),
name: 'CountToDemo', name: 'CountToDemo',
meta: { title: 'countTo' } meta: { title: 'countTo' }
}, },
@ -68,31 +68,31 @@ const componentsRouter = {
}, },
{ {
path: 'back-to-top', path: 'back-to-top',
component: () => import('@/views/components-demo/backToTop'), component: () => import('@/views/components-demo/back-to-top'),
name: 'BackToTopDemo', name: 'BackToTopDemo',
meta: { title: 'backToTop' } meta: { title: 'backToTop' }
}, },
{ {
path: 'drag-dialog', path: 'drag-dialog',
component: () => import('@/views/components-demo/dragDialog'), component: () => import('@/views/components-demo/drag-dialog'),
name: 'DragDialogDemo', name: 'DragDialogDemo',
meta: { title: 'dragDialog' } meta: { title: 'dragDialog' }
}, },
{ {
path: 'drag-select', path: 'drag-select',
component: () => import('@/views/components-demo/dragSelect'), component: () => import('@/views/components-demo/drag-select'),
name: 'DragSelectDemo', name: 'DragSelectDemo',
meta: { title: 'dragSelect' } meta: { title: 'dragSelect' }
}, },
{ {
path: 'dnd-list', path: 'dnd-list',
component: () => import('@/views/components-demo/dndList'), component: () => import('@/views/components-demo/dnd-list'),
name: 'DndListDemo', name: 'DndListDemo',
meta: { title: 'dndList' } meta: { title: 'dndList' }
}, },
{ {
path: 'drag-kanban', path: 'drag-kanban',
component: () => import('@/views/components-demo/dragKanban'), component: () => import('@/views/components-demo/drag-kanban'),
name: 'DragKanbanDemo', name: 'DragKanbanDemo',
meta: { title: 'dragKanban' } meta: { title: 'dragKanban' }
} }

View File

@ -14,25 +14,25 @@ const tableRouter = {
children: [ children: [
{ {
path: 'dynamic-table', path: 'dynamic-table',
component: () => import('@/views/table/dynamicTable/index'), component: () => import('@/views/table/dynamic-table/index'),
name: 'DynamicTable', name: 'DynamicTable',
meta: { title: 'dynamicTable' } meta: { title: 'dynamicTable' }
}, },
{ {
path: 'drag-table', path: 'drag-table',
component: () => import('@/views/table/dragTable'), component: () => import('@/views/table/drag-table'),
name: 'DragTable', name: 'DragTable',
meta: { title: 'dragTable' } meta: { title: 'dragTable' }
}, },
{ {
path: 'inline-edit-table', path: 'inline-edit-table',
component: () => import('@/views/table/inlineEditTable'), component: () => import('@/views/table/inline-edit-table'),
name: 'InlineEditTable', name: 'InlineEditTable',
meta: { title: 'inlineEditTable' } meta: { title: 'inlineEditTable' }
}, },
{ {
path: 'complex-table', path: 'complex-table',
component: () => import('@/views/table/complexTable'), component: () => import('@/views/table/complex-table'),
name: 'ComplexTable', name: 'ComplexTable',
meta: { title: 'complexTable' } meta: { title: 'complexTable' }
} }

View File

@ -1,7 +1,5 @@
import variables from '@/styles/element-variables.scss' module.exports = {
title: 'Vue Element Admin',
export default {
theme: variables.theme,
/** /**
* @type {boolean} true | false * @type {boolean} true | false

View File

@ -1,7 +1,7 @@
import { asyncRoutes, constantRoutes } from '@/router' import { asyncRoutes, constantRoutes } from '@/router'
/** /**
* 通过meta.role判断是否与当前用户权限匹配 * Use meta.role to determine if the current user has permission
* @param roles * @param roles
* @param route * @param route
*/ */
@ -14,7 +14,7 @@ function hasPermission(roles, route) {
} }
/** /**
* 递归过滤异步路由表返回符合用户角色权限的路由表 * Filter asynchronous routing tables by recursion
* @param routes asyncRoutes * @param routes asyncRoutes
* @param roles * @param roles
*/ */

View File

@ -1,8 +1,10 @@
import variables from '@/styles/element-variables.scss'
import defaultSettings from '@/settings' import defaultSettings from '@/settings'
const { showSettings, tagsView, fixedHeader, sidebarLogo, theme } = defaultSettings
const { showSettings, tagsView, fixedHeader, sidebarLogo } = defaultSettings
const state = { const state = {
theme: theme, theme: variables.theme,
showSettings: showSettings, showSettings: showSettings,
tagsView: tagsView, tagsView: tagsView,
fixedHeader: fixedHeader, fixedHeader: fixedHeader,

View File

@ -1,4 +1,4 @@
//覆盖一些element-ui样式 // cover some element-ui styles
.el-breadcrumb__inner, .el-breadcrumb__inner,
.el-breadcrumb__inner a { .el-breadcrumb__inner a {
@ -46,7 +46,7 @@
} }
} }
//暂时性解决dialog 问题 https://github.com/ElemeFE/element/issues/2461 // to fixed https://github.com/ElemeFE/element/issues/2461
.el-dialog { .el-dialog {
transform: none; transform: none;
left: 0; left: 0;
@ -54,18 +54,7 @@
margin: 0 auto; margin: 0 auto;
} }
//文章页textarea修改样式 // refine element ui upload
.article-textarea {
textarea {
padding-right: 40px;
resize: none;
border: none;
border-radius: 0px;
border-bottom: 1px solid #bfcbd9;
}
}
//element ui upload
.upload-container { .upload-container {
.el-upload { .el-upload {
width: 100%; width: 100%;
@ -83,3 +72,8 @@
display: block display: block
} }
} }
// fix date-picker ui bug in filter-item
.el-range-editor.el-input__inner {
display: inline-flex !important;
}

View File

@ -96,14 +96,18 @@ div:focus {
} }
} }
code { aside {
background: #eef1f6; background: #eef1f6;
padding: 15px 16px; padding: 8px 24px;
margin-bottom: 20px; margin-bottom: 20px;
border-radius: 2px;
display: block; display: block;
line-height: 36px; line-height: 32px;
font-size: 15px; font-size: 16px;
font-family: "Source Sans Pro", "Helvetica Neue", Arial, sans-serif; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;
color: #2c3e50;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
a { a {
color: #337ab7; color: #337ab7;
@ -115,20 +119,6 @@ code {
} }
} }
.warn-content {
background: rgba(66, 185, 131, .1);
border-radius: 2px;
padding: 16px;
padding: 1rem;
line-height: 1.6rem;
word-spacing: .05rem;
a {
color: #42b983;
font-weight: 600;
}
}
//main-container全局样式 //main-container全局样式
.app-container { .app-container {
padding: 20px; padding: 20px;

View File

@ -1,6 +1,5 @@
#app { #app {
// 主体区域 Main container
.main-container { .main-container {
min-height: 100%; min-height: 100%;
transition: margin-left .28s; transition: margin-left .28s;
@ -8,7 +7,6 @@
position: relative; position: relative;
} }
// 侧边栏 Sidebar container
.sidebar-container { .sidebar-container {
transition: width 0.28s; transition: width 0.28s;
width: $sideBarWidth !important; width: $sideBarWidth !important;
@ -149,7 +147,7 @@
min-width: $sideBarWidth !important; min-width: $sideBarWidth !important;
} }
// 适配移动端, Mobile responsive // mobile responsive
.mobile { .mobile {
.main-container { .main-container {
margin-left: 0px; margin-left: 0px;

View File

@ -7,7 +7,7 @@ import settings from '@/settings'
// errorLog:'production' | ['production', 'development'] // errorLog:'production' | ['production', 'development']
const { errorLog: needErrorLog } = settings const { errorLog: needErrorLog } = settings
function checkNeed(arg) { function checkNeed() {
const env = process.env.NODE_ENV const env = process.env.NODE_ENV
if (isString(needErrorLog)) { if (isString(needErrorLog)) {
return env === needErrorLog return env === needErrorLog

View File

@ -0,0 +1,13 @@
import defaultSettings from '@/settings'
import i18n from '@/lang'
const title = defaultSettings.title || 'Vue Element Admin'
export default function getPageTitle(key) {
const hasKey = i18n.te(`route.${key}`)
if (hasKey) {
const pageName = i18n.t(`route.${key}`)
return `${pageName} - ${title}`
}
return `${title}`
}

View File

@ -2,6 +2,12 @@
* Created by jiachenpan on 16/11/18. * Created by jiachenpan on 16/11/18.
*/ */
/**
* Parse the time to string
* @param {(Object|string|number)} time
* @param {string} cFormat
* @returns {string}
*/
export function parseTime(time, cFormat) { export function parseTime(time, cFormat) {
if (arguments.length === 0) { if (arguments.length === 0) {
return null return null
@ -40,6 +46,11 @@ export function parseTime(time, cFormat) {
return time_str return time_str
} }
/**
* @param {number} time
* @param {string} option
* @returns {string}
*/
export function formatTime(time, option) { export function formatTime(time, option) {
if (('' + time).length === 10) { if (('' + time).length === 10) {
time = parseInt(time) * 1000 time = parseInt(time) * 1000
@ -78,7 +89,10 @@ export function formatTime(time, option) {
} }
} }
// 格式化时间 /**
* @param {string} url
* @returns {Object}
*/
export function getQueryObject(url) { export function getQueryObject(url) {
url = url == null ? window.location.href : url url = url == null ? window.location.href : url
const search = url.substring(url.lastIndexOf('?') + 1) const search = url.substring(url.lastIndexOf('?') + 1)
@ -95,7 +109,7 @@ export function getQueryObject(url) {
} }
/** /**
* @param {Sting} input value * @param {string} input value
* @returns {number} output value * @returns {number} output value
*/ */
export function byteLength(str) { export function byteLength(str) {
@ -110,6 +124,10 @@ export function byteLength(str) {
return s return s
} }
/**
* @param {Array} actual
* @returns {Array}
*/
export function cleanArray(actual) { export function cleanArray(actual) {
const newArray = [] const newArray = []
for (let i = 0; i < actual.length; i++) { for (let i = 0; i < actual.length; i++) {
@ -120,6 +138,10 @@ export function cleanArray(actual) {
return newArray return newArray
} }
/**
* @param {Object} json
* @returns {Array}
*/
export function param(json) { export function param(json) {
if (!json) return '' if (!json) return ''
return cleanArray( return cleanArray(
@ -130,6 +152,10 @@ export function param(json) {
).join('&') ).join('&')
} }
/**
* @param {string} url
* @returns {Object}
*/
export function param2Obj(url) { export function param2Obj(url) {
const search = url.split('?')[1] const search = url.split('?')[1]
if (!search) { if (!search) {
@ -146,16 +172,23 @@ export function param2Obj(url) {
) )
} }
/**
* @param {string} val
* @returns {string}
*/
export function html2Text(val) { export function html2Text(val) {
const div = document.createElement('div') const div = document.createElement('div')
div.innerHTML = val div.innerHTML = val
return div.textContent || div.innerText return div.textContent || div.innerText
} }
/**
* Merges two objects, giving the last one precedence
* @param {Object} target
* @param {(Object|Array)} source
* @returns {Object}
*/
export function objectMerge(target, source) { export function objectMerge(target, source) {
/* Merges two objects,
giving the last one precedence */
if (typeof target !== 'object') { if (typeof target !== 'object') {
target = {} target = {}
} }
@ -173,6 +206,10 @@ export function objectMerge(target, source) {
return target return target
} }
/**
* @param {HTMLElement} element
* @param {string} className
*/
export function toggleClass(element, className) { export function toggleClass(element, className) {
if (!element || !className) { if (!element || !className) {
return return
@ -189,45 +226,10 @@ export function toggleClass(element, className) {
element.className = classString element.className = classString
} }
export const pickerOptions = [ /**
{ * @param {string} type
text: '今天', * @returns {Date}
onClick(picker) { */
const end = new Date()
const start = new Date(new Date().toDateString())
end.setTime(start.getTime())
picker.$emit('pick', [start, end])
}
},
{
text: '最近一周',
onClick(picker) {
const end = new Date(new Date().toDateString())
const start = new Date()
start.setTime(end.getTime() - 3600 * 1000 * 24 * 7)
picker.$emit('pick', [start, end])
}
},
{
text: '最近一个月',
onClick(picker) {
const end = new Date(new Date().toDateString())
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 30)
picker.$emit('pick', [start, end])
}
},
{
text: '最近三个月',
onClick(picker) {
const end = new Date(new Date().toDateString())
const start = new Date()
start.setTime(start.getTime() - 3600 * 1000 * 24 * 90)
picker.$emit('pick', [start, end])
}
}
]
export function getTime(type) { export function getTime(type) {
if (type === 'start') { if (type === 'start') {
return new Date().getTime() - 3600 * 1000 * 24 * 90 return new Date().getTime() - 3600 * 1000 * 24 * 90
@ -236,6 +238,12 @@ export function getTime(type) {
} }
} }
/**
* @param {Function} func
* @param {number} wait
* @param {boolean} immediate
* @return {*}
*/
export function debounce(func, wait, immediate) { export function debounce(func, wait, immediate) {
let timeout, args, context, timestamp, result let timeout, args, context, timestamp, result
@ -275,6 +283,8 @@ export function debounce(func, wait, immediate) {
* This is just a simple version of deep copy * This is just a simple version of deep copy
* Has a lot of edge cases bug * Has a lot of edge cases bug
* If you want to use a perfect deep copy, use lodash's _.cloneDeep * If you want to use a perfect deep copy, use lodash's _.cloneDeep
* @param {Object} source
* @returns {Object}
*/ */
export function deepClone(source) { export function deepClone(source) {
if (!source && typeof source !== 'object') { if (!source && typeof source !== 'object') {
@ -291,22 +301,47 @@ export function deepClone(source) {
return targetObj return targetObj
} }
/**
* @param {Array} arr
* @returns {Array}
*/
export function uniqueArr(arr) { export function uniqueArr(arr) {
return Array.from(new Set(arr)) return Array.from(new Set(arr))
} }
/**
* @returns {string}
*/
export function createUniqueString() { export function createUniqueString() {
const timestamp = +new Date() + '' const timestamp = +new Date() + ''
const randomNum = parseInt((1 + Math.random()) * 65536) + '' const randomNum = parseInt((1 + Math.random()) * 65536) + ''
return (+(randomNum + timestamp)).toString(32) return (+(randomNum + timestamp)).toString(32)
} }
/**
* Check if an element has a class
* @param {HTMLElement} elm
* @param {string} cls
* @returns {boolean}
*/
export function hasClass(ele, cls) { export function hasClass(ele, cls) {
return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')) return !!ele.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)'))
} }
/**
* Add class to element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function addClass(ele, cls) { export function addClass(ele, cls) {
if (!hasClass(ele, cls)) ele.className += ' ' + cls if (!hasClass(ele, cls)) ele.className += ' ' + cls
} }
/**
* Remove class from element
* @param {HTMLElement} elm
* @param {string} cls
*/
export function removeClass(ele, cls) { export function removeClass(ele, cls) {
if (hasClass(ele, cls)) { if (hasClass(ele, cls)) {
const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)') const reg = new RegExp('(\\s|^)' + cls + '(\\s|$)')

View File

@ -5,7 +5,6 @@
* @param {Number} w * @param {Number} w
* @param {Number} h * @param {Number} h
*/ */
export default function openWindow(url, title, w, h) { export default function openWindow(url, title, w, h) {
// Fixes dual-screen position Most browsers Firefox // Fixes dual-screen position Most browsers Firefox
const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left const dualScreenLeft = window.screenLeft !== undefined ? window.screenLeft : screen.left

View File

@ -5,23 +5,25 @@ import { getToken } from '@/utils/auth'
// create an axios instance // create an axios instance
const service = axios.create({ const service = axios.create({
baseURL: process.env.VUE_APP_BASE_API, // api 的 base_url baseURL: process.env.VUE_APP_BASE_API, // url = base url + request url
withCredentials: true, // 跨域请求时发送 cookies withCredentials: true, // send cookies when cross-domain requests
timeout: 5000 // request timeout timeout: 5000 // request timeout
}) })
// request interceptor // request interceptor
service.interceptors.request.use( service.interceptors.request.use(
config => { config => {
// Do something before request is sent // do something before request is sent
if (store.getters.token) { if (store.getters.token) {
// 让每个请求携带token-- ['X-Token']为自定义key 请根据实际情况自行修改 // let each request carry token --['X-Token'] as a custom key.
// please modify it according to the actual situation.
config.headers['X-Token'] = getToken() config.headers['X-Token'] = getToken()
} }
return config return config
}, },
error => { error => {
// Do something with request error // do something with request error
console.log(error) // for debug console.log(error) // for debug
return Promise.reject(error) return Promise.reject(error)
} }
@ -33,31 +35,33 @@ service.interceptors.response.use(
* If you want to get information such as headers or status * If you want to get information such as headers or status
* Please return response => response * Please return response => response
*/ */
/** /**
* 下面的注释为通过在response里自定义code来标示请求状态 * Determine the request status by custom code
* 当code返回如下情况则说明权限有问题登出并返回到登录页 * Here is just an example
* 如想通过 XMLHttpRequest 来状态码标识 逻辑可写在下面error中 * You can also judge the status by HTTP Status Code.
* 以下代码均为样例请结合自生需求加以修改若不需要则可删除
*/ */
response => { response => {
const res = response.data const res = response.data
// if the custom code is not 20000, it is judged as an error.
if (res.code !== 20000) { if (res.code !== 20000) {
Message({ Message({
message: res.message || 'error', message: res.message || 'error',
type: 'error', type: 'error',
duration: 5 * 1000 duration: 5 * 1000
}) })
// 50008:非法的token; 50012:其他客户端登录了; 50014:Token 过期了;
// 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired;
if (res.code === 50008 || res.code === 50012 || res.code === 50014) { if (res.code === 50008 || res.code === 50012 || res.code === 50014) {
// 请自行在引入 MessageBox // to re-login
// import { Message, MessageBox } from 'element-ui' MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', {
MessageBox.confirm('你已被登出,可以取消继续留在该页面,或者重新登录', '确定登出', { confirmButtonText: 'Re-Login',
confirmButtonText: '重新登录', cancelButtonText: 'Cancel',
cancelButtonText: '取消',
type: 'warning' type: 'warning'
}).then(() => { }).then(() => {
store.dispatch('user/resetToken').then(() => { store.dispatch('user/resetToken').then(() => {
location.reload() // 为了重新实例化vue-router对象 避免bug location.reload()
}) })
}) })
} }

View File

@ -12,7 +12,10 @@ var requestAnimFrame = (function() {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) } return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
})() })()
// because it's so fucking difficult to detect the scrolling element, just move them all /**
* Because it's so fucking difficult to detect the scrolling element, just move them all
* @param {number} amount
*/
function move(amount) { function move(amount) {
document.documentElement.scrollTop = amount document.documentElement.scrollTop = amount
document.body.parentNode.scrollTop = amount document.body.parentNode.scrollTop = amount
@ -23,6 +26,11 @@ function position() {
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
} }
/**
* @param {number} to
* @param {number} duration
* @param {Function} callback
*/
export function scrollTo(to, duration, callback) { export function scrollTo(to, duration, callback) {
const start = position() const start = position()
const change = to - start const change = to - start

View File

@ -1,41 +1,72 @@
/** /**
* Created by jiachenpan on 16/11/18. * Created by jiachenpan on 16/11/18.
*/ */
/**
* @param {string} path
* @returns {Boolean}
*/
export function isExternal(path) { export function isExternal(path) {
return /^(https?:|mailto:|tel:)/.test(path) return /^(https?:|mailto:|tel:)/.test(path)
} }
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUsername(str) { export function validUsername(str) {
const valid_map = ['admin', 'editor'] const valid_map = ['admin', 'editor']
return valid_map.indexOf(str.trim()) >= 0 return valid_map.indexOf(str.trim()) >= 0
} }
/**
* @param {string} url
* @returns {Boolean}
*/
export function validURL(url) { export function validURL(url) {
const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/ const reg = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
return reg.test(url) return reg.test(url)
} }
/**
* @param {string} str
* @returns {Boolean}
*/
export function validLowerCase(str) { export function validLowerCase(str) {
const reg = /^[a-z]+$/ const reg = /^[a-z]+$/
return reg.test(str) return reg.test(str)
} }
/**
* @param {string} str
* @returns {Boolean}
*/
export function validUpperCase(str) { export function validUpperCase(str) {
const reg = /^[A-Z]+$/ const reg = /^[A-Z]+$/
return reg.test(str) return reg.test(str)
} }
/**
* @param {string} str
* @returns {Boolean}
*/
export function validAlphabets(str) { export function validAlphabets(str) {
const reg = /^[A-Za-z]+$/ const reg = /^[A-Za-z]+$/
return reg.test(str) return reg.test(str)
} }
/**
* @param {string} email
* @returns {Boolean}
*/
export function validEmail(email) { export function validEmail(email) {
const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/ const reg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
return reg.test(email) return reg.test(email)
} }
/**
* @param {string} str
* @returns {Boolean}
*/
export function isString(str) { export function isString(str) {
if (typeof str === 'string' || str instanceof String) { if (typeof str === 'string' || str instanceof String) {
return true return true
@ -43,6 +74,10 @@ export function isString(str) {
return false return false
} }
/**
* @param {Array} arg
* @returns {Boolean}
*/
export function isArray(arg) { export function isArray(arg) {
if (typeof Array.isArray === 'undefined') { if (typeof Array.isArray === 'undefined') {
return Object.prototype.toString.call(arg) === '[object Array]' return Object.prototype.toString.call(arg) === '[object Array]'

View File

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import Chart from '@/components/Charts/keyboard' import Chart from '@/components/Charts/Keyboard'
export default { export default {
name: 'KeyboardChart', name: 'KeyboardChart',

View File

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import Chart from '@/components/Charts/lineMarker' import Chart from '@/components/Charts/LineMarker'
export default { export default {
name: 'LineChart', name: 'LineChart',

View File

@ -5,7 +5,7 @@
</template> </template>
<script> <script>
import Chart from '@/components/Charts/mixChart' import Chart from '@/components/Charts/MixChart'
export default { export default {
name: 'MixChart', name: 'MixChart',

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code>This is based on <aside>This is based on
<a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>. <a class="link-type" href="//github.com/dai-siki/vue-image-crop-upload"> vue-image-crop-upload</a>.
{{ $t('components.imageUploadTips') }} {{ $t('components.imageUploadTips') }}
</code> </aside>
<pan-thumb :image="image" /> <pan-thumb :image="image" />

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code>{{ $t('components.backToTopTips1') }}</code> <aside>{{ $t('components.backToTopTips1') }}</aside>
<code>{{ $t('components.backToTopTips2') }}</code> <aside>{{ $t('components.backToTopTips2') }}</aside>
<div class="placeholder-container"> <div class="placeholder-container">
<div>placeholder</div> <div>placeholder</div>
<div>placeholder</div> <div>placeholder</div>
@ -113,8 +113,7 @@
<div>placeholder</div> <div>placeholder</div>
<div>placeholder</div> <div>placeholder</div>
</div> </div>
<!--可自定义按钮的样式show/hide临界点返回的位置 --> <!-- you can add element-ui's tooltip -->
<!--如需文字提示可在外部添加element的<el-tooltip></el-tooltip> -->
<el-tooltip placement="top" content="tooltip"> <el-tooltip placement="top" content="tooltip">
<back-to-top :custom-style="myBackToTopStyle" :visibility-height="300" :back-position="50" transition-name="fade" /> <back-to-top :custom-style="myBackToTopStyle" :visibility-height="300" :back-position="50" transition-name="fade" />
</el-tooltip> </el-tooltip>
@ -129,6 +128,7 @@ export default {
components: { BackToTop }, components: { BackToTop },
data() { data() {
return { return {
// customizable button style, show/hide critical point, return position
myBackToTopStyle: { myBackToTopStyle: {
right: '50px', right: '50px',
bottom: '50px', bottom: '50px',

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<p class="warn-content"> <aside>
<a href="https://github.com/PanJiaChen/vue-countTo" target="_blank">countTo-component</a> <a href="https://github.com/PanJiaChen/vue-countTo" target="_blank">countTo-component</a>
</p> </aside>
<count-to <count-to
ref="example" ref="example"
:start-val="_startVal" :start-val="_startVal"
@ -45,9 +45,9 @@
<input v-model="setSuffix" name="suffixInput"> <input v-model="setSuffix" name="suffixInput">
</label> </label>
</div> </div>
<code>&lt;count-to :start-val=&#x27;{{ _startVal }}&#x27; :end-val=&#x27;{{ _endVal }}&#x27; :duration=&#x27;{{ _duration }}&#x27; <aside>&lt;count-to :start-val=&#x27;{{ _startVal }}&#x27; :end-val=&#x27;{{ _endVal }}&#x27; :duration=&#x27;{{ _duration }}&#x27;
:decimals=&#x27;{{ _decimals }}&#x27; :separator=&#x27;{{ _separator }}&#x27; :prefix=&#x27;{{ _prefix }}&#x27; :suffix=&#x27;{{ _suffix }}&#x27; :decimals=&#x27;{{ _decimals }}&#x27; :separator=&#x27;{{ _separator }}&#x27; :prefix=&#x27;{{ _prefix }}&#x27; :suffix=&#x27;{{ _suffix }}&#x27;
:autoplay=false&gt;</code> :autoplay=false&gt;</aside>
</div> </div>
</template> </template>

View File

@ -1,8 +1,8 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code>drag-list base on <aside>drag-list base on
<a href="https://github.com/SortableJS/Vue.Draggable" target="_blank">Vue.Draggable</a> <a href="https://github.com/SortableJS/Vue.Draggable" target="_blank">Vue.Draggable</a>
</code> </aside>
<div class="editor-container"> <div class="editor-container">
<dnd-list :list1="list1" :list2="list2" list1-title="List" list2-title="Article pool" /> <dnd-list :list1="list1" :list2="list2" list1-title="List" list2-title="Article pool" />
</div> </div>

View File

@ -17,7 +17,7 @@
</template> </template>
<script> <script>
import elDragDialog from '@/directive/el-dragDialog' // base on element-ui import elDragDialog from '@/directive/el-drag-dialog' // base on element-ui
export default { export default {
name: 'DragDialogDemo', name: 'DragDialogDemo',

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code> <aside>
Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>. Based on <a class="link-type" href="https://github.com/rowanwins/vue-dropzone"> dropzone </a>.
{{ $t('components.dropzoneTips') }} {{ $t('components.dropzoneTips') }}
</code> </aside>
<div class="editor-container"> <div class="editor-container">
<dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS" /> <dropzone id="myVueDropzone" url="https://httpbin.org/post" @dropzone-removedFile="dropzoneR" @dropzone-success="dropzoneS" />
</div> </div>

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code>Json-Editor is base on <a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirrorr</a>. Lint <aside>Json-Editor is base on <a href="https://github.com/codemirror/CodeMirror" target="_blank">CodeMirrorr</a>. Lint
base on <a base on <a
href="https://github.com/codemirror/CodeMirror/blob/master/addon/lint/json-lint.js" href="https://github.com/codemirror/CodeMirror/blob/master/addon/lint/json-lint.js"
target="_blank" target="_blank"
>json-lint</a>.</code> >json-lint</a>.</aside>
<div class="editor-container"> <div class="editor-container">
<json-editor ref="jsonEditor" v-model="value" /> <json-editor ref="jsonEditor" v-model="value" />
</div> </div>

View File

@ -1,13 +1,13 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code>Markdown is based on <aside>Markdown is based on
<a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> simply wrapped with Vue. <a href="https://github.com/nhnent/tui.editor" target="_blank">tui.editor</a> simply wrapped with Vue.
<a <a
target="_blank" target="_blank"
href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html" href="https://panjiachen.github.io/vue-element-admin-site/feature/component/markdown-editor.html"
> >
Documentation </a> Documentation </a>
</code> </aside>
<div class="editor-container"> <div class="editor-container">
<el-tag class="tag-title"> <el-tag class="tag-title">

View File

@ -115,7 +115,7 @@
import PanThumb from '@/components/PanThumb' import PanThumb from '@/components/PanThumb'
import MdInput from '@/components/MDinput' import MdInput from '@/components/MDinput'
import Mallki from '@/components/TextHoverEffect/Mallki' import Mallki from '@/components/TextHoverEffect/Mallki'
import DropdownMenu from '@/components/Share/dropdownMenu' import DropdownMenu from '@/components/Share/DropdownMenu'
import waves from '@/directive/waves/index.js' // import waves from '@/directive/waves/index.js' //
export default { export default {

View File

@ -1,10 +1,10 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code><strong>SplitPane</strong> If you've used <aside><strong>SplitPane</strong> If you've used
<a href="http://codepen.io/" target="_blank"> codepen</a>, <a href="https://codepen.io/" target="_blank"> codepen</a>,
<a href="https://jsfiddle.net/" target="_blank"> jsfiddle </a>will not be unfamiliar. <a href="https://jsfiddle.net/" target="_blank"> jsfiddle </a>will not be unfamiliar.
<a href="https://github.com/PanJiaChen/vue-split-pane" target="_blank"> Github repository</a> <a href="https://github.com/PanJiaChen/vue-split-pane" target="_blank"> Github repository</a>
</code> </aside>
<split-pane split="vertical" @resize="resize"> <split-pane split="vertical" @resize="resize">
<template slot="paneL"> <template slot="paneL">
<div class="left-container" /> <div class="left-container" />

View File

@ -28,7 +28,7 @@
</el-dropdown> </el-dropdown>
<div class="time-container"> <div class="time-container">
<el-date-picker v-model="time" :picker-options="pickerOptions" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Release time" /> <el-date-picker v-model="time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Release time" />
</div> </div>
<el-button style="margin-left: 10px;" type="success"> <el-button style="margin-left: 10px;" type="success">
@ -37,7 +37,7 @@
</sticky> </sticky>
<div class="components-container"> <div class="components-container">
<code>Sticky header, {{ $t('components.stickyTips') }}</code> <aside>Sticky header, {{ $t('components.stickyTips') }}</aside>
<div>placeholder</div> <div>placeholder</div>
<div>placeholder</div> <div>placeholder</div>
<div>placeholder</div> <div>placeholder</div>

View File

@ -1,9 +1,9 @@
<template> <template>
<div class="components-container"> <div class="components-container">
<code> <aside>
{{ $t('components.tinymceTips') }} {{ $t('components.tinymceTips') }}
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html"> {{ $t('components.documentation') }}</a> <a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html"> {{ $t('components.documentation') }}</a>
</code> </aside>
<div> <div>
<tinymce v-model="content" :height="300" /> <tinymce v-model="content" :height="300" />
</div> </div>

View File

@ -21,7 +21,7 @@
</template> </template>
<script> <script>
import { transactionList } from '@/api/remoteSearch' import { transactionList } from '@/api/remote-search'
export default { export default {
filters: { filters: {

View File

@ -7,7 +7,7 @@
</div> </div>
</template> </template>
<script> <script>
import DropdownMenu from '@/components/Share/dropdownMenu' import DropdownMenu from '@/components/Share/DropdownMenu'
export default { export default {
name: 'Documentation', name: 'Documentation',

View File

@ -1,15 +1,15 @@
<template> <template>
<div class="errPage-container"> <div class="errPage-container">
<errorA /> <ErrorA />
<errorB /> <ErrorB />
<!-- $t is vue-i18n global function to translate lang --> <!-- $t is vue-i18n global function to translate lang -->
<h3>{{ $t('errorLog.tips') }}</h3> <h3>{{ $t('errorLog.tips') }}</h3>
<code> <aside>
{{ $t('errorLog.description') }} {{ $t('errorLog.description') }}
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/error.html"> <a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/guide/advanced/error.html">
{{ $t('errorLog.documentation') }} {{ $t('errorLog.documentation') }}
</a> </a>
</code> </aside>
<a href="#"> <a href="#">
<img src="https://wpimg.wallstcn.com/360e4842-4db5-42d0-b078-f9a84a825546.gif"> <img src="https://wpimg.wallstcn.com/360e4842-4db5-42d0-b078-f9a84a825546.gif">
</a> </a>
@ -17,12 +17,12 @@
</template> </template>
<script> <script>
import errorA from './errorTestA' import ErrorA from './components/ErrorTestA'
import errorB from './errorTestB' import ErrorB from './components/ErrorTestB'
export default { export default {
name: 'ErrorLog', name: 'ErrorLog',
components: { errorA, errorB } components: { ErrorA, ErrorB }
} }
</script> </script>

View File

@ -6,10 +6,10 @@
<PlatformDropdown v-model="postForm.platforms" /> <PlatformDropdown v-model="postForm.platforms" />
<SourceUrlDropdown v-model="postForm.source_uri" /> <SourceUrlDropdown v-model="postForm.source_uri" />
<el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm"> <el-button v-loading="loading" style="margin-left: 10px;" type="success" @click="submitForm">
发布 Publush
</el-button> </el-button>
<el-button v-loading="loading" type="warning" @click="draftForm"> <el-button v-loading="loading" type="warning" @click="draftForm">
草稿 Draft
</el-button> </el-button>
</sticky> </sticky>
@ -20,28 +20,28 @@
<el-col :span="24"> <el-col :span="24">
<el-form-item style="margin-bottom: 40px;" prop="title"> <el-form-item style="margin-bottom: 40px;" prop="title">
<MDinput v-model="postForm.title" :maxlength="100" name="name" required> <MDinput v-model="postForm.title" :maxlength="100" name="name" required>
标题 Title
</MDinput> </MDinput>
</el-form-item> </el-form-item>
<div class="postInfo-container"> <div class="postInfo-container">
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
<el-form-item label-width="45px" label="作者:" class="postInfo-container-item"> <el-form-item label-width="60px" label="Author:" class="postInfo-container-item">
<el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable default-first-option remote placeholder="搜索用户"> <el-select v-model="postForm.author" :remote-method="getRemoteUserList" filterable default-first-option remote placeholder="Search user">
<el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item" /> <el-option v-for="(item,index) in userListOptions" :key="item+index" :label="item" :value="item" />
</el-select> </el-select>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="10"> <el-col :span="10">
<el-form-item label-width="80px" label="发布时间:" class="postInfo-container-item"> <el-form-item label-width="120px" label="Publush Time:" class="postInfo-container-item">
<el-date-picker v-model="postForm.display_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="选择日期时间" /> <el-date-picker v-model="postForm.display_time" type="datetime" format="yyyy-MM-dd HH:mm:ss" placeholder="Select date and time" />
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="6"> <el-col :span="6">
<el-form-item label-width="60px" label="重要性:" class="postInfo-container-item"> <el-form-item label-width="90px" label="Importance:" class="postInfo-container-item">
<el-rate <el-rate
v-model="postForm.importance" v-model="postForm.importance"
:max="3" :max="3"
@ -57,9 +57,9 @@
</el-col> </el-col>
</el-row> </el-row>
<el-form-item style="margin-bottom: 40px;" label-width="45px" label="摘要:"> <el-form-item style="margin-bottom: 40px;" label-width="70px" label="Summary:">
<el-input v-model="postForm.content_short" :rows="1" type="textarea" class="article-textarea" autosize placeholder="请输入内容" /> <el-input v-model="postForm.content_short" :rows="1" type="textarea" class="article-textarea" autosize placeholder="Please enter the content" />
<span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}</span> <span v-show="contentShortLength" class="word-counter">{{ contentShortLength }}words</span>
</el-form-item> </el-form-item>
<el-form-item prop="content" style="margin-bottom: 30px;"> <el-form-item prop="content" style="margin-bottom: 30px;">
@ -76,12 +76,12 @@
<script> <script>
import Tinymce from '@/components/Tinymce' import Tinymce from '@/components/Tinymce'
import Upload from '@/components/Upload/singleImage3' import Upload from '@/components/Upload/SingleImage3'
import MDinput from '@/components/MDinput' import MDinput from '@/components/MDinput'
import Sticky from '@/components/Sticky' // header import Sticky from '@/components/Sticky' // header
import { validURL } from '@/utils/validate' import { validURL } from '@/utils/validate'
import { fetchArticle } from '@/api/article' import { fetchArticle } from '@/api/article'
import { searchUser } from '@/api/remoteSearch' import { searchUser } from '@/api/remote-search'
import Warning from './Warning' import Warning from './Warning'
import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown' import { CommentDropdown, PlatformDropdown, SourceUrlDropdown } from './Dropdown'
@ -236,24 +236,39 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
@import "~@/styles/mixin.scss"; @import "~@/styles/mixin.scss";
.createPost-container { .createPost-container {
position: relative; position: relative;
.createPost-main-container { .createPost-main-container {
padding: 40px 45px 20px 50px; padding: 40px 45px 20px 50px;
.postInfo-container { .postInfo-container {
position: relative; position: relative;
@include clearfix; @include clearfix;
margin-bottom: 10px; margin-bottom: 10px;
.postInfo-container-item { .postInfo-container-item {
float: left; float: left;
} }
} }
} }
.word-counter { .word-counter {
width: 40px; width: 40px;
position: absolute; position: absolute;
right: -10px; right: 10px;
top: 0px; top: 0px;
} }
} }
.article-textarea /deep/ {
textarea {
padding-right: 40px;
resize: none;
border: none;
border-radius: 0px;
border-bottom: 1px solid #bfcbd9;
}
}
</style> </style>

View File

@ -1,17 +1,17 @@
<template> <template>
<el-dropdown :show-timeout="100" trigger="click"> <el-dropdown :show-timeout="100" trigger="click">
<el-button plain> <el-button plain>
{{ !comment_disabled?'评论已打开':'评论已关闭' }} {{ !comment_disabled?'Comment: opened':'Comment: closed' }}
<i class="el-icon-caret-bottom el-icon--right" /> <i class="el-icon-caret-bottom el-icon--right" />
</el-button> </el-button>
<el-dropdown-menu slot="dropdown" class="no-padding"> <el-dropdown-menu slot="dropdown" class="no-padding">
<el-dropdown-item> <el-dropdown-item>
<el-radio-group v-model="comment_disabled" style="padding: 10px;"> <el-radio-group v-model="comment_disabled" style="padding: 10px;">
<el-radio :label="true"> <el-radio :label="true">
关闭评论 Close comment
</el-radio> </el-radio>
<el-radio :label="false"> <el-radio :label="false">
打开评论 Open comment
</el-radio> </el-radio>
</el-radio-group> </el-radio-group>
</el-dropdown-item> </el-dropdown-item>

View File

@ -1,7 +1,7 @@
<template> <template>
<el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click"> <el-dropdown :hide-on-click="false" :show-timeout="100" trigger="click">
<el-button plain> <el-button plain>
平台({{ platforms.length }}) Platfroms({{ platforms.length }})
<i class="el-icon-caret-bottom el-icon--right" /> <i class="el-icon-caret-bottom el-icon--right" />
</el-button> </el-button>
<el-dropdown-menu slot="dropdown" class="no-border"> <el-dropdown-menu slot="dropdown" class="no-border">

View File

@ -1,14 +1,14 @@
<template> <template>
<el-dropdown :show-timeout="100" trigger="click"> <el-dropdown :show-timeout="100" trigger="click">
<el-button plain> <el-button plain>
外链 Link
<i class="el-icon-caret-bottom el-icon--right" /> <i class="el-icon-caret-bottom el-icon--right" />
</el-button> </el-button>
<el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px"> <el-dropdown-menu slot="dropdown" class="no-padding no-border" style="width:400px">
<el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri"> <el-form-item label-width="0px" style="margin-bottom: 0px" prop="source_uri">
<el-input v-model="source_uri" placeholder="请输入内容"> <el-input v-model="source_uri" placeholder="Please enter the content">
<template slot="prepend"> <template slot="prepend">
填写url URL
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>

View File

@ -1,11 +1,10 @@
<template> <template>
<p class="warn-content"> <aside>
创建和编辑页面是不能被keep-alive 缓存的因为keep-alive 的include 目前不支持根据路由来缓存所以目前都是基于component name 来缓存的如果你想要实现缓存的效果可以使用localstorage 等浏览器缓存方案或者不要使用keep-alive {{ $t('example.warning') }}
的include直接缓存所有页面详情见
<a <a
href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html" href="https://panjiachen.github.io/vue-element-admin-site/guide/essentials/tags-view.html"
target="_blank" target="_blank"
>文档</a> >Document</a>
</p> </aside>
</template> </template>

View File

@ -4,8 +4,8 @@
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="document" @click="handleDownload">Export</el-button> <el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="document" @click="handleDownload">Export</el-button>
<el-table <el-table
v-loading="listLoading"
ref="multipleTable" ref="multipleTable"
v-loading="listLoading"
:data="list" :data="list"
element-loading-text="Loading" element-loading-text="Loading"
border border

View File

@ -1,10 +1,9 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<p class="warn-content"> <aside>
{{ $t('guide.description') }} {{ $t('guide.description') }}
<a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js. <a href="https://github.com/kamranahmedse/driver.js" target="_blank">driver.js.</a>
</a> </aside>
</p>
<el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide"> <el-button icon="el-icon-question" type="primary" @click.prevent.stop="guide">
{{ $t('guide.button') }} {{ $t('guide.button') }}
</el-button> </el-button>
@ -14,7 +13,7 @@
<script> <script>
import Driver from 'driver.js' // import driver.js import Driver from 'driver.js' // import driver.js
import 'driver.js/dist/driver.min.css' // import driver.js css import 'driver.js/dist/driver.min.css' // import driver.js css
import steps from './defineSteps' import steps from './steps'
export default { export default {
name: 'Guide', name: 'Guide',

View File

@ -10,7 +10,7 @@
</template> </template>
<script> <script>
// import openWindow from '@/utils/openWindow' // import openWindow from '@/utils/open-window'
export default { export default {
name: 'SocialSignin', name: 'SocialSignin',

View File

@ -81,7 +81,7 @@
<script> <script>
import { validUsername } from '@/utils/validate' import { validUsername } from '@/utils/validate'
import LangSelect from '@/components/LangSelect' import LangSelect from '@/components/LangSelect'
import SocialSign from './socialSignin' import SocialSign from './components/SocialSignin'
export default { export default {
name: 'Login', name: 'Login',

View File

@ -1,6 +1,6 @@
<template> <template>
<div class="app-container"> <div class="app-container">
<code style="margin-top:15px;">{{ $t('pdf.tips') }}</code> <aside style="margin-top:15px;">{{ $t('pdf.tips') }}</aside>
<router-link target="_blank" to="/pdf/download"> <router-link target="_blank" to="/pdf/download">
<el-button type="primary"> <el-button type="primary">
Click to download PDF Click to download PDF

Some files were not shown because too many files have changed in this diff Show More