Compare commits

..

2 Commits

Author SHA1 Message Date
潘嘉晨 81fefb313d perf: refine 2020-03-20 19:49:04 +08:00
aisen60 d54cd25de2 /src/utils/index.js parseTime 添加IE浏览器(版本10以下,包括版本10)兼容。 2020-03-20 00:08:41 +08:00
49 changed files with 256 additions and 481 deletions

View File

@ -3,3 +3,12 @@ ENV = 'development'
# base api # base api
VUE_APP_BASE_API = '/dev-api' VUE_APP_BASE_API = '/dev-api'
# vue-cli uses the VUE_CLI_BABEL_TRANSPILE_MODULES environment variable,
# to control whether the babel-plugin-dynamic-import-node plugin is enabled.
# It only does one thing by converting all import() to require().
# This configuration can significantly increase the speed of hot updates,
# when you have a large number of pages.
# Detail: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/babel-preset-app/index.js
VUE_CLI_BABEL_TRANSPILE_MODULES = true

View File

@ -51,62 +51,51 @@ Vue Element Admin es una solución práctica basada en la nueva plataforma de de
- Plantilla de Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Créditos: [@Armour](https://github.com/Armour)) - Plantilla de Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Créditos: [@Armour](https://github.com/Armour))
- [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312) - [awesome-project](https://github.com/PanJiaChen/vue-element-admin/issues/2312)
**Después de la versión `v4.1.0+`, la rama por defecto master no tendrá soporte para i18n. Por favor utilice la rama [i18n](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), los cambios serán incluidos en la rama master** **Después de la versión `v4.1.0+`, la rama por defecto master no tendrá soporte para i18n. Por favor use [i18n](https://github.com/PanJiaChen/vue-element-admin/tree/i18n), los cambios serán incluidos en la rama master**
**la versión actual es `v4.0+` construida con `vue-cli`. Si encuentra algún problema, por favor coloque un [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). Si desea usar la versión anterior, puede cambiar de rama a [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), no relacionado con `vue-cli`** **la versión actual es `v4.0+` construida con `vue-cli`. Si encuentra algún problema, por favor coloque un [issue](https://github.com/PanJiaChen/vue-element-admin/issues/new). Si desea usar la versión anterior, puede cambiar de rama a [tag/3.11.0](https://github.com/PanJiaChen/vue-element-admin/tree/tag/3.11.0), no relacionado con `vue-cli`**
**Este proyecto no está soportado para versiones antigüas de navegadores (ej. IE).** **Este proyecto no está soportado para versiones muy viejas de navegadores (e.g. IE).**
## Preparación ## Preparación
Necesita instalar [node](https://nodejs.org/) y [git](https://git-scm.com/) localmente. El proyecto es basado en [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), toda la solicitud de datos simulada se realiza a través de [Mock.js](https://github.com/nuysoft/Mock). Necesita instalar [node](https://nodejs.org/) y [git](https://git-scm.com/) localmente. El proyecto es basado en [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), toda la solicitud de datos simulada se realiza a través de [Mock.js](https://github.com/nuysoft/Mock).
Entendiendo y aprendiendo esto pudiera ayudarle con su proyecto. Entendiendo y aprendiendo esto pudiera ayudarle con su proyecto.
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox) <p align="center">
<p align="center">
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
</p> </p>
## Patrocinantes ## Patrocinantes
Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un enlace directo a su sitio web. [[Se un Patrocinante]](https://www.patreon.com/panjiachen) Se un patrocinante y pon tu logo en nuestro README on GitHub con un enlace directo a tu sitio web. [[Se un Patrocinante]](https://www.patreon.com/panjiachen)
### Akveo <a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Plantilla de Dashboard de administración hecha con Vue, React y Angular.</p>
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Get Java backend for Vue admin with 20% discount for 39$ use coupon code SWB0RAZPZR1M
</p>
### Flatlogic
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
## Características ## Características
``` ```
- Iniciar / Cerrar Sesión - Iniciar / Cerrar Sesión
- Permisos de Autenticación - Permisos de Authentication
- Página de Permisos - Página de Permisos
- Directivas de permisos - Directivas de permisos
- Página de configuración de permisos - Página de configuración de permisos
- Autenticación por dos pasos - Autenticación por dos pasos
- Construcción Multi-entorno - Construcción Multi-entorno
- Desarrollo (dev) - dev sit stage producción
- sit
- Escenario de pruebas (stage),
- Producción (prod)
- Características Globales - Características Globales
- I18n - I18n
- Temas dinámicos - Temas dinámicos
- Menu lateral dinámico (soporte a rutas multi-nivel) - Dynamic sidebar (soporte a rutas multi-nivel)
- Barra de rutas dinámica - Barra de rutas dinámica
- Tags-view (Pestañas de página, Soporta operación de clic derecho) - Tags-view (Tab page Support right-click operation)
- Svg Sprite - Svg Sprite
- Datos de simulación con Mock - Datos de simulación con Mock
- Pantalla completa - Pantalla completa
- Menu lateral responsivo - Responsive Sidebar
- Editor - Editor
- Editor de Texto Enriquecido - Editor de Texto Enriquecido
@ -117,7 +106,7 @@ Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un enlace d
- Exportación a Excel - Exportación a Excel
- Carga de Excel - Carga de Excel
- Visualización de Excel - Visualización de Excel
- Exportación como ZIP - Exportación como zip
- Tabla - Tabla
- Tabla Dinámica - Tabla Dinámica
@ -146,7 +135,7 @@ Sea un patrocinante y coloque su logo en nuestro LEEME en GitHub con un enlace d
- Página de Guías - Página de Guías
- ECharts (Gráficos) - ECharts (Gráficos)
- Portapapeles - Portapapeles
- Convertidor de Markdown a HTML - Convertidor de Markdown a html
``` ```
## Iniciando ## Iniciando
@ -219,7 +208,7 @@ Navegadores modernos e 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" />](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 | | [<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 | últimas 2 versiones | últimas 2 versiones | últimas 2 versiones | | IE10, IE11, Edge| últimas 2 versiones| últimas 2 versiones| últimas 2 versiones
## Licencia ## Licencia

View File

@ -59,9 +59,7 @@
**バグ修正や新規機能追加のissue と pull requestは大歓迎です。** **バグ修正や新規機能追加のissue と pull requestは大歓迎です。**
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox) <p align="center">
<p align="center">
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
</p> </p>
@ -69,12 +67,6 @@
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen) Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
### Akveo
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Get Java backend for Vue admin with 20% discount for 39$ use coupon code SWB0RAZPZR1M
</p>
### Flatlogic
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p> <a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
## 機能一覧 ## 機能一覧
@ -89,10 +81,7 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
- 外部IDでログイン - 外部IDでログイン
- 複数環境デプロイ - 複数環境デプロイ
- dev - dev sit stage prod
- sit
- stage
- prod
- 共通機能 - 共通機能
- 多言語切替 - 多言語切替
@ -215,7 +204,7 @@ 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" />](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 | | [<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
## License ## License

View File

@ -28,28 +28,6 @@
English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md) English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md)
<p align="center">
<b>SPONSORED BY</b>
</p>
<table align="center" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="center" valign="middle" width="250">
<a href="https://www.duohui.cn/?utm_source=vue-element-admin&utm_medium=web&utm_campaign=vue-element-admin_github" title="多会" target="_blank">
<img height="60px" src="https://qiniu.cdn.duohui.co/brand/duohui.png" title="多会 - 活动服务销售平台">
<p>活动服务销售平台</p>
</a>
</td>
<td align="center" valign="middle" width="250">
<a href="https://youke.co/?utm_source=vue-element-admin&utm_medium=web&utm_campaign=vue-element-admin_github" title="有客" target="_blank">
<img height="60px" src="https://qiniu.cdn.duohui.co/brand/youke.png" title="有客 - 客户消息直达工作群">
<p>客户消息直达工作群</p>
</a>
</td>
</tr>
</tbody>
</table>
## Introduction ## Introduction
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) is a production-ready front-end solution for admin interfaces. It is based on [vue](https://github.com/vuejs/vue) and uses 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 is based on [vue](https://github.com/vuejs/vue) and uses the UI Toolkit [element-ui](https://github.com/ElemeFE/element).
@ -84,9 +62,7 @@ English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spa
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). 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.
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox) <p align="center">
<p align="center">
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
</p> </p>
@ -94,12 +70,6 @@ Understanding and learning this knowledge in advance will greatly help the use o
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen) Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
### Akveo
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Get Java backend for Vue admin with 20% discount for 39$ use coupon code SWB0RAZPZR1M
</p>
### Flatlogic
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p> <a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
## Features ## Features
@ -114,10 +84,7 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
- Two-step login - Two-step login
- Multi-environment build - Multi-environment build
- Develop (dev) - dev sit stage prod
- sit
- Stage Test (stage)
- Production (prod)
- Global Features - Global Features
- I18n - I18n
@ -241,7 +208,7 @@ 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" />](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 | | [<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
## License ## License

View File

@ -28,28 +28,6 @@
简体中文 | [English](./README.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md) 简体中文 | [English](./README.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md)
<p align="center">
<b>SPONSORED BY</b>
</p>
<table align="center" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td align="center" valign="middle" width="250">
<a href="https://www.duohui.cn/?utm_source=vue-element-admin&utm_medium=web&utm_campaign=vue-element-admin_github" title="多会" target="_blank">
<img height="60px" src="https://qiniu.cdn.duohui.co/brand/duohui.png" title="多会 - 活动服务销售平台">
<p>活动服务销售平台</p>
</a>
</td>
<td align="center" valign="middle" width="250">
<a href="https://youke.co/?utm_source=vue-element-admin&utm_medium=web&utm_campaign=vue-element-admin_github" title="有客" target="_blank">
<img height="60px" src="https://qiniu.cdn.duohui.co/brand/youke.png" title="有客 - 客户消息直达工作群">
<p>客户消息直达工作群</p>
</a>
</td>
</tr>
</tbody>
</table>
## 简介 ## 简介
[vue-element-admin](https://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 国际化解决方案,动态路由,权限验证,提炼了典型的业务模型,提供了丰富的功能组件,它可以帮助你快速搭建企业级中后台产品原型。相信不管你的需求是什么,本项目都能帮助到你。
@ -99,9 +77,7 @@
**如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr** **如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr**
[![Edit on CodeSandbox](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/github/PanJiaChen/vue-element-admin/tree/CodeSandbox) <p align="center">
<p align="center">
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png"> <img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
</p> </p>
@ -109,14 +85,8 @@
Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen) Become a sponsor and get your logo on our README on GitHub with a link to your site. [[Become a sponsor]](https://www.patreon.com/panjiachen)
### Akveo
<a href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=github_banner"><img width="500px" src="https://raw.githubusercontent.com/PanJiaChen/vue-element-admin-site/master/docs/.vuepress/public/images/vue-java-banner.png" /></a><p>Java 后端整合可以使用优惠码SWB0RAZPZR1M获得20%的价格优化</p>
### Flatlogic
<a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p> <a href="https://flatlogic.com/admin-dashboards?from=vue-element-admin"><img width="150px" src="https://wpimg.wallstcn.com/9c0b719b-5551-4c1e-b776-63994632d94a.png" /></a><p>Admin Dashboard Templates made with Vue, React and Angular.</p>
## 功能 ## 功能
``` ```
@ -129,10 +99,7 @@ Become a sponsor and get your logo on our README on GitHub with a link to your s
- 二步登录 - 二步登录
- 多环境发布 - 多环境发布
- dev - dev sit stage prod
- sit
- stage
- prod
- 全局功能 - 全局功能
- 国际化多语言 - 国际化多语言
@ -254,17 +221,13 @@ Detailed changes for each release are documented in the [release notes](https://
[Buy me a coffee](https://www.buymeacoffee.com/Pan) [Buy me a coffee](https://www.buymeacoffee.com/Pan)
## 购买贴纸
你也可以通过 购买[官方授权的贴纸](https://smallsticker.com/product/vue-element-admin) 的方式来支持 vue-element-admin - 每售出一张贴纸,本项目将获得 2 元的捐赠。
## Browsers support ## Browsers support
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" />](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 | | [<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
## License ## License

View File

@ -1,14 +1,5 @@
module.exports = { module.exports = {
presets: [ presets: [
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app '@vue/app'
'@vue/cli-plugin-babel/preset' ]
],
'env': {
'development': {
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
'plugins': ['dynamic-import-node']
}
}
} }

View File

@ -1,4 +1,4 @@
const Mock = require('mockjs') import Mock from 'mockjs'
const List = [] const List = []
const count = 100 const count = 100
@ -27,7 +27,7 @@ for (let i = 0; i < count; i++) {
})) }))
} }
module.exports = [ export default [
{ {
url: '/vue-element-admin/article/list', url: '/vue-element-admin/article/list',
type: 'get', type: 'get',

View File

@ -1,10 +1,10 @@
const Mock = require('mockjs') import Mock from 'mockjs'
const { param2Obj } = require('./utils') import { param2Obj } from '../src/utils'
const user = require('./user') import user from './user'
const role = require('./role') import role from './role'
const article = require('./article') import article from './article'
const search = require('./remote-search') import search from './remote-search'
const mocks = [ const mocks = [
...user, ...user,
@ -16,7 +16,7 @@ const mocks = [
// for front mock // for front mock
// please use it cautiously, it will redefine XMLHttpRequest, // please use it cautiously, it will redefine XMLHttpRequest,
// which will cause many of your third-party libraries to be invalidated(like progress event). // which will cause many of your third-party libraries to be invalidated(like progress event).
function mockXHR() { export function mockXHR() {
// mock patch // mock patch
// https://github.com/nuysoft/Mock/issues/300 // https://github.com/nuysoft/Mock/issues/300
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
@ -54,7 +54,4 @@ function mockXHR() {
} }
} }
module.exports = { export default mocks
mocks,
mockXHR
}

View File

@ -8,7 +8,7 @@ const mockDir = path.join(process.cwd(), 'mock')
function registerRoutes(app) { function registerRoutes(app) {
let mockLastIndex let mockLastIndex
const { mocks } = require('./index.js') const { default: mocks } = require('./index.js')
const mocksForServer = mocks.map(route => { const mocksForServer = mocks.map(route => {
return responseFake(route.url, route.type, route.response) return responseFake(route.url, route.type, route.response)
}) })
@ -44,6 +44,9 @@ const responseFake = (url, type, respond) => {
} }
module.exports = app => { module.exports = app => {
// es6 polyfill
require('@babel/register')
// parse app.body // parse app.body
// https://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())

View File

@ -1,4 +1,4 @@
const Mock = require('mockjs') import Mock from 'mockjs'
const NameList = [] const NameList = []
const count = 100 const count = 100
@ -10,7 +10,7 @@ for (let i = 0; i < count; i++) {
} }
NameList.push({ name: 'mock-Pan' }) NameList.push({ name: 'mock-Pan' })
module.exports = [ export default [
// username search // username search
{ {
url: '/vue-element-admin/search/user', url: '/vue-element-admin/search/user',

View File

@ -1,6 +1,6 @@
const Mock = require('mockjs') import Mock from 'mockjs'
const { deepClone } = require('../utils') import { deepClone } from '../../src/utils/index.js'
const { asyncRoutes, constantRoutes } = require('./routes.js') import { asyncRoutes, constantRoutes } from './routes.js'
const routes = deepClone([...constantRoutes, ...asyncRoutes]) const routes = deepClone([...constantRoutes, ...asyncRoutes])
@ -35,7 +35,7 @@ const roles = [
} }
] ]
module.exports = [ export default [
// mock get all routes form server // mock get all routes form server
{ {
url: '/vue-element-admin/routes', url: '/vue-element-admin/routes',

View File

@ -1,6 +1,6 @@
// Just a mock data // Just a mock data
const constantRoutes = [ export const constantRoutes = [
{ {
path: '/redirect', path: '/redirect',
component: 'layout/Layout', component: 'layout/Layout',
@ -72,7 +72,7 @@ const constantRoutes = [
} }
] ]
const asyncRoutes = [ export const asyncRoutes = [
{ {
path: '/permission', path: '/permission',
component: 'layout/Layout', component: 'layout/Layout',
@ -523,8 +523,3 @@ const asyncRoutes = [
{ path: '*', redirect: '/404', hidden: true } { path: '*', redirect: '/404', hidden: true }
] ]
module.exports = {
constantRoutes,
asyncRoutes
}

View File

@ -23,7 +23,7 @@ const users = {
} }
} }
module.exports = [ export default [
// user login // user login
{ {
url: '/vue-element-admin/user/login', url: '/vue-element-admin/user/login',

View File

@ -1,48 +0,0 @@
/**
* @param {string} url
* @returns {Object}
*/
function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
const val = v.substring(index + 1, v.length)
obj[name] = val
}
})
return obj
}
/**
* This is just a simple version of deep copy
* Has a lot of edge cases bug
* If you want to use a perfect deep copy, use lodash's _.cloneDeep
* @param {Object} source
* @returns {Object}
*/
function deepClone(source) {
if (!source && typeof source !== 'object') {
throw new Error('error arguments', 'deepClone')
}
const targetObj = source.constructor === Array ? [] : {}
Object.keys(source).forEach(keys => {
if (source[keys] && typeof source[keys] === 'object') {
targetObj[keys] = deepClone(source[keys])
} else {
targetObj[keys] = source[keys]
}
})
return targetObj
}
module.exports = {
param2Obj,
deepClone
}

View File

@ -1,28 +1,55 @@
{ {
"name": "vue-element-admin", "name": "vue-element-admin",
"version": "4.4.0", "version": "4.2.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",
"scripts": { "scripts": {
"dev": "vue-cli-service serve", "dev": "vue-cli-service serve",
"lint": "eslint --ext .js,.vue src",
"build:prod": "vue-cli-service build", "build:prod": "vue-cli-service build",
"build:stage": "vue-cli-service build --mode staging", "build:stage": "vue-cli-service build --mode staging",
"preview": "node build/index.js --preview", "preview": "node build/index.js --preview",
"new": "plop", "lint": "eslint --ext .js,.vue src",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
"test:unit": "jest --clearCache && vue-cli-service test:unit", "test:unit": "jest --clearCache && vue-cli-service test:unit",
"test:ci": "npm run lint && npm run test:unit" "test:ci": "npm run lint && npm run test:unit",
"svgo": "svgo -f src/icons/svg --config=src/icons/svgo.yml",
"new": "plop"
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"keywords": [
"vue",
"admin",
"dashboard",
"element-ui",
"boilerplate",
"admin-template",
"management-system"
],
"repository": {
"type": "git",
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
},
"bugs": {
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
}, },
"dependencies": { "dependencies": {
"axios": "0.18.1", "axios": "0.18.1",
"clipboard": "2.0.4", "clipboard": "2.0.4",
"codemirror": "5.45.0", "codemirror": "5.45.0",
"core-js": "3.6.5",
"driver.js": "0.9.5", "driver.js": "0.9.5",
"dropzone": "5.5.1", "dropzone": "5.5.1",
"echarts": "4.2.1", "echarts": "4.2.1",
"element-ui": "2.13.2", "element-ui": "2.13.0",
"file-saver": "2.0.1", "file-saver": "2.0.1",
"fuse.js": "3.4.4", "fuse.js": "3.4.4",
"js-cookie": "2.2.0", "js-cookie": "2.2.0",
@ -33,6 +60,7 @@
"path-to-regexp": "2.4.0", "path-to-regexp": "2.4.0",
"screenfull": "4.2.0", "screenfull": "4.2.0",
"script-loader": "0.7.2", "script-loader": "0.7.2",
"showdown": "1.9.0",
"sortablejs": "1.8.4", "sortablejs": "1.8.4",
"tui-editor": "1.3.3", "tui-editor": "1.3.3",
"vue": "2.6.10", "vue": "2.6.10",
@ -44,68 +72,42 @@
"xlsx": "0.14.1" "xlsx": "0.14.1"
}, },
"devDependencies": { "devDependencies": {
"@vue/cli-plugin-babel": "4.4.4", "@babel/core": "7.0.0",
"@vue/cli-plugin-eslint": "4.4.4", "@babel/register": "7.0.0",
"@vue/cli-plugin-unit-jest": "4.4.4", "@vue/cli-plugin-babel": "3.5.3",
"@vue/cli-service": "4.4.4", "@vue/cli-plugin-eslint": "^3.9.1",
"@vue/cli-plugin-unit-jest": "3.5.3",
"@vue/cli-service": "3.5.3",
"@vue/test-utils": "1.0.0-beta.29", "@vue/test-utils": "1.0.0-beta.29",
"autoprefixer": "9.5.1", "autoprefixer": "^9.5.1",
"babel-eslint": "10.1.0", "babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.0.1",
"babel-jest": "23.6.0", "babel-jest": "23.6.0",
"babel-plugin-dynamic-import-node": "2.3.3",
"chalk": "2.4.2", "chalk": "2.4.2",
"chokidar": "2.1.5", "chokidar": "2.1.5",
"connect": "3.6.6", "connect": "3.6.6",
"eslint": "6.7.2", "eslint": "5.15.3",
"eslint-plugin-vue": "6.2.2", "eslint-plugin-vue": "5.2.2",
"html-webpack-plugin": "3.2.0", "html-webpack-plugin": "3.2.0",
"husky": "1.3.1", "husky": "1.3.1",
"lint-staged": "8.1.5", "lint-staged": "8.1.5",
"mockjs": "1.0.1-beta3", "mockjs": "1.0.1-beta3",
"node-sass": "^4.9.0",
"plop": "2.3.0", "plop": "2.3.0",
"runjs": "4.3.2", "runjs": "^4.3.2",
"sass": "1.26.2", "sass-loader": "^7.1.0",
"sass-loader": "8.0.2",
"script-ext-html-webpack-plugin": "2.1.3", "script-ext-html-webpack-plugin": "2.1.3",
"serve-static": "1.13.2", "serve-static": "^1.13.2",
"svg-sprite-loader": "4.1.3", "svg-sprite-loader": "4.1.3",
"svgo": "1.2.0", "svgo": "1.2.0",
"vue-template-compiler": "2.6.10" "vue-template-compiler": "2.6.10"
}, },
"browserslist": [
"> 1%",
"last 2 versions"
],
"bugs": {
"url": "https://github.com/PanJiaChen/vue-element-admin/issues"
},
"engines": { "engines": {
"node": ">=8.9", "node": ">=8.9",
"npm": ">= 3.0.0" "npm": ">= 3.0.0"
}, },
"keywords": [ "browserslist": [
"vue", "> 1%",
"admin", "last 2 versions"
"dashboard", ]
"element-ui",
"boilerplate",
"admin-template",
"management-system"
],
"license": "MIT",
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix",
"git add"
]
},
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"repository": {
"type": "git",
"url": "git+https://github.com/PanJiaChen/vue-element-admin.git"
}
} }

View File

@ -1,2 +1,9 @@
exports.notEmpty = name => v => exports.notEmpty = name => {
!v || v.trim() === '' ? `${name} is required` : true return v => {
if (!v || v.trim === '') {
return `${name} is required`
} else {
return true
}
}
}

View File

@ -48,18 +48,14 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style scoped>
.drag-select { .drag-select >>> .sortable-ghost {
::v-deep { opacity: .8;
.sortable-ghost { color: #fff!important;
opacity: .8; background: #42b983!important;
color: #fff !important; }
background: #42b983 !important;
}
.el-tag { .drag-select >>> .el-tag {
cursor: pointer; cursor: pointer;
}
}
} }
</style> </style>

View File

@ -159,7 +159,7 @@ export default {
display: inline-block; display: inline-block;
vertical-align: middle; vertical-align: middle;
::v-deep .el-input__inner { /deep/ .el-input__inner {
border-radius: 0; border-radius: 0;
border: 0; border: 0;
padding-left: 0; padding-left: 0;

View File

@ -248,7 +248,6 @@ export default {
// //
isSupported, isSupported,
// //
// eslint-disable-next-line no-prototype-builtins
isSupportTouch: document.hasOwnProperty('ontouchstart'), isSupportTouch: document.hasOwnProperty('ontouchstart'),
// //
step: 1, // 1 2 3 step: 1, // 1 2 3

View File

@ -54,24 +54,19 @@ export default {
} }
</script> </script>
<style lang="scss" scoped> <style scoped>
.json-editor { .json-editor{
height: 100%; height: 100%;
position: relative; position: relative;
}
::v-deep { .json-editor >>> .CodeMirror {
.CodeMirror { height: auto;
height: auto; min-height: 300px;
min-height: 300px; }
} .json-editor >>> .CodeMirror-scroll{
min-height: 300px;
.CodeMirror-scroll { }
min-height: 300px; .json-editor >>> .cm-s-rubyblue span.cm-string {
} color: #F08047;
.cm-s-rubyblue span.cm-string {
color: #F08047;
}
}
} }
</style> </style>

View File

@ -1,7 +1,7 @@
<template> <template>
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" /> <div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners"> <svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
<use :xlink:href="iconName" /> <use :href="iconName" />
</svg> </svg>
</template> </template>

View File

@ -104,7 +104,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.editor-slide-upload { .editor-slide-upload {
margin-bottom: 20px; margin-bottom: 20px;
::v-deep .el-upload--picture-card { /deep/ .el-upload--picture-card {
width: 100%; width: 100%;
} }
} }

View File

@ -147,11 +147,7 @@ export default {
editor.on('FullscreenStateChanged', (e) => { editor.on('FullscreenStateChanged', (e) => {
_this.fullscreen = e.state _this.fullscreen = e.state
}) })
}, }
// it will try to keep these URLs intact
// https://www.tiny.cloud/docs-3x/reference/configuration/Configuration3x@convert_urls/
// https://stackoverflow.com/questions/5196205/disable-tinymce-absolute-to-relative-url-conversions
convert_urls: false
// //
// images_dataimg_filter(img) { // images_dataimg_filter(img) {
// setTimeout(() => { // setTimeout(() => {
@ -204,43 +200,37 @@ export default {
window.tinymce.get(this.tinymceId).getContent() window.tinymce.get(this.tinymceId).getContent()
}, },
imageSuccessCBK(arr) { imageSuccessCBK(arr) {
arr.forEach(v => window.tinymce.get(this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)) const _this = this
arr.forEach(v => {
window.tinymce.get(_this.tinymceId).insertContent(`<img class="wscnph" src="${v.url}" >`)
})
} }
} }
} }
</script> </script>
<style lang="scss" scoped> <style scoped>
.tinymce-container { .tinymce-container {
position: relative; position: relative;
line-height: normal; line-height: normal;
} }
.tinymce-container>>>.mce-fullscreen {
.tinymce-container { z-index: 10000;
::v-deep {
.mce-fullscreen {
z-index: 10000;
}
}
} }
.tinymce-textarea { .tinymce-textarea {
visibility: hidden; visibility: hidden;
z-index: -1; z-index: -1;
} }
.editor-custom-btn-container { .editor-custom-btn-container {
position: absolute; position: absolute;
right: 4px; right: 4px;
top: 4px; top: 4px;
/*z-index: 2005;*/ /*z-index: 2005;*/
} }
.fullscreen .editor-custom-btn-container { .fullscreen .editor-custom-btn-container {
z-index: 10000; z-index: 10000;
position: fixed; position: fixed;
} }
.editor-upload-btn { .editor-upload-btn {
display: inline-block; display: inline-block;
} }

View File

@ -1,11 +1,11 @@
import store from '@/store' import store from '@/store'
function checkPermission(el, binding) { export default {
const { value } = binding inserted(el, binding, vnode) {
const roles = store.getters && store.getters.roles const { value } = binding
const roles = store.getters && store.getters.roles
if (value && value instanceof Array) { if (value && value instanceof Array && value.length > 0) {
if (value.length > 0) {
const permissionRoles = value const permissionRoles = value
const hasPermission = roles.some(role => { const hasPermission = roles.some(role => {
@ -15,17 +15,8 @@ function checkPermission(el, binding) {
if (!hasPermission) { if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el) el.parentNode && el.parentNode.removeChild(el)
} }
} else {
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
} }
} else {
throw new Error(`need roles! Like v-permission="['admin','editor']"`)
}
}
export default {
inserted(el, binding) {
checkPermission(el, binding)
},
update(el, binding) {
checkPermission(el, binding)
} }
} }

View File

@ -17,11 +17,7 @@ export default {
const vnodes = [] const vnodes = []
if (icon) { if (icon) {
if (icon.includes('el-icon')) { vnodes.push(<svg-icon icon-class={icon}/>)
vnodes.push(<i class={[icon, 'sub-el-icon']} />)
} else {
vnodes.push(<svg-icon icon-class={icon}/>)
}
} }
if (title) { if (title) {
@ -31,11 +27,3 @@ export default {
} }
} }
</script> </script>
<style scoped>
.sub-el-icon {
color: currentColor;
width: 1em;
height: 1em;
}
</style>

View File

@ -1,5 +1,7 @@
<template> <template>
<component :is="type" v-bind="linkProps(to)"> <!-- eslint-disable vue/require-component-is -->
<component v-bind="linkProps(to)">
<slot /> <slot />
</component> </component>
</template> </template>
@ -14,28 +16,19 @@ export default {
required: true required: true
} }
}, },
computed: {
isExternal() {
return isExternal(this.to)
},
type() {
if (this.isExternal) {
return 'a'
}
return 'router-link'
}
},
methods: { methods: {
linkProps(to) { linkProps(url) {
if (this.isExternal) { if (isExternal(url)) {
return { return {
href: to, is: 'a',
href: url,
target: '_blank', target: '_blank',
rel: 'noopener' rel: 'noopener'
} }
} }
return { return {
to: to is: 'router-link',
to: url
} }
} }
} }

View File

@ -19,21 +19,12 @@ export default {
return this.$refs.scrollContainer.$refs.wrap return this.$refs.scrollContainer.$refs.wrap
} }
}, },
mounted() {
this.scrollWrapper.addEventListener('scroll', this.emitScroll, true)
},
beforeDestroy() {
this.scrollWrapper.removeEventListener('scroll', this.emitScroll)
},
methods: { methods: {
handleScroll(e) { handleScroll(e) {
const eventDelta = e.wheelDelta || -e.deltaY * 40 const eventDelta = e.wheelDelta || -e.deltaY * 40
const $scrollWrapper = this.scrollWrapper const $scrollWrapper = this.scrollWrapper
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4 $scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
}, },
emitScroll() {
this.$emit('scroll')
},
moveToTarget(currentTag) { moveToTarget(currentTag) {
const $container = this.$refs.scrollContainer.$el const $container = this.$refs.scrollContainer.$el
const $containerWidth = $container.offsetWidth const $containerWidth = $container.offsetWidth
@ -82,7 +73,7 @@ export default {
position: relative; position: relative;
overflow: hidden; overflow: hidden;
width: 100%; width: 100%;
::v-deep { /deep/ {
.el-scrollbar__bar { .el-scrollbar__bar {
bottom: 0px; bottom: 0px;
} }

View File

@ -1,6 +1,6 @@
<template> <template>
<div id="tags-view-container" class="tags-view-container"> <div id="tags-view-container" class="tags-view-container">
<scroll-pane ref="scrollPane" class="tags-view-wrapper" @scroll="handleScroll"> <scroll-pane ref="scrollPane" class="tags-view-wrapper">
<router-link <router-link
v-for="tag in visitedViews" v-for="tag in visitedViews"
ref="tag" ref="tag"
@ -189,9 +189,6 @@ export default {
}, },
closeMenu() { closeMenu() {
this.visible = false this.visible = false
},
handleScroll() {
this.closeMenu()
} }
} }
} }

View File

@ -6,7 +6,6 @@ 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'
import enLang from 'element-ui/lib/locale/lang/en'// 如果使用中文语言包请默认支持,无需额外引入,请删除该依赖
import '@/styles/index.scss' // global css import '@/styles/index.scss' // global css
@ -34,8 +33,7 @@ if (process.env.NODE_ENV === 'production') {
} }
Vue.use(Element, { Vue.use(Element, {
size: Cookies.get('size') || 'medium', // set element-ui default size size: Cookies.get('size') || 'medium' // set element-ui default size
locale: enLang // 如果使用中文,无需设置,请删除
}) })
// register global utility filters // register global utility filters

View File

@ -24,7 +24,7 @@ router.beforeEach(async(to, from, next) => {
if (to.path === '/login') { if (to.path === '/login') {
// if is logged in, redirect to the home page // if is logged in, redirect to the home page
next({ path: '/' }) next({ path: '/' })
NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939 NProgress.done()
} else { } else {
// determine whether the user has obtained his permission roles through getInfo // determine whether the user has obtained his permission roles through getInfo
const hasRoles = store.getters.roles && store.getters.roles.length > 0 const hasRoles = store.getters.roles && store.getters.roles.length > 0

View File

@ -25,7 +25,7 @@ import nestedRouter from './modules/nested'
* 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)
title: 'title' the name show in sidebar and breadcrumb (recommend set) title: 'title' the name show in sidebar and breadcrumb (recommend set)
icon: 'svg-name'/'el-icon-x' the icon show in the sidebar icon: 'svg-name' the icon show in the sidebar
noCache: true if set true, the page will no be cached(default is false) noCache: true if set true, the page will no be cached(default is false)
affix: true if set true, the tag will affix in the tags-view affix: true if set true, the tag will affix in the tags-view
breadcrumb: false if set false, the item will hidden in breadcrumb(default is true) breadcrumb: false if set false, the item will hidden in breadcrumb(default is true)
@ -197,7 +197,7 @@ export const asyncRoutes = [
name: 'Example', name: 'Example',
meta: { meta: {
title: 'Example', title: 'Example',
icon: 'el-icon-s-help' icon: 'example'
}, },
children: [ children: [
{ {

View File

@ -13,7 +13,6 @@ const state = {
const mutations = { const mutations = {
CHANGE_SETTING: (state, { key, value }) => { CHANGE_SETTING: (state, { key, value }) => {
// eslint-disable-next-line no-prototype-builtins
if (state.hasOwnProperty(key)) { if (state.hasOwnProperty(key)) {
state[key] = value state[key] = value
} }

View File

@ -103,23 +103,28 @@ const actions = {
}, },
// dynamically modify permissions // dynamically modify permissions
async changeRoles({ commit, dispatch }, role) { changeRoles({ commit, dispatch }, role) {
const token = role + '-token' return new Promise(async resolve => {
const token = role + '-token'
commit('SET_TOKEN', token) commit('SET_TOKEN', token)
setToken(token) setToken(token)
const { roles } = await dispatch('getInfo') const { roles } = await dispatch('getInfo')
resetRouter() resetRouter()
// generate accessible routes map based on roles // generate accessible routes map based on roles
const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true }) const accessRoutes = await dispatch('permission/generateRoutes', roles, { root: true })
// dynamically add accessible routes
router.addRoutes(accessRoutes)
// reset visited views and cached views // dynamically add accessible routes
dispatch('tagsView/delAllViews', null, { root: true }) router.addRoutes(accessRoutes)
// reset visited views and cached views
dispatch('tagsView/delAllViews', null, { root: true })
resolve()
})
} }
} }

View File

@ -31,7 +31,7 @@
.fixed-width { .fixed-width {
.el-button--mini { .el-button--mini {
padding: 7px 10px; padding: 7px 10px;
min-width: 60px; width: 60px;
} }
} }

View File

@ -6,7 +6,7 @@
/* theme color */ /* theme color */
$--color-primary: #1890ff; $--color-primary: #1890ff;
$--color-success: #13ce66; $--color-success: #13ce66;
$--color-warning: #ffba00; $--color-warning: #FFBA00;
$--color-danger: #ff4949; $--color-danger: #ff4949;
// $--color-info: #1E1E1E; // $--color-info: #1E1E1E;
@ -17,10 +17,10 @@ $--button-font-weight: 400;
$--border-color-light: #dfe4ed; $--border-color-light: #dfe4ed;
$--border-color-lighter: #e6ebf5; $--border-color-lighter: #e6ebf5;
$--table-border: 1px solid #dfe6ec; $--table-border:1px solid#dfe6ec;
/* icon font path, required */ /* icon font path, required */
$--font-path: "~element-ui/lib/theme-chalk/fonts"; $--font-path: '~element-ui/lib/theme-chalk/fonts';
@import "~element-ui/packages/theme-chalk/src/index"; @import "~element-ui/packages/theme-chalk/src/index";

View File

@ -57,11 +57,6 @@
margin-right: 16px; margin-right: 16px;
} }
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
.el-menu { .el-menu {
border: none; border: none;
height: 100%; height: 100%;
@ -110,10 +105,6 @@
.svg-icon { .svg-icon {
margin-left: 20px; margin-left: 20px;
} }
.sub-el-icon {
margin-left: 19px;
}
} }
} }
@ -127,10 +118,6 @@
margin-left: 20px; margin-left: 20px;
} }
.sub-el-icon {
margin-left: 19px;
}
.el-submenu__icon-arrow { .el-submenu__icon-arrow {
display: none; display: none;
} }
@ -191,10 +178,6 @@
.svg-icon { .svg-icon {
margin-right: 16px; margin-right: 16px;
} }
.sub-el-icon {
margin-right: 12px;
margin-left: -2px;
}
} }
.nest-menu .el-submenu>.el-submenu__title, .nest-menu .el-submenu>.el-submenu__title,

View File

@ -9,7 +9,7 @@
* @returns {string | null} * @returns {string | null}
*/ */
export function parseTime(time, cFormat) { export function parseTime(time, cFormat) {
if (arguments.length === 0 || !time) { if (arguments.length === 0) {
return null return null
} }
const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}' const format = cFormat || '{y}-{m}-{d} {h}:{i}:{s}'
@ -162,21 +162,19 @@ export function param(json) {
* @returns {Object} * @returns {Object}
*/ */
export function param2Obj(url) { export function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ') const search = url.split('?')[1]
if (!search) { if (!search) {
return {} return {}
} }
const obj = {} return JSON.parse(
const searchArr = search.split('&') '{"' +
searchArr.forEach(v => { decodeURIComponent(search)
const index = v.indexOf('=') .replace(/"/g, '\\"')
if (index !== -1) { .replace(/&/g, '","')
const name = v.substring(0, index) .replace(/=/g, '":"')
const val = v.substring(index + 1, v.length) .replace(/\+/g, ' ') +
obj[name] = val '"}'
} )
})
return obj
} }
/** /**

View File

@ -13,7 +13,11 @@ export default function checkPermission(value) {
const hasPermission = roles.some(role => { const hasPermission = roles.some(role => {
return permissionRoles.includes(role) return permissionRoles.includes(role)
}) })
return hasPermission
if (!hasPermission) {
return false
}
return true
} else { } else {
console.error(`need roles! Like v-permission="['admin','editor']"`) console.error(`need roles! Like v-permission="['admin','editor']"`)
return false return false

View File

@ -2,7 +2,7 @@
<div class="components-container"> <div class="components-container">
<aside> <aside>
Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction. Rich text is a core feature of the management backend, but at the same time it is a place with lots of pits. In the process of selecting rich texts, I also took a lot of detours. The common rich texts on the market have been basically used, and I finally chose Tinymce. See the more detailed rich text comparison and introduction.
<a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/feature/component/rich-editor.html">Documentation</a> <a target="_blank" class="link-type" href="https://panjiachen.github.io/vue-element-admin-site/component/rich-editor.html">Documentation</a>
</aside> </aside>
<div> <div>
<tinymce v-model="content" :height="300" /> <tinymce v-model="content" :height="300" />

View File

@ -15,7 +15,7 @@
<el-progress :percentage="18" /> <el-progress :percentage="18" />
</div> </div>
<div class="progress-item"> <div class="progress-item">
<span>CSS</span> <span>Css</span>
<el-progress :percentage="12" /> <el-progress :percentage="12" />
</div> </div>
<div class="progress-item"> <div class="progress-item">
@ -101,7 +101,7 @@ export default {
background-color: #fff; background-color: #fff;
margin: auto; margin: auto;
box-shadow: none!important; box-shadow: none!important;
::v-deep .pan-info { /deep/ .pan-info {
box-shadow: none!important; box-shadow: none!important;
} }
} }

View File

@ -70,7 +70,7 @@ export default {
indicator: [ indicator: [
{ name: 'Sales', max: 10000 }, { name: 'Sales', max: 10000 },
{ name: 'Administration', max: 20000 }, { name: 'Administration', max: 20000 },
{ name: 'Information Technology', max: 20000 }, { name: 'Information Techology', max: 20000 },
{ name: 'Customer Support', max: 20000 }, { name: 'Customer Support', max: 20000 },
{ name: 'Development', max: 20000 }, { name: 'Development', max: 20000 },
{ name: 'Marketing', max: 20000 } { name: 'Marketing', max: 20000 }

View File

@ -1,6 +1,5 @@
<template> <template>
<div class="app-container documentation-container"> <div class="app-container documentation-container">
<a class="document-btn" target="_blank" href="https://store.akveo.com/products/vue-java-admin-dashboard-spring?utm_campaign=akveo_store-Vue-Vue_demo%2Fgithub&utm_source=vue_admin&utm_medium=referral&utm_content=demo_English_button">Java backend integration</a>
<a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/">Documentation</a> <a class="document-btn" target="_blank" href="https://panjiachen.github.io/vue-element-admin-site/">Documentation</a>
<a class="document-btn" target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">Github Repository</a> <a class="document-btn" target="_blank" href="https://github.com/PanJiaChen/vue-element-admin/">Github Repository</a>
<a class="document-btn" target="_blank" href="https://panjiachen.gitee.io/vue-element-admin-site/zh/">国内文档</a> <a class="document-btn" target="_blank" href="https://panjiachen.gitee.io/vue-element-admin-site/zh/">国内文档</a>
@ -38,7 +37,7 @@ export default {
margin: 50px; margin: 50px;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: flex-start; justify-content: space-evenly;
.document-btn { .document-btn {
flex-shrink: 0; flex-shrink: 0;
@ -47,8 +46,8 @@ export default {
background: black; background: black;
color: white; color: white;
height: 60px; height: 60px;
padding: 0 16px; width: 200px;
margin: 16px; margin-bottom: 16px;
line-height: 60px; line-height: 60px;
font-size: 20px; font-size: 20px;
text-align: center; text-align: center;

View File

@ -277,7 +277,7 @@ export default {
} }
} }
.article-textarea ::v-deep { .article-textarea /deep/ {
textarea { textarea {
padding-right: 40px; padding-right: 40px;
resize: none; resize: none;

View File

@ -71,21 +71,21 @@ export default {
}, },
handleDownload() { handleDownload() {
this.downloadLoading = true this.downloadLoading = true
import('@/vendor/Export2Excel').then(excel => { import('@/vendor/Export2Excel').then(excel => {
const multiHeader = [['Id', 'Main Information', '', '', 'Date']] const multiHeader = [['Id', 'Main Information', '', '', 'Date']]
const header = ['', 'Title', 'Author', 'Readings', ''] const header = ['', 'Title', 'Author', 'Readings', '']
const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time'] const filterVal = ['id', 'title', 'author', 'pageviews', 'display_time']
const list = this.list const list = this.list
const data = this.formatJson(filterVal, list) const data = this.formatJson(filterVal, list)
const merges = ['A1:A2', 'B1:D1', 'E1:E2'] const merges = ['A1:A2', 'B1:D1', 'E1:E2']
excel.export_json_to_excel({ excel.export_json_to_excel({
multiHeader, multiHeader,
header, header,
merges, merges,
data data
})
this.downloadLoading = false
}) })
this.downloadLoading = false
})
}, },
formatJson(filterVal, jsonData) { formatJson(filterVal, jsonData) {
return jsonData.map(v => filterVal.map(j => { return jsonData.map(v => filterVal.map(j => {

View File

@ -91,7 +91,7 @@ export default {
<style lang="scss" scoped> <style lang="scss" scoped>
.app-container { .app-container {
::v-deep .permission-alert { /deep/ .permission-alert {
width: 320px; width: 320px;
margin-top: 15px; margin-top: 15px;
background-color: #f0f9eb; background-color: #f0f9eb;
@ -100,10 +100,10 @@ export default {
border-radius: 4px; border-radius: 4px;
display: inline-block; display: inline-block;
} }
::v-deep .permission-sourceCode { /deep/ .permission-sourceCode {
margin-left: 15px; margin-left: 15px;
} }
::v-deep .permission-tag { /deep/ .permission-tag {
background-color: #ecf5ff; background-color: #ecf5ff;
} }
} }

View File

@ -13,11 +13,11 @@
</template> </template>
<script> <script>
import TabPane from './components/TabPane' import tabPane from './components/TabPane'
export default { export default {
name: 'Tab', name: 'Tab',
components: { TabPane }, components: { tabPane },
data() { data() {
return { return {
tabMapOptions: [ tabMapOptions: [

View File

@ -1,14 +0,0 @@
import { param2Obj } from '@/utils/index.js'
describe('Utils:param2Obj', () => {
const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95'
it('param2Obj test', () => {
expect(param2Obj(url)).toEqual({
name: 'bill',
age: '29',
sex: '1',
field: window.btoa('test'),
key: '测试'
})
})
})

View File

@ -1,5 +1,4 @@
import { parseTime } from '@/utils/index.js' import { parseTime } from '@/utils/index.js'
describe('Utils:parseTime', () => { describe('Utils:parseTime', () => {
const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01"
it('timestamp', () => { it('timestamp', () => {
@ -30,8 +29,4 @@ describe('Utils:parseTime', () => {
it('empty argument', () => { it('empty argument', () => {
expect(parseTime()).toBeNull() expect(parseTime()).toBeNull()
}) })
it('null', () => {
expect(parseTime(null)).toBeNull()
})
}) })

View File

@ -49,20 +49,8 @@ module.exports = {
} }
}, },
chainWebpack(config) { chainWebpack(config) {
// it can improve the speed of the first screen, it is recommended to turn on preload config.plugins.delete('preload') // TODO: need test
// it can improve the speed of the first screen, it is recommended to turn on preload config.plugins.delete('prefetch') // TODO: need test
config.plugin('preload').tap(() => [
{
rel: 'preload',
// to ignore runtime.js
// https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/config/app.js#L171
fileBlacklist: [/\.map$/, /hot-update\.js$/, /runtime\..*\.js$/],
include: 'initial'
}
])
// when there are many pages, it will cause too many meaningless requests
config.plugins.delete('prefetch')
// set svg-sprite-loader // set svg-sprite-loader
config.module config.module
@ -81,6 +69,23 @@ module.exports = {
}) })
.end() .end()
// set preserveWhitespace
config.module
.rule('vue')
.use('vue-loader')
.loader('vue-loader')
.tap(options => {
options.compilerOptions.preserveWhitespace = true
return options
})
.end()
config
// https://webpack.js.org/configuration/devtool/#development
.when(process.env.NODE_ENV === 'development',
config => config.devtool('cheap-source-map')
)
config config
.when(process.env.NODE_ENV !== 'development', .when(process.env.NODE_ENV !== 'development',
config => { config => {
@ -116,7 +121,6 @@ module.exports = {
} }
} }
}) })
// https:// webpack.js.org/configuration/optimization/#optimizationruntimechunk
config.optimization.runtimeChunk('single') config.optimization.runtimeChunk('single')
} }
) )