commit
7466c2be8d
|
@ -198,6 +198,14 @@ If you find this project useful, you can buy author a glass of juice :tropical_d
|
||||||
|
|
||||||
[Buy me a coffee](https://www.buymeacoffee.com/Pan)
|
[Buy me a coffee](https://www.buymeacoffee.com/Pan)
|
||||||
|
|
||||||
|
## Browsers support
|
||||||
|
|
||||||
|
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 |
|
||||||
|
| --------- | --------- | --------- | --------- |
|
||||||
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
||||||
|
|
|
@ -210,6 +210,14 @@ Detailed changes for each release are documented in the [release notes](https://
|
||||||
|
|
||||||
[Paypal Me](https://www.paypal.me/panfree23)
|
[Paypal Me](https://www.paypal.me/panfree23)
|
||||||
|
|
||||||
|
## Browsers support
|
||||||
|
|
||||||
|
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 |
|
||||||
|
| --------- | --------- | --------- | --------- |
|
||||||
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
||||||
|
|
|
@ -58,8 +58,10 @@ const devWebpackConfig = merge(baseWebpackConfig, {
|
||||||
inject: true,
|
inject: true,
|
||||||
favicon: resolve('favicon.ico'),
|
favicon: resolve('favicon.ico'),
|
||||||
title: 'vue-element-admin',
|
title: 'vue-element-admin',
|
||||||
path: config.dev.assetsPublicPath + config.dev.assetsSubDirectory
|
templateParameters: {
|
||||||
})
|
BASE_URL: config.dev.assetsPublicPath + config.dev.assetsSubDirectory,
|
||||||
|
},
|
||||||
|
}),
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,9 @@ const webpackConfig = merge(baseWebpackConfig, {
|
||||||
inject: true,
|
inject: true,
|
||||||
favicon: resolve('favicon.ico'),
|
favicon: resolve('favicon.ico'),
|
||||||
title: 'vue-element-admin',
|
title: 'vue-element-admin',
|
||||||
path: config.build.assetsPublicPath + config.build.assetsSubDirectory,
|
templateParameters: {
|
||||||
|
BASE_URL: config.build.assetsPublicPath + config.build.assetsSubDirectory,
|
||||||
|
},
|
||||||
minify: {
|
minify: {
|
||||||
removeComments: true,
|
removeComments: true,
|
||||||
collapseWhitespace: true,
|
collapseWhitespace: true,
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
<title>vue-element-admin</title>
|
<title>vue-element-admin</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce4.7.5/tinymce.min.js></script>
|
<script src=<%= BASE_URL %>/tinymce4.7.5/tinymce.min.js></script>
|
||||||
<div id="app"></div>
|
<div id="app"></div>
|
||||||
<!-- built files will be auto injected -->
|
<!-- built files will be auto injected -->
|
||||||
</body>
|
</body>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "vue-element-admin",
|
"name": "vue-element-admin",
|
||||||
"version": "3.9.0",
|
"version": "3.9.1",
|
||||||
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
"description": "A magical vue admin. Typical templates 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",
|
||||||
|
@ -94,6 +94,7 @@
|
||||||
"node-sass": "^4.7.2",
|
"node-sass": "^4.7.2",
|
||||||
"optimize-css-assets-webpack-plugin": "5.0.0",
|
"optimize-css-assets-webpack-plugin": "5.0.0",
|
||||||
"ora": "3.0.0",
|
"ora": "3.0.0",
|
||||||
|
"path-to-regexp": "2.4.0",
|
||||||
"portfinder": "1.0.13",
|
"portfinder": "1.0.13",
|
||||||
"postcss-import": "11.1.0",
|
"postcss-import": "11.1.0",
|
||||||
"postcss-loader": "2.1.6",
|
"postcss-loader": "2.1.6",
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { generateTitle } from '@/utils/i18n'
|
import { generateTitle } from '@/utils/i18n'
|
||||||
|
import pathToRegexp from 'path-to-regexp'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
@ -29,7 +30,15 @@ export default {
|
||||||
methods: {
|
methods: {
|
||||||
generateTitle,
|
generateTitle,
|
||||||
getBreadcrumb() {
|
getBreadcrumb() {
|
||||||
let matched = this.$route.matched.filter(item => item.name)
|
const { params } = this.$route
|
||||||
|
let matched = this.$route.matched.filter(item => {
|
||||||
|
if (item.name) {
|
||||||
|
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
|
||||||
|
var toPath = pathToRegexp.compile(item.path)
|
||||||
|
item.path = toPath(params)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
})
|
||||||
const first = matched[0]
|
const first = matched[0]
|
||||||
if (first && first.name.trim().toLocaleLowerCase() !== 'Dashboard'.toLocaleLowerCase()) {
|
if (first && first.name.trim().toLocaleLowerCase() !== 'Dashboard'.toLocaleLowerCase()) {
|
||||||
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
|
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item :disabled="language==='zh'" command="zh">中文</el-dropdown-item>
|
<el-dropdown-item :disabled="language==='zh'" command="zh">中文</el-dropdown-item>
|
||||||
<el-dropdown-item :disabled="language==='en'" command="en">English</el-dropdown-item>
|
<el-dropdown-item :disabled="language==='en'" command="en">English</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="language==='es'" command="es">Español</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -0,0 +1,155 @@
|
||||||
|
export default {
|
||||||
|
route: {
|
||||||
|
dashboard: 'Panel de control',
|
||||||
|
introduction: 'Introducción',
|
||||||
|
documentation: 'Documentación',
|
||||||
|
guide: 'Guía',
|
||||||
|
permission: 'Permisos',
|
||||||
|
pagePermission: 'Permisos de la página',
|
||||||
|
directivePermission: 'Permisos de la directiva',
|
||||||
|
icons: 'Iconos',
|
||||||
|
components: 'Componentes',
|
||||||
|
componentIndex: 'Introducción',
|
||||||
|
tinymce: 'Tinymce',
|
||||||
|
markdown: 'Markdown',
|
||||||
|
jsonEditor: 'Editor JSON',
|
||||||
|
dndList: 'Lista Dnd',
|
||||||
|
splitPane: 'Panel dividido',
|
||||||
|
avatarUpload: 'Subir avatar',
|
||||||
|
dropzone: 'Subir ficheros',
|
||||||
|
sticky: 'Sticky',
|
||||||
|
countTo: 'CountTo',
|
||||||
|
componentMixin: 'Mixin',
|
||||||
|
backToTop: 'Ir arriba',
|
||||||
|
dragDialog: 'Drag Dialog',
|
||||||
|
dragKanban: 'Drag Kanban',
|
||||||
|
charts: 'Gráficos',
|
||||||
|
keyboardChart: 'Keyboard Chart',
|
||||||
|
lineChart: 'Gráfico de líneas',
|
||||||
|
mixChart: 'Mix Chart',
|
||||||
|
example: 'Ejemplo',
|
||||||
|
nested: 'Rutas anidadass',
|
||||||
|
menu1: 'Menu 1',
|
||||||
|
'menu1-1': 'Menu 1-1',
|
||||||
|
'menu1-2': 'Menu 1-2',
|
||||||
|
'menu1-2-1': 'Menu 1-2-1',
|
||||||
|
'menu1-2-2': 'Menu 1-2-2',
|
||||||
|
'menu1-3': 'Menu 1-3',
|
||||||
|
menu2: 'Menu 2',
|
||||||
|
Table: 'Tabla',
|
||||||
|
dynamicTable: 'Tabla dinámica',
|
||||||
|
dragTable: 'Arrastrar tabla',
|
||||||
|
inlineEditTable: 'Editor',
|
||||||
|
complexTable: 'Complex Table',
|
||||||
|
treeTable: 'Tree Table',
|
||||||
|
customTreeTable: 'Custom TreeTable',
|
||||||
|
tab: 'Pestaña',
|
||||||
|
form: 'Formulario',
|
||||||
|
createArticle: 'Crear artículo',
|
||||||
|
editArticle: 'Editar artículo',
|
||||||
|
articleList: 'Listado de artículos',
|
||||||
|
errorPages: 'Páginas de error',
|
||||||
|
page401: '401',
|
||||||
|
page404: '404',
|
||||||
|
errorLog: 'Registro de errores',
|
||||||
|
excel: 'Excel',
|
||||||
|
exportExcel: 'Exportar a Excel',
|
||||||
|
selectExcel: 'Export seleccionado',
|
||||||
|
uploadExcel: 'Subir Excel',
|
||||||
|
zip: 'Zip',
|
||||||
|
exportZip: 'Exportar a Zip',
|
||||||
|
theme: 'Tema',
|
||||||
|
clipboardDemo: 'Clipboard',
|
||||||
|
i18n: 'I18n',
|
||||||
|
externalLink: 'Enlace externo'
|
||||||
|
},
|
||||||
|
navbar: {
|
||||||
|
logOut: 'Salir',
|
||||||
|
dashboard: 'Panel de control',
|
||||||
|
github: 'Github',
|
||||||
|
screenfull: 'Pantalla completa',
|
||||||
|
theme: 'Tema',
|
||||||
|
size: 'Tamaño global'
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
title: 'Formulario de acceso',
|
||||||
|
logIn: 'Acceso',
|
||||||
|
username: 'Usuario',
|
||||||
|
password: 'Contraseña',
|
||||||
|
any: 'nada',
|
||||||
|
thirdparty: 'Conectar con',
|
||||||
|
thirdpartyTips: 'No se puede simular en local, así que combine su propia simulación de negocios. ! !'
|
||||||
|
},
|
||||||
|
documentation: {
|
||||||
|
documentation: 'Documentación',
|
||||||
|
github: 'Repositorio Github'
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
roles: 'Tus permisos',
|
||||||
|
switchRoles: 'Cambiar permisos'
|
||||||
|
},
|
||||||
|
guide: {
|
||||||
|
description: 'The guide page is useful for some people who entered the project for the first time. You can briefly introduce the features of the project. Demo is based on ',
|
||||||
|
button: 'Ver guía'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
documentation: 'Documentación',
|
||||||
|
tinymceTips: 'Rich text editor is a core part of management system, but at the same time is a place with lots of problems. In the process of selecting rich texts, I also walked a lot of detours. The common rich text editors in the market are basically used, and the finally chose Tinymce. See documentation for more detailed rich text editor comparisons and introductions.',
|
||||||
|
dropzoneTips: 'Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.',
|
||||||
|
stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.',
|
||||||
|
backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner',
|
||||||
|
backToTopTips2: 'You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally',
|
||||||
|
imageUploadTips: 'Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
dynamicTips1: 'Fixed header, sorted by header order',
|
||||||
|
dynamicTips2: 'Not fixed header, sorted by click order',
|
||||||
|
dragTips1: 'Orden por defecto',
|
||||||
|
dragTips2: 'The after dragging order',
|
||||||
|
title: 'Título',
|
||||||
|
importance: 'Importancia',
|
||||||
|
type: 'Tipo',
|
||||||
|
remark: 'Remark',
|
||||||
|
search: 'Buscar',
|
||||||
|
add: 'Añadir',
|
||||||
|
export: 'Exportar',
|
||||||
|
reviewer: 'reviewer',
|
||||||
|
id: 'ID',
|
||||||
|
date: 'Fecha',
|
||||||
|
author: 'Autor',
|
||||||
|
readings: 'Lector',
|
||||||
|
status: 'Estado',
|
||||||
|
actions: 'Acciones',
|
||||||
|
edit: 'Editar',
|
||||||
|
publish: 'Publicar',
|
||||||
|
draft: 'Draft',
|
||||||
|
delete: 'Eliminar',
|
||||||
|
cancel: 'Cancelar',
|
||||||
|
confirm: 'Confirmar'
|
||||||
|
},
|
||||||
|
errorLog: {
|
||||||
|
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.',
|
||||||
|
documentation: 'Documento de introducción'
|
||||||
|
},
|
||||||
|
excel: {
|
||||||
|
export: 'Exportar',
|
||||||
|
selectedExport: 'Exportar seleccionados',
|
||||||
|
placeholder: 'Por favor escribe un nombre de fichero'
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
export: 'Exportar',
|
||||||
|
placeholder: 'Por favor escribe un nombre de fichero'
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
change: 'Cambiar tema',
|
||||||
|
documentation: 'Documentación del tema',
|
||||||
|
tips: 'Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.'
|
||||||
|
},
|
||||||
|
tagsView: {
|
||||||
|
refresh: 'Actualizar',
|
||||||
|
close: 'Cerrar',
|
||||||
|
closeOthers: 'Cerrar otros',
|
||||||
|
closeAll: 'Cerrar todos'
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,8 +3,10 @@ import VueI18n from 'vue-i18n'
|
||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
|
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
|
||||||
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
|
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
|
||||||
|
import elementEsLocale from 'element-ui/lib/locale/lang/es'// element-ui lang
|
||||||
import enLocale from './en'
|
import enLocale from './en'
|
||||||
import zhLocale from './zh'
|
import zhLocale from './zh'
|
||||||
|
import esLocale from './es'
|
||||||
|
|
||||||
Vue.use(VueI18n)
|
Vue.use(VueI18n)
|
||||||
|
|
||||||
|
@ -16,12 +18,16 @@ const messages = {
|
||||||
zh: {
|
zh: {
|
||||||
...zhLocale,
|
...zhLocale,
|
||||||
...elementZhLocale
|
...elementZhLocale
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
...esLocale,
|
||||||
|
...elementEsLocale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const i18n = new VueI18n({
|
const i18n = new VueI18n({
|
||||||
// set locale
|
// set locale
|
||||||
// options: en or zh
|
// options: en | zh | es
|
||||||
locale: Cookies.get('language') || 'en',
|
locale: Cookies.get('language') || 'en',
|
||||||
// set locale messages
|
// set locale messages
|
||||||
messages
|
messages
|
||||||
|
|
|
@ -4,6 +4,16 @@ import articleAPI from './article'
|
||||||
import remoteSearchAPI from './remoteSearch'
|
import remoteSearchAPI from './remoteSearch'
|
||||||
import transactionAPI from './transaction'
|
import transactionAPI from './transaction'
|
||||||
|
|
||||||
|
// 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题
|
||||||
|
// https://github.com/nuysoft/Mock/issues/300
|
||||||
|
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
|
||||||
|
Mock.XHR.prototype.send = function() {
|
||||||
|
if (this.custom.xhr) {
|
||||||
|
this.custom.xhr.withCredentials = this.withCredentials || false
|
||||||
|
}
|
||||||
|
this.proxy_send(...arguments)
|
||||||
|
}
|
||||||
|
|
||||||
// Mock.setup({
|
// Mock.setup({
|
||||||
// timeout: '350-600'
|
// timeout: '350-600'
|
||||||
// })
|
// })
|
||||||
|
|
|
@ -47,6 +47,9 @@
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
.is-active > .el-submenu__title{
|
||||||
|
color: #f4f4f5!important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.hideSidebar {
|
.hideSidebar {
|
||||||
.sidebar-container {
|
.sidebar-container {
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
// translate router.meta.title, be used in breadcrumb sidebar tagsview
|
// translate router.meta.title, be used in breadcrumb sidebar tagsview
|
||||||
export function generateTitle(title) {
|
export function generateTitle(title) {
|
||||||
const hasKey = this.$te('route.' + title)
|
const hasKey = this.$te('route.' + title)
|
||||||
const translatedTitle = this.$t('route.' + title) // $t :this method from vue-i18n, inject in @/lang/index.js
|
|
||||||
|
|
||||||
if (hasKey) {
|
if (hasKey) {
|
||||||
|
// $t :this method from vue-i18n, inject in @/lang/index.js
|
||||||
|
const translatedTitle = this.$t('route.' + title)
|
||||||
|
|
||||||
return translatedTitle
|
return translatedTitle
|
||||||
}
|
}
|
||||||
return title
|
return title
|
||||||
|
|
|
@ -296,3 +296,7 @@ export function deepClone(source) {
|
||||||
export function uniqueArr(arr) {
|
export function uniqueArr(arr) {
|
||||||
return Array.from(new Set(arr))
|
return Array.from(new Set(arr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isExternal(path) {
|
||||||
|
return /^(https?:|mailto:|tel:)/.test(path)
|
||||||
|
}
|
||||||
|
|
|
@ -1,176 +0,0 @@
|
||||||
/* eslint-disable */
|
|
||||||
/* Blob.js
|
|
||||||
* A Blob implementation.
|
|
||||||
* 2014-05-27
|
|
||||||
*
|
|
||||||
* By Eli Grey, http://eligrey.com
|
|
||||||
* By Devin Samarin, https://github.com/eboyjr
|
|
||||||
* License: X11/MIT
|
|
||||||
* See LICENSE.md
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*global self, unescape */
|
|
||||||
/*jslint bitwise: true, regexp: true, confusion: true, es5: true, vars: true, white: true,
|
|
||||||
plusplus: true */
|
|
||||||
|
|
||||||
/*! @source http://purl.eligrey.com/github/Blob.js/blob/master/Blob.js */
|
|
||||||
|
|
||||||
(function (view) {
|
|
||||||
"use strict";
|
|
||||||
|
|
||||||
view.URL = view.URL || view.webkitURL;
|
|
||||||
|
|
||||||
if (view.Blob && view.URL) {
|
|
||||||
try {
|
|
||||||
new Blob;
|
|
||||||
return;
|
|
||||||
} catch (e) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internally we use a BlobBuilder implementation to base Blob off of
|
|
||||||
// in order to support older browsers that only have BlobBuilder
|
|
||||||
var BlobBuilder = view.BlobBuilder || view.WebKitBlobBuilder || view.MozBlobBuilder || (function (view) {
|
|
||||||
var
|
|
||||||
get_class = function (object) {
|
|
||||||
return Object.prototype.toString.call(object).match(/^\[object\s(.*)\]$/)[1];
|
|
||||||
},
|
|
||||||
FakeBlobBuilder = function BlobBuilder() {
|
|
||||||
this.data = [];
|
|
||||||
},
|
|
||||||
FakeBlob = function Blob(data, type, encoding) {
|
|
||||||
this.data = data;
|
|
||||||
this.size = data.length;
|
|
||||||
this.type = type;
|
|
||||||
this.encoding = encoding;
|
|
||||||
},
|
|
||||||
FBB_proto = FakeBlobBuilder.prototype,
|
|
||||||
FB_proto = FakeBlob.prototype,
|
|
||||||
FileReaderSync = view.FileReaderSync,
|
|
||||||
FileException = function (type) {
|
|
||||||
this.code = this[this.name = type];
|
|
||||||
},
|
|
||||||
file_ex_codes = (
|
|
||||||
"NOT_FOUND_ERR SECURITY_ERR ABORT_ERR NOT_READABLE_ERR ENCODING_ERR " +
|
|
||||||
"NO_MODIFICATION_ALLOWED_ERR INVALID_STATE_ERR SYNTAX_ERR"
|
|
||||||
).split(" "),
|
|
||||||
file_ex_code = file_ex_codes.length,
|
|
||||||
real_URL = view.URL || view.webkitURL || view,
|
|
||||||
real_create_object_URL = real_URL.createObjectURL,
|
|
||||||
real_revoke_object_URL = real_URL.revokeObjectURL,
|
|
||||||
URL = real_URL,
|
|
||||||
btoa = view.btoa,
|
|
||||||
atob = view.atob
|
|
||||||
|
|
||||||
,
|
|
||||||
ArrayBuffer = view.ArrayBuffer,
|
|
||||||
Uint8Array = view.Uint8Array;
|
|
||||||
FakeBlob.fake = FB_proto.fake = true;
|
|
||||||
while (file_ex_code--) {
|
|
||||||
FileException.prototype[file_ex_codes[file_ex_code]] = file_ex_code + 1;
|
|
||||||
}
|
|
||||||
if (!real_URL.createObjectURL) {
|
|
||||||
URL = view.URL = {};
|
|
||||||
}
|
|
||||||
URL.createObjectURL = function (blob) {
|
|
||||||
var
|
|
||||||
type = blob.type,
|
|
||||||
data_URI_header;
|
|
||||||
if (type === null) {
|
|
||||||
type = "application/octet-stream";
|
|
||||||
}
|
|
||||||
if (blob instanceof FakeBlob) {
|
|
||||||
data_URI_header = "data:" + type;
|
|
||||||
if (blob.encoding === "base64") {
|
|
||||||
return data_URI_header + ";base64," + blob.data;
|
|
||||||
} else if (blob.encoding === "URI") {
|
|
||||||
return data_URI_header + "," + decodeURIComponent(blob.data);
|
|
||||||
}
|
|
||||||
if (btoa) {
|
|
||||||
return data_URI_header + ";base64," + btoa(blob.data);
|
|
||||||
} else {
|
|
||||||
return data_URI_header + "," + encodeURIComponent(blob.data);
|
|
||||||
}
|
|
||||||
} else if (real_create_object_URL) {
|
|
||||||
return real_create_object_URL.call(real_URL, blob);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
URL.revokeObjectURL = function (object_URL) {
|
|
||||||
if (object_URL.substring(0, 5) !== "data:" && real_revoke_object_URL) {
|
|
||||||
real_revoke_object_URL.call(real_URL, object_URL);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
FBB_proto.append = function (data /*, endings*/ ) {
|
|
||||||
var bb = this.data;
|
|
||||||
// decode data to a binary string
|
|
||||||
if (Uint8Array && (data instanceof ArrayBuffer || data instanceof Uint8Array)) {
|
|
||||||
var
|
|
||||||
str = "",
|
|
||||||
buf = new Uint8Array(data),
|
|
||||||
i = 0,
|
|
||||||
buf_len = buf.length;
|
|
||||||
for (; i < buf_len; i++) {
|
|
||||||
str += String.fromCharCode(buf[i]);
|
|
||||||
}
|
|
||||||
bb.push(str);
|
|
||||||
} else if (get_class(data) === "Blob" || get_class(data) === "File") {
|
|
||||||
if (FileReaderSync) {
|
|
||||||
var fr = new FileReaderSync;
|
|
||||||
bb.push(fr.readAsBinaryString(data));
|
|
||||||
} else {
|
|
||||||
// async FileReader won't work as BlobBuilder is sync
|
|
||||||
throw new FileException("NOT_READABLE_ERR");
|
|
||||||
}
|
|
||||||
} else if (data instanceof FakeBlob) {
|
|
||||||
if (data.encoding === "base64" && atob) {
|
|
||||||
bb.push(atob(data.data));
|
|
||||||
} else if (data.encoding === "URI") {
|
|
||||||
bb.push(decodeURIComponent(data.data));
|
|
||||||
} else if (data.encoding === "raw") {
|
|
||||||
bb.push(data.data);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (typeof data !== "string") {
|
|
||||||
data += ""; // convert unsupported types to strings
|
|
||||||
}
|
|
||||||
// decode UTF-16 to binary string
|
|
||||||
bb.push(unescape(encodeURIComponent(data)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
FBB_proto.getBlob = function (type) {
|
|
||||||
if (!arguments.length) {
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
return new FakeBlob(this.data.join(""), type, "raw");
|
|
||||||
};
|
|
||||||
FBB_proto.toString = function () {
|
|
||||||
return "[object BlobBuilder]";
|
|
||||||
};
|
|
||||||
FB_proto.slice = function (start, end, type) {
|
|
||||||
var args = arguments.length;
|
|
||||||
if (args < 3) {
|
|
||||||
type = null;
|
|
||||||
}
|
|
||||||
return new FakeBlob(
|
|
||||||
this.data.slice(start, args > 1 ? end : this.data.length), type, this.encoding
|
|
||||||
);
|
|
||||||
};
|
|
||||||
FB_proto.toString = function () {
|
|
||||||
return "[object Blob]";
|
|
||||||
};
|
|
||||||
FB_proto.close = function () {
|
|
||||||
this.size = this.data.length = 0;
|
|
||||||
};
|
|
||||||
return FakeBlobBuilder;
|
|
||||||
}(view));
|
|
||||||
|
|
||||||
view.Blob = function Blob(blobParts, options) {
|
|
||||||
var type = options ? (options.type || "") : "";
|
|
||||||
var builder = new BlobBuilder();
|
|
||||||
if (blobParts) {
|
|
||||||
for (var i = 0, len = blobParts.length; i < len; i++) {
|
|
||||||
builder.append(blobParts[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return builder.getBlob(type);
|
|
||||||
};
|
|
||||||
}(typeof self !== "undefined" && self || typeof window !== "undefined" && window || this.content || this));
|
|
|
@ -1,6 +1,5 @@
|
||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
require('script-loader!file-saver');
|
require('script-loader!file-saver');
|
||||||
require('script-loader!@/vendor/Blob');
|
|
||||||
import XLSX from 'xlsx'
|
import XLSX from 'xlsx'
|
||||||
|
|
||||||
function generateArray(table) {
|
function generateArray(table) {
|
||||||
|
@ -149,7 +148,8 @@ export function export_json_to_excel({
|
||||||
header,
|
header,
|
||||||
data,
|
data,
|
||||||
filename,
|
filename,
|
||||||
autoWidth = true
|
autoWidth = true,
|
||||||
|
bookType= 'xlsx'
|
||||||
} = {}) {
|
} = {}) {
|
||||||
/* original data */
|
/* original data */
|
||||||
filename = filename || 'excel-list'
|
filename = filename || 'excel-list'
|
||||||
|
@ -196,11 +196,11 @@ export function export_json_to_excel({
|
||||||
wb.Sheets[ws_name] = ws;
|
wb.Sheets[ws_name] = ws;
|
||||||
|
|
||||||
var wbout = XLSX.write(wb, {
|
var wbout = XLSX.write(wb, {
|
||||||
bookType: 'xlsx',
|
bookType: bookType,
|
||||||
bookSST: false,
|
bookSST: false,
|
||||||
type: 'binary'
|
type: 'binary'
|
||||||
});
|
});
|
||||||
saveAs(new Blob([s2ab(wbout)], {
|
saveAs(new Blob([s2ab(wbout)], {
|
||||||
type: "application/octet-stream"
|
type: "application/octet-stream"
|
||||||
}), filename + ".xlsx");
|
}), `${filename}.${bookType}`);
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,6 +149,9 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
contentShortLength() {
|
contentShortLength() {
|
||||||
return this.postForm.content_short.length
|
return this.postForm.content_short.length
|
||||||
|
},
|
||||||
|
lang() {
|
||||||
|
return this.$store.getters.language
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -166,10 +169,18 @@ export default {
|
||||||
// Just for test
|
// Just for test
|
||||||
this.postForm.title += ` Article Id:${this.postForm.id}`
|
this.postForm.title += ` Article Id:${this.postForm.id}`
|
||||||
this.postForm.content_short += ` Article Id:${this.postForm.id}`
|
this.postForm.content_short += ` Article Id:${this.postForm.id}`
|
||||||
|
|
||||||
|
// Set tagsview title
|
||||||
|
this.setTagsViewTitle()
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.log(err)
|
console.log(err)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
setTagsViewTitle() {
|
||||||
|
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
|
||||||
|
const route = Object.assign({}, this.$route, { title: `${title}-${this.postForm.id}` })
|
||||||
|
this.$store.dispatch('updateVisitedView', route)
|
||||||
|
},
|
||||||
submitForm() {
|
submitForm() {
|
||||||
this.postForm.display_time = parseInt(this.display_time / 1000)
|
this.postForm.display_time = parseInt(this.display_time / 1000)
|
||||||
console.log(this.postForm)
|
console.log(this.postForm)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
|
||||||
<el-table v-loading.body="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
<el-table v-loading="listLoading" :data="list" border fit highlight-current-row style="width: 100%">
|
||||||
<el-table-column align="center" label="ID" width="80">
|
<el-table-column align="center" label="ID" width="80">
|
||||||
<template slot-scope="scope">
|
<template slot-scope="scope">
|
||||||
<span>{{ scope.row.id }}</span>
|
<span>{{ scope.row.id }}</span>
|
||||||
|
@ -87,7 +87,7 @@ export default {
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
listQuery: {
|
listQuery: {
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10
|
limit: 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
<template>
|
||||||
|
<div style="display:inline-block;">
|
||||||
|
<label class="radio-label">Cell Auto-Width: </label>
|
||||||
|
<el-radio-group v-model="autoWidth">
|
||||||
|
<el-radio :label="true" border>True</el-radio>
|
||||||
|
<el-radio :label="false" border>False</el-radio>
|
||||||
|
</el-radio-group>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
autoWidth: {
|
||||||
|
get() {
|
||||||
|
return this.value
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('input', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,38 @@
|
||||||
|
<template>
|
||||||
|
<div style="display:inline-block;">
|
||||||
|
<label class="radio-label">Book Type: </label>
|
||||||
|
<el-select v-model="bookType" style="width:120px;" >
|
||||||
|
<el-option
|
||||||
|
v-for="item in options"
|
||||||
|
:key="item"
|
||||||
|
:label="item"
|
||||||
|
:value="item"/>
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: 'xlsx'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
options: ['xlsx', 'csv', 'txt']
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
bookType: {
|
||||||
|
get() {
|
||||||
|
return this.value
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('input', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<div style="display:inline-block;">
|
||||||
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
|
<label class="radio-label" style="padding-left:0;">Filename: </label>
|
||||||
|
<el-input :placeholder="$t('excel.placeholder')" v-model="filename" style="width:340px;" prefix-icon="el-icon-document"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
value: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
filename: {
|
||||||
|
get() {
|
||||||
|
return this.value
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('input', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -2,14 +2,15 @@
|
||||||
<!-- $t is vue-i18n global function to translate lang -->
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
<div class="app-container">
|
<div class="app-container">
|
||||||
|
|
||||||
<label class="radio-label" style="padding-left:0;">Filename: </label>
|
<div>
|
||||||
<el-input :placeholder="$t('excel.placeholder')" v-model="filename" style="width:340px;" prefix-icon="el-icon-document"/>
|
<FilenameOption v-model="filename" />
|
||||||
<label class="radio-label">Cell Auto-Width: </label>
|
<AutoWidthOption v-model="autoWidth" />
|
||||||
<el-radio-group v-model="autoWidth">
|
<BookTypeOption v-model="bookType" />
|
||||||
<el-radio :label="true" border>True</el-radio>
|
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="handleDownload">{{ $t('excel.export') }} Excel</el-button>
|
||||||
<el-radio :label="false" border>False</el-radio>
|
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||||
</el-radio-group>
|
<el-tag type="info">Documentation</el-tag>
|
||||||
<el-button :loading="downloadLoading" style="margin:0 0 20px 20px;" type="primary" icon="document" @click="handleDownload">{{ $t('excel.export') }} Excel</el-button>
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
|
<el-table v-loading="listLoading" :data="list" element-loading-text="拼命加载中" border fit highlight-current-row>
|
||||||
<el-table-column align="center" label="Id" width="95">
|
<el-table-column align="center" label="Id" width="95">
|
||||||
|
@ -46,15 +47,22 @@
|
||||||
import { fetchList } from '@/api/article'
|
import { fetchList } from '@/api/article'
|
||||||
import { parseTime } from '@/utils'
|
import { parseTime } from '@/utils'
|
||||||
|
|
||||||
|
// options components
|
||||||
|
import FilenameOption from './components/FilenameOption'
|
||||||
|
import AutoWidthOption from './components/AutoWidthOption'
|
||||||
|
import BookTypeOption from './components/BookTypeOption'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ExportExcel',
|
name: 'ExportExcel',
|
||||||
|
components: { FilenameOption, AutoWidthOption, BookTypeOption },
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
list: null,
|
list: null,
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
downloadLoading: false,
|
downloadLoading: false,
|
||||||
filename: '',
|
filename: '',
|
||||||
autoWidth: true
|
autoWidth: true,
|
||||||
|
bookType: 'xlsx'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -79,7 +87,8 @@ export default {
|
||||||
header: tHeader,
|
header: tHeader,
|
||||||
data,
|
data,
|
||||||
filename: this.filename,
|
filename: this.filename,
|
||||||
autoWidth: this.autoWidth
|
autoWidth: this.autoWidth,
|
||||||
|
bookType: this.bookType
|
||||||
})
|
})
|
||||||
this.downloadLoading = false
|
this.downloadLoading = false
|
||||||
})
|
})
|
||||||
|
|
|
@ -3,6 +3,9 @@
|
||||||
<!-- $t is vue-i18n global function to translate lang -->
|
<!-- $t is vue-i18n global function to translate lang -->
|
||||||
<el-input :placeholder="$t('excel.placeholder')" v-model="filename" style="width:340px;" prefix-icon="el-icon-document"/>
|
<el-input :placeholder="$t('excel.placeholder')" v-model="filename" style="width:340px;" prefix-icon="el-icon-document"/>
|
||||||
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="document" @click="handleDownload">{{ $t('excel.selectedExport') }}</el-button>
|
<el-button :loading="downloadLoading" style="margin-bottom:20px" type="primary" icon="document" @click="handleDownload">{{ $t('excel.selectedExport') }}</el-button>
|
||||||
|
<a href="https://panjiachen.github.io/vue-element-admin-site/feature/component/excel.html" target="_blank" style="margin-left:15px;">
|
||||||
|
<el-tag type="info">Documentation</el-tag>
|
||||||
|
</a>
|
||||||
<el-table
|
<el-table
|
||||||
v-loading="listLoading"
|
v-loading="listLoading"
|
||||||
ref="multipleTable"
|
ref="multipleTable"
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
<el-radio-group v-model="lang" size="small">
|
<el-radio-group v-model="lang" size="small">
|
||||||
<el-radio label="zh" border>简体中文</el-radio>
|
<el-radio label="zh" border>简体中文</el-radio>
|
||||||
<el-radio label="en" border>English</el-radio>
|
<el-radio label="en" border>English</el-radio>
|
||||||
|
<el-radio label="es" border>Español</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<el-tag style="margin-top:15px;display:block;" type="info">{{ $t('i18nView.note') }}</el-tag>
|
<el-tag style="margin-top:15px;display:block;" type="info">{{ $t('i18nView.note') }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
|
@ -101,6 +102,7 @@ export default {
|
||||||
if (!this.$i18n.getLocaleMessage('en')[viewName]) {
|
if (!this.$i18n.getLocaleMessage('en')[viewName]) {
|
||||||
this.$i18n.mergeLocaleMessage('en', local.en)
|
this.$i18n.mergeLocaleMessage('en', local.en)
|
||||||
this.$i18n.mergeLocaleMessage('zh', local.zh)
|
this.$i18n.mergeLocaleMessage('zh', local.zh)
|
||||||
|
this.$i18n.mergeLocaleMessage('es', local.es)
|
||||||
}
|
}
|
||||||
this.setOptions() // set default select options
|
this.setOptions() // set default select options
|
||||||
},
|
},
|
||||||
|
|
|
@ -39,5 +39,25 @@ export default {
|
||||||
two: 'Two',
|
two: 'Two',
|
||||||
three: 'Three'
|
three: 'Three'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
i18nView: {
|
||||||
|
title: 'Switch Language',
|
||||||
|
note: 'The internationalization of this project is based on vue-i18n',
|
||||||
|
datePlaceholder: 'Pick a day',
|
||||||
|
selectPlaceholder: 'Select',
|
||||||
|
tableDate: 'tableDate',
|
||||||
|
tableName: 'tableName',
|
||||||
|
tableAddress: 'tableAddress',
|
||||||
|
default: 'default:',
|
||||||
|
primary: 'primary',
|
||||||
|
success: 'success',
|
||||||
|
info: 'info',
|
||||||
|
warning: 'warning',
|
||||||
|
danger: 'danger',
|
||||||
|
one: 'One',
|
||||||
|
two: 'Two',
|
||||||
|
three: 'Three'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
device() {
|
||||||
|
return this.$store.state.app.device
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// In order to fix the click on menu on the ios device will trigger the mouseeleave bug
|
||||||
|
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
|
||||||
|
this.fixBugIniOS()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fixBugIniOS() {
|
||||||
|
const $submenu = this.$refs.submenu
|
||||||
|
if ($submenu) {
|
||||||
|
const handleMouseleave = $submenu.handleMouseleave
|
||||||
|
$submenu.handleMouseleave = (e) => {
|
||||||
|
if (this.device === 'mobile') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handleMouseleave(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,7 +7,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { validateURL } from '@/utils/validate'
|
import { isExternal } from '@/utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
|
@ -18,7 +18,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isExternalLink(routePath) {
|
isExternalLink(routePath) {
|
||||||
return validateURL(routePath)
|
return isExternal(routePath)
|
||||||
},
|
},
|
||||||
linkProps(url) {
|
linkProps(url) {
|
||||||
if (this.isExternalLink(url)) {
|
if (this.isExternalLink(url)) {
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
</app-link>
|
</app-link>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<el-submenu v-else :index="item.name||item.path">
|
<el-submenu v-else ref="submenu" :index="resolvePath(item.path)">
|
||||||
<template slot="title">
|
<template slot="title">
|
||||||
<item v-if="item.meta" :icon="item.meta.icon" :title="generateTitle(item.meta.title)" />
|
<item v-if="item.meta" :icon="item.meta.icon" :title="generateTitle(item.meta.title)" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -37,13 +37,15 @@
|
||||||
<script>
|
<script>
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { generateTitle } from '@/utils/i18n'
|
import { generateTitle } from '@/utils/i18n'
|
||||||
import { validateURL } from '@/utils/validate'
|
import { isExternal } from '@/utils'
|
||||||
import Item from './Item'
|
import Item from './Item'
|
||||||
import AppLink from './Link'
|
import AppLink from './Link'
|
||||||
|
import FixiOSBug from './FixiOSBug'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'SidebarItem',
|
name: 'SidebarItem',
|
||||||
components: { Item, AppLink },
|
components: { Item, AppLink },
|
||||||
|
mixins: [FixiOSBug],
|
||||||
props: {
|
props: {
|
||||||
// route object
|
// route object
|
||||||
item: {
|
item: {
|
||||||
|
@ -96,7 +98,7 @@ export default {
|
||||||
return path.resolve(this.basePath, routePath)
|
return path.resolve(this.basePath, routePath)
|
||||||
},
|
},
|
||||||
isExternalLink(routePath) {
|
isExternalLink(routePath) {
|
||||||
return validateURL(routePath)
|
return isExternal(routePath)
|
||||||
},
|
},
|
||||||
generateTitle
|
generateTitle
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
text-color="#bfcbd9"
|
text-color="#bfcbd9"
|
||||||
active-text-color="#409EFF"
|
active-text-color="#409EFF"
|
||||||
>
|
>
|
||||||
<sidebar-item v-for="route in permission_routers" :key="route.name" :item="route" :base-path="route.path"/>
|
<sidebar-item v-for="route in permission_routers" :key="route.path" :item="route" :base-path="route.path"/>
|
||||||
</el-menu>
|
</el-menu>
|
||||||
</el-scrollbar>
|
</el-scrollbar>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -2,12 +2,14 @@
|
||||||
<div class="tags-view-container">
|
<div class="tags-view-container">
|
||||||
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
|
<scroll-pane ref="scrollPane" class="tags-view-wrapper">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="tag in Array.from(visitedViews)"
|
v-for="tag in visitedViews"
|
||||||
ref="tag"
|
ref="tag"
|
||||||
:class="isActive(tag)?'active':''"
|
:class="isActive(tag)?'active':''"
|
||||||
:to="tag"
|
:to="tag.fullPath"
|
||||||
:key="tag.path"
|
:key="tag.path"
|
||||||
|
tag="span"
|
||||||
class="tags-view-item"
|
class="tags-view-item"
|
||||||
|
@click.middle.native="closeSelectedTag(tag)"
|
||||||
@contextmenu.prevent.native="openMenu(tag,$event)">
|
@contextmenu.prevent.native="openMenu(tag,$event)">
|
||||||
{{ generateTitle(tag.title) }}
|
{{ generateTitle(tag.title) }}
|
||||||
<span class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)"/>
|
<span class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)"/>
|
||||||
|
@ -59,21 +61,15 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
generateTitle, // generateTitle by vue-i18n
|
generateTitle, // generateTitle by vue-i18n
|
||||||
generateRoute() {
|
|
||||||
if (this.$route.name) {
|
|
||||||
return this.$route
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
isActive(route) {
|
isActive(route) {
|
||||||
return route.path === this.$route.path
|
return route.path === this.$route.path
|
||||||
},
|
},
|
||||||
addViewTags() {
|
addViewTags() {
|
||||||
const route = this.generateRoute()
|
const { name } = this.$route
|
||||||
if (!route) {
|
if (name) {
|
||||||
return false
|
this.$store.dispatch('addView', this.$route)
|
||||||
}
|
}
|
||||||
this.$store.dispatch('addView', route)
|
return false
|
||||||
},
|
},
|
||||||
moveToCurrentTag() {
|
moveToCurrentTag() {
|
||||||
const tags = this.$refs.tag
|
const tags = this.$refs.tag
|
||||||
|
@ -149,6 +145,7 @@ export default {
|
||||||
.tags-view-item {
|
.tags-view-item {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
height: 26px;
|
height: 26px;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
border: 1px solid #d8dce5;
|
border: 1px solid #d8dce5;
|
||||||
|
|
Loading…
Reference in New Issue