commit
2fad27f54d
|
@ -0,0 +1,4 @@
|
|||
# These are supported funding model platforms
|
||||
|
||||
patreon: panjiachen
|
||||
custom: https://panjiachen.github.io/vue-element-admin-site/donate
|
|
@ -12,3 +12,24 @@ about: Asking questions about use
|
|||
Before asking a question, please make sure that you have tried your best to solve this problem.
|
||||
If it's a code-related issue, please don't just take screenshots. Please provide an online demo to save each other's time.
|
||||
-->
|
||||
|
||||
#### Steps to reproduce(问题复现步骤)
|
||||
<!--
|
||||
1. [xxx]
|
||||
2. [xxx]
|
||||
3. [xxxx]
|
||||
-->
|
||||
|
||||
#### Screenshot or Gif(截图或动态图)
|
||||
|
||||
|
||||
#### Link to minimal reproduction(最小可在线还原demo)
|
||||
|
||||
<!--
|
||||
Please only use Codepen, JSFiddle, CodeSandbox or a github repo
|
||||
-->
|
||||
|
||||
#### Other relevant information(格外信息)
|
||||
- Your OS:
|
||||
- Node.js version:
|
||||
- vue-element-admin version:
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||
|
||||
module.exports = {
|
||||
"plugins": {
|
||||
// to edit target browsers: use "browserslist" field in package.json
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
<p align="center">
|
||||
<img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg">
|
||||
</p>
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/vuejs/vue">
|
||||
<img src="https://img.shields.io/badge/vue-2.6.10-brightgreen.svg" alt="vue">
|
||||
</a>
|
||||
<a href="https://github.com/ElemeFE/element">
|
||||
<img src="https://img.shields.io/badge/element--ui-2.7.0-brightgreen.svg" alt="element-ui">
|
||||
</a>
|
||||
<a href="https://travis-ci.org/PanJiaChen/vue-element-admin" rel="nofollow">
|
||||
<img src="https://travis-ci.org/PanJiaChen/vue-element-admin.svg?branch=master" alt="Estado de Construcción">
|
||||
</a>
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/mashape/apistatus.svg" alt="Licencia">
|
||||
</a>
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin/releases">
|
||||
<img src="https://img.shields.io/github/release/PanJiaChen/vue-element-admin.svg" alt="Liberación Github">
|
||||
</a>
|
||||
<a href="https://gitter.im/vue-element-admin/discuss">
|
||||
<img src="https://badges.gitter.im/Join%20Chat.svg" alt="Gitter">
|
||||
</a>
|
||||
<a href="https://panjiachen.github.io/vue-element-admin-site/donate">
|
||||
<img src="https://img.shields.io/badge/%24-donate-ff69b4.svg" alt="Donación">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
Español | [English](./README.md) | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md)
|
||||
|
||||
## Introducción
|
||||
|
||||
[vue-element-admin](https://panjiachen.github.io/vue-element-admin) es una interfáz de administración preparada para producción. Está basada en [vue](https://github.com/vuejs/vue) y usa [element-ui](https://github.com/ElemeFE/element) como conjunto de herramientas de interfáz de usuario.
|
||||
|
||||
Vue Element Admin es una solución práctica basada en la nueva plataforma de desarrollo de vue, construida con soporte a i18 para el manejo de múltiples lenguajes, plantillas estándares para aplicaciones de negocio y un conjunto de asombrosas características. Esta herramienta ayuda a construir largas y complejas Aplicacones de una sola página (SPA). Creo que lo que necesites hacer, este proyecto te ayudará.
|
||||
|
||||
- [Vista Prévia de la Aplicación](https://panjiachen.github.io/vue-element-admin)
|
||||
|
||||
- [Documentación](https://panjiachen.github.io/vue-element-admin-site/)
|
||||
|
||||
- [Canal de Gitter](https://gitter.im/vue-element-admin/discuss)
|
||||
|
||||
- [Para Donaciones](https://panjiachen.github.io/vue-element-admin-site/donate/)
|
||||
|
||||
- [Enlace de Wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
||||
|
||||
- [Canal de Gitee](https://panjiachen.gitee.io/vue-element-admin/)
|
||||
|
||||
- Plantilla base recomendada para usar: [vue-admin-template](https://github.com/PanJiaChen/vue-admin-template)
|
||||
- Aplicación de Escritorio: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
||||
- Plantilla de Typescript: [vue-typescript-admin-template](https://github.com/Armour/vue-typescript-admin-template) (Créditos: [@Armour](https://github.com/Armour))
|
||||
|
||||
**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`**
|
||||
|
||||
**Este proyecto no está soportado para versiones muy viejas de navegadores (e.g. IE).**
|
||||
|
||||
## 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).
|
||||
Entendiendo y aprendiendo esto pudiera ayudarle con su proyecto.
|
||||
|
||||
<p align="center">
|
||||
<img width="900" src="https://wpimg.wallstcn.com/a5894c1b-f6af-456e-82df-1151da0839bf.png">
|
||||
</p>
|
||||
|
||||
## Patrocinantes
|
||||
|
||||
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)
|
||||
|
||||
<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>
|
||||
|
||||
## Características
|
||||
|
||||
```
|
||||
- Iniciar / Cerrar Sesión
|
||||
|
||||
- Permisos de Authentication
|
||||
- Página de Permisos
|
||||
- Directivas de permisos
|
||||
- Página de configuración de permisos
|
||||
- Autenticación por dos pasos
|
||||
|
||||
- Construcción Multi-entorno
|
||||
- dev sit stage producción
|
||||
|
||||
- Características Globales
|
||||
- I18n
|
||||
- Temas dinámicos
|
||||
- Dynamic sidebar (soporte a rutas multi-nivel)
|
||||
- Barra de rutas dinámica
|
||||
- Tags-view (Tab page Support right-click operation)
|
||||
- Svg Sprite
|
||||
- Datos de simulación con Mock
|
||||
- Pantalla completa
|
||||
- Responsive Sidebar
|
||||
|
||||
- Editor
|
||||
- Editor de Texto Enriquecido
|
||||
- Editor Markdown
|
||||
- Editor JSON
|
||||
|
||||
- Excel
|
||||
- Exportación a Excel
|
||||
- Carga de Excel
|
||||
- Visualización de Excel
|
||||
- Exportación como zip
|
||||
|
||||
- Tabla
|
||||
- Tabla Dinámica
|
||||
- Tabla con Arrastrar y Soltar
|
||||
- Tabla de edición en línea
|
||||
|
||||
- Páginas de Error
|
||||
- 401
|
||||
- 404
|
||||
|
||||
- Componentes
|
||||
- Carga de Avatar
|
||||
- Botón para subir al inicio
|
||||
- Arrastrar y Soltar (Diaglogo)
|
||||
- Arrastrar y Soltar (Seleccionar)
|
||||
- Arrastrar y Soltar (Kanban)
|
||||
- Arrastrar y Soltar (Lista)
|
||||
- Panel de división
|
||||
- Componente para soltar archivos
|
||||
- Adhesión de objetos
|
||||
- Contador hasta
|
||||
|
||||
- Ejemplo Avanzado
|
||||
- Registro de Errores
|
||||
- Tablero de indicadores
|
||||
- Página de Guías
|
||||
- ECharts (Gráficos)
|
||||
- Portapapeles
|
||||
- Convertidor de Markdown a html
|
||||
```
|
||||
|
||||
## Iniciando
|
||||
|
||||
```bash
|
||||
# clone el proyecto
|
||||
git clone https://github.com/PanJiaChen/vue-element-admin.git
|
||||
|
||||
# vaya al directorio clonado
|
||||
cd vue-element-admin
|
||||
|
||||
# instale las dependencias
|
||||
npm install
|
||||
|
||||
# corra el proyecto como desarrollador
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Automáticamente se abrirá el siguiente enlace en su navegador http://localhost:9527
|
||||
|
||||
## Construcción
|
||||
|
||||
```bash
|
||||
# Construcción para entornos de prueba
|
||||
npm run build:stage
|
||||
|
||||
# Construcción para entornos de producción
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
## Avanzado
|
||||
|
||||
```bash
|
||||
# Vista previa con efectos de entorno
|
||||
npm run preview
|
||||
|
||||
# Vista previa con efectos + análisis de recursos estáticos
|
||||
npm run preview -- --report
|
||||
|
||||
# Chequeo de formato de código
|
||||
npm run lint
|
||||
|
||||
# Chequeo de formato de código y auto-corrección
|
||||
npm run lint -- --fix
|
||||
```
|
||||
|
||||
Vaya a [Documentación](https://panjiachen.github.io/vue-element-admin-site/guide/essentials/deploy.html) para mayor información
|
||||
|
||||
## Registro de Cambios
|
||||
|
||||
Los cambios detallados por cada liberación se encuentran en [notas de liberación](https://github.com/PanJiaChen/vue-element-admin/releases).
|
||||
|
||||
## Demostración en línea
|
||||
|
||||
[Vista Prévia de la Aplicación](https://panjiachen.github.io/vue-element-admin)
|
||||
|
||||
## Donación
|
||||
|
||||
Si este proyecto es de mucha ayuda para ti, puedes comprarle al autor un vaso de jugo :tropical_drink:
|
||||
|
||||

|
||||
|
||||
[dona por Paypal](https://www.paypal.me/panfree23)
|
||||
|
||||
[Comprame un Café](https://www.buymeacoffee.com/Pan)
|
||||
|
||||
## Navegadores Soportados
|
||||
|
||||
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 |
|
||||
| --------- | --------- | --------- | --------- |
|
||||
| IE10, IE11, Edge| últimas 2 versiones| últimas 2 versiones| últimas 2 versiones
|
||||
|
||||
## Licencia
|
||||
|
||||
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
||||
|
||||
Copyright (c) 2017-presente PanJiaChen
|
|
@ -26,7 +26,7 @@
|
|||
</a>
|
||||
</p>
|
||||
|
||||
日本語 | [English](./README.md) | [简体中文](./README.zh-CN.md)
|
||||
日本語 | [English](./README.md) | [简体中文](./README.zh-CN.md) | [Spanish](./README.es.md)
|
||||
|
||||
## 概要
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</a>
|
||||
</p>
|
||||
|
||||
English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md)
|
||||
English | [简体中文](./README.zh-CN.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md)
|
||||
|
||||
## Introduction
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
</a>
|
||||
</p>
|
||||
|
||||
简体中文 | [English](./README.md)
|
||||
简体中文 | [English](./README.md) | [日本語](./README.ja.md) | [Spanish](./README.es.md)
|
||||
|
||||
## 简介
|
||||
|
||||
|
@ -68,6 +68,7 @@
|
|||
- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
|
||||
- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
|
||||
- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
|
||||
- [手摸手,带你用vue撸后台 系列五(v4.0新版本)](https://juejin.im/post/5c92ff94f265da6128275a85)
|
||||
- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
|
||||
- [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09)
|
||||
- [手摸手,带你用合理的姿势使用 webpack4(上)](https://juejin.im/post/5b56909a518825195f499806)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "vue-element-admin",
|
||||
"version": "4.1.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",
|
||||
"author": "Pan <panfree23@gmail.com>",
|
||||
"license": "MIT",
|
||||
|
@ -78,6 +78,7 @@
|
|||
"@vue/cli-plugin-unit-jest": "3.5.3",
|
||||
"@vue/cli-service": "3.5.3",
|
||||
"@vue/test-utils": "1.0.0-beta.29",
|
||||
"autoprefixer": "^9.5.1",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "10.0.1",
|
||||
"babel-jest": "23.6.0",
|
||||
|
@ -107,7 +108,6 @@
|
|||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
"last 2 versions"
|
||||
]
|
||||
}
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
module.exports = {
|
||||
plugins: {
|
||||
autoprefixer: {}
|
||||
}
|
||||
}
|
|
@ -9,10 +9,6 @@
|
|||
<title><%= webpackConfig.name %></title>
|
||||
</head>
|
||||
<body>
|
||||
<!-- import cdn js -->
|
||||
<% for(var js of htmlWebpackPlugin.options.cdn.js) { %>
|
||||
<script src="<%=js%>"></script>
|
||||
<% } %>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
|
|
|
@ -19,7 +19,11 @@ export default {
|
|||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
$route(route) {
|
||||
// if you go to the redirect page, do not update the breadcrumbs
|
||||
if (route.path.startsWith('/redirect/')) {
|
||||
return
|
||||
}
|
||||
this.getBreadcrumb()
|
||||
}
|
||||
},
|
||||
|
|
|
@ -6,7 +6,11 @@
|
|||
</el-button>
|
||||
</el-badge>
|
||||
|
||||
<el-dialog :visible.sync="dialogTableVisible" title="Error Log" width="80%" append-to-body>
|
||||
<el-dialog :visible.sync="dialogTableVisible" width="80%" append-to-body>
|
||||
<div slot="title">
|
||||
<span style="padding-right: 10px;">Error Log</span>
|
||||
<el-button size="mini" type="primary" icon="el-icon-delete" @click="clearAll">Clear All</el-button>
|
||||
</div>
|
||||
<el-table :data="errorLogs" border>
|
||||
<el-table-column label="Message">
|
||||
<template slot-scope="{row}">
|
||||
|
@ -54,6 +58,12 @@ export default {
|
|||
errorLogs() {
|
||||
return this.$store.getters.errorLogs
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clearAll() {
|
||||
this.dialogTableVisible = false
|
||||
this.$store.dispatch('errorLog/clearErrorLog')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -86,32 +86,27 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.rightPanel-background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
transition: opacity .3s cubic-bezier(.7, .3, .1, 1);
|
||||
background: rgba(0, 0, 0, .2);
|
||||
width: 0;
|
||||
height: 0;
|
||||
top: 0;
|
||||
left: 0;
|
||||
position: fixed;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.rightPanel {
|
||||
background: #fff;
|
||||
z-index: 3000;
|
||||
position: fixed;
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
max-width: 260px;
|
||||
top: 0px;
|
||||
left: 0px;
|
||||
height: 100vh;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, .05);
|
||||
transition: all .25s cubic-bezier(.7, .3, .1, 1);
|
||||
transform: translate(100%);
|
||||
background: #fff;
|
||||
z-index: 40000;
|
||||
left: auto;
|
||||
right: 0px;
|
||||
}
|
||||
|
||||
.show {
|
||||
|
@ -130,20 +125,18 @@ export default {
|
|||
}
|
||||
|
||||
.handle-button {
|
||||
position: absolute;
|
||||
left: -48px;
|
||||
border-radius: 6px 0 0 6px !important;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
pointer-events: auto;
|
||||
z-index: 0;
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
font-size: 24px;
|
||||
position: absolute;
|
||||
left: -48px;
|
||||
text-align: center;
|
||||
font-size: 24px;
|
||||
border-radius: 6px 0 0 6px !important;
|
||||
z-index: 0;
|
||||
pointer-events: auto;
|
||||
cursor: pointer;
|
||||
color: #fff;
|
||||
line-height: 48px;
|
||||
|
||||
i {
|
||||
font-size: 24px;
|
||||
line-height: 48px;
|
||||
|
|
|
@ -38,7 +38,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<style lang="scss" >
|
||||
$n: 8; //和items.length 相同
|
||||
$n: 9; //和items.length 相同
|
||||
$t: .1s;
|
||||
.share-dropdown-menu {
|
||||
width: 250px;
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
<template>
|
||||
<svg :class="svgClass" aria-hidden="true" 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">
|
||||
<use :xlink:href="iconName" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
|
||||
import { isExternal } from '@/utils/validate'
|
||||
|
||||
export default {
|
||||
name: 'SvgIcon',
|
||||
props: {
|
||||
|
@ -18,6 +22,9 @@ export default {
|
|||
}
|
||||
},
|
||||
computed: {
|
||||
isExternal() {
|
||||
return isExternal(this.iconClass)
|
||||
},
|
||||
iconName() {
|
||||
return `#icon-${this.iconClass}`
|
||||
},
|
||||
|
@ -27,6 +34,12 @@ export default {
|
|||
} else {
|
||||
return 'svg-icon'
|
||||
}
|
||||
},
|
||||
styleExternalIcon() {
|
||||
return {
|
||||
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
|
||||
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,4 +53,10 @@ export default {
|
|||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.svg-external-icon {
|
||||
background-color: currentColor;
|
||||
mask-size: cover!important;
|
||||
display: inline-block;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
let callbacks = []
|
||||
|
||||
function loadedTinymce() {
|
||||
// to fixed https://github.com/PanJiaChen/vue-element-admin/issues/2144
|
||||
// check is successfully downloaded script
|
||||
return window.tinymce
|
||||
}
|
||||
|
||||
const dynamicLoadScript = (src, callback) => {
|
||||
const existingScript = document.getElementById(src)
|
||||
const cb = callback || function() {}
|
||||
|
||||
if (!existingScript) {
|
||||
const script = document.createElement('script')
|
||||
script.src = src // src url for the third-party library being loaded.
|
||||
script.id = src
|
||||
document.body.appendChild(script)
|
||||
callbacks.push(cb)
|
||||
const onEnd = 'onload' in script ? stdOnEnd : ieOnEnd
|
||||
onEnd(script)
|
||||
}
|
||||
|
||||
if (existingScript && cb) {
|
||||
if (loadedTinymce()) {
|
||||
cb(null, existingScript)
|
||||
} else {
|
||||
callbacks.push(cb)
|
||||
}
|
||||
}
|
||||
|
||||
function stdOnEnd(script) {
|
||||
script.onload = function() {
|
||||
// this.onload = null here is necessary
|
||||
// because even IE9 works not like others
|
||||
this.onerror = this.onload = null
|
||||
for (const cb of callbacks) {
|
||||
cb(null, script)
|
||||
}
|
||||
callbacks = null
|
||||
}
|
||||
script.onerror = function() {
|
||||
this.onerror = this.onload = null
|
||||
cb(new Error('Failed to load ' + src), script)
|
||||
}
|
||||
}
|
||||
|
||||
function ieOnEnd(script) {
|
||||
script.onreadystatechange = function() {
|
||||
if (this.readyState !== 'complete' && this.readyState !== 'loaded') return
|
||||
this.onreadystatechange = null
|
||||
for (const cb of callbacks) {
|
||||
cb(null, script) // there is no way to catch loading errors in IE8
|
||||
}
|
||||
callbacks = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default dynamicLoadScript
|
|
@ -15,6 +15,10 @@
|
|||
import editorImage from './components/EditorImage'
|
||||
import plugins from './plugins'
|
||||
import toolbar from './toolbar'
|
||||
import load from './dynamicLoadScript'
|
||||
|
||||
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
|
||||
const tinymceCDN = 'https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.3/tinymce.min.js'
|
||||
|
||||
export default {
|
||||
name: 'Tinymce',
|
||||
|
@ -60,7 +64,9 @@ export default {
|
|||
fullscreen: false,
|
||||
languageTypeList: {
|
||||
'en': 'en',
|
||||
'zh': 'zh_CN'
|
||||
'zh': 'zh_CN',
|
||||
'es': 'es_MX',
|
||||
'ja': 'ja'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -82,10 +88,12 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initTinymce()
|
||||
this.init()
|
||||
},
|
||||
activated() {
|
||||
this.initTinymce()
|
||||
if (window.tinymce) {
|
||||
this.initTinymce()
|
||||
}
|
||||
},
|
||||
deactivated() {
|
||||
this.destroyTinymce()
|
||||
|
@ -94,10 +102,21 @@ export default {
|
|||
this.destroyTinymce()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// dynamic load tinymce from cdn
|
||||
load(tinymceCDN, (err) => {
|
||||
if (err) {
|
||||
this.$message.error(err.message)
|
||||
return
|
||||
}
|
||||
this.initTinymce()
|
||||
})
|
||||
},
|
||||
initTinymce() {
|
||||
const _this = this
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
language: this.languageTypeList['en'],
|
||||
height: this.height,
|
||||
body_class: 'panel-body ',
|
||||
object_resizing: false,
|
||||
|
|
|
@ -16,7 +16,7 @@ export default {
|
|||
return this.$store.state.tagsView.cachedViews
|
||||
},
|
||||
key() {
|
||||
return this.$route.fullPath
|
||||
return this.$route.path
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,8 +33,6 @@ export default {
|
|||
|
||||
.fixed-header+.app-main {
|
||||
padding-top: 50px;
|
||||
height: 100vh;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.hasTagsView {
|
||||
|
@ -49,3 +47,11 @@ export default {
|
|||
}
|
||||
</style>
|
||||
|
||||
<style lang="scss">
|
||||
// fix css style bug in open el-dialog
|
||||
.el-popup-parent--hidden {
|
||||
.fixed-header {
|
||||
padding-right: 15px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
12
src/main.js
12
src/main.js
|
@ -21,12 +21,16 @@ import * as filters from './filters' // global filters
|
|||
|
||||
/**
|
||||
* If you don't want to use mock-server
|
||||
* you want to use mockjs for request interception
|
||||
* you can execute:
|
||||
* you want to use MockJs for mock api
|
||||
* you can execute: mockXHR()
|
||||
*
|
||||
* import { mockXHR } from '../mock'
|
||||
* mockXHR()
|
||||
* Currently MockJs will be used in the production environment,
|
||||
* please remove it before going online! ! !
|
||||
*/
|
||||
import { mockXHR } from '../mock'
|
||||
if (process.env.NODE_ENV === 'production') {
|
||||
mockXHR()
|
||||
}
|
||||
|
||||
Vue.use(Element, {
|
||||
size: Cookies.get('size') || 'medium' // set element-ui default size
|
||||
|
|
|
@ -5,7 +5,7 @@ import getters from './getters'
|
|||
Vue.use(Vuex)
|
||||
|
||||
// https://webpack.js.org/guides/dependency-management/#requirecontext
|
||||
const modulesFiles = require.context('./modules', false, /\.js$/)
|
||||
const modulesFiles = require.context('./modules', true, /\.js$/)
|
||||
|
||||
// you do not need `import app from './modules/app'`
|
||||
// it will auto require all vuex module from modules file
|
||||
|
|
|
@ -5,12 +5,18 @@ const state = {
|
|||
const mutations = {
|
||||
ADD_ERROR_LOG: (state, log) => {
|
||||
state.logs.push(log)
|
||||
},
|
||||
CLEAR_ERROR_LOG: (state) => {
|
||||
state.logs.splice(0)
|
||||
}
|
||||
}
|
||||
|
||||
const actions = {
|
||||
addErrorLog({ commit }, log) {
|
||||
commit('ADD_ERROR_LOG', log)
|
||||
},
|
||||
clearErrorLog({ commit }) {
|
||||
commit('CLEAR_ERROR_LOG')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -115,6 +115,9 @@ const actions = {
|
|||
// dynamically add accessible routes
|
||||
router.addRoutes(accessRoutes)
|
||||
|
||||
// reset visited views and cached views
|
||||
dispatch('tagsView/delAllViews', null, { root: true })
|
||||
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
|
|
|
@ -95,10 +95,6 @@
|
|||
margin-left: 54px;
|
||||
}
|
||||
|
||||
.svg-icon {
|
||||
margin-right: 0px;
|
||||
}
|
||||
|
||||
.submenu-title-noDropdown {
|
||||
padding: 0 !important;
|
||||
position: relative;
|
||||
|
|
|
@ -48,7 +48,7 @@ service.interceptors.response.use(
|
|||
// if the custom code is not 20000, it is judged as an error.
|
||||
if (res.code !== 20000) {
|
||||
Message({
|
||||
message: res.message || 'error',
|
||||
message: res.message || 'Error',
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
|
@ -66,7 +66,7 @@ service.interceptors.response.use(
|
|||
})
|
||||
})
|
||||
}
|
||||
return Promise.reject(res.message || 'error')
|
||||
return Promise.reject(new Error(res.message || 'Error'))
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@ export default {
|
|||
{ title: '登录权限篇', href: 'https://juejin.im/post/591aa14f570c35006961acac' },
|
||||
{ title: '实战篇', href: 'https://juejin.im/post/593121aa0ce4630057f70d35' },
|
||||
{ title: 'vue-admin-template 篇', href: 'https://juejin.im/post/595b4d776fb9a06bbe7dba56' },
|
||||
{ title: 'v4.0 篇', href: 'https://juejin.im/post/5c92ff94f265da6128275a85' },
|
||||
{ title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' }
|
||||
]
|
||||
}
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
<script>
|
||||
import echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import { debounce } from '@/utils'
|
||||
import resize from './mixins/resize'
|
||||
|
||||
const animationDuration = 6000
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
|
@ -30,19 +31,14 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.chart) {
|
||||
this.chart.resize()
|
||||
}
|
||||
}, 100)
|
||||
window.addEventListener('resize', this.__resizeHandler)
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
window.removeEventListener('resize', this.__resizeHandler)
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
<script>
|
||||
import echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import { debounce } from '@/utils'
|
||||
import resize from './mixins/resize'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
|
@ -32,8 +33,7 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null,
|
||||
sidebarElm: null
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -45,38 +45,21 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
if (this.autoResize) {
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.chart) {
|
||||
this.chart.resize()
|
||||
}
|
||||
}, 100)
|
||||
window.addEventListener('resize', this.__resizeHandler)
|
||||
}
|
||||
|
||||
// 监听侧边栏的变化
|
||||
this.sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
||||
this.sidebarElm && this.sidebarElm.addEventListener('transitionend', this.sidebarResizeHandler)
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
if (this.autoResize) {
|
||||
window.removeEventListener('resize', this.__resizeHandler)
|
||||
}
|
||||
|
||||
this.sidebarElm && this.sidebarElm.removeEventListener('transitionend', this.sidebarResizeHandler)
|
||||
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
sidebarResizeHandler(e) {
|
||||
if (e.propertyName === 'width') {
|
||||
this.__resizeHandler()
|
||||
}
|
||||
initChart() {
|
||||
this.chart = echarts.init(this.$el, 'macarons')
|
||||
this.setOptions(this.chartData)
|
||||
},
|
||||
setOptions({ expectedData, actualData } = {}) {
|
||||
this.chart.setOption({
|
||||
|
@ -146,10 +129,6 @@ export default {
|
|||
animationEasing: 'quadraticOut'
|
||||
}]
|
||||
})
|
||||
},
|
||||
initChart() {
|
||||
this.chart = echarts.init(this.$el, 'macarons')
|
||||
this.setOptions(this.chartData)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,9 +73,11 @@ export default {
|
|||
<style lang="scss" scoped>
|
||||
.panel-group {
|
||||
margin-top: 18px;
|
||||
.card-panel-col{
|
||||
|
||||
.card-panel-col {
|
||||
margin-bottom: 32px;
|
||||
}
|
||||
|
||||
.card-panel {
|
||||
height: 108px;
|
||||
cursor: pointer;
|
||||
|
@ -86,35 +88,45 @@ export default {
|
|||
background: #fff;
|
||||
box-shadow: 4px 4px 40px rgba(0, 0, 0, .05);
|
||||
border-color: rgba(0, 0, 0, .05);
|
||||
|
||||
&:hover {
|
||||
.card-panel-icon-wrapper {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.icon-people {
|
||||
background: #40c9c6;
|
||||
background: #40c9c6;
|
||||
}
|
||||
|
||||
.icon-message {
|
||||
background: #36a3f7;
|
||||
}
|
||||
|
||||
.icon-money {
|
||||
background: #f4516c;
|
||||
}
|
||||
|
||||
.icon-shopping {
|
||||
background: #34bfa3
|
||||
}
|
||||
}
|
||||
|
||||
.icon-people {
|
||||
color: #40c9c6;
|
||||
}
|
||||
|
||||
.icon-message {
|
||||
color: #36a3f7;
|
||||
}
|
||||
|
||||
.icon-money {
|
||||
color: #f4516c;
|
||||
}
|
||||
|
||||
.icon-shopping {
|
||||
color: #34bfa3
|
||||
}
|
||||
|
||||
.card-panel-icon-wrapper {
|
||||
float: left;
|
||||
margin: 14px 0 0 14px;
|
||||
|
@ -122,25 +134,48 @@ export default {
|
|||
transition: all 0.38s ease-out;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.card-panel-icon {
|
||||
float: left;
|
||||
font-size: 48px;
|
||||
}
|
||||
|
||||
.card-panel-description {
|
||||
float: right;
|
||||
font-weight: bold;
|
||||
margin: 26px;
|
||||
margin-left: 0px;
|
||||
|
||||
.card-panel-text {
|
||||
line-height: 18px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 16px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.card-panel-num {
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:550px) {
|
||||
.card-panel-description {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.card-panel-icon-wrapper {
|
||||
float: none !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 !important;
|
||||
|
||||
.svg-icon {
|
||||
display: block;
|
||||
margin: 14px auto !important;
|
||||
float: none !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
<script>
|
||||
import echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import { debounce } from '@/utils'
|
||||
import resize from './mixins/resize'
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
|
@ -28,19 +29,14 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.chart) {
|
||||
this.chart.resize()
|
||||
}
|
||||
}, 100)
|
||||
window.addEventListener('resize', this.__resizeHandler)
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
window.removeEventListener('resize', this.__resizeHandler)
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
|
@ -58,7 +54,6 @@ export default {
|
|||
bottom: '10',
|
||||
data: ['Industries', 'Technology', 'Forex', 'Gold', 'Forecasts']
|
||||
},
|
||||
calculable: true,
|
||||
series: [
|
||||
{
|
||||
name: 'WEEKLY WRITE ARTICLES',
|
||||
|
|
|
@ -5,11 +5,12 @@
|
|||
<script>
|
||||
import echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import { debounce } from '@/utils'
|
||||
import resize from './mixins/resize'
|
||||
|
||||
const animationDuration = 3000
|
||||
|
||||
export default {
|
||||
mixins: [resize],
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
|
@ -30,19 +31,14 @@ export default {
|
|||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
this.__resizeHandler = debounce(() => {
|
||||
if (this.chart) {
|
||||
this.chart.resize()
|
||||
}
|
||||
}, 100)
|
||||
window.addEventListener('resize', this.__resizeHandler)
|
||||
this.$nextTick(() => {
|
||||
this.initChart()
|
||||
})
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
window.removeEventListener('resize', this.__resizeHandler)
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
$_sidebarElm: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.$_initResizeEvent()
|
||||
this.$_initSidebarResizeEvent()
|
||||
},
|
||||
beforeDestroy() {
|
||||
this.$_destroyResizeEvent()
|
||||
this.$_destroySidebarResizeEvent()
|
||||
},
|
||||
// to fixed bug when cached by keep-alive
|
||||
// https://github.com/PanJiaChen/vue-element-admin/issues/2116
|
||||
activated() {
|
||||
this.$_initResizeEvent()
|
||||
this.$_initSidebarResizeEvent()
|
||||
},
|
||||
deactivated() {
|
||||
this.$_destroyResizeEvent()
|
||||
this.$_destroySidebarResizeEvent()
|
||||
},
|
||||
methods: {
|
||||
// use $_ for mixins properties
|
||||
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
|
||||
$_resizeHandler() {
|
||||
return debounce(() => {
|
||||
if (this.chart) {
|
||||
this.chart.resize()
|
||||
}
|
||||
}, 100)()
|
||||
},
|
||||
$_initResizeEvent() {
|
||||
window.addEventListener('resize', this.$_resizeHandler)
|
||||
},
|
||||
$_destroyResizeEvent() {
|
||||
window.removeEventListener('resize', this.$_resizeHandler)
|
||||
},
|
||||
$_sidebarResizeHandler(e) {
|
||||
if (e.propertyName === 'width') {
|
||||
this.$_resizeHandler()
|
||||
}
|
||||
},
|
||||
$_initSidebarResizeEvent() {
|
||||
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
|
||||
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
|
||||
},
|
||||
$_destroySidebarResizeEvent() {
|
||||
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -115,4 +115,10 @@ export default {
|
|||
margin-bottom: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:1024px) {
|
||||
.chart-wrapper {
|
||||
padding: 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -32,6 +32,7 @@ export default {
|
|||
{ title: '登录权限篇', href: 'https://juejin.im/post/591aa14f570c35006961acac' },
|
||||
{ title: '实战篇', href: 'https://juejin.im/post/593121aa0ce4630057f70d35' },
|
||||
{ title: 'vue-admin-template 篇', href: 'https://juejin.im/post/595b4d776fb9a06bbe7dba56' },
|
||||
{ title: 'v4.0 篇', href: 'https://juejin.im/post/5c92ff94f265da6128275a85' },
|
||||
{ title: '自行封装 component', href: 'https://segmentfault.com/a/1190000009090836' },
|
||||
{ title: '优雅的使用 icon', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' },
|
||||
{ title: 'webpack4(上)', href: 'https://juejin.im/post/59bb864b5188257e7a427c09' },
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
:colors="['#99A9BF', '#F7BA2A', '#FF9900']"
|
||||
:low-threshold="1"
|
||||
:high-threshold="3"
|
||||
style="margin-top:8px;"
|
||||
style="display:inline-block"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -183,12 +183,16 @@ export default {
|
|||
fetchData(id) {
|
||||
fetchArticle(id).then(response => {
|
||||
this.postForm = response.data
|
||||
// Just for test
|
||||
|
||||
// just for test
|
||||
this.postForm.title += ` Article Id:${this.postForm.id}`
|
||||
this.postForm.content_short += ` Article Id:${this.postForm.id}`
|
||||
|
||||
// Set tagsview title
|
||||
// set tagsview title
|
||||
this.setTagsViewTitle()
|
||||
|
||||
// set page title
|
||||
this.setPageTitle()
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
})
|
||||
|
@ -198,6 +202,10 @@ export default {
|
|||
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
|
||||
this.$store.dispatch('tagsView/updateVisitedView', route)
|
||||
},
|
||||
setPageTitle() {
|
||||
const title = 'Edit Article'
|
||||
document.title = `${title} - ${this.postForm.id}`
|
||||
},
|
||||
submitForm() {
|
||||
console.log(this.postForm)
|
||||
this.$refs.postForm.validate(valid => {
|
||||
|
|
|
@ -108,13 +108,18 @@ export default {
|
|||
capsTooltip: false,
|
||||
loading: false,
|
||||
showDialog: false,
|
||||
redirect: undefined
|
||||
redirect: undefined,
|
||||
otherQuery: {}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: {
|
||||
handler: function(route) {
|
||||
this.redirect = route.query && route.query.redirect
|
||||
const query = route.query
|
||||
if (query) {
|
||||
this.redirect = query.redirect
|
||||
this.otherQuery = this.getOtherQuery(query)
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
|
@ -161,7 +166,7 @@ export default {
|
|||
this.loading = true
|
||||
this.$store.dispatch('user/login', this.loginForm)
|
||||
.then(() => {
|
||||
this.$router.push({ path: this.redirect || '/' })
|
||||
this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
|
||||
this.loading = false
|
||||
})
|
||||
.catch(() => {
|
||||
|
@ -172,6 +177,14 @@ export default {
|
|||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
getOtherQuery(query) {
|
||||
return Object.keys(query).reduce((acc, cur) => {
|
||||
if (cur !== 'redirect') {
|
||||
acc[cur] = query[cur]
|
||||
}
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
// afterQRScan() {
|
||||
// if (e.key === 'x-admin-oauth-code') {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<el-card>
|
||||
<el-card style="margin-bottom:20px;">
|
||||
<div slot="header" class="clearfix">
|
||||
<span>About me</span>
|
||||
</div>
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<div v-if="user">
|
||||
<el-row :gutter="20">
|
||||
|
||||
<el-col :span="6">
|
||||
<el-col :span="6" :xs="24">
|
||||
<user-card :user="user" />
|
||||
</el-col>
|
||||
|
||||
<el-col :span="18">
|
||||
<el-col :span="18" :xs="24">
|
||||
<el-card>
|
||||
<el-tabs v-model="activeTab">
|
||||
<el-tab-pane label="Activity" name="activity">
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script>
|
||||
export default {
|
||||
beforeCreate() {
|
||||
created() {
|
||||
const { params, query } = this.$route
|
||||
const { path } = params
|
||||
this.$router.replace({ path: '/' + path, query })
|
||||
|
|
|
@ -30,6 +30,18 @@ export default {
|
|||
createdTimes: 0
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
activeName(val) {
|
||||
this.$router.push(`${this.$route.path}?tab=${val}`)
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// init the default selected tab
|
||||
const tab = this.$route.query.tab
|
||||
if (tab) {
|
||||
this.activeName = tab
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showCreatedTimes() {
|
||||
this.createdTimes = this.createdTimes + 1
|
||||
|
|
|
@ -37,7 +37,7 @@ module.exports = {
|
|||
// change xxx-api/login => mock/login
|
||||
// detail: https://cli.vuejs.org/config/#devserver-proxy
|
||||
[process.env.VUE_APP_BASE_API]: {
|
||||
target: `http://localhost:${port}/mock`,
|
||||
target: `http://127.0.0.1:${port}/mock`,
|
||||
changeOrigin: true,
|
||||
pathRewrite: {
|
||||
['^' + process.env.VUE_APP_BASE_API]: ''
|
||||
|
@ -57,16 +57,6 @@ module.exports = {
|
|||
}
|
||||
},
|
||||
chainWebpack(config) {
|
||||
const cdn = {
|
||||
// inject tinymce into index.html
|
||||
// why use this cdn, detail see https://github.com/PanJiaChen/tinymce-all-in-one
|
||||
js: ['https://cdn.jsdelivr.net/npm/tinymce-all-in-one@4.9.2/tinymce.min.js']
|
||||
}
|
||||
config.plugin('html')
|
||||
.tap(args => {
|
||||
args[0].cdn = cdn
|
||||
return args
|
||||
})
|
||||
config.plugins.delete('preload') // TODO: need test
|
||||
config.plugins.delete('prefetch') // TODO: need test
|
||||
|
||||
|
|
Loading…
Reference in New Issue