Compare commits
145 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
54ac74e14d | ||
|
705b9ccefd | ||
|
c84964d77c | ||
|
8f9de5c641 | ||
|
96a7035b1d | ||
|
7f2bd58035 | ||
|
b4b9d166c4 | ||
|
da24d61008 | ||
|
8ce571b61d | ||
|
38192b828d | ||
|
72f653dcc7 | ||
|
4dfa878fc6 | ||
|
cef1f11931 | ||
|
443c7aed3c | ||
|
0f5304112c | ||
|
dd3e22d5a1 | ||
|
d99cb068aa | ||
|
394f366aac | ||
|
e5ed2a39a5 | ||
|
39d26068ec | ||
|
d68d464142 | ||
|
d476e32032 | ||
|
8f2b0c94ba | ||
|
e00f2aedc7 | ||
|
df28ad7078 | ||
|
4feb89c94e | ||
|
a56d6f0cbd | ||
|
bee26561aa | ||
|
2ec9fe74a8 | ||
|
dec160fd1e | ||
|
c06baffb17 | ||
|
f876b9b678 | ||
|
061fa1f2a5 | ||
|
e0b8f09a9e | ||
|
ede541e2f5 | ||
|
e0f6248d0e | ||
|
1c4c3380e6 | ||
|
073b7219ff | ||
|
98604af104 | ||
|
3cb1e321d3 | ||
|
f2fcdee815 | ||
|
497b96f931 | ||
|
ed34ea3e07 | ||
|
47a373803e | ||
|
e8ad1f835c | ||
|
43a51148fe | ||
|
3f9df15c30 | ||
|
a9363ce541 | ||
|
690c779c64 | ||
|
f6279077de | ||
|
6b9e89055d | ||
|
6b13ffce66 | ||
|
d20585a3f9 | ||
|
46b4f74969 | ||
|
8c204b9837 | ||
|
339d760771 | ||
|
6d6a9df5b8 | ||
|
1286324214 | ||
|
372c4489f0 | ||
|
1511fe3778 | ||
|
122f7cafa6 | ||
|
6d1059f6a8 | ||
|
1d4f12187f | ||
|
925dbeb045 | ||
|
35055c5e51 | ||
|
e0a1e249ee | ||
|
a0d83e2ffc | ||
|
53059d5ccf | ||
|
fa5e6d9ecf | ||
|
4e25a17bff | ||
|
61095a9f2c | ||
|
61deec548c | ||
|
5eda0685ed | ||
|
11beefdb44 | ||
|
7e1ba16d12 | ||
|
7451ed6299 | ||
|
71aa416d71 | ||
|
4723a02a4b | ||
|
e05da2650b | ||
|
bb1d939a94 | ||
|
ac5d087ea4 | ||
|
c53fb7fbb1 | ||
|
660ff765f5 | ||
|
aaf24b4654 | ||
|
8211016078 | ||
|
374fd3ffeb | ||
|
e8b34bbc0d | ||
|
74cbb26209 | ||
|
fe31c88193 | ||
|
3b89cde53a | ||
|
59e240eb9a | ||
|
98d5f9a247 | ||
|
3666148ddc | ||
|
d56831679e | ||
|
2c868f47d9 | ||
|
1ae31fdd45 | ||
|
a932272b8f | ||
|
577e4dc17e | ||
|
0d9188b206 | ||
|
5b3b8b87d1 | ||
|
2c82d0a28e | ||
|
913f6c8bec | ||
|
76f4017470 | ||
|
feb6785654 | ||
|
59073fb013 | ||
|
c82ed3fcbf | ||
|
f99b97d9f1 | ||
|
99417081ed | ||
|
88d1338f29 | ||
|
3ded46cf23 | ||
|
5857db3393 | ||
|
a465652be6 | ||
|
a8459fa572 | ||
|
cddace507d | ||
|
e762056e80 | ||
|
18ec63d238 | ||
|
ccddfe87bc | ||
|
87a44ae7f5 | ||
|
1c852db0ef | ||
|
9463c50e06 | ||
|
658abf664d | ||
|
4940dd4040 | ||
|
91bd31e1e2 | ||
|
a8602e78f0 | ||
|
516897b97a | ||
|
2725285d26 | ||
|
a842a4b451 | ||
|
be0606ebbc | ||
|
a10de2e8d8 | ||
|
2282135b44 | ||
|
329f3b3714 | ||
|
065eaa93a2 | ||
|
4f2f136dd0 | ||
|
8d53ae1259 | ||
|
a185412446 | ||
|
3cf048e80b | ||
|
fcf7c0ba50 | ||
|
807aa548b2 | ||
|
db61251d89 | ||
|
582c6f4ae4 | ||
|
9c2a7e9485 | ||
|
fde12e8ef9 | ||
|
8945476c22 | ||
|
14ff09a414 | ||
|
a14547aaf9 |
4
.babelrc
@@ -1,6 +1,8 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", { "modules": false }],
|
||||
["env", {
|
||||
"modules": false
|
||||
}],
|
||||
"stage-2"
|
||||
],
|
||||
"plugins": ["transform-runtime"],
|
||||
|
@@ -52,7 +52,7 @@ module.exports = {
|
||||
'no-class-assign': 2,
|
||||
'no-cond-assign': 2,
|
||||
'no-const-assign': 2,
|
||||
'no-control-regex': 2,
|
||||
'no-control-regex': 0,
|
||||
'no-delete-var': 2,
|
||||
'no-dupe-args': 2,
|
||||
'no-dupe-class-members': 2,
|
||||
|
2
.gitignore
vendored
@@ -1,10 +1,10 @@
|
||||
.DS_Store
|
||||
node_modules/
|
||||
dist/
|
||||
static/ckeditor
|
||||
gifs/
|
||||
npm-debug.log
|
||||
test/unit/coverage
|
||||
test/e2e/reports
|
||||
selenium-debug.log
|
||||
.idea
|
||||
package-lock.json
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
module.exports = {
|
||||
"plugins": {
|
||||
// to edit target browsers: use "browserlist" field in package.json
|
||||
// to edit target browsers: use "browserslist" field in package.json
|
||||
"autoprefixer": {}
|
||||
}
|
||||
}
|
||||
|
@@ -32,8 +32,9 @@
|
||||
- ECharts
|
||||
- 401, 404 error page
|
||||
- Error log
|
||||
- Exporting to Excel
|
||||
- Export Excel
|
||||
- Upload Excel
|
||||
- Export Zip
|
||||
- Table example
|
||||
- Interactive table example
|
||||
- Drag & drop table example
|
||||
@@ -47,6 +48,7 @@
|
||||
- screenfull
|
||||
- markdown2html
|
||||
- views-tab
|
||||
- clipboard
|
||||
|
||||
## Development
|
||||
|
||||
|
168
README.md
@@ -1,47 +1,54 @@
|
||||
# vue-element-admin #
|
||||
<p align="center">
|
||||
<img width="320" src="https://wpimg.wallstcn.com/ecc53a42-d79b-42e2-8852-5126b810a4c8.svg">
|
||||
</p>
|
||||
|
||||
[](https://github.com/vuejs/vue)
|
||||
[](https://github.com/ElemeFE/element)
|
||||
# vue-element-admin
|
||||
|
||||
[](https://github.com/vuejs/vue)
|
||||
[](https://github.com/ElemeFE/element)
|
||||
[](https://github.com/PanJiaChen/vue-element-admin/blob/master/LICENSE)
|
||||
[]()
|
||||
|
||||
**A magical vue admin.**
|
||||
|
||||
[线上地址](http://panjiachen.github.io/vue-element-admin)
|
||||
- [线上地址](http://panjiachen.github.io/vue-element-admin)
|
||||
|
||||
[English Document](https://github.com/PanJiaChen/vue-element-admin/blob/master/README-en.md)
|
||||
- [使用文档](https://panjiachen.github.io/vue-element-admin-site/#/)
|
||||
|
||||
[wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
||||
- [English Document](https://github.com/PanJiaChen/vue-element-admin/blob/master/README-en.md)
|
||||
|
||||
[donate](https://github.com/PanJiaChen/vue-element-admin#donate)
|
||||
- [wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
||||
|
||||
- [donate](https://panjiachen.github.io/vue-element-admin-site/#/donate)
|
||||
|
||||
**本项目的定位是后台集成方案,不适合当基础模板来开发。**
|
||||
- 模板建议使用: [vueAdmin-template](https://github.com/PanJiaChen/vueAdmin-template)
|
||||
- 桌面端: [electron-vue-admin](https://github.com/PanJiaChen/electron-vue-admin)
|
||||
|
||||
|
||||
**注意:该项目目前使用element-ui@2.0.5版本,所以最低兼容 Vue 2.5.0**
|
||||
|
||||
**注意:该项目目前使用element-ui@1.4.2版本,所以最低兼容 Vue 2.3.0**
|
||||
楼主这里有一份调查[问卷](https://www.wjx.cn/m/16866569.aspx) 有空请填写一下,以表对本项目的支持~ps:不是给这个调查问卷网站做广告,所以填完问卷不用点上面抽奖有的没的那些东西
|
||||
|
||||
## 前言
|
||||
> 这半年来一直在用vue写管理后台,目前后台已经有百来个页面,十几种权限,但维护成本依然很低,所以准备开源分享一下后台开发的经验和成果。目前的技术栈主要的采用vue+element+axios由webpack2打包。由于是个人项目,所以数据请求都是用了mockjs模拟。注意:在此项目基础上改造开发时请移除mock文件。
|
||||
## 前序准备
|
||||
|
||||
你的本地环境需要安装 [node](http://nodejs.org/) 和 [git](https://git-scm.com/)。我们的技术栈基于 [ES2015+](http://es6.ruanyifeng.com/)、[vue](https://cn.vuejs.org/index.html)、[vuex](https://vuex.vuejs.org/zh-cn/)、[vue-router](https://router.vuejs.org/zh-cn/) 和 [element-ui](https://github.com/ElemeFE/element),提前了解和学习这些知识会对使用本项目有很大的帮助。
|
||||
|
||||
写了一个系列的教程配套文章,如何从零构建后一个完整的后台项目:
|
||||
|
||||
- [wiki](https://github.com/PanJiaChen/vue-element-admin/wiki)
|
||||
同时配套一个系列的教程文章,如何从零构建后一个完整的后台项目,建议大家先看完这些文章再来实践本项目
|
||||
- [手摸手,带你用 vue 撸后台 系列一(基础篇)](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
|
||||
- [手摸手,带你用 vue 撸后台 系列二(登录权限篇)](https://juejin.im/post/591aa14f570c35006961acac)
|
||||
- [手摸手,带你用 vue 撸后台 系列三 (实战篇)](https://juejin.im/post/593121aa0ce4630057f70d35)
|
||||
- [手摸手,带你用vue撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
|
||||
- [手摸手,带你封装一个vue component](https://segmentfault.com/a/1190000009090836)
|
||||
- [手摸手,带你用 vue 撸后台 系列四(vueAdmin 一个极简的后台基础模板)](https://juejin.im/post/595b4d776fb9a06bbe7dba56)
|
||||
- [手摸手,带你封装一个 vue component](https://segmentfault.com/a/1190000009090836)
|
||||
- [手摸手,带你优雅的使用 icon](https://juejin.im/post/59bb864b5188257e7a427c09)
|
||||
|
||||
相应需求,开了一个qq群 `591724180` 方便大家交流
|
||||
|
||||
或者可以加入该 **[圈子](https://jianshiapp.com/circles/1209)** 讨论问题
|
||||
|
||||
**如有问题请先看上述文章和Wiki,若不能满足,欢迎 issue 和 pr**
|
||||
**如有问题请先看上述使用文档和文章,若不能满足,欢迎 issue 和 pr**
|
||||
|
||||
**该项目并不是一个脚手架,更倾向于是一个集成解决方案**
|
||||
**本项目并不是一个脚手架,更倾向于是一个集成解决方案**
|
||||
|
||||
**该项目不支持低版本游览器(如ie),有需求请自行添加polyfill [详情](https://github.com/PanJiaChen/vue-element-admin/wiki#babel-polyfill)**
|
||||
|
||||
@@ -49,35 +56,38 @@
|
||||
## 功能
|
||||
- 登录/注销
|
||||
- 权限验证
|
||||
- 侧边栏
|
||||
- 面包屑
|
||||
- 多环境发布
|
||||
- 动态侧边栏(支持多级路由)
|
||||
- 动态面包屑
|
||||
- 国际化多语言
|
||||
- 多种动态换肤
|
||||
- 快捷导航(标签页)
|
||||
- 富文本编辑器
|
||||
- Markdown编辑器
|
||||
- JSON编辑器
|
||||
- Screenfull全屏
|
||||
- 列表拖拽
|
||||
- plitPane
|
||||
- Dropzone
|
||||
- Sticky
|
||||
- CountTo
|
||||
- echarts图表
|
||||
- 401,404错误页面
|
||||
- Svg Sprite 图标
|
||||
- Dashboard
|
||||
- 本地mock数据
|
||||
- Echarts 图表
|
||||
- Clipboard(剪贴复制)
|
||||
- 401/404错误页面
|
||||
- 错误日志
|
||||
- 导出excel
|
||||
- 导出zip
|
||||
- 前端可视化excel
|
||||
- table example
|
||||
- Table example
|
||||
- 动态table example
|
||||
- 拖拽table example
|
||||
- 内联编辑table example
|
||||
- form example
|
||||
- 多环境发布
|
||||
- dashboard
|
||||
- 二次登录
|
||||
- 动态侧边栏(支持多级路由)
|
||||
- mock数据
|
||||
- cache tabs example
|
||||
- screenfull
|
||||
- markdown2html
|
||||
- views-tab
|
||||
- Form example
|
||||
- 二步登录
|
||||
- SplitPane
|
||||
- Dropzone
|
||||
- Sticky
|
||||
- CountTo
|
||||
- Markdown2html
|
||||
|
||||
|
||||
## 开发
|
||||
@@ -87,7 +97,8 @@
|
||||
|
||||
# 安装依赖
|
||||
npm install
|
||||
//or # 建议不要用cnpm 安装有各种诡异的bug 可以通过如下操作解决npm速度慢的问题
|
||||
|
||||
//or # 建议不要用cnpm 安装有各种诡异的bug 可以通过如下操作解决npm速度慢的问题
|
||||
npm install --registry=https://registry.npm.taobao.org
|
||||
|
||||
# 本地开发 开启服务
|
||||
@@ -104,6 +115,8 @@
|
||||
npm run build:prod
|
||||
```
|
||||
|
||||
更多信息请参考 [使用文档](https://panjiachen.github.io/vue-element-admin-site/#/)
|
||||
|
||||
## 目录结构
|
||||
```shell
|
||||
├── build // 构建相关
|
||||
@@ -113,15 +126,19 @@
|
||||
│ ├── assets // 主题 字体等静态资源
|
||||
│ ├── components // 全局公用组件
|
||||
│ ├── directive // 全局指令
|
||||
│ ├── filtres // 全局filter
|
||||
│ ├── mock // mock数据
|
||||
│ ├── filtres // 全局 filter
|
||||
│ ├── icons // 项目所有 svg icons
|
||||
│ ├── lang // 国际化 language
|
||||
│ ├── mock // 项目mock 模拟数据
|
||||
│ ├── router // 路由
|
||||
│ ├── store // 全局store管理
|
||||
│ ├── store // 全局 store管理
|
||||
│ ├── styles // 全局样式
|
||||
│ ├── utils // 全局公用方法
|
||||
│ ├── view // view
|
||||
│ ├── vendor // 公用vendor
|
||||
│ ├── views // view
|
||||
│ ├── App.vue // 入口页面
|
||||
│ └── main.js // 入口 加载组件 初始化等
|
||||
│ ├── main.js // 入口 加载组件 初始化等
|
||||
│ └── permission.js // 权限管理
|
||||
├── static // 第三方不打包资源
|
||||
│ └── Tinymce // 富文本
|
||||
├── .babelrc // babel-loader 配置
|
||||
@@ -136,74 +153,13 @@
|
||||
## Changelog
|
||||
Detailed changes for each release are documented in the [release notes](https://github.com/PanJiaChen/vue-element-admin/releases).
|
||||
|
||||
## [查看更多demo](http://panjiachen.github.io/vue-element-admin)
|
||||

|
||||
|
||||
## Donate
|
||||
If you find this project useful, you can buy me a cup of coffee
|
||||

|
||||
|
||||
## 状态管理
|
||||
后台只有user和app配置相关状态使用vuex存在全局,其它数据都由每个业务页面自己管理。
|
||||
|
||||
|
||||
## 效果图
|
||||
|
||||
#### 两步验证登录 支持微信和qq
|
||||
|
||||

|
||||
|
||||
#### 真正的动态换肤
|
||||
|
||||
<br />
|
||||
|
||||
#### tabs
|
||||
|
||||
<br />
|
||||
|
||||
|
||||
|
||||
#### 可收起侧边栏
|
||||
|
||||

|
||||
|
||||
#### table拖拽排序
|
||||
|
||||

|
||||
|
||||
|
||||
#### 动态table
|
||||
|
||||

|
||||
|
||||
|
||||
#### 上传裁剪头像
|
||||
|
||||

|
||||
|
||||
|
||||
#### 错误统计
|
||||
|
||||

|
||||
|
||||
|
||||
#### 富文本(整合七牛 打水印等个性化功能)
|
||||
|
||||

|
||||
|
||||
#### 封装table组件
|
||||
|
||||

|
||||
|
||||
#### 图表
|
||||
|
||||

|
||||
|
||||
|
||||
#### 导出excel
|
||||
|
||||

|
||||
|
||||
|
||||
## [查看更多demo](http://panjiachen.github.io/vue-element-admin)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
@@ -9,9 +9,7 @@ var webpack = require('webpack');
|
||||
var config = require('../config');
|
||||
var webpackConfig = require('./webpack.prod.conf');
|
||||
|
||||
console.log(process.env.NODE_ENV)
|
||||
|
||||
var spinner = ora('building for ' + process.env.NODE_ENV + '...')
|
||||
var spinner = ora('building for ' + process.env.NODE_ENV + ' of ' + process.env.env_config+ ' mode...' )
|
||||
spinner.start()
|
||||
|
||||
|
||||
|
@@ -1,4 +1,5 @@
|
||||
require('./check-versions')(); // 检查 Node 和 npm 版本
|
||||
|
||||
var config = require('../config');
|
||||
if (!process.env.NODE_ENV) {
|
||||
process.env.NODE_ENV = JSON.parse(config.dev.env.NODE_ENV)
|
||||
@@ -28,19 +29,19 @@ var devMiddleware = require('webpack-dev-middleware')(compiler, {
|
||||
});
|
||||
|
||||
var hotMiddleware = require('webpack-hot-middleware')(compiler, {
|
||||
log: () => {
|
||||
}
|
||||
log: false,
|
||||
heartbeat: 2000
|
||||
});
|
||||
|
||||
// force page reload when html-webpack-plugin template changes
|
||||
compiler.plugin('compilation', function (compilation) {
|
||||
compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
|
||||
hotMiddleware.publish({action: 'reload'});
|
||||
cb()
|
||||
})
|
||||
});
|
||||
|
||||
// compiler.apply(new DashboardPlugin());
|
||||
// currently disabled until this is resolved:
|
||||
// https://github.com/jantimon/html-webpack-plugin/issues/680
|
||||
// compiler.plugin('compilation', function (compilation) {
|
||||
// compilation.plugin('html-webpack-plugin-after-emit', function (data, cb) {
|
||||
// hotMiddleware.publish({ action: 'reload' })
|
||||
// cb()
|
||||
// })
|
||||
// })
|
||||
|
||||
// proxy api requests
|
||||
Object.keys(proxyTable).forEach(function (context) {
|
||||
@@ -67,18 +68,26 @@ app.use(staticPath, express.static('./static'));
|
||||
|
||||
var uri = 'http://localhost:' + port
|
||||
|
||||
devMiddleware.waitUntilValid(function () {
|
||||
console.log('> Listening at ' + uri + '\n')
|
||||
});
|
||||
var _resolve
|
||||
var readyPromise = new Promise(resolve => {
|
||||
_resolve = resolve
|
||||
})
|
||||
|
||||
module.exports = app.listen(port, function (err) {
|
||||
if (err) {
|
||||
console.log(err);
|
||||
return
|
||||
}
|
||||
console.log('> Starting dev server...')
|
||||
devMiddleware.waitUntilValid(() => {
|
||||
console.log('> Listening at ' + uri + '\n')
|
||||
// when env is testing, don't need open it
|
||||
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
|
||||
opn(uri)
|
||||
}
|
||||
_resolve()
|
||||
})
|
||||
|
||||
// when env is testing, don't need open it
|
||||
if (autoOpenBrowser && process.env.NODE_ENV !== 'testing') {
|
||||
opn(uri)
|
||||
}
|
||||
});
|
||||
var server = app.listen(port)
|
||||
|
||||
module.exports = {
|
||||
ready: readyPromise,
|
||||
close: () => {
|
||||
server.close()
|
||||
}
|
||||
}
|
||||
|
@@ -20,9 +20,16 @@ exports.cssLoaders = function (options) {
|
||||
}
|
||||
}
|
||||
|
||||
var postcssLoader = {
|
||||
loader: 'postcss-loader',
|
||||
options: {
|
||||
sourceMap: true
|
||||
}
|
||||
}
|
||||
|
||||
// generate loader string to be used with extract text plugin
|
||||
function generateLoaders (loader, loaderOptions) {
|
||||
var loaders = [cssLoader]
|
||||
var loaders = options.usePostCSS !== false ? [cssLoader, postcssLoader] : [cssLoader]
|
||||
if (loader) {
|
||||
loaders.push({
|
||||
loader: loader + '-loader',
|
||||
|
@@ -14,7 +14,7 @@ module.exports = {
|
||||
output: {
|
||||
path: config.build.assetsRoot,
|
||||
filename: '[name].js',
|
||||
publicPath: process.env.NODE_ENV !== 'development' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
|
||||
publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js', '.vue', '.json'],
|
||||
@@ -38,13 +38,13 @@ module.exports = {
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.(js|vue)$/,
|
||||
loader: 'eslint-loader',
|
||||
enforce: "pre",
|
||||
include: [resolve('src'), resolve('test')],
|
||||
options: {
|
||||
formatter: require('eslint-friendly-formatter')
|
||||
}
|
||||
test: /\.(js|vue)$/,
|
||||
loader: 'eslint-loader',
|
||||
enforce: "pre",
|
||||
include: [resolve('src'), resolve('test')],
|
||||
options: {
|
||||
formatter: require('eslint-friendly-formatter')
|
||||
}
|
||||
},
|
||||
{
|
||||
test: /\.vue$/,
|
||||
|
@@ -18,9 +18,7 @@ function resolveApp(relativePath) {
|
||||
|
||||
module.exports = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.dev.cssSourceMap
|
||||
})
|
||||
rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
|
||||
},
|
||||
// cheap-source-map is faster for development
|
||||
devtool: '#cheap-source-map',
|
||||
|
@@ -9,7 +9,7 @@ var HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||
var ExtractTextPlugin = require('extract-text-webpack-plugin')
|
||||
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
|
||||
|
||||
var env = process.env.NODE_ENV === 'production' ? config.build.prodEnv : config.build.sitEnv
|
||||
var env = config.build[process.env.env_config+'Env']
|
||||
|
||||
function resolveApp(relativePath) {
|
||||
return path.resolve(relativePath);
|
||||
@@ -19,7 +19,8 @@ var webpackConfig = merge(baseWebpackConfig, {
|
||||
module: {
|
||||
rules: utils.styleLoaders({
|
||||
sourceMap: config.build.productionSourceMap,
|
||||
extract: true
|
||||
extract: true,
|
||||
usePostCSS: true
|
||||
})
|
||||
},
|
||||
devtool: config.build.productionSourceMap ? '#source-map' : false,
|
||||
@@ -38,7 +39,8 @@ var webpackConfig = merge(baseWebpackConfig, {
|
||||
compress: {
|
||||
warnings: false
|
||||
},
|
||||
sourceMap: true
|
||||
sourceMap: true,
|
||||
parallel: true
|
||||
}),
|
||||
// extract css into its own file
|
||||
new ExtractTextPlugin({
|
||||
@@ -73,10 +75,12 @@ var webpackConfig = merge(baseWebpackConfig, {
|
||||
}),
|
||||
// cache Module Identifiers
|
||||
new webpack.HashedModuleIdsPlugin(),
|
||||
// enable scope hoisting
|
||||
new webpack.optimize.ModuleConcatenationPlugin(),
|
||||
// split vendor js into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'vendor',
|
||||
minChunks: function (module, count) {
|
||||
minChunks: function (module) {
|
||||
// any required modules inside node_modules are extracted to vendor
|
||||
return (
|
||||
module.resource &&
|
||||
@@ -87,6 +91,12 @@ var webpackConfig = merge(baseWebpackConfig, {
|
||||
)
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
minChunks: Infinity
|
||||
}),
|
||||
// split echarts into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
async: 'echarts',
|
||||
@@ -95,12 +105,24 @@ var webpackConfig = merge(baseWebpackConfig, {
|
||||
return context && (context.indexOf('echarts') >= 0 || context.indexOf('zrender') >= 0);
|
||||
}
|
||||
}),
|
||||
// extract webpack runtime and module manifest to its own file in order to
|
||||
// prevent vendor hash from being updated whenever app bundle is updated
|
||||
// split xlsx into its own file
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'manifest',
|
||||
chunks: ['vendor']
|
||||
async: 'xlsx',
|
||||
minChunks(module) {
|
||||
var context = module.context;
|
||||
return context && (context.indexOf('xlsx') >= 0);
|
||||
}
|
||||
}),
|
||||
// This instance extracts shared chunks from code splitted chunks and bundles them
|
||||
// in a separate chunk, similar to the vendor chunk
|
||||
// see: https://webpack.js.org/plugins/commons-chunk-plugin/#extra-async-commons-chunk
|
||||
new webpack.optimize.CommonsChunkPlugin({
|
||||
name: 'app',
|
||||
async: 'vendor-async',
|
||||
children: true,
|
||||
minChunks: 3
|
||||
}),
|
||||
|
||||
// copy custom static assets
|
||||
new CopyWebpackPlugin([{
|
||||
from: path.resolve(__dirname, '../static'),
|
||||
@@ -109,9 +131,11 @@ var webpackConfig = merge(baseWebpackConfig, {
|
||||
}])
|
||||
]
|
||||
})
|
||||
|
||||
if (config.build.bundleAnalyzerReport) {
|
||||
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
|
||||
}
|
||||
|
||||
module.exports = webpackConfig
|
||||
|
||||
|
@@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
NODE_ENV: '"development"',
|
||||
ENV_CONFIG: '"dev"',
|
||||
BASE_API: '"https://api-dev"',
|
||||
APP_ORIGIN: '"https://wallstreetcn.com"'
|
||||
}
|
||||
|
@@ -3,37 +3,37 @@ var path = require('path')
|
||||
|
||||
module.exports = {
|
||||
build: {
|
||||
sitEnv: require('./sit.env'),
|
||||
prodEnv: require('./prod.env'),
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: './', //请根据自己路径配置更改
|
||||
productionSourceMap: false,
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
sitEnv: require('./sit.env'),
|
||||
prodEnv: require('./prod.env'),
|
||||
index: path.resolve(__dirname, '../dist/index.html'),
|
||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: './', //请根据自己路径配置更改
|
||||
productionSourceMap: false,
|
||||
// Gzip off by default as many popular static hosts such as
|
||||
// Surge or Netlify already gzip all static assets for you.
|
||||
// Before setting to `true`, make sure to:
|
||||
// npm install --save-dev compression-webpack-plugin
|
||||
productionGzip: false,
|
||||
productionGzipExtensions: ['js', 'css'],
|
||||
// Run the build command with an extra argument to
|
||||
// View the bundle analyzer report after build finishes:
|
||||
// `npm run build --report`
|
||||
// Set to `true` or `false` to always turn it on or off
|
||||
bundleAnalyzerReport: process.env.npm_config_report
|
||||
},
|
||||
dev: {
|
||||
env: require('./dev.env'),
|
||||
port: 9527,
|
||||
autoOpenBrowser: true,
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
// CSS Sourcemaps off by default because relative paths are "buggy"
|
||||
// with this option, according to the CSS-Loader README
|
||||
// (https://github.com/webpack/css-loader#sourcemaps)
|
||||
// In our experience, they generally work as expected,
|
||||
// just be aware of this issue when enabling this option.
|
||||
cssSourceMap: false
|
||||
env: require('./dev.env'),
|
||||
port: 9527,
|
||||
autoOpenBrowser: true,
|
||||
assetsSubDirectory: 'static',
|
||||
assetsPublicPath: '/',
|
||||
proxyTable: {},
|
||||
// CSS Sourcemaps off by default because relative paths are "buggy"
|
||||
// with this option, according to the CSS-Loader README
|
||||
// (https://github.com/webpack/css-loader#sourcemaps)
|
||||
// In our experience, they generally work as expected,
|
||||
// just be aware of this issue when enabling this option.
|
||||
cssSourceMap: false
|
||||
}
|
||||
}
|
||||
|
@@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"',
|
||||
ENV_CONFIG: '"prod"',
|
||||
BASE_API: '"https://api-prod"',
|
||||
APP_ORIGIN: '"https://wallstreetcn.com"'
|
||||
};
|
||||
|
@@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
NODE_ENV: '"production"',
|
||||
ENV_CONFIG: '"sit"',
|
||||
BASE_API: '"https://api-sit"',
|
||||
APP_ORIGIN: '"https://wallstreetcn.com"'
|
||||
};
|
||||
|
BIN
favicon.ico
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
24
index.html
@@ -1,15 +1,15 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title>Juicy</title>
|
||||
</head>
|
||||
<body>
|
||||
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce/tinymce.min.js></script>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="renderer" content="webkit">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||
<title>vue-element-admin</title>
|
||||
</head>
|
||||
<script src=<%= htmlWebpackPlugin.options.path %>/tinymce/tinymce.min.js></script>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
||||
|
115
package.json
@@ -1,96 +1,101 @@
|
||||
{
|
||||
"name": "juicy",
|
||||
"version": "2.1.0",
|
||||
"name": "vue-element-admin",
|
||||
"version": "3.1.0",
|
||||
"description": "A Vue.js admin",
|
||||
"author": "Pan <panfree23@gmail.com>",
|
||||
"license": "MIT",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "node build/dev-server.js",
|
||||
"build:prod": "cross-env NODE_ENV=production node build/build.js",
|
||||
"build:sit": "cross-env NODE_ENV=sit node build/build.js",
|
||||
"build:sit-preview": "cross-env NODE_ENV=sit npm_config_preview=true npm_config_report=true node build/build.js",
|
||||
"build:prod": "cross-env NODE_ENV=production env_config=prod node build/build.js",
|
||||
"build:sit": "cross-env NODE_ENV=production env_config=sit node build/build.js",
|
||||
"build:sit-preview": "cross-env NODE_ENV=production env_config=sit npm_config_preview=true npm_config_report=true node build/build.js",
|
||||
"lint": "eslint --ext .js,.vue src"
|
||||
},
|
||||
"dependencies": {
|
||||
"axios": "0.16.2",
|
||||
"codemirror": "5.26.0",
|
||||
"dropzone": "5.1.0",
|
||||
"echarts": "3.6.2",
|
||||
"element-ui": "1.4.2",
|
||||
"axios": "0.17.1",
|
||||
"clipboard": "1.7.1",
|
||||
"codemirror": "5.31.0",
|
||||
"dropzone": "5.2.0",
|
||||
"echarts": "3.8.5",
|
||||
"element-ui": "2.0.7",
|
||||
"file-saver": "1.3.3",
|
||||
"js-cookie": "2.1.4",
|
||||
"font-awesome": "4.7.0",
|
||||
"js-cookie": "2.2.0",
|
||||
"jsonlint": "1.6.2",
|
||||
"jszip": "3.1.4",
|
||||
"mockjs": "1.0.1-beta3",
|
||||
"normalize.css": "7.0.0",
|
||||
"nprogress": "0.2.0",
|
||||
"screenfull": "3.2.2",
|
||||
"showdown": "1.7.1",
|
||||
"screenfull": "3.3.2",
|
||||
"showdown": "1.8.2",
|
||||
"simplemde": "1.11.2",
|
||||
"sortablejs": "1.5.1",
|
||||
"vue": "2.4.2",
|
||||
"vue-count-to": "1.0.5",
|
||||
"vue-multiselect": "2.0.2",
|
||||
"vue-router": "2.7.0",
|
||||
"vue-splitpane": "^1.0.0",
|
||||
"vuedraggable": "2.14.1",
|
||||
"vuex": "2.3.1",
|
||||
"xlsx": "^0.10.8"
|
||||
"sortablejs": "1.6.1",
|
||||
"vue": "2.5.9",
|
||||
"vue-count-to": "1.0.10",
|
||||
"vue-i18n": "7.3.2",
|
||||
"vue-multiselect": "2.0.6",
|
||||
"vue-router": "3.0.1",
|
||||
"vue-splitpane": "1.0.0",
|
||||
"vuedraggable": "2.15.0",
|
||||
"vuex": "3.0.1",
|
||||
"xlsx": "^0.11.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "7.1.1",
|
||||
"babel-core": "6.25.0",
|
||||
"babel-eslint": "7.2.3",
|
||||
"babel-loader": "7.0.0",
|
||||
"autoprefixer": "7.1.6",
|
||||
"babel-core": "6.26.0",
|
||||
"babel-eslint": "8.0.2",
|
||||
"babel-loader": "7.1.2",
|
||||
"babel-plugin-transform-runtime": "6.23.0",
|
||||
"babel-preset-env": "1.5.2",
|
||||
"babel-preset-env": "1.6.1",
|
||||
"babel-preset-stage-2": "6.24.1",
|
||||
"babel-register": "6.24.1",
|
||||
"chalk": "1.1.3",
|
||||
"connect-history-api-fallback": "1.3.0",
|
||||
"copy-webpack-plugin": "4.0.1",
|
||||
"cross-env": "5.0.1",
|
||||
"css-loader": "0.28.4",
|
||||
"eslint": "3.19.0",
|
||||
"babel-register": "6.26.0",
|
||||
"chalk": "2.3.0",
|
||||
"connect-history-api-fallback": "1.4.0",
|
||||
"copy-webpack-plugin": "4.2.0",
|
||||
"cross-env": "5.1.1",
|
||||
"css-loader": "0.28.7",
|
||||
"eslint": "4.11.0",
|
||||
"eslint-friendly-formatter": "3.0.0",
|
||||
"eslint-import-resolver-webpack": "0.8.1",
|
||||
"eslint-loader": "1.7.1",
|
||||
"eslint-plugin-html": "3.0.0",
|
||||
"eslint-plugin-import": "2.3.0",
|
||||
"eslint-import-resolver-webpack": "0.8.3",
|
||||
"eslint-loader": "1.9.0",
|
||||
"eslint-plugin-html": "3.2.2",
|
||||
"eslint-plugin-import": "2.8.0",
|
||||
"eventsource-polyfill": "0.9.6",
|
||||
"express": "4.15.3",
|
||||
"extract-text-webpack-plugin": "2.1.2",
|
||||
"express": "4.16.2",
|
||||
"extract-text-webpack-plugin": "3.0.2",
|
||||
"file-loader": "0.11.2",
|
||||
"friendly-errors-webpack-plugin": "1.6.1",
|
||||
"function-bind": "1.1.0",
|
||||
"html-webpack-plugin": "2.28.0",
|
||||
"html-webpack-plugin": "2.30.0",
|
||||
"http-proxy-middleware": "0.17.4",
|
||||
"node-sass": "^4.5.0",
|
||||
"opn": "4.0.2",
|
||||
"optimize-css-assets-webpack-plugin": "1.3.0",
|
||||
"optimize-css-assets-webpack-plugin": "3.2.0",
|
||||
"ora": "1.1.0",
|
||||
"postcss-loader": "^2.0.8",
|
||||
"pushstate-server": "2.1.0",
|
||||
"rimraf": "2.6.0",
|
||||
"sass-loader": "6.0.5",
|
||||
"script-loader": "0.7.0",
|
||||
"sass-loader": "6.0.6",
|
||||
"script-loader": "0.7.2",
|
||||
"semver": "5.3.0",
|
||||
"style-loader": "0.17.0",
|
||||
"svg-sprite-loader": "3.2.4",
|
||||
"url-loader": "0.5.8",
|
||||
"vue-loader": "13.0.4",
|
||||
"vue-style-loader": "3.0.1",
|
||||
"vue-template-compiler": "2.4.2",
|
||||
"webpack": "2.6.1",
|
||||
"webpack-bundle-analyzer": "2.8.2",
|
||||
"webpack-dev-middleware": "1.10.2",
|
||||
"webpack-hot-middleware": "2.18.0",
|
||||
"style-loader": "0.19.0",
|
||||
"svg-sprite-loader": "3.4.1",
|
||||
"url-loader": "0.6.2",
|
||||
"vue-loader": "13.5.0",
|
||||
"vue-style-loader": "3.0.3",
|
||||
"vue-template-compiler": "2.5.9",
|
||||
"webpack": "3.8.1",
|
||||
"webpack-bundle-analyzer": "2.9.0",
|
||||
"webpack-dev-middleware": "1.12.0",
|
||||
"webpack-hot-middleware": "2.20.0",
|
||||
"webpack-merge": "4.1.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 4.0.0",
|
||||
"npm": ">= 3.0.0"
|
||||
},
|
||||
"browserlist": [
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 8"
|
||||
|
@@ -11,6 +11,6 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
@import '~normalize.css/normalize.css';// normalize.css 样式格式化
|
||||
@import './styles/index.scss'; // 全局自定义的css样式
|
||||
@import '~normalize.css/normalize.css'; // normalize.css 样式格式化
|
||||
@import './styles/index.scss'; // 全局自定义样式
|
||||
</style>
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import fetch from '@/utils/fetch'
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function fetchList(query) {
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/article/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
@@ -9,17 +9,32 @@ export function fetchList(query) {
|
||||
}
|
||||
|
||||
export function fetchArticle() {
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/article/detail',
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
export function fetchPv(pv) {
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/article/pv',
|
||||
method: 'get',
|
||||
params: { pv }
|
||||
})
|
||||
}
|
||||
|
||||
export function createArticle(data) {
|
||||
return request({
|
||||
url: '/article/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function updateArticle(data) {
|
||||
return request({
|
||||
url: '/article/update',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
import fetch from '@/utils/fetch'
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function loginByUsername(username, password) {
|
||||
const data = {
|
||||
username,
|
||||
password
|
||||
}
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/login/login',
|
||||
method: 'post',
|
||||
data
|
||||
@@ -13,14 +13,14 @@ export function loginByUsername(username, password) {
|
||||
}
|
||||
|
||||
export function logout() {
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/login/logout',
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
|
||||
export function getUserInfo(token) {
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/user/info',
|
||||
method: 'get',
|
||||
params: { token }
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import fetch from '@/utils/fetch'
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function getToken() {
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/qiniu/upload/token', // 假地址 自行替换
|
||||
method: 'get'
|
||||
})
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import fetch from '@/utils/fetch'
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function userSearch(name) {
|
||||
return fetch({
|
||||
return request({
|
||||
url: '/search/user',
|
||||
method: 'get',
|
||||
params: { name }
|
||||
|
9
src/api/transaction.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import request from '@/utils/request'
|
||||
|
||||
export function fetchList(query) {
|
||||
return request({
|
||||
url: '/transaction/list',
|
||||
method: 'get',
|
||||
params: query
|
||||
})
|
||||
}
|
54
src/components/Breadcrumb/index.vue
Normal file
@@ -0,0 +1,54 @@
|
||||
<template>
|
||||
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path" v-if='item.meta.title'>
|
||||
<span v-if='item.redirect==="noredirect"||index==levelList.length-1' class="no-redirect">{{generateTitle(item.meta.title)}}</span>
|
||||
<router-link v-else :to="item.redirect||item.path">{{generateTitle(item.meta.title)}}</router-link>
|
||||
</el-breadcrumb-item>
|
||||
</transition-group>
|
||||
</el-breadcrumb>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
created() {
|
||||
this.getBreadcrumb()
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
levelList: null
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route() {
|
||||
this.getBreadcrumb()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getBreadcrumb() {
|
||||
let matched = this.$route.matched.filter(item => item.name)
|
||||
const first = matched[0]
|
||||
if (first && first.name !== 'dashboard') {
|
||||
matched = [{ path: '/dashboard', meta: { title: 'dashboard' }}].concat(matched)
|
||||
}
|
||||
this.levelList = matched
|
||||
},
|
||||
generateTitle(title) {
|
||||
return this.$t('route.' + title)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.app-breadcrumb.el-breadcrumb {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 50px;
|
||||
margin-left: 10px;
|
||||
.no-redirect {
|
||||
color: #97a8be;
|
||||
cursor: text;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -45,21 +45,22 @@ export default {
|
||||
|
||||
const xAxisData = []
|
||||
const data = []
|
||||
for (let i = 0; i < 30; i++) {
|
||||
xAxisData.push(i + '号')
|
||||
data.push(Math.round(Math.random() * 2 + 3))
|
||||
const data2 = []
|
||||
for (let i = 0; i < 50; i++) {
|
||||
xAxisData.push(i)
|
||||
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
|
||||
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
|
||||
}
|
||||
|
||||
this.chart.setOption(
|
||||
{
|
||||
backgroundColor: '#08263a',
|
||||
tooltip: {
|
||||
trigger: 'axis'
|
||||
},
|
||||
xAxis: {
|
||||
xAxis: [{
|
||||
show: false,
|
||||
data: xAxisData
|
||||
},
|
||||
}, {
|
||||
show: false,
|
||||
data: xAxisData
|
||||
}],
|
||||
visualMap: {
|
||||
show: false,
|
||||
min: 0,
|
||||
@@ -84,28 +85,64 @@ export default {
|
||||
color: '#08263f'
|
||||
}
|
||||
},
|
||||
axisTick: {}
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: 'back',
|
||||
type: 'bar',
|
||||
data,
|
||||
name: '撸文数',
|
||||
data: data2,
|
||||
z: 1,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
opacity: 0.4,
|
||||
barBorderRadius: 5,
|
||||
shadowBlur: 10,
|
||||
shadowBlur: 3,
|
||||
shadowColor: '#111'
|
||||
}
|
||||
},
|
||||
animationEasing: 'elasticOut',
|
||||
animationEasingUpdate: 'elasticOut',
|
||||
animationDelay(idx) {
|
||||
return idx * 20
|
||||
},
|
||||
animationDelayUpdate(idx) {
|
||||
return idx * 20
|
||||
}
|
||||
}]
|
||||
}, {
|
||||
name: 'Simulate Shadow',
|
||||
type: 'line',
|
||||
data,
|
||||
z: 2,
|
||||
showSymbol: false,
|
||||
animationDelay: 0,
|
||||
animationEasing: 'linear',
|
||||
animationDuration: 1200,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
color: 'transparent'
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: '#08263a',
|
||||
shadowBlur: 50,
|
||||
shadowColor: '#000'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: 'front',
|
||||
type: 'bar',
|
||||
data,
|
||||
xAxisIndex: 1,
|
||||
z: 3,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
barBorderRadius: 5
|
||||
}
|
||||
}
|
||||
}],
|
||||
animationEasing: 'elasticOut',
|
||||
animationEasingUpdate: 'elasticOut',
|
||||
animationDelay(idx) {
|
||||
return idx * 20
|
||||
},
|
||||
animationDelayUpdate(idx) {
|
||||
return idx * 20
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -1,150 +0,0 @@
|
||||
<template>
|
||||
<div :class="className" :id="id" :style="{height:height,width:width}"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import echarts from 'echarts'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
className: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
id: {
|
||||
type: String,
|
||||
default: 'chart'
|
||||
},
|
||||
width: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '200px'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
chart: null
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.initChart()
|
||||
},
|
||||
beforeDestroy() {
|
||||
if (!this.chart) {
|
||||
return
|
||||
}
|
||||
this.chart.dispose()
|
||||
this.chart = null
|
||||
},
|
||||
methods: {
|
||||
initChart() {
|
||||
this.chart = echarts.init(document.getElementById(this.id))
|
||||
|
||||
const xAxisData = []
|
||||
const data = []
|
||||
const data2 = []
|
||||
for (let i = 0; i < 50; i++) {
|
||||
xAxisData.push(i)
|
||||
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5)
|
||||
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3)
|
||||
}
|
||||
this.chart.setOption(
|
||||
{
|
||||
backgroundColor: '#08263a',
|
||||
xAxis: [{
|
||||
show: false,
|
||||
data: xAxisData
|
||||
}, {
|
||||
show: false,
|
||||
data: xAxisData
|
||||
}],
|
||||
visualMap: {
|
||||
show: false,
|
||||
min: 0,
|
||||
max: 50,
|
||||
dimension: 0,
|
||||
inRange: {
|
||||
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055']
|
||||
}
|
||||
},
|
||||
yAxis: {
|
||||
axisLine: {
|
||||
show: false
|
||||
},
|
||||
axisLabel: {
|
||||
textStyle: {
|
||||
color: '#4a657a'
|
||||
}
|
||||
},
|
||||
splitLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: '#08263f'
|
||||
}
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
}
|
||||
},
|
||||
series: [{
|
||||
name: 'back',
|
||||
type: 'bar',
|
||||
data: data2,
|
||||
z: 1,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
opacity: 0.4,
|
||||
barBorderRadius: 5,
|
||||
shadowBlur: 3,
|
||||
shadowColor: '#111'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: 'Simulate Shadow',
|
||||
type: 'line',
|
||||
data,
|
||||
z: 2,
|
||||
showSymbol: false,
|
||||
animationDelay: 0,
|
||||
animationEasing: 'linear',
|
||||
animationDuration: 1200,
|
||||
lineStyle: {
|
||||
normal: {
|
||||
color: 'transparent'
|
||||
}
|
||||
},
|
||||
areaStyle: {
|
||||
normal: {
|
||||
color: '#08263a',
|
||||
shadowBlur: 50,
|
||||
shadowColor: '#000'
|
||||
}
|
||||
}
|
||||
}, {
|
||||
name: 'front',
|
||||
type: 'bar',
|
||||
data,
|
||||
xAxisIndex: 1,
|
||||
z: 3,
|
||||
itemStyle: {
|
||||
normal: {
|
||||
barBorderRadius: 5
|
||||
}
|
||||
}
|
||||
}],
|
||||
animationEasing: 'elasticOut',
|
||||
animationEasingUpdate: 'elasticOut',
|
||||
animationDelay(idx) {
|
||||
return idx * 20
|
||||
},
|
||||
animationDelayUpdate(idx) {
|
||||
return idx * 20
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="twoDndList">
|
||||
<div class="twoDndList-list" :style="{width:width1}">
|
||||
<div class="dndList">
|
||||
<div class="dndList-list" :style="{width:width1}">
|
||||
<h3>{{list1Title}}</h3>
|
||||
<draggable :list="list1" class="dragArea" :options="{group:'article'}">
|
||||
<div class="list-complete-item" v-for="element in list1" :key='element.id'>
|
||||
@@ -13,7 +13,7 @@
|
||||
</div>
|
||||
</draggable>
|
||||
</div>
|
||||
<div class="twoDndList-list" :style="{width:width2}">
|
||||
<div class="dndList-list" :style="{width:width2}">
|
||||
<h3>{{list2Title}}</h3>
|
||||
<draggable :list="filterList2" class="dragArea" :options="{group:'article'}">
|
||||
<div class="list-complete-item" v-for="element in filterList2" :key='element.id'>
|
||||
@@ -28,7 +28,7 @@
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
export default {
|
||||
name: 'twoDndList',
|
||||
name: 'DndList',
|
||||
components: { draggable },
|
||||
computed: {
|
||||
filterList2() {
|
||||
@@ -97,7 +97,7 @@ export default {
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.twoDndList {
|
||||
.dndList {
|
||||
background: #fff;
|
||||
padding-bottom: 40px;
|
||||
&:after {
|
||||
@@ -105,7 +105,7 @@ export default {
|
||||
display: table;
|
||||
clear: both;
|
||||
}
|
||||
.twoDndList-list {
|
||||
.dndList-list {
|
||||
float: left;
|
||||
padding-bottom: 30px;
|
||||
&:first-of-type {
|
@@ -7,7 +7,7 @@
|
||||
<script>
|
||||
import Dropzone from 'dropzone'
|
||||
import 'dropzone/dist/dropzone.css'
|
||||
// import { getToken } from 'api/qiniu';
|
||||
// import { getToken } from 'api/qiniu';
|
||||
|
||||
Dropzone.autoDiscover = false
|
||||
|
||||
@@ -59,18 +59,18 @@ export default {
|
||||
},
|
||||
accept: (file, done) => {
|
||||
/* 七牛*/
|
||||
// const token = this.$store.getters.token;
|
||||
// getToken(token).then(response => {
|
||||
// file.token = response.data.qiniu_token;
|
||||
// file.key = response.data.qiniu_key;
|
||||
// file.url = response.data.qiniu_url;
|
||||
// done();
|
||||
// })
|
||||
// const token = this.$store.getters.token;
|
||||
// getToken(token).then(response => {
|
||||
// file.token = response.data.qiniu_token;
|
||||
// file.key = response.data.qiniu_key;
|
||||
// file.url = response.data.qiniu_url;
|
||||
// done();
|
||||
// })
|
||||
done()
|
||||
},
|
||||
sending: (file, xhr, formData) => {
|
||||
// formData.append('token', file.token);
|
||||
// formData.append('key', file.key);
|
||||
// formData.append('token', file.token);
|
||||
// formData.append('key', file.key);
|
||||
vm.initOnce = false
|
||||
}
|
||||
})
|
||||
|
@@ -12,14 +12,14 @@
|
||||
<el-dialog title="bug日志" :visible.sync="dialogTableVisible">
|
||||
<el-table :data="logsList">
|
||||
<el-table-column label="message">
|
||||
<template scope="scope">
|
||||
<template slot-scope="scope">
|
||||
<div>msg:{{ scope.row.err.message }}</div>
|
||||
<br/>
|
||||
<div>url: {{scope.row.url}}</div>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="stack">
|
||||
<template scope="scope">
|
||||
<template slot-scope="scope">
|
||||
{{ scope.row.err.stack}}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<a href="https://github.com/PanJiaChen/vue-element-admin" target="_blank" class="github-corner" aria-label="View source on Github">
|
||||
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#4AB7BD; color:#fff; position: absolute; top: 50px; border: 0; right: 0;"
|
||||
<svg width="80" height="80" viewBox="0 0 250 250" style="fill:#40c9c6; color:#fff; position: absolute; top: 84px; border: 0; right: 0;"
|
||||
aria-hidden="true">
|
||||
<path d="M0,0 L115,115 L130,115 L142,142 L250,250 L250,0 Z"></path>
|
||||
<path d="M128.3,109.0 C113.8,99.7 119.0,89.6 119.0,89.6 C122.0,82.7 120.5,78.6 120.5,78.6 C119.2,72.0 123.4,76.3 123.4,76.3 C127.3,80.9 125.5,87.3 125.5,87.3 C122.9,97.6 130.6,101.9 134.4,103.2"
|
||||
@@ -11,3 +11,32 @@
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out
|
||||
}
|
||||
|
||||
@keyframes octocat-wave {
|
||||
0%,
|
||||
100% {
|
||||
transform: rotate(0)
|
||||
}
|
||||
20%,
|
||||
60% {
|
||||
transform: rotate(-25deg)
|
||||
}
|
||||
40%,
|
||||
80% {
|
||||
transform: rotate(10deg)
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width:500px) {
|
||||
.github-corner:hover .octo-arm {
|
||||
animation: none
|
||||
}
|
||||
.github-corner .octo-arm {
|
||||
animation: octocat-wave 560ms ease-in-out
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,15 +1,15 @@
|
||||
<template>
|
||||
<div>
|
||||
<svg t="1492500959545" @click="toggleClick" class="wscn-icon hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
|
||||
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
|
||||
<path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
|
||||
p-id="1692"></path>
|
||||
<path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
|
||||
p-id="1693"></path>
|
||||
<path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
|
||||
p-id="1694"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div>
|
||||
<svg t="1492500959545" @click="toggleClick" class="wscn-icon hamburger" :class="{'is-active':isActive}" style="" viewBox="0 0 1024 1024"
|
||||
version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1691" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64">
|
||||
<path d="M966.8023 568.849776 57.196677 568.849776c-31.397081 0-56.850799-25.452695-56.850799-56.850799l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 543.397081 998.200404 568.849776 966.8023 568.849776z"
|
||||
p-id="1692"></path>
|
||||
<path d="M966.8023 881.527125 57.196677 881.527125c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.849776 56.850799-56.849776l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.849776l0 0C1023.653099 856.07443 998.200404 881.527125 966.8023 881.527125z"
|
||||
p-id="1693"></path>
|
||||
<path d="M966.8023 256.17345 57.196677 256.17345c-31.397081 0-56.850799-25.452695-56.850799-56.849776l0 0c0-31.397081 25.452695-56.850799 56.850799-56.850799l909.605623 0c31.397081 0 56.849776 25.452695 56.849776 56.850799l0 0C1023.653099 230.720755 998.200404 256.17345 966.8023 256.17345z"
|
||||
p-id="1694"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -34,13 +34,12 @@ export default {
|
||||
cursor: pointer;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
transform: rotate(0deg);
|
||||
transform: rotate(90deg);
|
||||
transition: .38s;
|
||||
transform-origin: 50% 50%;
|
||||
}
|
||||
|
||||
.hamburger.is-active {
|
||||
transform: rotate(90deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@@ -1,22 +0,0 @@
|
||||
<template>
|
||||
<svg class="svg-icon" aria-hidden="true">
|
||||
<use :xlink:href="iconName"></use>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'icon-svg',
|
||||
props: {
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iconName() {
|
||||
return `#icon-${this.iconClass}`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -105,7 +105,7 @@
|
||||
<script>
|
||||
/* eslint-disable */
|
||||
import {effectRipple, data2blob} from './utils';
|
||||
import fetch from 'utils/fetch';
|
||||
import request from 'utils/request';
|
||||
import langBag from './lang';
|
||||
const mimes = {
|
||||
'jpg': 'image/jpeg',
|
||||
@@ -672,7 +672,7 @@
|
||||
that.loading = 1;
|
||||
that.setStep(3);
|
||||
that.$emit('crop-success', createImgUrl, field, ki);
|
||||
fetch({
|
||||
request({
|
||||
url,
|
||||
method: 'post',
|
||||
data: fmData
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class='json-editor'>
|
||||
<textarea ref='textarea'></textarea>
|
||||
<div class="json-editor">
|
||||
<textarea ref="textarea"></textarea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -57,7 +57,6 @@ export default {
|
||||
.CodeMirror {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.json-editor .cm-s-rubyblue span.cm-string {
|
||||
color: #F08047;
|
||||
}
|
@@ -1,297 +1,278 @@
|
||||
<template>
|
||||
<div class="material-input__component" :class="computedClasses">
|
||||
<input v-if="type === 'email'" type="email" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
|
||||
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
|
||||
@blur="handleFocus(false)" @input="handleModelInput">
|
||||
<input v-if="type === 'url'" type="url" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
|
||||
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
|
||||
@blur="handleFocus(false)" @input="handleModelInput">
|
||||
<input v-if="type === 'number'" type="number" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
|
||||
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :minlength="minlength" :maxlength="maxlength"
|
||||
:required="required" @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
|
||||
<input v-if="type === 'password'" type="password" class="material-input" :name="name" :id="id" :placeholder="placeholder"
|
||||
v-model="valueCopy" :readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :max="max" :min="min" :required="required"
|
||||
@focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
|
||||
<input v-if="type === 'tel'" type="tel" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
|
||||
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :required="required" @focus="handleFocus(true)"
|
||||
@blur="handleFocus(false)" @input="handleModelInput">
|
||||
<input v-if="type === 'text'" type="text" class="material-input" :name="name" :id="id" :placeholder="placeholder" v-model="valueCopy"
|
||||
:readonly="readonly" :disabled="disabled" :autocomplete="autocomplete" :minlength="minlength" :maxlength="maxlength"
|
||||
:required="required" @focus="handleFocus(true)" @blur="handleFocus(false)" @input="handleModelInput">
|
||||
|
||||
<span class="material-input-bar"></span>
|
||||
|
||||
<label class="material-label">
|
||||
<slot></slot>
|
||||
</label>
|
||||
<div v-if="errorMessages" class="material-errors">
|
||||
<div v-for="error in computedErrors" class="material-error" :key='error'>
|
||||
{{ error }}
|
||||
</div>
|
||||
<div :class="{iconClass:icon}">
|
||||
<i class="el-input__icon material-input__icon" :class="['el-icon-' + icon]" v-if="icon"></i>
|
||||
<input v-if="type === 'email'" type="email" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
|
||||
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :required="required" @focus="handleMdFocus"
|
||||
@blur="handleMdBlur" @input="handleModelInput">
|
||||
<input v-if="type === 'url'" type="url" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
|
||||
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :required="required" @focus="handleMdFocus"
|
||||
@blur="handleMdBlur" @input="handleModelInput">
|
||||
<input v-if="type === 'number'" type="number" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
|
||||
:step="step" :readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :max="max" :min="min" :minlength="minlength"
|
||||
:maxlength="maxlength" :required="required" @focus="handleMdFocus" @blur="handleMdBlur" @input="handleModelInput">
|
||||
<input v-if="type === 'password'" type="password" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
|
||||
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :max="max" :min="min" :required="required" @focus="handleMdFocus"
|
||||
@blur="handleMdBlur" @input="handleModelInput">
|
||||
<input v-if="type === 'tel'" type="tel" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
|
||||
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :required="required" @focus="handleMdFocus"
|
||||
@blur="handleMdBlur" @input="handleModelInput">
|
||||
<input v-if="type === 'text'" type="text" class="material-input" :name="name" :placeholder="fillPlaceHolder" v-model="currentValue"
|
||||
:readonly="readonly" :disabled="disabled" :autoComplete="autoComplete" :minlength="minlength" :maxlength="maxlength"
|
||||
:required="required" @focus="handleMdFocus" @blur="handleMdBlur" @input="handleModelInput">
|
||||
<span class="material-input-bar"></span>
|
||||
<label class="material-label">
|
||||
<slot></slot>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// source:https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue
|
||||
// source:https://github.com/wemake-services/vue-material-input/blob/master/src/components/MaterialInput.vue
|
||||
|
||||
export default {
|
||||
name: 'material-input',
|
||||
computed: {
|
||||
computedErrors() {
|
||||
return typeof this.errorMessages === 'string'
|
||||
? [this.errorMessages] : this.errorMessages
|
||||
},
|
||||
computedClasses() {
|
||||
return {
|
||||
'material--active': this.focus,
|
||||
'material--disabled': this.disabled,
|
||||
'material--has-errors': Boolean(!this.valid || (this.errorMessages && this.errorMessages.length)),
|
||||
'material--raised': Boolean(this.focus || this.valueCopy || // has value
|
||||
(this.placeholder && !this.valueCopy)) // has placeholder
|
||||
}
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
valueCopy: null,
|
||||
focus: false,
|
||||
valid: true
|
||||
}
|
||||
},
|
||||
beforeMount() {
|
||||
// Here we are following the Vue2 convention on custom v-model:
|
||||
// https://github.com/vuejs/vue/issues/2873#issuecomment-223759341
|
||||
this.copyValue(this.value)
|
||||
},
|
||||
methods: {
|
||||
handleModelInput(event) {
|
||||
this.$emit('input', event.target.value, event)
|
||||
this.handleValidation()
|
||||
},
|
||||
handleFocus(focused) {
|
||||
this.focus = focused
|
||||
},
|
||||
handleValidation() {
|
||||
this.valid = this.$el ? this.$el.querySelector('.material-input').validity.valid : this.valid
|
||||
},
|
||||
copyValue(value) {
|
||||
this.valueCopy = value
|
||||
this.handleValidation()
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newValue) {
|
||||
this.copyValue(newValue)
|
||||
}
|
||||
},
|
||||
name: 'md-input',
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
icon: String,
|
||||
name: String,
|
||||
type: {
|
||||
type: String,
|
||||
default: 'text'
|
||||
},
|
||||
value: {
|
||||
default: null
|
||||
},
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
readonly: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
min: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
max: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
minlength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
maxlength: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
value: [String, Number],
|
||||
placeholder: String,
|
||||
readonly: Boolean,
|
||||
disabled: Boolean,
|
||||
min: String,
|
||||
max: String,
|
||||
step: String,
|
||||
minlength: Number,
|
||||
maxlength: Number,
|
||||
required: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
autocomplete: {
|
||||
autoComplete: {
|
||||
type: String,
|
||||
default: 'off'
|
||||
},
|
||||
errorMessages: {
|
||||
type: [Array, String],
|
||||
default: null
|
||||
validateEvent: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
computedClasses() {
|
||||
return {
|
||||
'material--active': this.focus,
|
||||
'material--disabled': this.disabled,
|
||||
'material--raised': Boolean(this.focus || this.currentValue) // has value
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
value(newValue) {
|
||||
this.currentValue = newValue
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
currentValue: this.value,
|
||||
focus: false,
|
||||
fillPlaceHolder: null
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleModelInput(event) {
|
||||
const value = event.target.value
|
||||
this.$emit('input', value)
|
||||
if (this.$parent.$options.componentName === 'ElFormItem') {
|
||||
if (this.validateEvent) {
|
||||
this.$parent.$emit('el.form.change', [value])
|
||||
}
|
||||
}
|
||||
this.$emit('change', value)
|
||||
},
|
||||
handleMdFocus(event) {
|
||||
this.focus = true
|
||||
this.$emit('focus', event)
|
||||
if (this.placeholder && this.placeholder !== '') {
|
||||
this.fillPlaceHolder = this.placeholder
|
||||
}
|
||||
},
|
||||
handleMdBlur(event) {
|
||||
this.focus = false
|
||||
this.$emit('blur', event)
|
||||
this.fillPlaceHolder = null
|
||||
if (this.$parent.$options.componentName === 'ElFormItem') {
|
||||
if (this.validateEvent) {
|
||||
this.$parent.$emit('el.form.blur', [this.currentValue])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
// Fonts:
|
||||
$font-size-base: 16px;
|
||||
$font-size-small: 18px;
|
||||
$font-size-smallest: 12px;
|
||||
$font-weight-normal: normal;
|
||||
// Utils
|
||||
$spacer: 12px;
|
||||
$transition: 0.2s ease all;
|
||||
// Base clases:
|
||||
%base-bar-pseudo {
|
||||
content: '';
|
||||
height: 1px;
|
||||
width: 0;
|
||||
bottom: 0;
|
||||
// Fonts:
|
||||
$font-size-base: 16px;
|
||||
$font-size-small: 18px;
|
||||
$font-size-smallest: 12px;
|
||||
$font-weight-normal: normal;
|
||||
$font-weight-bold: bold;
|
||||
$apixel: 1px;
|
||||
// Utils
|
||||
$spacer: 12px;
|
||||
$transition: 0.2s ease all;
|
||||
$index: 0px;
|
||||
$index-has-icon: 30px;
|
||||
// Theme:
|
||||
$color-white: white;
|
||||
$color-grey: #9E9E9E;
|
||||
$color-grey-light: #E0E0E0;
|
||||
$color-blue: #2196F3;
|
||||
$color-red: #F44336;
|
||||
$color-black: black;
|
||||
// Base clases:
|
||||
%base-bar-pseudo {
|
||||
content: '';
|
||||
height: 1px;
|
||||
width: 0;
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
transition: $transition;
|
||||
}
|
||||
|
||||
// Mixins:
|
||||
@mixin slided-top() {
|
||||
top: - ($font-size-base + $spacer);
|
||||
left: 0;
|
||||
font-size: $font-size-base;
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
// Component:
|
||||
.material-input__component {
|
||||
margin-top: 36px;
|
||||
position: relative;
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.iconClass {
|
||||
.material-input__icon {
|
||||
position: absolute;
|
||||
transition: $transition;
|
||||
left: 0;
|
||||
line-height: $font-size-base;
|
||||
color: $color-blue;
|
||||
top: $spacer;
|
||||
width: $index-has-icon;
|
||||
height: $font-size-base;
|
||||
font-size: $font-size-base;
|
||||
font-weight: $font-weight-normal;
|
||||
pointer-events: none;
|
||||
}
|
||||
.material-label {
|
||||
left: $index-has-icon;
|
||||
}
|
||||
.material-input {
|
||||
text-indent: $index-has-icon;
|
||||
}
|
||||
}
|
||||
.material-input {
|
||||
font-size: $font-size-base;
|
||||
padding: $spacer $spacer $spacer - $apixel * 10 $spacer / 2;
|
||||
display: block;
|
||||
width: 100%;
|
||||
border: none;
|
||||
line-height: 1;
|
||||
border-radius: 0;
|
||||
&:focus {
|
||||
outline: none;
|
||||
border: none;
|
||||
border-bottom: 1px solid transparent; // fixes the height issue
|
||||
}
|
||||
}
|
||||
.material-label {
|
||||
font-weight: $font-weight-normal;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
left: $index;
|
||||
top: 0;
|
||||
transition: $transition;
|
||||
font-size: $font-size-small;
|
||||
}
|
||||
.material-input-bar {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
&:before {
|
||||
@extend %base-bar-pseudo;
|
||||
left: 50%;
|
||||
}
|
||||
&:after {
|
||||
@extend %base-bar-pseudo;
|
||||
right: 50%;
|
||||
}
|
||||
}
|
||||
// Disabled state:
|
||||
&.material--disabled {
|
||||
.material-input {
|
||||
border-bottom-style: dashed;
|
||||
}
|
||||
}
|
||||
// Raised state:
|
||||
&.material--raised {
|
||||
.material-label {
|
||||
@include slided-top();
|
||||
}
|
||||
}
|
||||
// Active state:
|
||||
&.material--active {
|
||||
.material-input-bar {
|
||||
&:before,
|
||||
&:after {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Mixins:
|
||||
@mixin slided-top() {
|
||||
top: -2 * $spacer;
|
||||
font-size: $font-size-small;
|
||||
.material-input__component {
|
||||
background: $color-white;
|
||||
.material-input {
|
||||
background: none;
|
||||
color: $color-black;
|
||||
text-indent: $index;
|
||||
border-bottom: 1px solid $color-grey-light;
|
||||
}
|
||||
|
||||
// Component:
|
||||
.material-input__component {
|
||||
/*margin-top: 30px;*/
|
||||
position: relative;
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
.material-input {
|
||||
font-size: $font-size-base;
|
||||
padding: $spacer $spacer $spacer $spacer / 2;
|
||||
display: block;
|
||||
width: 100%;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
&:focus {
|
||||
outline: none;
|
||||
border: none;
|
||||
border-bottom: 1px solid transparent; // fixes the height issue
|
||||
}
|
||||
}
|
||||
.material-label {
|
||||
font-size: $font-size-base;
|
||||
font-weight: $font-weight-normal;
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
left: 0;
|
||||
top: $spacer;
|
||||
transition: $transition;
|
||||
}
|
||||
.material-input-bar {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
&:before {
|
||||
@extend %base-bar-pseudo;
|
||||
left: 50%;
|
||||
}
|
||||
&:after {
|
||||
@extend %base-bar-pseudo;
|
||||
right: 50%;
|
||||
}
|
||||
}
|
||||
// Disabled state:
|
||||
&.material--disabled {
|
||||
.material-input {
|
||||
border-bottom-style: dashed;
|
||||
}
|
||||
}
|
||||
// Raised state:
|
||||
&.material--raised {
|
||||
.material-label {
|
||||
@include slided-top();
|
||||
}
|
||||
}
|
||||
// Active state:
|
||||
&.material--active {
|
||||
.material-input-bar {
|
||||
&:before,
|
||||
&:after {
|
||||
width: 50%;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Errors:
|
||||
.material-errors {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
.material-error {
|
||||
font-size: $font-size-smallest;
|
||||
line-height: $font-size-smallest + 2px;
|
||||
overflow: hidden;
|
||||
margin-top: 0;
|
||||
padding-top: $spacer / 2;
|
||||
padding-right: $spacer / 2;
|
||||
padding-left: 0;
|
||||
}
|
||||
}
|
||||
.material-label {
|
||||
color: $color-grey;
|
||||
}
|
||||
|
||||
// Theme:
|
||||
$color-white: white;
|
||||
$color-grey: #9E9E9E;
|
||||
$color-grey-light: #E0E0E0;
|
||||
$color-blue: #2196F3;
|
||||
$color-red: #F44336;
|
||||
$color-black: black;
|
||||
.material-input__component {
|
||||
background: $color-white;
|
||||
.material-input {
|
||||
background: none;
|
||||
color: $color-black;
|
||||
text-indent: 30px;
|
||||
border-bottom: 1px solid $color-grey-light;
|
||||
}
|
||||
.material-label {
|
||||
color: $color-grey;
|
||||
}
|
||||
.material-input-bar {
|
||||
&:before,
|
||||
&:after {
|
||||
background: $color-blue;
|
||||
}
|
||||
}
|
||||
// Active state:
|
||||
&.material--active {
|
||||
.material-label {
|
||||
color: $color-blue;
|
||||
}
|
||||
}
|
||||
// Errors:
|
||||
&.material--has-errors {
|
||||
&.material--active .material-label {
|
||||
color: $color-red;
|
||||
}
|
||||
.material-input-bar {
|
||||
&:before,
|
||||
&:after {
|
||||
background: $color-red;
|
||||
}
|
||||
}
|
||||
.material-errors {
|
||||
color: $color-red;
|
||||
}
|
||||
}
|
||||
.material-input-bar {
|
||||
&:before,
|
||||
&:after {
|
||||
background: $color-blue;
|
||||
}
|
||||
}
|
||||
// Active state:
|
||||
&.material--active {
|
||||
.material-label {
|
||||
color: $color-blue;
|
||||
}
|
||||
}
|
||||
// Errors:
|
||||
&.material--has-errors {
|
||||
&.material--active .material-label {
|
||||
color: $color-red;
|
||||
}
|
||||
.material-input-bar {
|
||||
&:before,
|
||||
&:after {
|
||||
background: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,11 +1,12 @@
|
||||
<template>
|
||||
<div class='simplemde-container' :style="{height:height+'px',zIndex:zIndex}">
|
||||
<textarea :id='id'>
|
||||
<div class="simplemde-container" :style="{height:height+'px',zIndex:zIndex}">
|
||||
<textarea :id="id">
|
||||
</textarea>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import 'font-awesome/css/font-awesome.min.css'
|
||||
import 'simplemde/dist/simplemde.min.css'
|
||||
import SimpleMDE from 'simplemde'
|
||||
|
||||
@@ -14,8 +15,7 @@ export default {
|
||||
props: {
|
||||
value: String,
|
||||
id: {
|
||||
type: String,
|
||||
default: 'markdown-editor'
|
||||
type: String
|
||||
},
|
||||
autofocus: {
|
||||
type: Boolean,
|
||||
@@ -51,7 +51,8 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
this.simplemde = new SimpleMDE({
|
||||
element: document.getElementById(this.id),
|
||||
element: document.getElementById(this.id || 'markdown-editor-' + +new Date()),
|
||||
autoDownloadFontAwesome: false,
|
||||
autofocus: this.autofocus,
|
||||
toolbar: this.toolbar,
|
||||
spellChecker: false,
|
||||
@@ -79,7 +80,6 @@ export default {
|
||||
|
||||
<style>
|
||||
.simplemde-container .CodeMirror {
|
||||
/*height: 150px;*/
|
||||
min-height: 150px;
|
||||
}
|
||||
|
||||
@@ -109,6 +109,11 @@ export default {
|
||||
font-weight: bold;
|
||||
color: #E61E1E;
|
||||
}
|
||||
|
||||
.simplemde-container .editor-toolbar.fullscreen,
|
||||
.simplemde-container .CodeMirror-fullscreen {
|
||||
z-index: 1003;
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
|
@@ -1,16 +1,24 @@
|
||||
<template>
|
||||
<svg @click='click' class="icon screenfull" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
t="1497503607356" viewBox="0 0 1024 1024" version="1.1" p-id="4109" :fill='fill' :width="width" :height="height">
|
||||
<path d="M604.157933 512l204.484208 204.484208 82.942037-82.942037c10.364045-10.952446 26.498514-13.83817 40.309054-8.067746 13.249769 5.742794 22.465664 18.99154 22.465664 33.977859l0 258.042008c0 20.168342-16.695241 36.863582-36.863582 36.863582L659.452283 954.357873c-14.986319 0-28.236088-9.215896-33.977859-23.025413-5.770424-13.249769-2.885723-29.384237 8.067746-39.748283l82.942037-82.942037L512 604.157933 307.515792 808.642141l82.942037 82.942037c10.952446 10.364045 13.83817 26.498514 8.067746 39.748283-5.742794 13.809517-18.99154 23.025413-33.977859 23.025413L106.504686 954.357873c-20.168342 0-36.863582-16.695241-36.863582-36.863582L69.641103 659.452283c0-14.986319 9.215896-28.236088 23.025413-33.977859 13.249769-5.770424 29.384237-2.8847 39.748283 8.067746l82.942037 82.942037 204.484208-204.484208L215.357859 307.515792l-82.942037 82.942037c-6.890944 6.918573-16.10684 10.952446-25.911136 10.952446-4.593622 0-9.804297-1.14815-13.83817-2.8847-13.809517-5.742794-23.025413-18.99154-23.025413-33.977859L69.641103 106.504686c0-20.168342 16.695241-36.863582 36.863582-36.863582L364.546693 69.641103c14.986319 0 28.236088 9.215896 33.977859 23.025413 5.770424 13.249769 2.8847 29.384237-8.067746 39.748283l-82.942037 82.942037 204.484208 204.484208L716.484208 215.357859l-82.942037-82.942037c-10.952446-10.364045-13.83817-26.498514-8.067746-39.748283 5.742794-13.809517 18.99154-23.025413 33.977859-23.025413l258.042008 0c20.168342 0 36.863582 16.695241 36.863582 36.863582l0 258.042008c0 14.986319-9.215896 28.236088-22.465664 33.977859-4.593622 1.736551-9.804297 2.8847-14.397918 2.8847-9.804297 0-19.020192-4.033873-25.911136-10.952446l-82.942037-82.942037L604.157933 512z"
|
||||
p-id="4110" />
|
||||
</svg>
|
||||
<div>
|
||||
<svg t="1508738709248" @click='click' class="screenfull-svg" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"
|
||||
p-id="2069" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32">
|
||||
<path d="M333.493443 428.647617 428.322206 333.832158 262.572184 168.045297 366.707916 64.444754 64.09683 64.444754 63.853283 366.570793 167.283957 262.460644Z"
|
||||
p-id="2070"></path>
|
||||
<path d="M854.845439 760.133334 688.61037 593.95864 593.805144 688.764889 759.554142 854.56096 655.44604 958.161503 958.055079 958.161503 958.274066 656.035464Z"
|
||||
p-id="2071"></path>
|
||||
<path d="M688.535669 428.550403 854.31025 262.801405 957.935352 366.921787 957.935352 64.34754 655.809313 64.081481 759.919463 167.535691 593.70793 333.731874Z"
|
||||
p-id="2072"></path>
|
||||
<path d="M333.590658 594.033341 167.8171 759.804852 64.218604 655.67219 64.218604 958.270996 366.342596 958.502263 262.234493 855.071589 428.421466 688.86108Z"
|
||||
p-id="2073"></path>
|
||||
</svg>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import screenfull from 'screenfull'
|
||||
|
||||
export default {
|
||||
name: 'hamburger',
|
||||
name: 'screenfull',
|
||||
props: {
|
||||
width: {
|
||||
type: Number,
|
||||
@@ -46,9 +54,12 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.screenfull {
|
||||
.screenfull-svg {
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
vertical-align: -0.15em;
|
||||
fill: #5a5e66;;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
vertical-align: 10px;
|
||||
}
|
||||
</style>
|
||||
|
56
src/components/ScrollBar/index.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<div class="scroll-container" ref="scrollContainer" @mousewheel="handleScroll">
|
||||
<div class="scroll-wrapper" ref="scrollWrapper" :style="{top: top + 'px'}">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const delta = 15
|
||||
export default {
|
||||
name: 'scrollBar',
|
||||
data() {
|
||||
return {
|
||||
top: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleScroll(e) {
|
||||
e.preventDefault()
|
||||
const $container = this.$refs.scrollContainer
|
||||
const $containerHeight = $container.offsetHeight
|
||||
const $wrapper = this.$refs.scrollWrapper
|
||||
const $wrapperHeight = $wrapper.offsetHeight
|
||||
if (e.wheelDelta > 0) {
|
||||
this.top = Math.min(0, this.top + e.wheelDelta)
|
||||
} else {
|
||||
if ($containerHeight - delta < $wrapperHeight) {
|
||||
if (this.top < -($wrapperHeight - $containerHeight + delta)) {
|
||||
this.top = this.top
|
||||
} else {
|
||||
this.top = Math.max(this.top + e.wheelDelta, $containerHeight - $wrapperHeight - delta)
|
||||
}
|
||||
} else {
|
||||
this.top = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
@import '../../styles/variables.scss';
|
||||
|
||||
.scroll-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background-color: $menuBg;
|
||||
.scroll-wrapper {
|
||||
position: absolute;
|
||||
width: 100%!important;
|
||||
}
|
||||
}
|
||||
</style>
|
71
src/components/ScrollPane/index.vue
Normal file
@@ -0,0 +1,71 @@
|
||||
<template>
|
||||
<div class="scroll-container" ref="scrollContainer" @mousewheel="handleScroll">
|
||||
<div class="scroll-wrapper" ref="scrollWrapper" :style="{left: left + 'px'}">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const padding = 15 // tag's padding
|
||||
|
||||
export default {
|
||||
name: 'scrollPane',
|
||||
data() {
|
||||
return {
|
||||
left: 0
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleScroll(e) {
|
||||
e.preventDefault()
|
||||
const $container = this.$refs.scrollContainer
|
||||
const $containerWidth = $container.offsetWidth
|
||||
const $wrapper = this.$refs.scrollWrapper
|
||||
const $wrapperWidth = $wrapper.offsetWidth
|
||||
|
||||
if (e.wheelDelta > 0) {
|
||||
this.left = Math.min(0, this.left + e.wheelDelta)
|
||||
} else {
|
||||
if ($containerWidth - padding < $wrapperWidth) {
|
||||
if (this.left < -($wrapperWidth - $containerWidth + padding)) {
|
||||
this.left = this.left
|
||||
} else {
|
||||
this.left = Math.max(this.left + e.wheelDelta, $containerWidth - $wrapperWidth - padding)
|
||||
}
|
||||
} else {
|
||||
this.left = 0
|
||||
}
|
||||
}
|
||||
},
|
||||
moveToTarget($target) {
|
||||
const $container = this.$refs.scrollContainer
|
||||
const $containerWidth = $container.offsetWidth
|
||||
const $targetLeft = $target.offsetLeft
|
||||
const $targetWidth = $target.offsetWidth
|
||||
|
||||
if ($targetLeft < -this.left) {
|
||||
// tag in the left
|
||||
this.left = -$targetLeft + padding
|
||||
} else if ($targetLeft + padding > -this.left && $targetLeft + $targetWidth < -this.left + $containerWidth - padding) {
|
||||
// tag in the current view
|
||||
// eslint-disable-line
|
||||
} else {
|
||||
// tag in the right
|
||||
this.left = -($targetLeft - ($containerWidth - $targetWidth) + padding)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" scoped>
|
||||
.scroll-container {
|
||||
white-space: nowrap;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
.scroll-wrapper {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
</style>
|
97
src/components/Share/dropdownMenu.vue
Normal file
@@ -0,0 +1,97 @@
|
||||
<template>
|
||||
<div class="share-dropdown-menu" :class="{active:isActive}">
|
||||
<div class="share-dropdown-menu-wrapper">
|
||||
<span class="share-dropdown-menu-title" @click.self="clickTitle">{{title}}</span>
|
||||
<div class="share-dropdown-menu-item" v-for="(item,index) of items" :key='index'>
|
||||
<a v-if="item.href" :href="item.href" target="_blank">{{item.title}}</a>
|
||||
<span v-else>{{item.title}}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
items: {
|
||||
type: Array
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: 'vue'
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isActive: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
clickTitle() {
|
||||
this.isActive = !this.isActive
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style rel="stylesheet/scss" lang="scss" >
|
||||
$n: 6; //和items.length 相同
|
||||
$t: .1s;
|
||||
.share-dropdown-menu {
|
||||
width: 250px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
&-title {
|
||||
width: 100%;
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
background: black;
|
||||
color: white;
|
||||
height: 60px;
|
||||
line-height: 60px;
|
||||
font-size: 20px;
|
||||
text-align: center;
|
||||
z-index: 2;
|
||||
transform: translate3d(0,0,0);
|
||||
}
|
||||
&-wrapper {
|
||||
position: relative;
|
||||
}
|
||||
&-item {
|
||||
text-align: center;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
background: #e0e0e0;
|
||||
line-height: 60px;
|
||||
height: 60px;
|
||||
cursor: pointer;
|
||||
font-size: 20px;
|
||||
opacity: 1;
|
||||
transition: transform 0.28s ease;
|
||||
&:hover {
|
||||
background: black;
|
||||
color: white;
|
||||
}
|
||||
@for $i from 1 through $n {
|
||||
&:nth-of-type(#{$i}) {
|
||||
z-index: -1;
|
||||
transition-delay: $i*$t;
|
||||
transform: translate3d(0, -60px, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
&.active {
|
||||
.share-dropdown-menu-wrapper {
|
||||
z-index: 1;
|
||||
}
|
||||
.share-dropdown-menu-item {
|
||||
@for $i from 1 through $n {
|
||||
&:nth-of-type(#{$i}) {
|
||||
transition-delay: ($n - $i)*$t;
|
||||
transform: translate3d(0, ($i - 1)*60px, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,44 +0,0 @@
|
||||
<template>
|
||||
<div :class="classes">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Pane',
|
||||
data() {
|
||||
const classes = ['Pane', this.$parent.split, 'className']
|
||||
return {
|
||||
classes: classes.join(' '),
|
||||
percent: 50
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.splitter-pane.vertical.splitter-paneL {
|
||||
position: absolute;
|
||||
left: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.splitter-pane.vertical.splitter-paneR {
|
||||
position: absolute;
|
||||
right: 0px;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.splitter-pane.horizontal.splitter-paneL {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.splitter-pane.horizontal.splitter-paneR {
|
||||
position: absolute;
|
||||
bottom: 0px;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@@ -1,72 +0,0 @@
|
||||
<template>
|
||||
<div :class="classes" @mousedown="onMouseDown"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
split: {
|
||||
validator(value) {
|
||||
return ['vertical', 'horizontal'].indexOf(value) >= 0
|
||||
},
|
||||
required: true
|
||||
},
|
||||
onMouseDown: {
|
||||
type: Function,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
const classes = ['Resizer', this.split, 'className']
|
||||
return {
|
||||
classes: classes.join(' ')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.Resizer {
|
||||
-moz-box-sizing: border-box;
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
background: #000;
|
||||
position: absolute;
|
||||
opacity: .2;
|
||||
z-index: 1;
|
||||
/*-moz-background-clip: padding;*/
|
||||
/*-webkit-background-clip: padding;*/
|
||||
/*background-clip: padding-box;*/
|
||||
}
|
||||
/*.Resizer:hover {*/
|
||||
/*-webkit-transition: all 2s ease;*/
|
||||
/*transition: all 2s ease;*/
|
||||
/*}*/
|
||||
|
||||
.Resizer.horizontal {
|
||||
height: 11px;
|
||||
margin: -5px 0;
|
||||
border-top: 5px solid rgba(255, 255, 255, 0);
|
||||
border-bottom: 5px solid rgba(255, 255, 255, 0);
|
||||
cursor: row-resize;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.Resizer.horizontal:hover {
|
||||
border-top: 5px solid rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 5px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
|
||||
.Resizer.vertical {
|
||||
width: 11px;
|
||||
height: 100%;
|
||||
border-left: 5px solid rgba(255, 255, 255, 0);
|
||||
border-right: 5px solid rgba(255, 255, 255, 0);
|
||||
cursor: col-resize;
|
||||
}
|
||||
|
||||
.Resizer.vertical:hover {
|
||||
border-left: 5px solid rgba(0, 0, 0, 0.5);
|
||||
border-right: 5px solid rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
</style>
|
@@ -1,111 +0,0 @@
|
||||
<template>
|
||||
<div ref :style="{ cursor, userSelect}" class="vue-splitter-container clearfix" @mouseup="onMouseUp" @mousemove="onMouseMove">
|
||||
<pane class="splitter-pane splitter-paneL" :split="split" :style="{ [type]: percent+'%'}">
|
||||
<slot name="paneL"></slot>
|
||||
</pane>
|
||||
<resizer :style="{ [resizeType]: percent+'%'}" :split="split" :onMouseDown="onMouseDown" @click="onClick"></resizer>
|
||||
<pane class="splitter-pane splitter-paneR" :split="split" :style="{ [type]: 100-percent+'%'}">
|
||||
<slot name="paneR"></slot>
|
||||
</pane>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Resizer from './Resizer'
|
||||
import Pane from './Pane'
|
||||
export default {
|
||||
name: 'splitPane',
|
||||
components: { Resizer, Pane },
|
||||
props: {
|
||||
margin: {
|
||||
type: Number,
|
||||
default: 10
|
||||
},
|
||||
split: {
|
||||
validator(value) {
|
||||
return ['vertical', 'horizontal'].indexOf(value) >= 0
|
||||
},
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
active: false,
|
||||
hasMoved: false,
|
||||
height: null,
|
||||
percent: 50,
|
||||
type: this.split === 'vertical' ? 'width' : 'height',
|
||||
resizeType: this.split === 'vertical' ? 'left' : 'top'
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
userSelect() {
|
||||
return this.active ? 'none' : ''
|
||||
},
|
||||
cursor() {
|
||||
return this.active ? 'col-resize' : ''
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
if (!this.hasMoved) {
|
||||
this.percent = 50
|
||||
this.$emit('resize')
|
||||
}
|
||||
},
|
||||
onMouseDown() {
|
||||
this.active = true
|
||||
this.hasMoved = false
|
||||
},
|
||||
onMouseUp() {
|
||||
this.active = false
|
||||
},
|
||||
onMouseMove(e) {
|
||||
if (e.buttons === 0 || e.which === 0) {
|
||||
this.active = false
|
||||
}
|
||||
if (this.active) {
|
||||
let offset = 0
|
||||
let target = e.currentTarget
|
||||
if (this.split === 'vertical') {
|
||||
while (target) {
|
||||
offset += target.offsetLeft
|
||||
target = target.offsetParent
|
||||
}
|
||||
} else {
|
||||
while (target) {
|
||||
offset += target.offsetTop
|
||||
target = target.offsetParent
|
||||
}
|
||||
}
|
||||
|
||||
const currentPage = this.split === 'vertical' ? e.pageX : e.pageY
|
||||
const targetOffset = this.split === 'vertical' ? e.currentTarget.offsetWidth : e.currentTarget.offsetHeight
|
||||
const percent = Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100
|
||||
if (percent > this.margin && percent < 100 - this.margin) {
|
||||
this.percent = percent
|
||||
}
|
||||
this.$emit('resize')
|
||||
this.hasMoved = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.clearfix:after {
|
||||
visibility: hidden;
|
||||
display: block;
|
||||
font-size: 0;
|
||||
content: " ";
|
||||
clear: both;
|
||||
height: 0;
|
||||
}
|
||||
|
||||
.vue-splitter-container {
|
||||
height: 100%;
|
||||
/*display: flex;*/
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
@@ -33,9 +33,18 @@ export default {
|
||||
height: undefined,
|
||||
child: null,
|
||||
stickyHeight: 0
|
||||
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.height = this.$el.getBoundingClientRect().height
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
},
|
||||
activated() {
|
||||
this.handleScroll()
|
||||
},
|
||||
destroyed() {
|
||||
window.removeEventListener('scroll', this.handleScroll)
|
||||
},
|
||||
methods: {
|
||||
sticky() {
|
||||
if (this.active) {
|
||||
@@ -62,13 +71,6 @@ export default {
|
||||
}
|
||||
this.reset()
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.height = this.$el.getBoundingClientRect().height
|
||||
window.addEventListener('scroll', this.handleScroll)
|
||||
},
|
||||
destroyed() {
|
||||
window.removeEventListener('scroll', this.handleScroll)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
42
src/components/SvgIcon/index.vue
Normal file
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<svg :class="svgClass" aria-hidden="true">
|
||||
<use :xlink:href="iconName"></use>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'svg-icon',
|
||||
props: {
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
className: {
|
||||
type: String
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
iconName() {
|
||||
return `#icon-${this.iconClass}`
|
||||
},
|
||||
svgClass() {
|
||||
if (this.className) {
|
||||
return 'svg-icon ' + this.className
|
||||
} else {
|
||||
return 'svg-icon'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
113
src/components/TextHoverEffect/Mallki.vue
Normal file
@@ -0,0 +1,113 @@
|
||||
<template>
|
||||
<a class="link--mallki" :class="className" href="#">
|
||||
{{text}}
|
||||
<span :data-letters="text"></span>
|
||||
<span :data-letters="text"></span>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
className: {
|
||||
type: String
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
default: 'vue-element-admin'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<style>
|
||||
/* Mallki */
|
||||
.link--mallki {
|
||||
font-weight: 800;
|
||||
color: #4dd9d5;
|
||||
font-family: 'Dosis', sans-serif;
|
||||
-webkit-transition: color 0.5s 0.25s;
|
||||
transition: color 0.5s 0.25s;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
line-height: 1;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.link--mallki:hover {
|
||||
-webkit-transition: none;
|
||||
transition: none;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
.link--mallki::before {
|
||||
content: '';
|
||||
width: 100%;
|
||||
height: 6px;
|
||||
margin: -3px 0 0 0;
|
||||
background: #3888fa;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
-webkit-transform: translate3d(-100%, 0, 0);
|
||||
transform: translate3d(-100%, 0, 0);
|
||||
-webkit-transition: -webkit-transform 0.4s;
|
||||
transition: transform 0.4s;
|
||||
-webkit-transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
|
||||
transition-timing-function: cubic-bezier(0.7, 0, 0.3, 1);
|
||||
}
|
||||
|
||||
.link--mallki:hover::before {
|
||||
-webkit-transform: translate3d(100%, 0, 0);
|
||||
transform: translate3d(100%, 0, 0);
|
||||
}
|
||||
|
||||
.link--mallki span {
|
||||
position: absolute;
|
||||
height: 50%;
|
||||
width: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.link--mallki span::before {
|
||||
content: attr(data-letters);
|
||||
color: red;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
color: #3888fa;
|
||||
-webkit-transition: -webkit-transform 0.5s;
|
||||
transition: transform 0.5s;
|
||||
}
|
||||
|
||||
.link--mallki span:nth-child(2) {
|
||||
top: 50%;
|
||||
}
|
||||
|
||||
.link--mallki span:first-child::before {
|
||||
top: 0;
|
||||
-webkit-transform: translate3d(0, 100%, 0);
|
||||
transform: translate3d(0, 100%, 0);
|
||||
}
|
||||
|
||||
.link--mallki span:nth-child(2)::before {
|
||||
bottom: 0;
|
||||
-webkit-transform: translate3d(0, -100%, 0);
|
||||
transform: translate3d(0, -100%, 0);
|
||||
}
|
||||
|
||||
.link--mallki:hover span::before {
|
||||
-webkit-transition-delay: 0.3s;
|
||||
transition-delay: 0.3s;
|
||||
-webkit-transform: translate3d(0, 0, 0);
|
||||
transform: translate3d(0, 0, 0);
|
||||
-webkit-transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
|
||||
transition-timing-function: cubic-bezier(0.2, 1, 0.3, 1);
|
||||
}
|
||||
|
||||
</style>
|
145
src/components/ThemePicker/index.vue
Normal file
@@ -0,0 +1,145 @@
|
||||
<template>
|
||||
<el-color-picker
|
||||
class="theme-picker"
|
||||
popper-class="theme-picker-dropdown"
|
||||
v-model="theme"></el-color-picker>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getVersion } from '@/utils/index.js'
|
||||
|
||||
const version = getVersion('element-ui') // element-ui version from package.json
|
||||
const ORIGINAL_THEME = '#409EFF' // default color
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
chalk: '', // content of theme-chalk css
|
||||
theme: ORIGINAL_THEME
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
theme(val, oldVal) {
|
||||
if (typeof val !== 'string') return
|
||||
const themeCluster = this.getThemeCluster(val.replace('#', ''))
|
||||
const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
|
||||
console.log(themeCluster, originalCluster)
|
||||
const getHandler = (variable, id) => {
|
||||
return () => {
|
||||
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
|
||||
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
|
||||
|
||||
let styleTag = document.getElementById(id)
|
||||
if (!styleTag) {
|
||||
styleTag = document.createElement('style')
|
||||
styleTag.setAttribute('id', id)
|
||||
document.head.appendChild(styleTag)
|
||||
}
|
||||
styleTag.innerText = newStyle
|
||||
}
|
||||
}
|
||||
|
||||
const chalkHandler = getHandler('chalk', 'chalk-style')
|
||||
|
||||
if (!this.chalk) {
|
||||
const url = `https://unpkg.com/element-ui@${version}/lib/theme-chalk/index.css`
|
||||
this.getCSSString(url, chalkHandler, 'chalk')
|
||||
} else {
|
||||
chalkHandler()
|
||||
}
|
||||
|
||||
const styles = [].slice.call(document.querySelectorAll('style'))
|
||||
.filter(style => {
|
||||
const text = style.innerText
|
||||
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
|
||||
})
|
||||
styles.forEach(style => {
|
||||
const { innerText } = style
|
||||
if (typeof innerText !== 'string') return
|
||||
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
|
||||
})
|
||||
this.$message({
|
||||
message: '换肤成功',
|
||||
type: 'success'
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
updateStyle(style, oldCluster, newCluster) {
|
||||
let newStyle = style
|
||||
oldCluster.forEach((color, index) => {
|
||||
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
|
||||
})
|
||||
return newStyle
|
||||
},
|
||||
|
||||
getCSSString(url, callback, variable) {
|
||||
const xhr = new XMLHttpRequest()
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === 4 && xhr.status === 200) {
|
||||
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
|
||||
callback()
|
||||
}
|
||||
}
|
||||
xhr.open('GET', url)
|
||||
xhr.send()
|
||||
},
|
||||
|
||||
getThemeCluster(theme) {
|
||||
const tintColor = (color, tint) => {
|
||||
let red = parseInt(color.slice(0, 2), 16)
|
||||
let green = parseInt(color.slice(2, 4), 16)
|
||||
let blue = parseInt(color.slice(4, 6), 16)
|
||||
|
||||
if (tint === 0) { // when primary color is in its rgb space
|
||||
return [red, green, blue].join(',')
|
||||
} else {
|
||||
red += Math.round(tint * (255 - red))
|
||||
green += Math.round(tint * (255 - green))
|
||||
blue += Math.round(tint * (255 - blue))
|
||||
|
||||
red = red.toString(16)
|
||||
green = green.toString(16)
|
||||
blue = blue.toString(16)
|
||||
|
||||
return `#${red}${green}${blue}`
|
||||
}
|
||||
}
|
||||
|
||||
const shadeColor = (color, shade) => {
|
||||
let red = parseInt(color.slice(0, 2), 16)
|
||||
let green = parseInt(color.slice(2, 4), 16)
|
||||
let blue = parseInt(color.slice(4, 6), 16)
|
||||
|
||||
red = Math.round((1 - shade) * red)
|
||||
green = Math.round((1 - shade) * green)
|
||||
blue = Math.round((1 - shade) * blue)
|
||||
|
||||
red = red.toString(16)
|
||||
green = green.toString(16)
|
||||
blue = blue.toString(16)
|
||||
|
||||
return `#${red}${green}${blue}`
|
||||
}
|
||||
|
||||
const clusters = [theme]
|
||||
for (let i = 0; i <= 9; i++) {
|
||||
clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
|
||||
}
|
||||
clusters.push(shadeColor(theme, 0.1))
|
||||
return clusters
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.theme-picker .el-color-picker__trigger {
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.theme-picker-dropdown .el-color-dropdown__link-btn {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
@@ -1,25 +1,18 @@
|
||||
<template>
|
||||
<div class="upload-container">
|
||||
<el-button icon='upload' :style="{background:color,borderColor:color}" @click=" dialogVisible=true" type="primary">上传图片
|
||||
</el-button>
|
||||
<el-dialog v-model="dialogVisible">
|
||||
<el-upload
|
||||
class="editor-slide-upload"
|
||||
action="https://httpbin.org/post"
|
||||
:multiple="true"
|
||||
:file-list="fileList"
|
||||
:show-file-list="true"
|
||||
list-type="picture-card"
|
||||
:on-remove="handleRemove"
|
||||
:on-success="handleSuccess"
|
||||
:before-upload="beforeUpload">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
</el-upload>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||
</el-dialog>
|
||||
</div>
|
||||
<div class="upload-container">
|
||||
<el-button icon='upload' :style="{background:color,borderColor:color}" @click=" dialogVisible=true" type="primary">上传图片
|
||||
</el-button>
|
||||
<el-dialog :visible.sync="dialogVisible">
|
||||
<el-upload class="editor-slide-upload" action="https://httpbin.org/post" :multiple="true" :file-list="fileList" :show-file-list="true"
|
||||
list-type="picture-card" :on-remove="handleRemove" :on-success="handleSuccess" :before-upload="beforeUpload">
|
||||
<el-button size="small" type="primary">点击上传</el-button>
|
||||
</el-upload>
|
||||
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确 定</el-button>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import { getToken } from 'api/qiniu'
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class='tinymce-container editor-container'>
|
||||
<textarea class='tinymce-textarea' :id="tinymceId"></textarea>
|
||||
<div class="tinymce-container editor-container">
|
||||
<textarea class="tinymce-textarea" :id="tinymceId"></textarea>
|
||||
<div class="editor-custom-btn-container">
|
||||
<editorImage color="#20a0ff" class="editor-upload-btn" @successCBK="imageSuccessCBK"></editorImage>
|
||||
</div>
|
||||
@@ -52,104 +52,91 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
const _this = this
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
height: this.height,
|
||||
body_class: 'panel-body ',
|
||||
object_resizing: false,
|
||||
toolbar: this.toolbar,
|
||||
menubar: this.menubar,
|
||||
plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools',
|
||||
end_container_on_empty_block: true,
|
||||
powerpaste_word_import: 'clean',
|
||||
code_dialog_height: 450,
|
||||
code_dialog_width: 1000,
|
||||
advlist_bullet_styles: 'square',
|
||||
advlist_number_styles: 'default',
|
||||
block_formats: '普通标签=p;小标题=h2;',
|
||||
imagetools_cors_hosts: ['wpimg.wallstcn.com', 'wallstreetcn.com'],
|
||||
imagetools_toolbar: 'watermark',
|
||||
default_link_target: '_blank',
|
||||
link_title: false,
|
||||
init_instance_callback: editor => {
|
||||
if (_this.value) {
|
||||
editor.setContent(_this.value)
|
||||
}
|
||||
_this.hasInit = true
|
||||
editor.on('NodeChange Change KeyUp', () => {
|
||||
this.hasChange = true
|
||||
this.$emit('input', editor.getContent({ format: 'raw' }))
|
||||
})
|
||||
},
|
||||
// 整合七牛上传
|
||||
// images_dataimg_filter(img) {
|
||||
// setTimeout(() => {
|
||||
// const $image = $(img);
|
||||
// $image.removeAttr('width');
|
||||
// $image.removeAttr('height');
|
||||
// if ($image[0].height && $image[0].width) {
|
||||
// $image.attr('data-wscntype', 'image');
|
||||
// $image.attr('data-wscnh', $image[0].height);
|
||||
// $image.attr('data-wscnw', $image[0].width);
|
||||
// $image.addClass('wscnph');
|
||||
// }
|
||||
// }, 0);
|
||||
// return img
|
||||
// },
|
||||
// images_upload_handler(blobInfo, success, failure, progress) {
|
||||
// progress(0);
|
||||
// const token = _this.$store.getters.token;
|
||||
// getToken(token).then(response => {
|
||||
// const url = response.data.qiniu_url;
|
||||
// const formData = new FormData();
|
||||
// formData.append('token', response.data.qiniu_token);
|
||||
// formData.append('key', response.data.qiniu_key);
|
||||
// formData.append('file', blobInfo.blob(), url);
|
||||
// upload(formData).then(() => {
|
||||
// success(url);
|
||||
// progress(100);
|
||||
// })
|
||||
// }).catch(err => {
|
||||
// failure('出现未知问题,刷新页面,或者联系程序员')
|
||||
// console.log(err);
|
||||
// });
|
||||
// },
|
||||
setup(editor) {
|
||||
editor.addButton('h2', {
|
||||
title: '小标题', // tooltip text seen on mouseover
|
||||
text: '小标题',
|
||||
onclick() {
|
||||
editor.execCommand('mceToggleFormat', false, 'h2')
|
||||
},
|
||||
onPostRender() {
|
||||
const btn = this
|
||||
editor.on('init', () => {
|
||||
editor.formatter.formatChanged('h2', state => {
|
||||
btn.active(state)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
editor.addButton('p', {
|
||||
title: '正文',
|
||||
text: '正文',
|
||||
onclick() {
|
||||
editor.execCommand('mceToggleFormat', false, 'p')
|
||||
},
|
||||
onPostRender() {
|
||||
const btn = this
|
||||
editor.on('init', () => {
|
||||
editor.formatter.formatChanged('p', state => {
|
||||
btn.active(state)
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
this.initTinymce()
|
||||
},
|
||||
activated() {
|
||||
this.initTinymce()
|
||||
},
|
||||
deactivated() {
|
||||
this.destroyTinymce()
|
||||
},
|
||||
methods: {
|
||||
initTinymce() {
|
||||
const _this = this
|
||||
window.tinymce.init({
|
||||
selector: `#${this.tinymceId}`,
|
||||
height: this.height,
|
||||
body_class: 'panel-body ',
|
||||
object_resizing: false,
|
||||
toolbar: this.toolbar,
|
||||
menubar: this.menubar,
|
||||
plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools',
|
||||
end_container_on_empty_block: true,
|
||||
powerpaste_word_import: 'clean',
|
||||
code_dialog_height: 450,
|
||||
code_dialog_width: 1000,
|
||||
advlist_bullet_styles: 'square',
|
||||
advlist_number_styles: 'default',
|
||||
imagetools_cors_hosts: ['wpimg.wallstcn.com', 'wallstreetcn.com'],
|
||||
imagetools_toolbar: 'watermark',
|
||||
default_link_target: '_blank',
|
||||
link_title: false,
|
||||
init_instance_callback: editor => {
|
||||
if (_this.value) {
|
||||
editor.setContent(_this.value)
|
||||
}
|
||||
_this.hasInit = true
|
||||
editor.on('NodeChange Change KeyUp', () => {
|
||||
this.hasChange = true
|
||||
this.$emit('input', editor.getContent({ format: 'raw' }))
|
||||
})
|
||||
}
|
||||
// 整合七牛上传
|
||||
// images_dataimg_filter(img) {
|
||||
// setTimeout(() => {
|
||||
// const $image = $(img);
|
||||
// $image.removeAttr('width');
|
||||
// $image.removeAttr('height');
|
||||
// if ($image[0].height && $image[0].width) {
|
||||
// $image.attr('data-wscntype', 'image');
|
||||
// $image.attr('data-wscnh', $image[0].height);
|
||||
// $image.attr('data-wscnw', $image[0].width);
|
||||
// $image.addClass('wscnph');
|
||||
// }
|
||||
// }, 0);
|
||||
// return img
|
||||
// },
|
||||
// images_upload_handler(blobInfo, success, failure, progress) {
|
||||
// progress(0);
|
||||
// const token = _this.$store.getters.token;
|
||||
// getToken(token).then(response => {
|
||||
// const url = response.data.qiniu_url;
|
||||
// const formData = new FormData();
|
||||
// formData.append('token', response.data.qiniu_token);
|
||||
// formData.append('key', response.data.qiniu_key);
|
||||
// formData.append('file', blobInfo.blob(), url);
|
||||
// upload(formData).then(() => {
|
||||
// success(url);
|
||||
// progress(100);
|
||||
// })
|
||||
// }).catch(err => {
|
||||
// failure('出现未知问题,刷新页面,或者联系程序员')
|
||||
// console.log(err);
|
||||
// });
|
||||
// },
|
||||
})
|
||||
},
|
||||
destroyTinymce() {
|
||||
if (window.tinymce.get(this.tinymceId)) {
|
||||
window.tinymce.get(this.tinymceId).destroy()
|
||||
}
|
||||
},
|
||||
setContent(value) {
|
||||
window.tinymce.get(this.tinymceId).setContent(value)
|
||||
},
|
||||
getContent() {
|
||||
window.tinymce.get(this.tinymceId).getContent()
|
||||
},
|
||||
imageSuccessCBK(arr) {
|
||||
const _this = this
|
||||
arr.forEach(v => {
|
||||
@@ -158,7 +145,7 @@ export default {
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
window.tinymce.get(this.tinymceId).destroy()
|
||||
this.destroyTinymce()
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
49
src/directive/clipboard/clipboard.js
Normal file
@@ -0,0 +1,49 @@
|
||||
// Inspired by https://github.com/Inndy/vue-clipboard2
|
||||
const Clipboard = require('clipboard')
|
||||
if (!Clipboard) {
|
||||
throw new Error('you shold npm install `clipboard` --save at first ')
|
||||
}
|
||||
|
||||
export default {
|
||||
bind(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
el._v_clipboard_success = binding.value
|
||||
} else if (binding.arg === 'error') {
|
||||
el._v_clipboard_error = binding.value
|
||||
} else {
|
||||
const clipboard = new Clipboard(el, {
|
||||
text() { return binding.value },
|
||||
action() { return binding.arg === 'cut' ? 'cut' : 'copy' }
|
||||
})
|
||||
clipboard.on('success', e => {
|
||||
const callback = el._v_clipboard_success
|
||||
callback && callback(e) // eslint-disable-line
|
||||
})
|
||||
clipboard.on('error', e => {
|
||||
const callback = el._v_clipboard_error
|
||||
callback && callback(e) // eslint-disable-line
|
||||
})
|
||||
el._v_clipboard = clipboard
|
||||
}
|
||||
},
|
||||
update(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
el._v_clipboard_success = binding.value
|
||||
} else if (binding.arg === 'error') {
|
||||
el._v_clipboard_error = binding.value
|
||||
} else {
|
||||
el._v_clipboard.text = function() { return binding.value }
|
||||
el._v_clipboard.action = function() { return binding.arg === 'cut' ? 'cut' : 'copy' }
|
||||
}
|
||||
},
|
||||
unbind(el, binding) {
|
||||
if (binding.arg === 'success') {
|
||||
delete el._v_clipboard_success
|
||||
} else if (binding.arg === 'error') {
|
||||
delete el._v_clipboard_error
|
||||
} else {
|
||||
el._v_clipboard.destroy()
|
||||
delete el._v_clipboard
|
||||
}
|
||||
}
|
||||
}
|
13
src/directive/clipboard/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import Clipboard from './clipboard'
|
||||
|
||||
const install = function(Vue) {
|
||||
Vue.directive('Clipboard', Clipboard)
|
||||
}
|
||||
|
||||
if (window.Vue) {
|
||||
window.clipboard = Clipboard
|
||||
Vue.use(install); // eslint-disable-line
|
||||
}
|
||||
|
||||
Clipboard.install = install
|
||||
export default Clipboard
|
@@ -10,12 +10,12 @@ vueSticky.install = Vue => {
|
||||
|
||||
elStyle.position = '-webkit-sticky'
|
||||
elStyle.position = 'sticky'
|
||||
// if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
|
||||
// if (~elStyle.position.indexOf('sticky')) {
|
||||
// elStyle.top = `${stickyTop}px`;
|
||||
// elStyle.zIndex = zIndex;
|
||||
// return
|
||||
// }
|
||||
// if the browser support css sticky(Currently Safari, Firefox and Chrome Canary)
|
||||
// if (~elStyle.position.indexOf('sticky')) {
|
||||
// elStyle.top = `${stickyTop}px`;
|
||||
// elStyle.zIndex = zIndex;
|
||||
// return
|
||||
// }
|
||||
const elHeight = el.getBoundingClientRect().height
|
||||
const elWidth = el.getBoundingClientRect().width
|
||||
elStyle.cssText = `top: ${stickyTop}px; z-index: ${zIndex}`
|
||||
|
13
src/directive/waves/index.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import waves from './waves'
|
||||
|
||||
const install = function(Vue) {
|
||||
Vue.directive('waves', waves)
|
||||
}
|
||||
|
||||
if (window.Vue) {
|
||||
window.waves = waves
|
||||
Vue.use(install); // eslint-disable-line
|
||||
}
|
||||
|
||||
waves.install = install
|
||||
export default waves
|
@@ -4,6 +4,7 @@ function pluralize(time, label) {
|
||||
}
|
||||
return time + label + 's'
|
||||
}
|
||||
|
||||
export function timeAgo(time) {
|
||||
const between = Date.now() / 1000 - Number(time)
|
||||
if (between < 3600) {
|
||||
@@ -77,12 +78,12 @@ export function formatTime(time, option) {
|
||||
/* 数字 格式化*/
|
||||
export function nFormatter(num, digits) {
|
||||
const si = [
|
||||
{ value: 1E18, symbol: 'E' },
|
||||
{ value: 1E15, symbol: 'P' },
|
||||
{ value: 1E12, symbol: 'T' },
|
||||
{ value: 1E9, symbol: 'G' },
|
||||
{ value: 1E6, symbol: 'M' },
|
||||
{ value: 1E3, symbol: 'k' }
|
||||
{ value: 1E18, symbol: 'E' },
|
||||
{ value: 1E15, symbol: 'P' },
|
||||
{ value: 1E12, symbol: 'T' },
|
||||
{ value: 1E9, symbol: 'G' },
|
||||
{ value: 1E6, symbol: 'M' },
|
||||
{ value: 1E3, symbol: 'k' }
|
||||
]
|
||||
for (let i = 0; i < si.length; i++) {
|
||||
if (num >= si[i].value) {
|
||||
|
@@ -1,12 +1,12 @@
|
||||
import Vue from 'vue'
|
||||
import IconSvg from '@/components/Icon-svg'// svg组件
|
||||
import generateIconsView from '@/views/svg-icons/generateIconsView.js'// just for views/icons , you can delete it
|
||||
// register globally
|
||||
import SvgIcon from '@/components/SvgIcon'// svg组件
|
||||
import generateIconsView from '@/views/svg-icons/generateIconsView.js'// just for @/views/icons , you can delete it
|
||||
|
||||
Vue.component('icon-svg', IconSvg)
|
||||
// register globally
|
||||
Vue.component('svg-icon', SvgIcon)
|
||||
|
||||
const requireAll = requireContext => requireContext.keys().map(requireContext)
|
||||
const req = require.context('./svg', false, /\.svg$/)
|
||||
const iconMap = requireAll(req)
|
||||
|
||||
generateIconsView.generate(iconMap) // just for views/icons , you can delete it
|
||||
generateIconsView.generate(iconMap) // just for @/views/icons , you can delete it
|
||||
|
Before Width: | Height: | Size: 552 B After Width: | Height: | Size: 552 B |
1
src/icons/svg/clipboard.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506419860538" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4662" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M438.857143 950.857143l512 0 0-365.714286-237.714286 0q-22.820571 0-38.838857-16.018286t-16.018286-38.838857l0-237.714286-219.428571 0 0 658.285714zM585.142857 128l0-36.571429q0-7.460571-5.412571-12.873143t-12.873143-5.412571l-402.285714 0q-7.460571 0-12.873143 5.412571t-5.412571 12.873143l0 36.571429q0 7.460571 5.412571 12.873143t12.873143 5.412571l402.285714 0q7.460571 0 12.873143-5.412571t5.412571-12.873143zM731.428571 512l170.861714 0-170.861714-170.861714 0 170.861714zM1024 585.142857l0 384q0 22.820571-16.018286 38.838857t-38.838857 16.018286l-548.571429 0q-22.820571 0-38.838857-16.018286t-16.018286-38.838857l0-91.428571-310.857143 0q-22.820571 0-38.838857-16.018286t-16.018286-38.838857l0-768q0-22.820571 16.018286-38.838857t38.838857-16.018286l621.714286 0q22.820571 0 38.838857 16.018286t16.018286 38.838857l0 187.465143q11.995429 7.460571 20.553143 16.018286l233.179429 233.179429q16.018286 16.018286 27.428571 43.446857t11.410286 50.322286z" p-id="4663"></path></svg>
|
After Width: | Height: | Size: 1.3 KiB |
1
src/icons/svg/component.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506329916765" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1661" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M64 64 448 64 448 448 64 448 64 64ZM64 576 448 576 448 960 64 960 64 576ZM576 576 960 576 960 960 576 960 576 576ZM768 448C874.038669 448 960 362.038672 960 256 960 149.961328 874.038669 64 768 64 661.961328 64 576 149.961328 576 256 576 362.038672 661.961328 448 768 448Z" p-id="1662"></path></svg>
|
After Width: | Height: | Size: 683 B |
1
src/icons/svg/dashboard.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509611822979" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10379" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M219.428571 658.285714q0-30.285714-21.428571-51.714285T146.285714 585.142857t-51.714285 21.428572T73.142857 658.285714t21.428572 51.714286T146.285714 731.428571t51.714286-21.428571T219.428571 658.285714z m109.714286-256q0-30.285714-21.428571-51.714285T256 329.142857t-51.714286 21.428572T182.857143 402.285714t21.428571 51.714286T256 475.428571t51.714286-21.428571T329.142857 402.285714z m244.571429 274.857143l57.714285-218.285714q3.428571-14.857143-4.285714-27.714286T605.142857 414.285714t-27.428571 3.714286-17.142857 22.571429l-57.714286 218.285714q-34.285714 2.857143-61.142857 24.857143t-36 56.285714q-11.428571 44 11.428571 83.428571t66.857143 50.857143 83.428571-11.428571 50.857143-66.857143q9.142857-34.285714-3.428571-66.857143t-41.142857-52z m377.142857-18.857143q0-30.285714-21.428572-51.714285T877.714286 585.142857t-51.714286 21.428572-21.428571 51.714285 21.428571 51.714286 51.714286 21.428571 51.714285-21.428571 21.428572-51.714286z m-365.714286-365.714285q0-30.285714-21.428571-51.714286T512 219.428571t-51.714286 21.428572T438.857143 292.571429t21.428571 51.714285T512 365.714286t51.714286-21.428572T585.142857 292.571429z m256 109.714285q0-30.285714-21.428571-51.714285T768 329.142857t-51.714286 21.428572T694.857143 402.285714t21.428571 51.714286T768 475.428571t51.714286-21.428571T841.142857 402.285714z m182.857143 256q0 149.142857-80.571429 276-10.857143 16.571429-30.857142 16.571429H111.428571q-20 0-30.857142-16.571429Q0 808 0 658.285714q0-104 40.571429-198.857143t109.142857-163.428571 163.428571-109.142857 198.857143-40.571429 198.857143 40.571429 163.428571 109.142857 109.142857 163.428571 40.571429 198.857143z" p-id="10380"></path></svg>
|
After Width: | Height: | Size: 2.0 KiB |
1
src/icons/svg/documentation.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510826638494" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1669" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M743.253333 144.184889H374.499556v734.378667H743.253333a92.017778 92.017778 0 0 0 92.16-91.818667V235.975111a91.989333 91.989333 0 0 0-92.16-91.790222z m-0.398222 293.888c0.398222 20.48-1.507556 26.794667-9.756444 26.794667-3.612444 0.597333-9.415111-1.621333-17.863111-8.874667-12.657778-8.931556-21.504-16.753778-29.155556-21.617778-6.798222-5.888-17.550222-5.205333-24.291556 0-8.874667 4.949333-21.532444 15.872-28.814222 21.617778-8.988444 7.907556-15.018667 8.874667-17.180444 8.874667-8.618667 0-10.837333-7.424-10.496-26.794667l-0.312889-223.601778c0-21.162667 8.561778-24.376889 17.265778-24.376889h103.708444c10.552889 0 17.294222 4.835556 17.294222 24.376889l-0.398222 223.601778zM190.122667 235.975111V786.773333a92.046222 92.046222 0 0 0 92.188444 91.818667h46.08V144.184889h-46.08a92.017778 92.017778 0 0 0-92.188444 91.790222z" fill="" p-id="1670"></path></svg>
|
After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 983 B After Width: | Height: | Size: 983 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 866 B After Width: | Height: | Size: 866 B |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
1
src/icons/svg/form.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506330387278" class="icon" style="" viewBox="0 0 1069 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1447" xmlns:xlink="http://www.w3.org/1999/xlink" width="66.8125" height="64"><defs><style type="text/css"></style></defs><path d="M746.027944 190.083832q-11.241517 0-18.906188-7.664671t-12.774451-17.884232-7.664671-20.9501-2.55489-17.884232l0-125.700599 2.043912 0q9.197605 0 17.373253 2.043912t19.928144 9.708583 28.61477 21.461078 42.411178 36.279441q27.592814 24.526946 43.944112 41.389222t25.037924 28.61477 10.730539 19.928144 2.043912 14.307385l0 16.351297-150.227545 0zM1063.856287 671.42515q3.065868 8.175649 4.087824 20.439122t-10.219561 23.50499q-5.10978 5.10978-9.197605 9.708583t-7.153693 7.664671q-4.087824 4.087824-7.153693 6.131737l-86.866267-85.844311q6.131737-5.10978 13.796407-12.263473t12.774451-11.241517q12.263473-11.241517 26.570858-9.708583t23.50499 6.642715q10.219561 5.10978 21.972056 17.884232t17.884232 27.081836zM703.105788 766.467066q22.483034 0 37.812375-12.263473l-198.259481 206.43513-282.05988 0q-19.417166 0-42.411178-11.241517t-42.922156-29.636727-33.213573-42.411178-13.285429-49.56487l0-695.952096q0-21.461078 9.708583-44.966068t26.570858-42.411178 38.323353-31.680639 44.966068-12.774451l391.409182 0 0 127.744511q0 19.417166 6.131737 41.9002t18.906188 41.389222 33.213573 31.680639 49.053892 12.774451l149.205589 0 0 338.267465-140.007984 145.117764q11.241517-16.351297 11.241517-35.768463 0-26.570858-18.906188-45.477046t-45.477046-18.906188l-383.233533 0q-26.570858 0-44.966068 18.906188t-18.39521 45.477046 18.39521 44.966068 44.966068 18.39521l383.233533 0zM319.872255 383.233533q-26.570858 0-44.966068 18.906188t-18.39521 45.477046 18.39521 44.966068 44.966068 18.39521l383.233533 0q26.570858 0 45.477046-18.39521t18.906188-44.966068-18.906188-45.477046-45.477046-18.906188l-383.233533 0zM705.149701 895.233533l13.285429-13.285429 25.548902-25.548902q15.329341-15.329341 33.724551-34.235529t36.790419-37.301397q43.944112-43.944112 99.129741-98.107784l85.844311 85.844311-99.129741 99.129741-36.790419 36.790419-33.724551 33.724551q-14.307385 14.307385-24.015968 24.526946t-10.730539 11.241517q-5.10978 4.087824-11.241517 8.686627t-12.263473 7.664671-18.906188 7.664671-26.05988 8.686627-25.548902 7.153693-18.39521 4.087824q-12.263473 2.043912-16.351297-3.065868t-2.043912-17.373253q1.021956-6.131737 4.087824-18.39521t7.153693-25.037924 7.664671-24.015968 5.620758-15.329341q6.131737-13.285429 16.351297-23.50499z" p-id="1448"></path></svg>
|
After Width: | Height: | Size: 2.6 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503993937334" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8099" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M960 256v64H64v-64c0-35.2 28.8-64 64-64h768c35.2 0 64 28.8 64 64z m0 128v384c0 35.2-28.8 64-64 64H128c-35.2 0-64-28.8-64-64V384h896zM256 640H128v32h128v-32z m128-64H128v32h256v-32z" p-id="8100"></path></svg>
|
Before Width: | Height: | Size: 591 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
1
src/icons/svg/international.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509677746926" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1419" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M666.298182 824.087273c-12.567273-30.72-54.225455-83.316364-123.578182-156.392728-18.618182-19.549091-17.454545-34.443636-10.705455-78.894545v-5.12c4.421818-30.487273 12.101818-48.407273 114.501819-64.698182 52.130909-8.145455 65.629091 12.567273 84.712727 41.425455l6.283636 9.541818a101.003636 101.003636 0 0 0 51.432728 41.658182c9.076364 4.189091 20.247273 9.309091 35.374545 17.92C861.090909 649.774545 861.090909 672.814545 861.090909 723.549091v5.818182a215.272727 215.272727 0 0 1-41.425454 139.636363 472.436364 472.436364 0 0 1-152.203637 88.203637c27.927273-52.363636 6.516364-114.501818 0-132.421818zM512 40.96a468.014545 468.014545 0 0 1 203.869091 46.545455 434.501818 434.501818 0 0 0-102.865455 82.618181c-7.447273 10.24-13.730909 19.781818-19.781818 28.625455-19.549091 29.556364-29.090909 42.821818-46.545454 44.916364a200.843636 200.843636 0 0 1-33.745455 0c-34.210909-2.327273-80.756364-5.12-95.650909 35.374545-9.541818 25.832727-11.170909 95.650909 19.549091 131.956364a32.349091 32.349091 0 0 1 2.56 28.625454 56.087273 56.087273 0 0 1-16.523636 25.832727 151.505455 151.505455 0 0 1-23.272728-23.272727 151.272727 151.272727 0 0 0-66.56-52.829091c-10.007273-2.792727-21.178182-5.12-31.883636-7.447272-30.254545-6.283636-64.232727-13.498182-72.145455-30.487273a119.156364 119.156364 0 0 1-5.818181-46.545455 175.476364 175.476364 0 0 0-11.17091-74.007272 70.981818 70.981818 0 0 0-44.450909-39.563637A469.643636 469.643636 0 0 1 512 40.96zM0 512A512 512 0 1 0 512 0 512 512 0 0 0 0 512z" p-id="1420"></path></svg>
|
After Width: | Height: | Size: 1.9 KiB |
1
src/icons/svg/language.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1509704884729" class="icon" style="" viewBox="0 0 1088 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6279" xmlns:xlink="http://www.w3.org/1999/xlink" width="34" height="32"><defs><style type="text/css"></style></defs><path d="M729.6 294.4c19.2 57.6 44.8 102.4 89.6 147.2 38.4-38.4 64-89.6 83.2-147.2h-172.8zM307.2 614.4h166.4L390.4 390.4z" p-id="6280"></path><path d="M947.2 0h-768C108.8 0 51.2 57.6 51.2 128v768c0 70.4 57.6 128 128 128h768c70.4 0 128-57.6 128-128V128c0-70.4-51.2-128-128-128zM633.6 825.6c-12.8 12.8-25.6 12.8-38.4 12.8-6.4 0-19.2 0-25.6-6.4s-12.8 0-12.8-6.4-6.4-12.8-12.8-25.6-6.4-19.2-12.8-32l-25.6-70.4H281.6L256 768c-12.8 25.6-19.2 44.8-25.6 57.6-6.4 12.8-19.2 12.8-38.4 12.8-12.8 0-25.6-6.4-38.4-12.8-12.8-12.8-19.2-19.2-19.2-32 0-6.4 0-12.8 6.4-25.6s6.4-19.2 12.8-32l140.8-358.4c6.4-12.8 6.4-25.6 12.8-38.4s12.8-25.6 19.2-32 12.8-19.2 25.6-25.6c12.8-6.4 25.6-6.4 38.4-6.4 12.8 0 25.6 0 38.4 6.4 12.8 6.4 19.2 12.8 25.6 25.6 6.4 6.4 12.8 19.2 19.2 32 6.4 12.8 12.8 25.6 19.2 44.8l140.8 352c12.8 25.6 19.2 44.8 19.2 57.6-6.4 6.4-12.8 19.2-19.2 32zM985.6 576c-70.4-25.6-121.6-57.6-166.4-96-44.8 44.8-102.4 76.8-172.8 96l-19.2-32c70.4-19.2 128-44.8 172.8-89.6-44.8-44.8-83.2-102.4-96-166.4h-64v-25.6h172.8c-12.8-19.2-25.6-44.8-38.4-64l19.2-6.4c12.8 19.2 32 44.8 44.8 70.4h160v32h-64c-19.2 64-51.2 121.6-89.6 160 44.8 38.4 96 70.4 166.4 89.6l-25.6 32z" p-id="6281"></path></svg>
|
After Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
1
src/icons/svg/message.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727568680" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2026" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M0 202.7V631c0 83.3 68.3 150.7 152.6 150.7h228.9l8 190.3 224.9-190.3h257c84.3 0 152.6-67.4 152.6-150.7V202.7C1024 119.4 955.7 52 871.4 52H152.6C68.3 52 0 119.4 0 202.7z m658.6 237.9c0-39.7 32.1-71.4 72.3-71.4 40.2 0 72.3 31.7 72.3 71.4S771 512 730.9 512c-40.2 0-72.3-31.7-72.3-71.4z m-220.9 0c0-39.7 32.1-71.4 72.3-71.4 40.2 0 72.3 31.7 72.3 71.4S550.1 512 510 512c-40.2 0-72.3-31.7-72.3-71.4z m-216.8 0c0-39.7 32.1-71.4 72.3-71.4 40.2 0 72.3 31.7 72.3 71.4S333.3 512 293.1 512c-40.1 0-72.2-31.7-72.2-71.4z" p-id="2027"></path></svg>
|
After Width: | Height: | Size: 917 B |
1
src/icons/svg/money.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727546462" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1764" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M463.3 958.3V772.1H228.8v-77.5h234.5v-80.5H228.8v-83.5H420L191.5 128h113.7L469 420.6c18.2 33.4 32.4 62.4 42.7 86.9 9-19.8 24.6-50.5 46.8-92.1L713.9 128h120.8L605.5 530.6h192.9v83.5H564.9v80.5h233.5v77.5H564.9v186.2H463.3z" p-id="1765"></path></svg>
|
After Width: | Height: | Size: 632 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
1
src/icons/svg/peoples.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727502091" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1640" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M765.184 873.941333c0 33.28-28.501333 60.288-63.829333 60.288L63.829333 934.229333C28.501333 934.229333 0 907.221333 0 873.941333c0-120.576 123.264-233.258667 249.216-277.674667-72.789333-42.496-121.728-118.058667-121.728-204.8L127.488 331.136c0-133.248 114.346667-241.365333 255.146667-241.365333s255.146667 108.117333 255.146667 241.365333l0 60.288c0 86.826667-48.981333 162.304-121.728 204.842667C641.962667 640.725333 765.184 753.365333 765.184 873.941333L765.184 873.941333z" p-id="1641"></path><path d="M848.256 870.570667l126.933333 0c27.008 0 48.810667-20.650667 48.810667-46.08 0-92.245333-94.293333-178.346667-190.549333-212.309333 55.637333-32.512 93.098667-90.282667 93.098667-156.672L926.549333 409.344c0-101.888-87.424-184.576-195.114667-184.576-13.397333 0-26.453333 1.28-39.125333 3.712 15.488 31.146667 24.149333 65.92 24.149333 102.613333l0 60.288c0 86.826667-24.448 152.746667-88.533333 204.842667C746.666667 625.365333 846.421333 751.018667 848.256 870.570667z" p-id="1642"></path></svg>
|
After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 8.0 KiB After Width: | Height: | Size: 8.0 KiB |
1
src/icons/svg/shoppingCard.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1510727582324" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2288" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32"><defs><style type="text/css"></style></defs><path d="M347.136 783.36q19.456 0 36.864 7.168t30.72 19.968 20.48 30.208 7.168 36.864-7.168 36.864-20.48 30.208-30.72 20.48-36.864 7.68q-20.48 0-37.376-7.68t-30.208-20.48-20.48-30.208-7.168-36.864 7.168-36.864 20.48-30.208 30.208-19.968 37.376-7.168zM773.12 785.408q19.456 0 37.376 7.168t30.72 19.968 20.48 30.208 7.68 36.864-7.68 36.864-20.48 30.208-30.72 20.48-37.376 7.68-36.864-7.68-30.208-20.48-20.48-30.208-7.68-36.864 7.68-36.864 20.48-30.208 30.208-19.968 36.864-7.168zM945.152 203.776q28.672 0 44.544 7.68t22.528 18.944 6.144 24.064-3.584 22.016-12.8 37.888-22.016 62.976-24.064 68.096-17.92 53.248q-13.312 40.96-33.792 56.832t-50.176 15.872l-34.816 0-66.56 0-87.04 0-95.232 0-253.952 0 15.36 92.16 516.096 0q49.152 0 49.152 41.984 0 20.48-9.728 35.328t-38.4 14.848l-49.152 0-95.232 0-117.76 0-119.808 0-98.304 0-56.32 0q-20.48 0-34.304-9.216t-23.04-24.064-14.848-32.256-8.704-32.768q-1.024-6.144-5.632-29.696t-11.264-58.88-14.848-78.848-16.384-87.552q-19.456-103.424-44.032-230.4l-76.8 0q-15.36 0-25.6-7.68t-16.896-18.432-9.216-23.04-2.56-22.528q0-20.48 13.824-33.792t37.376-13.312l22.528 0 20.48 0 25.6 0 34.816 0q20.48 0 32.768 6.144t19.456 15.36 10.24 19.456 5.12 17.408q2.048 8.192 4.096 23.04t4.096 30.208q3.072 18.432 6.144 38.912l700.416 0z" p-id="2289"></path></svg>
|
After Width: | Height: | Size: 1.6 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503994075075" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8325" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M896 192v704H256.8c-71.2 0-128.8-57.6-128.8-128.8V256.8C128 185.6 185.6 128 256.8 128H768v512H257.6c-36 0-65.6 29.6-65.6 65.6v60.8c0 36 29.6 65.6 65.6 65.6H832V192h64zM768 704H256v64h512v-64z" p-id="8326"></path></svg>
|
Before Width: | Height: | Size: 602 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
@@ -1 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503994012480" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8212" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M896 320H128V160c0-17.6 14.4-32 32-32h704c17.6 0 32 14.4 32 32v160zM320 896H160c-17.6 0-32-14.4-32-32V384h192v512zM864 896H384V384h512v480c0 17.6-14.4 32-32 32z" p-id="8213"></path></svg>
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506329761546" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1384" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M622.276923 39.384615H401.723077c-13.784615 0-23.630769 11.815385-23.630769 25.6v49.23077c0 13.784615 11.815385 25.6 23.630769 25.6h220.553846c13.784615 0 23.630769-11.815385 23.630769-25.6V64.984615c1.969231-13.784615-9.846154-25.6-23.630769-25.6z m336.738462 0H738.461538c-13.784615 0-25.6 11.815385-25.6 25.6v49.23077c0 13.784615 11.815385 25.6 25.6 25.6h220.553847c13.784615-1.969231 25.6-11.815385 25.6-25.6V64.984615c0-13.784615-11.815385-25.6-25.6-25.6z m0 165.415385H334.769231c-13.784615 0-25.6-11.815385-25.6-25.6V64.984615c0-13.784615-11.815385-25.6-25.6-25.6H64.984615C51.2 39.384615 39.384615 51.2 39.384615 64.984615v896c0 11.815385 11.815385 23.630769 25.6 23.63077h894.03077c13.784615 0 25.6-11.815385 25.6-25.6v-728.615385c0-13.784615-11.815385-25.6-25.6-25.6z" p-id="1385"></path></svg>
|
Before Width: | Height: | Size: 571 B After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 678 B |
Before Width: | Height: | Size: 678 B After Width: | Height: | Size: 678 B |
Before Width: | Height: | Size: 673 B After Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 777 B After Width: | Height: | Size: 777 B |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
1
src/icons/svg/zip.svg
Normal file
@@ -0,0 +1 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1506326020470" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2561" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M619.364365 933.396352c1.372783 0.06385 2.681715 0.191551 4.054497 0.191551h309.291099a65.670086 65.670086 0 0 0 65.606235-65.606235V150.974154a65.670086 65.670086 0 0 0-65.606235-65.606235H623.418862c-1.372783 0-2.71364 0.127701-4.054497 0.191551V-0.031925L15.691224 80.547217v858.404116l603.673141 82.654279v-88.20926z m0-810.101325c1.340857-0.191551 2.681715-0.415027 4.054497-0.415027h309.291099c15.515635 0 28.12608 12.610444 28.12608 28.12608v717.007513a28.158005 28.158005 0 0 1-28.12608 28.12608H623.418862c-1.372783 0-2.71364-0.223476-4.054497-0.415028V123.326952zM248.329977 605.429026l-143.918691-3.671395v-23.401154l86.868402-133.255682v-1.181231l-78.919033 1.308932v-36.043523l134.564614-3.51177v26.082869l-87.506906 133.734559v1.149307l88.911614 1.404707v37.352456z m72.406297 1.85166l-44.759096-1.149306v-201.192456l44.759096-1.149306v203.491068z m171.087015-92.966111c-16.664942 15.356009-41.151551 22.060296-69.341481 21.868745a113.81325 113.81325 0 0 1-16.122213-1.05353v74.353733l-46.099954-1.181231v-202.788714c14.238628-2.809415 34.383414-5.171878 63.179923-5.938083 29.498862-0.766204 50.792954 4.309899 65.191208 15.292159 13.887451 10.439532 23.305378 27.966454 23.305378 48.845518s-7.119314 38.629462-20.080936 50.601403z m-65.925487-79.174435a80.13219 80.13219 0 0 0-19.538207 2.202837v61.392113c4.022572 0.92583 8.970974 1.213157 15.834887 1.213156 25.380514-0.031925 41.215401-12.897771 41.215401-34.479189 0-19.378581-13.63205-30.712019-37.480156-30.296992z m306.322058-296.233702h73.523679v30.328917h-73.523679v-30.328917z m-73.555604 45.397599h73.523679v30.360842h-73.523679v-30.360842z m73.555604 49.675573h73.523679v30.360842h-73.523679v-30.360842z m0 95.903227h73.523679v30.328917h-73.523679v-30.328917z m-73.555604-48.717818h73.523679v30.328917h-73.523679v-30.328917z m72.821325 376.142417a72.7894 72.7894 0 0 0 72.7894-72.821325l-13.440499-121.986095c0-40.225721-19.155105-72.821325-59.380827-72.821325s-59.348901 32.595604-59.348901 72.821325l-13.472424 121.986095a72.7894 72.7894 0 0 0 72.821325 72.821325z m-24.103508-133.862261h48.207015v101.84131h-48.207015v-101.84131z" p-id="2562"></path></svg>
|
After Width: | Height: | Size: 2.5 KiB |
@@ -1 +0,0 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1503994912370" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10530" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><defs><style type="text/css"></style></defs><path d="M568.6 0h454.9v454.9H568.6V0z m0 568.6h454.9v454.9H568.6V568.6zM0 568.6h454.9v454.9H0V568.6zM0 0h454.9v454.9H0V0z" fill="" p-id="10531"></path></svg>
|
Before Width: | Height: | Size: 534 B |
48
src/lang/en.js
Normal file
@@ -0,0 +1,48 @@
|
||||
export default {
|
||||
route: {
|
||||
dashboard: 'Dashboard',
|
||||
introduction: 'Introduction',
|
||||
documentation: 'Documentation',
|
||||
permission: 'Permission',
|
||||
icons: 'Icons',
|
||||
components: 'Components',
|
||||
componentIndex: 'Introduction',
|
||||
tinymce: 'Tinymce',
|
||||
markdown: 'Markdown',
|
||||
jsonEditor: 'JSON Editor',
|
||||
dndList: 'Dnd List',
|
||||
splitPane: 'SplitPane',
|
||||
avatarUpload: 'Avatar Upload',
|
||||
dropzone: 'Dropzone',
|
||||
sticky: 'Sticky',
|
||||
countTo: 'CountTo',
|
||||
componentMixin: 'Mixin',
|
||||
backToTop: 'BackToTop',
|
||||
charts: 'Charts',
|
||||
keyboardChart: 'Keyboard Chart',
|
||||
lineChart: 'Line chart',
|
||||
mixChart: 'Mix Chart',
|
||||
example: 'Example',
|
||||
Table: 'Table',
|
||||
dynamicTable: 'Dynamic Table',
|
||||
dragTable: 'Drag Table',
|
||||
inlineEditTable: 'Inline Edit',
|
||||
complexTable: 'Complex Table',
|
||||
tab: 'Tab',
|
||||
form: 'Form',
|
||||
createForm: 'Create Form',
|
||||
editForm: 'Edit Form',
|
||||
errorPages: 'Error Pages',
|
||||
page401: '401',
|
||||
page404: '404',
|
||||
errorLog: 'Error Log',
|
||||
excel: 'Excel',
|
||||
exportExcel: 'Export Excel',
|
||||
selectExcel: 'Export Selected',
|
||||
uploadExcel: 'Upload Excel',
|
||||
exportZip: 'Zip',
|
||||
theme: 'Theme',
|
||||
clipboardDemo: 'Clipboard',
|
||||
i18n: 'I18n'
|
||||
}
|
||||
}
|
27
src/lang/index.js
Normal file
@@ -0,0 +1,27 @@
|
||||
import Vue from 'vue'
|
||||
import VueI18n from 'vue-i18n'
|
||||
import Cookies from 'js-cookie'
|
||||
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 enLocale from './en'
|
||||
import zhLocale from './zh'
|
||||
|
||||
Vue.use(VueI18n)
|
||||
|
||||
const messages = {
|
||||
en: {
|
||||
...enLocale,
|
||||
...elementEnLocale
|
||||
},
|
||||
zh: {
|
||||
...zhLocale,
|
||||
...elementZhLocale
|
||||
}
|
||||
}
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: Cookies.get('language') || 'zh', // set locale
|
||||
messages // set locale messages
|
||||
})
|
||||
|
||||
export default i18n
|
48
src/lang/zh.js
Normal file
@@ -0,0 +1,48 @@
|
||||
export default {
|
||||
route: {
|
||||
dashboard: '首页',
|
||||
introduction: '简述',
|
||||
documentation: '文档',
|
||||
permission: '权限测试页',
|
||||
icons: '图标',
|
||||
components: '组件',
|
||||
componentIndex: '介绍',
|
||||
tinymce: '富文本编辑器',
|
||||
markdown: 'Markdown',
|
||||
jsonEditor: 'JSON编辑器',
|
||||
dndList: '列表拖拽',
|
||||
splitPane: 'Splitpane',
|
||||
avatarUpload: '头像上传',
|
||||
dropzone: 'Dropzone',
|
||||
sticky: 'Sticky',
|
||||
countTo: 'CountTo',
|
||||
componentMixin: '小组件',
|
||||
backToTop: '返回顶部',
|
||||
charts: '图表',
|
||||
keyboardChart: '键盘图表',
|
||||
lineChart: '折线图',
|
||||
mixChart: '混合图表',
|
||||
example: '综合实例',
|
||||
Table: 'Table',
|
||||
dynamicTable: '动态table',
|
||||
dragTable: '拖拽table',
|
||||
inlineEditTable: 'table内编辑',
|
||||
complexTable: '综合table',
|
||||
tab: 'Tab',
|
||||
form: '表单',
|
||||
createForm: '创建表单',
|
||||
editForm: '编辑表单',
|
||||
errorPages: '错误页面',
|
||||
page401: '401',
|
||||
page404: '404',
|
||||
errorLog: '错误日志',
|
||||
excel: 'excel',
|
||||
exportExcel: 'export excel',
|
||||
selectExcel: 'export selected',
|
||||
uploadExcel: 'upload excel',
|
||||
exportZip: 'zip',
|
||||
theme: '换肤',
|
||||
clipboardDemo: 'clipboard',
|
||||
i18n: '国际化'
|
||||
}
|
||||
}
|
12
src/main.js
@@ -1,6 +1,7 @@
|
||||
import Vue from 'vue'
|
||||
import ElementUI from 'element-ui'
|
||||
import 'element-ui/lib/theme-default/index.css'
|
||||
import Element from 'element-ui'
|
||||
import 'element-ui/lib/theme-chalk/index.css'
|
||||
import i18n from './lang' // 国际化
|
||||
import App from './App'
|
||||
import router from './router'
|
||||
import store from './store'
|
||||
@@ -8,9 +9,11 @@ import * as filters from './filters' // 全局filter
|
||||
import './icons' // icon
|
||||
import './errorLog'// error log
|
||||
import './permission' // 权限
|
||||
import './mock' // 该项目所有请求使用mockjs模拟
|
||||
import './mock' // 该项目所有请求使用mockjs模拟
|
||||
|
||||
Vue.use(ElementUI)
|
||||
Vue.use(Element, {
|
||||
i18n: (key, value) => i18n.t(key, value)
|
||||
})
|
||||
|
||||
// register global utility filters.
|
||||
Object.keys(filters).forEach(key => {
|
||||
@@ -23,6 +26,7 @@ new Vue({
|
||||
el: '#app',
|
||||
router,
|
||||
store,
|
||||
i18n,
|
||||
template: '<App/>',
|
||||
components: { App }
|
||||
})
|
||||
|
@@ -50,7 +50,7 @@ export default {
|
||||
author: { key: 'mockPan' },
|
||||
source_name: '原创作者',
|
||||
category_item: [{ key: 'global', name: '全球' }],
|
||||
comment_disabled: false,
|
||||
comment_disabled: true,
|
||||
content: '<p>我是测试数据我是测试数据</p><p><img class="wscnph" src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943" data-wscntype="image" data-wscnh="300" data-wscnw="400" data-mce-src="https://wpimg.wallstcn.com/4c69009c-0fd4-4153-b112-6cb53d1cf943"></p>"',
|
||||
content_short: '我是测试数据',
|
||||
display_time: +new Date(),
|
||||
@@ -59,6 +59,12 @@ export default {
|
||||
source_uri: 'https://github.com/PanJiaChen/vue-element-admin',
|
||||
status: 'published',
|
||||
tags: [],
|
||||
title: ''
|
||||
title: 'vue-element-admin'
|
||||
}),
|
||||
createArticle: () => ({
|
||||
data: 'success'
|
||||
}),
|
||||
updateArticle: () => ({
|
||||
data: 'success'
|
||||
})
|
||||
}
|
||||
|
@@ -2,10 +2,11 @@ import Mock from 'mockjs'
|
||||
import loginAPI from './login'
|
||||
import articleAPI from './article'
|
||||
import remoteSearchAPI from './remoteSearch'
|
||||
import transactionAPI from './transaction'
|
||||
|
||||
Mock.setup({
|
||||
timeout: '350-600'
|
||||
})
|
||||
// Mock.setup({
|
||||
// timeout: '350-600'
|
||||
// })
|
||||
|
||||
// 登录相关
|
||||
Mock.mock(/\/login\/login/, 'post', loginAPI.loginByUsername)
|
||||
@@ -16,8 +17,13 @@ Mock.mock(/\/user\/info\.*/, 'get', loginAPI.getUserInfo)
|
||||
Mock.mock(/\/article\/list/, 'get', articleAPI.getList)
|
||||
Mock.mock(/\/article\/detail/, 'get', articleAPI.getArticle)
|
||||
Mock.mock(/\/article\/pv/, 'get', articleAPI.getPv)
|
||||
Mock.mock(/\/article\/create/, 'post', articleAPI.createArticle)
|
||||
Mock.mock(/\/article\/update/, 'post', articleAPI.updateArticle)
|
||||
|
||||
// 搜索相关
|
||||
Mock.mock(/\/search\/user/, 'get', remoteSearchAPI.searchUser)
|
||||
|
||||
// 账单相关
|
||||
Mock.mock(/\/transaction\/list/, 'get', transactionAPI.getList)
|
||||
|
||||
export default Mock
|
||||
|