Compare commits
10 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
baa7172a70 | ||
|
bc003fd78b | ||
|
41a5615ee5 | ||
|
df23405bde | ||
|
f94aa1aca3 | ||
|
96bda5515c | ||
|
0f6d830c19 | ||
|
e8ab82c2c1 | ||
|
a284c1f007 | ||
|
323408f8d9 |
@@ -198,6 +198,14 @@ If you find this project useful, you can buy author a glass of juice :tropical_d
|
|||||||
|
|
||||||
[Buy me a coffee](https://www.buymeacoffee.com/Pan)
|
[Buy me a coffee](https://www.buymeacoffee.com/Pan)
|
||||||
|
|
||||||
|
## Browsers support
|
||||||
|
|
||||||
|
Modern browsers and Internet Explorer 10+.
|
||||||
|
|
||||||
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
|
| --------- | --------- | --------- | --------- |
|
||||||
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
||||||
|
@@ -210,6 +210,14 @@ Detailed changes for each release are documented in the [release notes](https://
|
|||||||
|
|
||||||
[Paypal Me](https://www.paypal.me/panfree23)
|
[Paypal Me](https://www.paypal.me/panfree23)
|
||||||
|
|
||||||
|
## Browsers support
|
||||||
|
|
||||||
|
Modern browsers and Internet Explorer 10+.
|
||||||
|
|
||||||
|
| [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/edge/edge_48x48.png" alt="IE / Edge" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>IE / Edge | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/firefox/firefox_48x48.png" alt="Firefox" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Firefox | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/chrome/chrome_48x48.png" alt="Chrome" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Chrome | [<img src="https://raw.githubusercontent.com/alrra/browser-logos/master/src/safari/safari_48x48.png" alt="Safari" width="24px" height="24px" />](http://godban.github.io/browsers-support-badges/)</br>Safari |
|
||||||
|
| --------- | --------- | --------- | --------- |
|
||||||
|
| IE10, IE11, Edge| last 2 versions| last 2 versions| last 2 versions
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
|
||||||
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
[MIT](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
||||||
|
@@ -9,7 +9,7 @@ const CopyWebpackPlugin = require('copy-webpack-plugin')
|
|||||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
|
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin')
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||||
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
// const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
|
||||||
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
|
||||||
|
|
||||||
function resolve(dir) {
|
function resolve(dir) {
|
||||||
@@ -140,7 +140,7 @@ const webpackConfig = merge(baseWebpackConfig, {
|
|||||||
}),
|
}),
|
||||||
// Compress extracted CSS. We are using this plugin so that possible
|
// Compress extracted CSS. We are using this plugin so that possible
|
||||||
// duplicated CSS from different components can be deduped.
|
// duplicated CSS from different components can be deduped.
|
||||||
new OptimizeCSSAssetsPlugin()
|
// new OptimizeCSSAssetsPlugin()
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vue-element-admin",
|
"name": "vue-element-admin",
|
||||||
"version": "3.9.1",
|
"version": "3.9.2",
|
||||||
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
"description": "A magical vue admin. Typical templates for enterprise applications. Newest development stack of vue. Lots of awesome features",
|
||||||
"author": "Pan <panfree23@gmail.com>",
|
"author": "Pan <panfree23@gmail.com>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
@@ -6,6 +6,7 @@
|
|||||||
<el-dropdown-menu slot="dropdown">
|
<el-dropdown-menu slot="dropdown">
|
||||||
<el-dropdown-item :disabled="language==='zh'" command="zh">中文</el-dropdown-item>
|
<el-dropdown-item :disabled="language==='zh'" command="zh">中文</el-dropdown-item>
|
||||||
<el-dropdown-item :disabled="language==='en'" command="en">English</el-dropdown-item>
|
<el-dropdown-item :disabled="language==='en'" command="en">English</el-dropdown-item>
|
||||||
|
<el-dropdown-item :disabled="language==='es'" command="es">Español</el-dropdown-item>
|
||||||
</el-dropdown-menu>
|
</el-dropdown-menu>
|
||||||
</el-dropdown>
|
</el-dropdown>
|
||||||
</template>
|
</template>
|
||||||
|
99
src/components/Pagination/index.vue
Normal file
99
src/components/Pagination/index.vue
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
<template>
|
||||||
|
<div :class="{'hidden':hidden}" class="pagination-container">
|
||||||
|
<el-pagination
|
||||||
|
:background="background"
|
||||||
|
:current-page.sync="currentPage"
|
||||||
|
:page-size.sync="pageSize"
|
||||||
|
:layout="layout"
|
||||||
|
:total="total"
|
||||||
|
v-bind="$attrs"
|
||||||
|
@size-change="handleSizeChange"
|
||||||
|
@current-change="handleCurrentChange"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { scrollTo } from '@/utils/scrollTo'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'Pagination',
|
||||||
|
props: {
|
||||||
|
total: {
|
||||||
|
required: true,
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
page: {
|
||||||
|
type: Number,
|
||||||
|
default: 1
|
||||||
|
},
|
||||||
|
limit: {
|
||||||
|
type: Number,
|
||||||
|
default: 20
|
||||||
|
},
|
||||||
|
pageSizes: {
|
||||||
|
type: Array,
|
||||||
|
default() {
|
||||||
|
return [10, 20, 30, 50]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
type: String,
|
||||||
|
default: 'total, sizes, prev, pager, next, jumper'
|
||||||
|
},
|
||||||
|
background: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
autoScroll: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true
|
||||||
|
},
|
||||||
|
hidden: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
currentPage: {
|
||||||
|
get() {
|
||||||
|
return this.page
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:page', val)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
pageSize: {
|
||||||
|
get() {
|
||||||
|
return this.limit
|
||||||
|
},
|
||||||
|
set(val) {
|
||||||
|
this.$emit('update:limit', val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSizeChange(val) {
|
||||||
|
this.$emit('pagination', { page: this.currentPage, limit: val })
|
||||||
|
if (this.autoScroll) {
|
||||||
|
scrollTo(0, 800)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleCurrentChange(val) {
|
||||||
|
this.$emit('pagination', { page: val, limit: this.pageSize })
|
||||||
|
if (this.autoScroll) {
|
||||||
|
scrollTo(0, 800)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.pagination-container {
|
||||||
|
background: #fff;
|
||||||
|
padding: 32px 16px;
|
||||||
|
}
|
||||||
|
.pagination-container.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
@@ -5,7 +5,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
const padding = 15 // tag's padding
|
const tagAndTagSpacing = 4 // tagAndTagSpacing
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ScrollPane',
|
name: 'ScrollPane',
|
||||||
@@ -20,18 +20,54 @@ export default {
|
|||||||
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
|
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
|
||||||
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
$scrollWrapper.scrollLeft = $scrollWrapper.scrollLeft + eventDelta / 4
|
||||||
},
|
},
|
||||||
moveToTarget($target) {
|
moveToTarget(currentTag) {
|
||||||
const $container = this.$refs.scrollContainer.$el
|
const $container = this.$refs.scrollContainer.$el
|
||||||
const $containerWidth = $container.offsetWidth
|
const $containerWidth = $container.offsetWidth
|
||||||
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
|
const $scrollWrapper = this.$refs.scrollContainer.$refs.wrap
|
||||||
const $targetLeft = $target.offsetLeft
|
const tagList = this.$parent.$refs.tag
|
||||||
const $targetWidth = $target.offsetWidth
|
|
||||||
if ($targetLeft > $containerWidth) {
|
let firstTag = null
|
||||||
// tag in the right
|
let lastTag = null
|
||||||
$scrollWrapper.scrollLeft = $targetLeft - $containerWidth + $targetWidth + padding
|
let prevTag = null
|
||||||
|
let nextTag = null
|
||||||
|
|
||||||
|
// find first tag and last tag
|
||||||
|
if (tagList.length > 0) {
|
||||||
|
firstTag = tagList[0]
|
||||||
|
lastTag = tagList[tagList.length - 1]
|
||||||
|
}
|
||||||
|
|
||||||
|
// find preTag and nextTag
|
||||||
|
for (let i = 0; i < tagList.length; i++) {
|
||||||
|
if (tagList[i] === currentTag) {
|
||||||
|
if (i === 0) {
|
||||||
|
nextTag = tagList[i].length > 1 && tagList[i + 1]
|
||||||
|
} else if (i === tagList.length - 1) {
|
||||||
|
prevTag = tagList[i].length > 1 && tagList[i - 1]
|
||||||
|
} else {
|
||||||
|
prevTag = tagList[i - 1]
|
||||||
|
nextTag = tagList[i + 1]
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (firstTag === currentTag) {
|
||||||
|
$scrollWrapper.scrollLeft = 0
|
||||||
|
} else if (lastTag === currentTag) {
|
||||||
|
$scrollWrapper.scrollLeft = $scrollWrapper.scrollWidth - $containerWidth
|
||||||
} else {
|
} else {
|
||||||
// tag in the left
|
// the tag's offsetLeft after of nextTag
|
||||||
$scrollWrapper.scrollLeft = $targetLeft - padding
|
const afterNextTagOffsetLeft = nextTag.$el.offsetLeft + nextTag.$el.offsetWidth + tagAndTagSpacing
|
||||||
|
|
||||||
|
// the tag's offsetLeft before of prevTag
|
||||||
|
const beforePrevTagOffsetLeft = prevTag.$el.offsetLeft - tagAndTagSpacing
|
||||||
|
|
||||||
|
if (afterNextTagOffsetLeft > $scrollWrapper.scrollLeft + $containerWidth) {
|
||||||
|
$scrollWrapper.scrollLeft = afterNextTagOffsetLeft - $containerWidth
|
||||||
|
} else if (beforePrevTagOffsetLeft < $scrollWrapper.scrollLeft) {
|
||||||
|
$scrollWrapper.scrollLeft = beforePrevTagOffsetLeft
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
155
src/lang/es.js
Executable file
155
src/lang/es.js
Executable file
@@ -0,0 +1,155 @@
|
|||||||
|
export default {
|
||||||
|
route: {
|
||||||
|
dashboard: 'Panel de control',
|
||||||
|
introduction: 'Introducción',
|
||||||
|
documentation: 'Documentación',
|
||||||
|
guide: 'Guía',
|
||||||
|
permission: 'Permisos',
|
||||||
|
pagePermission: 'Permisos de la página',
|
||||||
|
directivePermission: 'Permisos de la directiva',
|
||||||
|
icons: 'Iconos',
|
||||||
|
components: 'Componentes',
|
||||||
|
componentIndex: 'Introducción',
|
||||||
|
tinymce: 'Tinymce',
|
||||||
|
markdown: 'Markdown',
|
||||||
|
jsonEditor: 'Editor JSON',
|
||||||
|
dndList: 'Lista Dnd',
|
||||||
|
splitPane: 'Panel dividido',
|
||||||
|
avatarUpload: 'Subir avatar',
|
||||||
|
dropzone: 'Subir ficheros',
|
||||||
|
sticky: 'Sticky',
|
||||||
|
countTo: 'CountTo',
|
||||||
|
componentMixin: 'Mixin',
|
||||||
|
backToTop: 'Ir arriba',
|
||||||
|
dragDialog: 'Drag Dialog',
|
||||||
|
dragKanban: 'Drag Kanban',
|
||||||
|
charts: 'Gráficos',
|
||||||
|
keyboardChart: 'Keyboard Chart',
|
||||||
|
lineChart: 'Gráfico de líneas',
|
||||||
|
mixChart: 'Mix Chart',
|
||||||
|
example: 'Ejemplo',
|
||||||
|
nested: 'Rutas anidadass',
|
||||||
|
menu1: 'Menu 1',
|
||||||
|
'menu1-1': 'Menu 1-1',
|
||||||
|
'menu1-2': 'Menu 1-2',
|
||||||
|
'menu1-2-1': 'Menu 1-2-1',
|
||||||
|
'menu1-2-2': 'Menu 1-2-2',
|
||||||
|
'menu1-3': 'Menu 1-3',
|
||||||
|
menu2: 'Menu 2',
|
||||||
|
Table: 'Tabla',
|
||||||
|
dynamicTable: 'Tabla dinámica',
|
||||||
|
dragTable: 'Arrastrar tabla',
|
||||||
|
inlineEditTable: 'Editor',
|
||||||
|
complexTable: 'Complex Table',
|
||||||
|
treeTable: 'Tree Table',
|
||||||
|
customTreeTable: 'Custom TreeTable',
|
||||||
|
tab: 'Pestaña',
|
||||||
|
form: 'Formulario',
|
||||||
|
createArticle: 'Crear artículo',
|
||||||
|
editArticle: 'Editar artículo',
|
||||||
|
articleList: 'Listado de artículos',
|
||||||
|
errorPages: 'Páginas de error',
|
||||||
|
page401: '401',
|
||||||
|
page404: '404',
|
||||||
|
errorLog: 'Registro de errores',
|
||||||
|
excel: 'Excel',
|
||||||
|
exportExcel: 'Exportar a Excel',
|
||||||
|
selectExcel: 'Export seleccionado',
|
||||||
|
uploadExcel: 'Subir Excel',
|
||||||
|
zip: 'Zip',
|
||||||
|
exportZip: 'Exportar a Zip',
|
||||||
|
theme: 'Tema',
|
||||||
|
clipboardDemo: 'Clipboard',
|
||||||
|
i18n: 'I18n',
|
||||||
|
externalLink: 'Enlace externo'
|
||||||
|
},
|
||||||
|
navbar: {
|
||||||
|
logOut: 'Salir',
|
||||||
|
dashboard: 'Panel de control',
|
||||||
|
github: 'Github',
|
||||||
|
screenfull: 'Pantalla completa',
|
||||||
|
theme: 'Tema',
|
||||||
|
size: 'Tamaño global'
|
||||||
|
},
|
||||||
|
login: {
|
||||||
|
title: 'Formulario de acceso',
|
||||||
|
logIn: 'Acceso',
|
||||||
|
username: 'Usuario',
|
||||||
|
password: 'Contraseña',
|
||||||
|
any: 'nada',
|
||||||
|
thirdparty: 'Conectar con',
|
||||||
|
thirdpartyTips: 'No se puede simular en local, así que combine su propia simulación de negocios. ! !'
|
||||||
|
},
|
||||||
|
documentation: {
|
||||||
|
documentation: 'Documentación',
|
||||||
|
github: 'Repositorio Github'
|
||||||
|
},
|
||||||
|
permission: {
|
||||||
|
roles: 'Tus permisos',
|
||||||
|
switchRoles: 'Cambiar permisos'
|
||||||
|
},
|
||||||
|
guide: {
|
||||||
|
description: 'The guide page is useful for some people who entered the project for the first time. You can briefly introduce the features of the project. Demo is based on ',
|
||||||
|
button: 'Ver guía'
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
documentation: 'Documentación',
|
||||||
|
tinymceTips: 'Rich text editor is a core part of management system, but at the same time is a place with lots of problems. In the process of selecting rich texts, I also walked a lot of detours. The common rich text editors in the market are basically used, and the finally chose Tinymce. See documentation for more detailed rich text editor comparisons and introductions.',
|
||||||
|
dropzoneTips: 'Because my business has special needs, and has to upload images to qiniu, so instead of a third party, I chose encapsulate it by myself. It is very simple, you can see the detail code in @/components/Dropzone.',
|
||||||
|
stickyTips: 'when the page is scrolled to the preset position will be sticky on the top.',
|
||||||
|
backToTopTips1: 'When the page is scrolled to the specified position, the Back to Top button appears in the lower right corner',
|
||||||
|
backToTopTips2: 'You can customize the style of the button, show / hide, height of appearance, height of the return. If you need a text prompt, you can use element-ui el-tooltip elements externally',
|
||||||
|
imageUploadTips: 'Since I was using only the vue@1 version, and it is not compatible with mockjs at the moment, I modified it myself, and if you are going to use it, it is better to use official version.'
|
||||||
|
},
|
||||||
|
table: {
|
||||||
|
dynamicTips1: 'Fixed header, sorted by header order',
|
||||||
|
dynamicTips2: 'Not fixed header, sorted by click order',
|
||||||
|
dragTips1: 'Orden por defecto',
|
||||||
|
dragTips2: 'The after dragging order',
|
||||||
|
title: 'Título',
|
||||||
|
importance: 'Importancia',
|
||||||
|
type: 'Tipo',
|
||||||
|
remark: 'Remark',
|
||||||
|
search: 'Buscar',
|
||||||
|
add: 'Añadir',
|
||||||
|
export: 'Exportar',
|
||||||
|
reviewer: 'reviewer',
|
||||||
|
id: 'ID',
|
||||||
|
date: 'Fecha',
|
||||||
|
author: 'Autor',
|
||||||
|
readings: 'Lector',
|
||||||
|
status: 'Estado',
|
||||||
|
actions: 'Acciones',
|
||||||
|
edit: 'Editar',
|
||||||
|
publish: 'Publicar',
|
||||||
|
draft: 'Draft',
|
||||||
|
delete: 'Eliminar',
|
||||||
|
cancel: 'Cancelar',
|
||||||
|
confirm: 'Confirmar'
|
||||||
|
},
|
||||||
|
errorLog: {
|
||||||
|
tips: 'Please click the bug icon in the upper right corner',
|
||||||
|
description: 'Now the management system are basically the form of the spa, it enhances the user experience, but it also increases the possibility of page problems, a small negligence may lead to the entire page deadlock. Fortunately Vue provides a way to catch handling exceptions, where you can handle errors or report exceptions.',
|
||||||
|
documentation: 'Documento de introducción'
|
||||||
|
},
|
||||||
|
excel: {
|
||||||
|
export: 'Exportar',
|
||||||
|
selectedExport: 'Exportar seleccionados',
|
||||||
|
placeholder: 'Por favor escribe un nombre de fichero'
|
||||||
|
},
|
||||||
|
zip: {
|
||||||
|
export: 'Exportar',
|
||||||
|
placeholder: 'Por favor escribe un nombre de fichero'
|
||||||
|
},
|
||||||
|
theme: {
|
||||||
|
change: 'Cambiar tema',
|
||||||
|
documentation: 'Documentación del tema',
|
||||||
|
tips: 'Tips: It is different from the theme-pick on the navbar is two different skinning methods, each with different application scenarios. Refer to the documentation for details.'
|
||||||
|
},
|
||||||
|
tagsView: {
|
||||||
|
refresh: 'Actualizar',
|
||||||
|
close: 'Cerrar',
|
||||||
|
closeOthers: 'Cerrar otros',
|
||||||
|
closeAll: 'Cerrar todos'
|
||||||
|
}
|
||||||
|
}
|
@@ -3,8 +3,10 @@ import VueI18n from 'vue-i18n'
|
|||||||
import Cookies from 'js-cookie'
|
import Cookies from 'js-cookie'
|
||||||
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
|
import elementEnLocale from 'element-ui/lib/locale/lang/en' // element-ui lang
|
||||||
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
|
import elementZhLocale from 'element-ui/lib/locale/lang/zh-CN'// element-ui lang
|
||||||
|
import elementEsLocale from 'element-ui/lib/locale/lang/es'// element-ui lang
|
||||||
import enLocale from './en'
|
import enLocale from './en'
|
||||||
import zhLocale from './zh'
|
import zhLocale from './zh'
|
||||||
|
import esLocale from './es'
|
||||||
|
|
||||||
Vue.use(VueI18n)
|
Vue.use(VueI18n)
|
||||||
|
|
||||||
@@ -16,12 +18,16 @@ const messages = {
|
|||||||
zh: {
|
zh: {
|
||||||
...zhLocale,
|
...zhLocale,
|
||||||
...elementZhLocale
|
...elementZhLocale
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
...esLocale,
|
||||||
|
...elementEsLocale
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const i18n = new VueI18n({
|
const i18n = new VueI18n({
|
||||||
// set locale
|
// set locale
|
||||||
// options: en or zh
|
// options: en | zh | es
|
||||||
locale: Cookies.get('language') || 'en',
|
locale: Cookies.get('language') || 'en',
|
||||||
// set locale messages
|
// set locale messages
|
||||||
messages
|
messages
|
||||||
|
@@ -4,6 +4,16 @@ import articleAPI from './article'
|
|||||||
import remoteSearchAPI from './remoteSearch'
|
import remoteSearchAPI from './remoteSearch'
|
||||||
import transactionAPI from './transaction'
|
import transactionAPI from './transaction'
|
||||||
|
|
||||||
|
// 修复在使用 MockJS 情况下,设置 withCredentials = true,且未被拦截的跨域请求丢失 Cookies 的问题
|
||||||
|
// https://github.com/nuysoft/Mock/issues/300
|
||||||
|
Mock.XHR.prototype.proxy_send = Mock.XHR.prototype.send
|
||||||
|
Mock.XHR.prototype.send = function() {
|
||||||
|
if (this.custom.xhr) {
|
||||||
|
this.custom.xhr.withCredentials = this.withCredentials || false
|
||||||
|
}
|
||||||
|
this.proxy_send(...arguments)
|
||||||
|
}
|
||||||
|
|
||||||
// Mock.setup({
|
// Mock.setup({
|
||||||
// timeout: '350-600'
|
// timeout: '350-600'
|
||||||
// })
|
// })
|
||||||
|
@@ -164,17 +164,6 @@ export function objectMerge(target, source) {
|
|||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scrollTo(element, to, duration) {
|
|
||||||
if (duration <= 0) return
|
|
||||||
const difference = to - element.scrollTop
|
|
||||||
const perTick = (difference / duration) * 10
|
|
||||||
setTimeout(() => {
|
|
||||||
element.scrollTop = element.scrollTop + perTick
|
|
||||||
if (element.scrollTop === to) return
|
|
||||||
scrollTo(element, to, duration - 10)
|
|
||||||
}, 10)
|
|
||||||
}
|
|
||||||
|
|
||||||
export function toggleClass(element, className) {
|
export function toggleClass(element, className) {
|
||||||
if (!element || !className) {
|
if (!element || !className) {
|
||||||
return
|
return
|
||||||
@@ -296,3 +285,7 @@ export function deepClone(source) {
|
|||||||
export function uniqueArr(arr) {
|
export function uniqueArr(arr) {
|
||||||
return Array.from(new Set(arr))
|
return Array.from(new Set(arr))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isExternal(path) {
|
||||||
|
return /^(https?:|mailto:|tel:)/.test(path)
|
||||||
|
}
|
||||||
|
50
src/utils/scrollTo.js
Normal file
50
src/utils/scrollTo.js
Normal file
@@ -0,0 +1,50 @@
|
|||||||
|
Math.easeInOutQuad = function(t, b, c, d) {
|
||||||
|
t /= d / 2
|
||||||
|
if (t < 1) {
|
||||||
|
return c / 2 * t * t + b
|
||||||
|
}
|
||||||
|
t--
|
||||||
|
return -c / 2 * (t * (t - 2) - 1) + b
|
||||||
|
}
|
||||||
|
|
||||||
|
// requestAnimationFrame for Smart Animating http://goo.gl/sx5sts
|
||||||
|
var requestAnimFrame = (function() {
|
||||||
|
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function(callback) { window.setTimeout(callback, 1000 / 60) }
|
||||||
|
})()
|
||||||
|
|
||||||
|
// because it's so fucking difficult to detect the scrolling element, just move them all
|
||||||
|
function move(amount) {
|
||||||
|
document.documentElement.scrollTop = amount
|
||||||
|
document.body.parentNode.scrollTop = amount
|
||||||
|
document.body.scrollTop = amount
|
||||||
|
}
|
||||||
|
|
||||||
|
function position() {
|
||||||
|
return document.documentElement.scrollTop || document.body.parentNode.scrollTop || document.body.scrollTop
|
||||||
|
}
|
||||||
|
|
||||||
|
export function scrollTo(to, duration, callback) {
|
||||||
|
const start = position()
|
||||||
|
const change = to - start
|
||||||
|
const increment = 20
|
||||||
|
let currentTime = 0
|
||||||
|
duration = (typeof (duration) === 'undefined') ? 500 : duration
|
||||||
|
var animateScroll = function() {
|
||||||
|
// increment the time
|
||||||
|
currentTime += increment
|
||||||
|
// find the value with the quadratic in-out easing function
|
||||||
|
var val = Math.easeInOutQuad(currentTime, start, change, duration)
|
||||||
|
// move the document.body
|
||||||
|
move(val)
|
||||||
|
// do the animation unless its over
|
||||||
|
if (currentTime < duration) {
|
||||||
|
requestAnimFrame(animateScroll)
|
||||||
|
} else {
|
||||||
|
if (callback && typeof (callback) === 'function') {
|
||||||
|
// the animation is done so lets callback
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
animateScroll()
|
||||||
|
}
|
@@ -143,7 +143,8 @@ export default {
|
|||||||
title: [{ validator: validateRequire }],
|
title: [{ validator: validateRequire }],
|
||||||
content: [{ validator: validateRequire }],
|
content: [{ validator: validateRequire }],
|
||||||
source_uri: [{ validator: validateSourceUri, trigger: 'blur' }]
|
source_uri: [{ validator: validateSourceUri, trigger: 'blur' }]
|
||||||
}
|
},
|
||||||
|
tempRoute: {}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@@ -161,6 +162,11 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.postForm = Object.assign({}, defaultForm)
|
this.postForm = Object.assign({}, defaultForm)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Why need to make a copy of this.$route here?
|
||||||
|
// Because if you enter this page and quickly switch tag, may be in the execution of the setTagsViewTitle function, this.$route is no longer pointing to the current page
|
||||||
|
// https://github.com/PanJiaChen/vue-element-admin/issues/1221
|
||||||
|
this.tempRoute = Object.assign({}, this.$route)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
fetchData(id) {
|
fetchData(id) {
|
||||||
@@ -178,7 +184,7 @@ export default {
|
|||||||
},
|
},
|
||||||
setTagsViewTitle() {
|
setTagsViewTitle() {
|
||||||
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
|
const title = this.lang === 'zh' ? '编辑文章' : 'Edit Article'
|
||||||
const route = Object.assign({}, this.$route, { title: `${title}-${this.postForm.id}` })
|
const route = Object.assign({}, this.tempRoute, { title: `${title}-${this.postForm.id}` })
|
||||||
this.$store.dispatch('updateVisitedView', route)
|
this.$store.dispatch('updateVisitedView', route)
|
||||||
},
|
},
|
||||||
submitForm() {
|
submitForm() {
|
||||||
|
@@ -50,26 +50,18 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-container">
|
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
|
||||||
<el-pagination
|
|
||||||
:current-page="listQuery.page"
|
|
||||||
:page-sizes="[10,20,30, 50]"
|
|
||||||
:page-size="listQuery.limit"
|
|
||||||
:total="total"
|
|
||||||
background
|
|
||||||
layout="total, sizes, prev, pager, next, jumper"
|
|
||||||
@size-change="handleSizeChange"
|
|
||||||
@current-change="handleCurrentChange"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchList } from '@/api/article'
|
import { fetchList } from '@/api/article'
|
||||||
|
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ArticleList',
|
name: 'ArticleList',
|
||||||
|
components: { Pagination },
|
||||||
filters: {
|
filters: {
|
||||||
statusFilter(status) {
|
statusFilter(status) {
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
|
@@ -9,6 +9,7 @@
|
|||||||
<el-radio-group v-model="lang" size="small">
|
<el-radio-group v-model="lang" size="small">
|
||||||
<el-radio label="zh" border>简体中文</el-radio>
|
<el-radio label="zh" border>简体中文</el-radio>
|
||||||
<el-radio label="en" border>English</el-radio>
|
<el-radio label="en" border>English</el-radio>
|
||||||
|
<el-radio label="es" border>Español</el-radio>
|
||||||
</el-radio-group>
|
</el-radio-group>
|
||||||
<el-tag style="margin-top:15px;display:block;" type="info">{{ $t('i18nView.note') }}</el-tag>
|
<el-tag style="margin-top:15px;display:block;" type="info">{{ $t('i18nView.note') }}</el-tag>
|
||||||
</div>
|
</div>
|
||||||
@@ -101,6 +102,7 @@ export default {
|
|||||||
if (!this.$i18n.getLocaleMessage('en')[viewName]) {
|
if (!this.$i18n.getLocaleMessage('en')[viewName]) {
|
||||||
this.$i18n.mergeLocaleMessage('en', local.en)
|
this.$i18n.mergeLocaleMessage('en', local.en)
|
||||||
this.$i18n.mergeLocaleMessage('zh', local.zh)
|
this.$i18n.mergeLocaleMessage('zh', local.zh)
|
||||||
|
this.$i18n.mergeLocaleMessage('es', local.es)
|
||||||
}
|
}
|
||||||
this.setOptions() // set default select options
|
this.setOptions() // set default select options
|
||||||
},
|
},
|
||||||
|
@@ -39,5 +39,25 @@ export default {
|
|||||||
two: 'Two',
|
two: 'Two',
|
||||||
three: 'Three'
|
three: 'Three'
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
i18nView: {
|
||||||
|
title: 'Switch Language',
|
||||||
|
note: 'The internationalization of this project is based on vue-i18n',
|
||||||
|
datePlaceholder: 'Pick a day',
|
||||||
|
selectPlaceholder: 'Select',
|
||||||
|
tableDate: 'tableDate',
|
||||||
|
tableName: 'tableName',
|
||||||
|
tableAddress: 'tableAddress',
|
||||||
|
default: 'default:',
|
||||||
|
primary: 'primary',
|
||||||
|
success: 'success',
|
||||||
|
info: 'info',
|
||||||
|
warning: 'warning',
|
||||||
|
danger: 'danger',
|
||||||
|
one: 'One',
|
||||||
|
two: 'Two',
|
||||||
|
three: 'Three'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { validateURL } from '@/utils/validate'
|
import { isExternal } from '@/utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
@@ -18,7 +18,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
isExternalLink(routePath) {
|
isExternalLink(routePath) {
|
||||||
return validateURL(routePath)
|
return isExternal(routePath)
|
||||||
},
|
},
|
||||||
linkProps(url) {
|
linkProps(url) {
|
||||||
if (this.isExternalLink(url)) {
|
if (this.isExternalLink(url)) {
|
||||||
|
@@ -37,7 +37,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { generateTitle } from '@/utils/i18n'
|
import { generateTitle } from '@/utils/i18n'
|
||||||
import { validateURL } from '@/utils/validate'
|
import { isExternal } from '@/utils'
|
||||||
import Item from './Item'
|
import Item from './Item'
|
||||||
import AppLink from './Link'
|
import AppLink from './Link'
|
||||||
import FixiOSBug from './FixiOSBug'
|
import FixiOSBug from './FixiOSBug'
|
||||||
@@ -98,7 +98,7 @@ export default {
|
|||||||
return path.resolve(this.basePath, routePath)
|
return path.resolve(this.basePath, routePath)
|
||||||
},
|
},
|
||||||
isExternalLink(routePath) {
|
isExternalLink(routePath) {
|
||||||
return validateURL(routePath)
|
return isExternal(routePath)
|
||||||
},
|
},
|
||||||
generateTitle
|
generateTitle
|
||||||
}
|
}
|
||||||
|
@@ -5,14 +5,14 @@
|
|||||||
v-for="tag in visitedViews"
|
v-for="tag in visitedViews"
|
||||||
ref="tag"
|
ref="tag"
|
||||||
:class="isActive(tag)?'active':''"
|
:class="isActive(tag)?'active':''"
|
||||||
:to="tag.fullPath"
|
:to="{ path: tag.path, query: tag.query, fullPath: tag.fullPath }"
|
||||||
:key="tag.path"
|
:key="tag.path"
|
||||||
tag="span"
|
tag="span"
|
||||||
class="tags-view-item"
|
class="tags-view-item"
|
||||||
@click.middle.native="closeSelectedTag(tag)"
|
@click.middle.native="closeSelectedTag(tag)"
|
||||||
@contextmenu.prevent.native="openMenu(tag,$event)">
|
@contextmenu.prevent.native="openMenu(tag,$event)">
|
||||||
{{ generateTitle(tag.title) }}
|
{{ generateTitle(tag.title) }}
|
||||||
<span class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)"/>
|
<span class="el-icon-close" @click.prevent.stop="closeSelectedTag(tag)" />
|
||||||
</router-link>
|
</router-link>
|
||||||
</scroll-pane>
|
</scroll-pane>
|
||||||
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
<ul v-show="visible" :style="{left:left+'px',top:top+'px'}" class="contextmenu">
|
||||||
@@ -76,7 +76,7 @@ export default {
|
|||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
for (const tag of tags) {
|
for (const tag of tags) {
|
||||||
if (tag.to.path === this.$route.path) {
|
if (tag.to.path === this.$route.path) {
|
||||||
this.$refs.scrollPane.moveToTarget(tag.$el)
|
this.$refs.scrollPane.moveToTarget(tag)
|
||||||
|
|
||||||
// when query is different then update
|
// when query is different then update
|
||||||
if (tag.to.fullPath !== this.$route.fullPath) {
|
if (tag.to.fullPath !== this.$route.fullPath) {
|
||||||
|
@@ -80,9 +80,7 @@
|
|||||||
</el-table-column>
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
|
|
||||||
<div class="pagination-container">
|
<pagination v-show="total>0" :total="total" :page.sync="listQuery.page" :limit.sync="listQuery.limit" @pagination="getList" />
|
||||||
<el-pagination v-show="total>0" :current-page="listQuery.page" :page-sizes="[10,20,30, 50]" :page-size="listQuery.limit" :total="total" background layout="total, sizes, prev, pager, next, jumper" @size-change="handleSizeChange" @current-change="handleCurrentChange"/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
<el-dialog :title="textMap[dialogStatus]" :visible.sync="dialogFormVisible">
|
||||||
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
<el-form ref="dataForm" :rules="rules" :model="temp" label-position="left" label-width="70px" style="width: 400px; margin-left:50px;">
|
||||||
@@ -130,8 +128,9 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
|
import { fetchList, fetchPv, createArticle, updateArticle } from '@/api/article'
|
||||||
import waves from '@/directive/waves' // 水波纹指令
|
import waves from '@/directive/waves' // Waves directive
|
||||||
import { parseTime } from '@/utils'
|
import { parseTime } from '@/utils'
|
||||||
|
import Pagination from '@/components/Pagination' // Secondary package based on el-pagination
|
||||||
|
|
||||||
const calendarTypeOptions = [
|
const calendarTypeOptions = [
|
||||||
{ key: 'CN', display_name: 'China' },
|
{ key: 'CN', display_name: 'China' },
|
||||||
@@ -148,9 +147,8 @@ const calendarTypeKeyValue = calendarTypeOptions.reduce((acc, cur) => {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ComplexTable',
|
name: 'ComplexTable',
|
||||||
directives: {
|
components: { Pagination },
|
||||||
waves
|
directives: { waves },
|
||||||
},
|
|
||||||
filters: {
|
filters: {
|
||||||
statusFilter(status) {
|
statusFilter(status) {
|
||||||
const statusMap = {
|
const statusMap = {
|
||||||
@@ -168,7 +166,7 @@ export default {
|
|||||||
return {
|
return {
|
||||||
tableKey: 0,
|
tableKey: 0,
|
||||||
list: null,
|
list: null,
|
||||||
total: null,
|
total: 0,
|
||||||
listLoading: true,
|
listLoading: true,
|
||||||
listQuery: {
|
listQuery: {
|
||||||
page: 1,
|
page: 1,
|
||||||
@@ -228,14 +226,6 @@ export default {
|
|||||||
this.listQuery.page = 1
|
this.listQuery.page = 1
|
||||||
this.getList()
|
this.getList()
|
||||||
},
|
},
|
||||||
handleSizeChange(val) {
|
|
||||||
this.listQuery.limit = val
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
handleCurrentChange(val) {
|
|
||||||
this.listQuery.page = val
|
|
||||||
this.getList()
|
|
||||||
},
|
|
||||||
handleModifyStatus(row, status) {
|
handleModifyStatus(row, status) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: '操作成功',
|
message: '操作成功',
|
||||||
|
Reference in New Issue
Block a user