importing UI
|
@ -0,0 +1,39 @@
|
|||
[*]
|
||||
charset=utf-8
|
||||
end_of_line=lf
|
||||
insert_final_newline=false
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{*.ng,*.sht,*.html,*.shtm,*.shtml,*.htm}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{*.jhm,*.xslt,*.xul,*.rng,*.xsl,*.xsd,*.ant,*.tld,*.fxml,*.jrxml,*.xml,*.jnlp,*.wsdl}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{.babelrc,.stylelintrc,jest.config,.eslintrc,.prettierrc,*.json,*.jsb3,*.jsb2,*.bowerrc}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.svg]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.js.map]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.less]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[*.vue]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
||||
[{.analysis_options,*.yml,*.yaml}]
|
||||
indent_style=space
|
||||
indent_size=2
|
||||
|
|
@ -0,0 +1 @@
|
|||
public/* linguist-vendored
|
|
@ -0,0 +1,21 @@
|
|||
.DS_Store
|
||||
node_modules
|
||||
/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Editor directories and files
|
||||
.idea
|
||||
.vscode
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
|
@ -0,0 +1,5 @@
|
|||
{
|
||||
"printWidth": 120,
|
||||
"semi": false,
|
||||
"singleQuote": true
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
language: node_js
|
||||
node_js:
|
||||
- 10.15.0
|
||||
cache: yarn
|
||||
script:
|
||||
- yarn
|
||||
- yarn run lint --no-fix && yarn run build
|
|
@ -0,0 +1,190 @@
|
|||
# Keel UI
|
||||
|
||||
TODO:
|
||||
|
||||
- [x] authentication
|
||||
- [x] set authorization headers
|
||||
- [x] main dashboard with all the resources
|
||||
- [ ] detail view of each resource
|
||||
- [x] set/update policies
|
||||
- [x] minor/major/patch/all
|
||||
- [x] glob
|
||||
- [x] regexp
|
||||
- [x] view approvals
|
||||
- [x] approve/reject
|
||||
- [x] view all tracked images
|
||||
- [x] pause updates
|
||||
- [ ] SSE client
|
||||
|
||||
TODO keel side:
|
||||
|
||||
- [ ] SSE server side
|
||||
- [ ] internal metrics API via https://github.com/rcrowley/go-metrics
|
||||
- [x] set/update policies endpoint: /v1/resources/{identifier}/policy
|
||||
- [x] new annotation/label to pause deployment updates
|
||||
|
||||
Non functional:
|
||||
|
||||
- [ ] view stats on received webhooks
|
||||
- [x] view stats on update history
|
||||
- [ ] view webhooks received over time
|
||||
- [x] view updates done over time
|
||||
- [ ] notification system
|
||||
|
||||
|
||||
English | [简体中文](./README.zh-CN.md)
|
||||
|
||||
<h1 align="center">Ant Design Pro Vue</h1>
|
||||
|
||||
<div align="center">
|
||||
An out-of-box UI solution for enterprise applications as a Vue boilerplate. based on <a href="https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/" target="_blank">Ant Design of Vue</a>
|
||||
</div>
|
||||
|
||||
<div align="center">
|
||||
|
||||
[](#backers) [](#sponsors) [](https://github.com/sendya/ant-design-pro-vue/blob/master/LICENSE)
|
||||
[](https://github.com/sendya/ant-design-pro-vue/releases/latest)
|
||||
[](https://travis-ci.org/sendya/ant-design-pro-vue)
|
||||
|
||||
</div>
|
||||
|
||||
- Preview: https://preview.pro.loacg.com
|
||||
- Home Page: https://pro.loacg.com
|
||||
- Documentation: https://pro.loacg.com/docs/getting-started
|
||||
- ChangeLog: https://pro.loacg.com/docs/changelog
|
||||
- FAQ: https://pro.loacg.com/docs/faq
|
||||
- Branches:
|
||||
- demo/router-view-table: CRUD view in router
|
||||
- feature/demand_load: loaded on demand
|
||||
- feature/lang: i18n support
|
||||
- feature/dynamic-menu: dynamic menu demo
|
||||
- lite: lite template (legacy)
|
||||
|
||||
|
||||
Overview
|
||||
----
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
### Env and dependencies
|
||||
|
||||
- node
|
||||
- yarn
|
||||
- webpack
|
||||
- eslint
|
||||
- @vue/cli ~3
|
||||
- [ant-design-vue](https://github.com/vueComponent/ant-design-vue) - Ant Design Of Vue
|
||||
- [vue-cropper](https://github.com/xyxiao001/vue-cropper) - Picture edit
|
||||
- [@antv/g2](https://antv.alipay.com/zh-cn/index.html) - AntV G2
|
||||
- [Viser-vue](https://viserjs.github.io/docs.html#/viser/guide/installation) - Antv/G2 of Vue
|
||||
|
||||
> Note: [Yarn](https://yarnpkg.com/) package management is recommended, the exact same version loaded with the demo site of this project (yarn.lock) . but you can also use npm
|
||||
|
||||
|
||||
### Project setup
|
||||
|
||||
- Clone repo
|
||||
```bash
|
||||
git clone https://github.com/sendya/ant-design-pro-vue.git
|
||||
cd ant-design-pro-vue
|
||||
```
|
||||
|
||||
- Install dependencies
|
||||
```
|
||||
yarn install
|
||||
```
|
||||
|
||||
- Compiles and hot-reloads for development
|
||||
```
|
||||
yarn run serve
|
||||
```
|
||||
|
||||
- Compiles and minifies for production
|
||||
```
|
||||
yarn run build
|
||||
```
|
||||
|
||||
- Lints and fixes files
|
||||
```
|
||||
yarn run lint
|
||||
```
|
||||
|
||||
|
||||
### Other
|
||||
|
||||
- **IMPORTANT : About Issue feedback !! when opening Issue read [Issue / PR Contributing](https://github.com/sendya/ant-design-pro-vue/issues/90)**
|
||||
|
||||
- [Vue-cli3](https://cli.vuejs.org/guide/) used by the project.
|
||||
- Disable Eslint (not recommended): remove `eslintConfig` field in `package.json` and `vue.config.js` field `lintOnSave: false`
|
||||
|
||||
- Load on Demand: modify `/src/main.js` L7, append `import './core/lazy_use'` code.
|
||||
|
||||
- Customize Theme: `vue.config.js`
|
||||
eg:
|
||||
```ecmascript 6
|
||||
css: {
|
||||
loaderOptions: {
|
||||
less: {
|
||||
modifyVars: {
|
||||
/* Less variables, required modifyVars*/
|
||||
|
||||
'primary-color': '#F5222D',
|
||||
'link-color': '#F5222D',
|
||||
'border-radius-base': '4px',
|
||||
},
|
||||
javascriptEnabled: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- **polyfill**
|
||||
|
||||
- remove polyfill:
|
||||
> [Vue CLI Polyfill](https://cli.vuejs.org/zh/guide/browser-compatibility.html#usebuiltins-usage)
|
||||
|
||||
- remove `import '@babel/polyfill'` field in `src/main.js`
|
||||
- `babel.conflg.js` remove
|
||||
```ecmascript 6
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
'useBuiltIns': 'entry'
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
## Contributors
|
||||
|
||||
This project exists thanks to all the people who contribute.
|
||||
<a href="https://github.com/sendya/ant-design-pro-vue/graphs/contributors"><img src="https://opencollective.com/ant-design-pro-vue/contributors.svg?width=890&button=false" /></a>
|
||||
|
||||
|
||||
## Backers
|
||||
|
||||
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/ant-design-pro-vue#backer)]
|
||||
|
||||
<a href="https://opencollective.com/ant-design-pro-vue#backers" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/backers.svg?width=890"></a>
|
||||
|
||||
|
||||
## Sponsors
|
||||
|
||||
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/ant-design-pro-vue#sponsor)]
|
||||
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/0/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/0/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/1/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/1/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/2/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/2/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/3/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/3/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/4/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/4/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/5/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/5/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/6/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/6/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/7/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/7/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/8/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/8/avatar.svg"></a>
|
||||
<a href="https://opencollective.com/ant-design-pro-vue/sponsor/9/website" target="_blank"><img src="https://opencollective.com/ant-design-pro-vue/sponsor/9/avatar.svg"></a>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app',
|
||||
[
|
||||
'@babel/preset-env',
|
||||
{
|
||||
'useBuiltIns': 'entry'
|
||||
}
|
||||
]
|
||||
]
|
||||
// if your use import on Demand, Use this code
|
||||
// ,
|
||||
// plugins: [
|
||||
// [ 'import', {
|
||||
// 'libraryName': 'ant-design-vue',
|
||||
// 'libraryDirectory': 'es',
|
||||
// 'style': true // `style: true` 会加载 less 文件
|
||||
// } ]
|
||||
// ]
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
为首屏增加 加载动画
|
||||
====
|
||||
|
||||
|
||||
|
||||
## 需求
|
||||
|
||||
> 为了缓解用户第一次访问时,加载 JS 过大所导致用户等待白屏时间过长导致的用户体验不好,进行的一个优化动效。
|
||||
|
||||
|
||||
|
||||
## 实现方案
|
||||
|
||||
1. 将 动画加载 dom 元素放在 #app 内,Vue 生命周期开始时,会自动清掉 #app 下的所有元素。
|
||||
2. 将 动画加载 dom 元素放在 body 下,Vue 生命周期开始时 App.vue (created, mounted) 调用 `@/utils/utll` 下的 removeLoadingAnimate(#id, timeout) 则会移除加载动画
|
||||
|
||||
最后一步:
|
||||
将样式插入到 `public/index.html` 文件的 `<head></head>` 最好写成内联 `<style>动画样式</style>`
|
||||
|
||||
|
||||
|
||||
----
|
||||
|
||||
目前提供有两个样式,均在 `public/loading` 文件夹内。且 pro 已经默认使用了一套 loading 动画方案,可以直接参考 `public/index.html`
|
||||
|
||||
|
||||
## 写在最后
|
||||
|
||||
目前 pro 有页面 overflow 显示出浏览器滚动条时,页面会抖动一下的问题。
|
||||
|
||||
欢迎各位提供能解决的方案和实现 demo。如果在条件允许的情况下,建议请直接使用 pro 进行改造,也欢迎直接 PR 到 pro 的仓库
|
|
@ -0,0 +1,101 @@
|
|||
按需加载 减小打包
|
||||
====
|
||||
|
||||
|
||||
|
||||
## 按需引入组件依赖
|
||||
|
||||
`Ant Design Pro Vue` 默认编码工作并不支持按需引入,不过可以通过以下操作结合 [Ant Design Of Vue](https://vuecomponent.github.io/ant-design-vue/docs/vue/introduce-cn/) 官方文档来进行按需引入。
|
||||
|
||||
- 增加项目按需引入依赖
|
||||
- 修改引入组件方式
|
||||
|
||||
|
||||
|
||||
1. 增加按需引入所需依赖 `babel-plugin-import`
|
||||
并且修改文件 `babel.config.js`
|
||||
```ecmascript 6
|
||||
module.exports = {
|
||||
presets: [
|
||||
'@vue/app'
|
||||
],
|
||||
plugins: [
|
||||
[ "import", {
|
||||
"libraryName": "ant-design-vue",
|
||||
"libraryDirectory": "es",
|
||||
"style": "css"
|
||||
} ]
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
2. 修改引入组件方式 (注意,这只是一个例子,请完整引入你所需要的组件)
|
||||
|
||||
文件 `@/components/use.js`
|
||||
|
||||
```javascript
|
||||
import Vue from 'vue'
|
||||
import {
|
||||
Input,
|
||||
Button,
|
||||
Select,
|
||||
Card,
|
||||
Form,
|
||||
Row,
|
||||
Col,
|
||||
Modal,
|
||||
Table,
|
||||
notification
|
||||
} from 'ant-design-vue'
|
||||
|
||||
Vue.use(Input)
|
||||
Vue.use(Button)
|
||||
Vue.use(Select)
|
||||
Vue.use(Card)
|
||||
Vue.use(Form)
|
||||
Vue.use(Row)
|
||||
Vue.use(Col)
|
||||
Vue.use(Modal)
|
||||
Vue.use(Table)
|
||||
Vue.use(notification)
|
||||
|
||||
Vue.prototype.$notification = notification;
|
||||
```
|
||||
|
||||
|
||||
3. 最后在 `main.js` 中引入 `@/components/use.js` 文件即可,如下
|
||||
|
||||
```javascript
|
||||
|
||||
import Vue from 'vue'
|
||||
import App from './App'
|
||||
|
||||
// 引入 按需组件的统一引入文件
|
||||
import './components/use'
|
||||
|
||||
import './style/index.less'
|
||||
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
new Vue({
|
||||
render: h => h(App),
|
||||
}).$mount('#app')
|
||||
|
||||
```
|
||||
|
||||
**具体完整实现可参考分支 [feature/demand_load](https://github.com/sendya/ant-design-pro-vue/tree/feature/demand_load)**
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
## 其他 减少打包大小
|
||||
|
||||
|
||||
|
||||
1. Ant Design Vue 1.2.x 版本起,采用的 ant-design 官方方案 svg Icon 组件,整个项目打包会变大很多,图标进行按需加载可参考 https://github.com/HeskeyBaozi/reduce-antd-icons-bundle-demo
|
||||
2. moment 按需加载 可参考 https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
|
|
@ -0,0 +1,20 @@
|
|||
多(页签)标签 模式
|
||||
====
|
||||
|
||||
|
||||
## 让框架支持打开的页面增加多标签,可随时切换
|
||||
|
||||
### 关于如何移除该功能 组件
|
||||
1. 移除 `/src/components/layouts/BasicLayout.vue` L3, L12, L19
|
||||
```vue
|
||||
<multi-tab v-if="$store.getters.multiTab"></multi-tab>
|
||||
```
|
||||
2. 移除 `/src/config/defaultSettings.js` L25
|
||||
|
||||
3. 移除 `src/store/modules/app.js` L27, L76-L79, L118-L120
|
||||
|
||||
4. 移除 `src/utils/mixin.js` L21
|
||||
|
||||
5. 删除组件目录 `src/components/MultiTab`
|
||||
|
||||
> 以上 `L x` 均代表行N ,如 L3 = 行3
|
|
@ -0,0 +1,40 @@
|
|||
先增加依赖
|
||||
|
||||
```bash
|
||||
// npm
|
||||
$ npm install --save-dev webpack-bundle-analyzer
|
||||
|
||||
// or yarn
|
||||
$ yarn add webpack-bundle-analyzer -D
|
||||
```
|
||||
|
||||
配置文件 `vue.config.js` 增加 `configureWebpack.plugins` 参数
|
||||
|
||||
```
|
||||
const path = require('path')
|
||||
const webpack = require('webpack')
|
||||
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
|
||||
|
||||
function resolve (dir) {
|
||||
return path.join(__dirname, dir)
|
||||
}
|
||||
|
||||
// vue.config.js
|
||||
module.exports = {
|
||||
configureWebpack: {
|
||||
plugins: [
|
||||
// Ignore all locale files of moment.js
|
||||
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
|
||||
// 依赖大小分析工具
|
||||
new BundleAnalyzerPlugin(),
|
||||
]
|
||||
},
|
||||
|
||||
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
启动 `cli` 的 `build` 命令进行项目编译,编译完成时,会自动运行一个 http://localhost:8888 的地址,完整显示了支持库依赖
|
|
@ -0,0 +1,23 @@
|
|||
module.exports = {
|
||||
moduleFileExtensions: [
|
||||
'js',
|
||||
'jsx',
|
||||
'json',
|
||||
'vue'
|
||||
],
|
||||
transform: {
|
||||
'^.+\\.vue$': 'vue-jest',
|
||||
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 'jest-transform-stub',
|
||||
'^.+\\.jsx?$': 'babel-jest'
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'^@/(.*)$': '<rootDir>/src/$1'
|
||||
},
|
||||
snapshotSerializers: [
|
||||
'jest-serializer-vue'
|
||||
],
|
||||
testMatch: [
|
||||
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
|
||||
],
|
||||
testURL: 'http://localhost/'
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["src/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "dist"],
|
||||
"include": ["src/**/*"]
|
||||
}
|
|
@ -0,0 +1,135 @@
|
|||
{
|
||||
"name": "vue-antd-pro",
|
||||
"version": "2.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"build:preview": "vue-cli-service build --mode preview",
|
||||
"lint": "vue-cli-service lint",
|
||||
"lint:nofix": "vue-cli-service lint --no-fix",
|
||||
"test:unit": "vue-cli-service test:unit",
|
||||
"postinstall": "opencollective-postinstall"
|
||||
},
|
||||
"dependencies": {
|
||||
"@antv/data-set": "^0.10.1",
|
||||
"@websanova/vue-auth": "^2.21.14-beta",
|
||||
"ant-design-vue": "~1.3.8",
|
||||
"axios": "^0.18.0",
|
||||
"core-js": "^2.6.5",
|
||||
"enquire.js": "^2.1.6",
|
||||
"js-cookie": "^2.2.0",
|
||||
"lodash.get": "^4.4.2",
|
||||
"lodash.pick": "^4.4.0",
|
||||
"md5": "^2.2.1",
|
||||
"mockjs2": "^1.0.5",
|
||||
"moment": "^2.24.0",
|
||||
"nprogress": "^0.2.0",
|
||||
"viser-vue": "^2.3.3",
|
||||
"vue": "^2.5.22",
|
||||
"vue-clipboard2": "^0.2.1",
|
||||
"vue-cropper": "0.4.4",
|
||||
"vue-ls": "^3.2.0",
|
||||
"vue-resource": "^1.5.1",
|
||||
"vue-router": "^3.0.1",
|
||||
"vue-svg-component-runtime": "^1.0.1",
|
||||
"vuex": "^3.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"@vue/cli-plugin-babel": "^3.3.0",
|
||||
"@vue/cli-plugin-eslint": "^3.3.0",
|
||||
"@vue/cli-plugin-unit-jest": "^3.3.0",
|
||||
"@vue/cli-service": "^3.3.0",
|
||||
"@vue/eslint-config-standard": "^4.0.0",
|
||||
"@vue/test-utils": "^1.0.0-beta.20",
|
||||
"babel-core": "7.0.0-bridge.0",
|
||||
"babel-eslint": "^10.0.1",
|
||||
"babel-jest": "^23.6.0",
|
||||
"babel-plugin-import": "^1.11.0",
|
||||
"eslint": "^5.8.0",
|
||||
"eslint-plugin-html": "^5.0.0",
|
||||
"eslint-plugin-vue": "^5.0.0",
|
||||
"less": "^3.8.1",
|
||||
"less-loader": "^4.1.0",
|
||||
"opencollective": "^1.0.3",
|
||||
"opencollective-postinstall": "^2.0.2",
|
||||
"vue-svg-icon-loader": "^2.1.1",
|
||||
"vue-template-compiler": "^2.5.22"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
"env": {
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:vue/strongly-recommended",
|
||||
"@vue/standard"
|
||||
],
|
||||
"parserOptions": {
|
||||
"parser": "babel-eslint"
|
||||
},
|
||||
"rules": {
|
||||
"generator-star-spacing": "off",
|
||||
"no-mixed-operators": 0,
|
||||
"vue/max-attributes-per-line": [
|
||||
2,
|
||||
{
|
||||
"singleline": 5,
|
||||
"multiline": {
|
||||
"max": 1,
|
||||
"allowFirstLine": false
|
||||
}
|
||||
}
|
||||
],
|
||||
"vue/attribute-hyphenation": 0,
|
||||
"vue/html-self-closing": 0,
|
||||
"vue/component-name-in-template-casing": 0,
|
||||
"vue/html-closing-bracket-spacing": 0,
|
||||
"vue/singleline-html-element-content-newline": 0,
|
||||
"vue/no-unused-components": 0,
|
||||
"vue/multiline-html-element-content-newline": 0,
|
||||
"vue/no-use-v-if-with-v-for": 0,
|
||||
"vue/html-closing-bracket-newline": 0,
|
||||
"vue/no-parsing-error": 0,
|
||||
"no-console": 0,
|
||||
"no-tabs": 0,
|
||||
"quotes": [
|
||||
2,
|
||||
"single",
|
||||
{
|
||||
"avoidEscape": true,
|
||||
"allowTemplateLiterals": true
|
||||
}
|
||||
],
|
||||
"semi": [
|
||||
2,
|
||||
"never",
|
||||
{
|
||||
"beforeStatementContinuationChars": "never"
|
||||
}
|
||||
],
|
||||
"no-delete-var": 2,
|
||||
"prefer-const": [
|
||||
2,
|
||||
{
|
||||
"ignoreReadBeforeAssign": false
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
"autoprefixer": {}
|
||||
}
|
||||
},
|
||||
"browserslist": [
|
||||
"> 1%",
|
||||
"last 2 versions",
|
||||
"not ie <= 10"
|
||||
],
|
||||
"collective": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/ant-design-pro-vue"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||
<link rel="icon" href="<%= BASE_URL %>logo.png">
|
||||
<title>Keel </title>
|
||||
<style>#loading-mask{position:fixed;left:0;top:0;height:100%;width:100%;background:#fff;user-select:none;z-index:9999;overflow:hidden}.loading-wrapper{position:absolute;top:50%;left:50%;transform:translate(-50%,-100%)}.loading-dot{animation:antRotate 1.2s infinite linear;transform:rotate(45deg);position:relative;display:inline-block;font-size:64px;width:64px;height:64px;box-sizing:border-box}.loading-dot i{width:22px;height:22px;position:absolute;display:block;background-color:#1890ff;border-radius:100%;transform:scale(.75);transform-origin:50% 50%;opacity:.3;animation:antSpinMove 1s infinite linear alternate}.loading-dot i:nth-child(1){top:0;left:0}.loading-dot i:nth-child(2){top:0;right:0;-webkit-animation-delay:.4s;animation-delay:.4s}.loading-dot i:nth-child(3){right:0;bottom:0;-webkit-animation-delay:.8s;animation-delay:.8s}.loading-dot i:nth-child(4){bottom:0;left:0;-webkit-animation-delay:1.2s;animation-delay:1.2s}@keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@-webkit-keyframes antRotate{to{-webkit-transform:rotate(405deg);transform:rotate(405deg)}}@keyframes antSpinMove{to{opacity:1}}@-webkit-keyframes antSpinMove{to{opacity:1}}</style>
|
||||
</head>
|
||||
<body>
|
||||
<noscript>
|
||||
<strong>We're sorry but Keel UI doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||
</noscript>
|
||||
<div id="app">
|
||||
<div id="loading-mask">
|
||||
<div class="loading-wrapper">
|
||||
<span class="loading-dot loading-dot-spin"><i></i><i></i><i></i><i></i></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- built files will be auto injected -->
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1 @@
|
|||
#preloadingAnimation{position:fixed;left:0;top:0;height:100%;width:100%;background:#ffffff;user-select:none;z-index: 9999;overflow: hidden}.lds-roller{display:inline-block;position:relative;left:50%;top:50%;transform:translate(-50%,-50%);width:64px;height:64px;}.lds-roller div{animation:lds-roller 1.2s cubic-bezier(0.5,0,0.5,1) infinite;transform-origin:32px 32px;}.lds-roller div:after{content:" ";display:block;position:absolute;width:6px;height:6px;border-radius:50%;background:#13c2c2;margin:-3px 0 0 -3px;}.lds-roller div:nth-child(1){animation-delay:-0.036s;}.lds-roller div:nth-child(1):after{top:50px;left:50px;}.lds-roller div:nth-child(2){animation-delay:-0.072s;}.lds-roller div:nth-child(2):after{top:54px;left:45px;}.lds-roller div:nth-child(3){animation-delay:-0.108s;}.lds-roller div:nth-child(3):after{top:57px;left:39px;}.lds-roller div:nth-child(4){animation-delay:-0.144s;}.lds-roller div:nth-child(4):after{top:58px;left:32px;}.lds-roller div:nth-child(5){animation-delay:-0.18s;}.lds-roller div:nth-child(5):after{top:57px;left:25px;}.lds-roller div:nth-child(6){animation-delay:-0.216s;}.lds-roller div:nth-child(6):after{top:54px;left:19px;}.lds-roller div:nth-child(7){animation-delay:-0.252s;}.lds-roller div:nth-child(7):after{top:50px;left:14px;}.lds-roller div:nth-child(8){animation-delay:-0.288s;}.lds-roller div:nth-child(8):after{top:45px;left:10px;}#preloadingAnimation .load-tips{color: #13c2c2;font-size:2rem;position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin-top:80px;text-align:center;width:400px;height:64px;} @keyframes lds-roller{0%{transform:rotate(0deg);} 100%{transform:rotate(360deg);}}
|
|
@ -0,0 +1 @@
|
|||
<div id="preloadingAnimation"><div class=lds-roller><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div><div class=load-tips>Loading</div></div>
|
|
@ -0,0 +1,5 @@
|
|||
<div class="preloading-animate">
|
||||
<div class="preloading-wrapper">
|
||||
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1 @@
|
|||
.preloading-animate{background:#ffffff;width:100%;height:100%;position:fixed;left:0;top:0;z-index:299;}.preloading-animate .preloading-wrapper{position:absolute;width:5rem;height:5rem;left:50%;top:50%;transform:translate(-50%,-50%);}.preloading-animate .preloading-wrapper .preloading-balls{font-size:5rem;}
|
|
@ -0,0 +1 @@
|
|||
<svg class="preloading-balls" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><circle cx="67.802" cy="59.907" r="6" fill="#51CACC"><animate attributeName="cx" values="75;57.72542485937369" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="50;73.77641290737884" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#51CACC;#9DF871" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="46.079" cy="69.992" r="6" fill="#9DF871"><animate attributeName="cx" values="57.72542485937369;29.774575140626318" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="73.77641290737884;64.69463130731182" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#9DF871;#E0FF77" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="29.775" cy="52.449" r="6" fill="#E0FF77"><animate attributeName="cx" values="29.774575140626318;29.774575140626315" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="64.69463130731182;35.30536869268818" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#E0FF77;#DE9DD6" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="41.421" cy="31.521" r="6" fill="#DE9DD6"><animate attributeName="cx" values="29.774575140626315;57.72542485937368" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="35.30536869268818;26.22358709262116" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#DE9DD6;#FF708E" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle><circle cx="64.923" cy="36.13" r="6" fill="#FF708E"><animate attributeName="cx" values="57.72542485937368;75" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="cy" values="26.22358709262116;49.99999999999999" keyTimes="0;1" dur="1s" repeatCount="indefinite"/><animate attributeName="fill" values="#FF708E;#51CACC" keyTimes="0;1" dur="1s" repeatCount="indefinite"/></circle></svg>
|
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 37 KiB |
|
@ -0,0 +1,32 @@
|
|||
<template>
|
||||
<a-locale-provider :locale="locale">
|
||||
<div id="app">
|
||||
<router-view/>
|
||||
</div>
|
||||
</a-locale-provider>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// import zhCN from 'ant-design-vue/lib/locale-provider/zh_CN'
|
||||
import enUS from 'ant-design-vue/lib/locale-provider/en_US'
|
||||
import { AppDeviceEnquire } from '@/utils/mixin'
|
||||
|
||||
export default {
|
||||
mixins: [AppDeviceEnquire],
|
||||
data () {
|
||||
return {
|
||||
locale: enUS
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
},
|
||||
|
||||
methods: {
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style>
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,62 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
export default {
|
||||
get (url, request) {
|
||||
return Vue.http.get(url, request)
|
||||
.then((response) => Promise.resolve(response.body))
|
||||
.catch((error) => Promise.reject(error))
|
||||
},
|
||||
post (url, request) {
|
||||
return Vue.http.post(url, request)
|
||||
.then((response) => Promise.resolve(response))
|
||||
.catch((error) => Promise.reject(error))
|
||||
},
|
||||
put (url, request) {
|
||||
return Vue.http.put(url, request)
|
||||
.then((response) => Promise.resolve(response))
|
||||
.catch((error) => Promise.reject(error))
|
||||
},
|
||||
patch (url, request) {
|
||||
return Vue.http.patch(url, request)
|
||||
.then((response) => Promise.resolve(response))
|
||||
.catch((error) => Promise.reject(error))
|
||||
},
|
||||
delete (url, request) {
|
||||
return Vue.http.delete(url, request)
|
||||
.then((response) => Promise.resolve(response))
|
||||
.catch((error) => Promise.reject(error))
|
||||
}
|
||||
}
|
||||
|
||||
// import { axios } from '@/utils/request'
|
||||
|
||||
// export default {
|
||||
// get (url, request) {
|
||||
// return axios({
|
||||
// url: url,
|
||||
// method: 'get',
|
||||
// data: request
|
||||
// })
|
||||
// },
|
||||
// put (url, request) {
|
||||
// return axios({
|
||||
// url: url,
|
||||
// method: 'put',
|
||||
// data: request
|
||||
// })
|
||||
// },
|
||||
// post (url, request) {
|
||||
// return axios({
|
||||
// url: url,
|
||||
// method: 'post',
|
||||
// data: request
|
||||
// })
|
||||
// },
|
||||
// delete (url, request) {
|
||||
// return axios({
|
||||
// url: url,
|
||||
// method: 'delete',
|
||||
// data: request
|
||||
// })
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,61 @@
|
|||
import api from './index'
|
||||
import { axios } from '@/utils/request'
|
||||
|
||||
/**
|
||||
* login func
|
||||
* parameter: {
|
||||
* username: '',
|
||||
* password: '',
|
||||
* remember_me: true,
|
||||
* captcha: '12345'
|
||||
* }
|
||||
* @param parameter
|
||||
* @returns {*}
|
||||
*/
|
||||
export function login (parameter) {
|
||||
return axios({
|
||||
url: '/auth/login',
|
||||
method: 'post',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getSmsCaptcha (parameter) {
|
||||
return axios({
|
||||
url: api.SendSms,
|
||||
method: 'post',
|
||||
data: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getInfo () {
|
||||
return axios({
|
||||
url: '/user/info',
|
||||
method: 'get',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export function logout () {
|
||||
return axios({
|
||||
url: '/auth/logout',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'application/json;charset=UTF-8'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* get user 2step code open?
|
||||
* @param parameter {*}
|
||||
*/
|
||||
export function get2step (parameter) {
|
||||
return axios({
|
||||
url: api.twoStepCode,
|
||||
method: 'post',
|
||||
data: parameter
|
||||
})
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
import { axios } from '@/utils/request'
|
||||
|
||||
const api = {
|
||||
user: '/user',
|
||||
role: '/role',
|
||||
service: '/service',
|
||||
permission: '/permission',
|
||||
permissionNoPager: '/permission/no-pager',
|
||||
orgTree: '/org/tree'
|
||||
}
|
||||
|
||||
export default api
|
||||
|
||||
export function getUserList (parameter) {
|
||||
return axios({
|
||||
url: api.user,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getRoleList (parameter) {
|
||||
return axios({
|
||||
url: api.role,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getServiceList (parameter) {
|
||||
return axios({
|
||||
url: api.service,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getPermissions (parameter) {
|
||||
return axios({
|
||||
url: api.permissionNoPager,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
export function getOrgTree (parameter) {
|
||||
return axios({
|
||||
url: api.orgTree,
|
||||
method: 'get',
|
||||
params: parameter
|
||||
})
|
||||
}
|
||||
|
||||
// id == 0 add post
|
||||
// id != 0 update put
|
||||
export function saveService (parameter) {
|
||||
return axios({
|
||||
url: api.service,
|
||||
method: parameter.id === 0 ? 'post' : 'put',
|
||||
data: parameter
|
||||
})
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="1361px" height="609px" viewBox="0 0 1361 609" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 46.2 (44496) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Group 21</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="Ant-Design-Pro-3.0" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="账户密码登录-校验" transform="translate(-79.000000, -82.000000)">
|
||||
<g id="Group-21" transform="translate(77.000000, 73.000000)">
|
||||
<g id="Group-18" opacity="0.8" transform="translate(74.901416, 569.699158) rotate(-7.000000) translate(-74.901416, -569.699158) translate(4.901416, 525.199158)">
|
||||
<ellipse id="Oval-11" fill="#CFDAE6" opacity="0.25" cx="63.5748792" cy="32.468367" rx="21.7830479" ry="21.766008"></ellipse>
|
||||
<ellipse id="Oval-3" fill="#CFDAE6" opacity="0.599999964" cx="5.98746479" cy="13.8668601" rx="5.2173913" ry="5.21330997"></ellipse>
|
||||
<path d="M38.1354514,88.3520215 C43.8984227,88.3520215 48.570234,83.6838647 48.570234,77.9254015 C48.570234,72.1669383 43.8984227,67.4987816 38.1354514,67.4987816 C32.3724801,67.4987816 27.7006688,72.1669383 27.7006688,77.9254015 C27.7006688,83.6838647 32.3724801,88.3520215 38.1354514,88.3520215 Z" id="Oval-3-Copy" fill="#CFDAE6" opacity="0.45"></path>
|
||||
<path d="M64.2775582,33.1704963 L119.185836,16.5654915" id="Path-12" stroke="#CFDAE6" stroke-width="1.73913043" stroke-linecap="round" stroke-linejoin="round"></path>
|
||||
<path d="M42.1431708,26.5002681 L7.71190162,14.5640702" id="Path-16" stroke="#E0B4B7" stroke-width="0.702678964" opacity="0.7" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<path d="M63.9262187,33.521561 L43.6721326,69.3250951" id="Path-15" stroke="#BACAD9" stroke-width="0.702678964" stroke-linecap="round" stroke-linejoin="round" stroke-dasharray="1.405357899873153,2.108036953469981"></path>
|
||||
<g id="Group-17" transform="translate(126.850922, 13.543654) rotate(30.000000) translate(-126.850922, -13.543654) translate(117.285705, 4.381889)" fill="#CFDAE6">
|
||||
<ellipse id="Oval-4" opacity="0.45" cx="9.13482653" cy="9.12768076" rx="9.13482653" ry="9.12768076"></ellipse>
|
||||
<path d="M18.2696531,18.2553615 C18.2696531,13.2142826 14.1798519,9.12768076 9.13482653,9.12768076 C4.08980114,9.12768076 0,13.2142826 0,18.2553615 L18.2696531,18.2553615 Z" id="Oval-4" transform="translate(9.134827, 13.691521) scale(-1, -1) translate(-9.134827, -13.691521) "></path>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Group-14" transform="translate(216.294700, 123.725600) rotate(-5.000000) translate(-216.294700, -123.725600) translate(106.294700, 35.225600)">
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.25" cx="29.1176471" cy="29.1402439" rx="29.1176471" ry="29.1402439"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#CFDAE6" opacity="0.3" cx="29.1176471" cy="29.1402439" rx="21.5686275" ry="21.5853659"></ellipse>
|
||||
<ellipse id="Oval-2-Copy" stroke="#CFDAE6" opacity="0.4" cx="179.019608" cy="138.146341" rx="23.7254902" ry="23.7439024"></ellipse>
|
||||
<ellipse id="Oval-2" fill="#BACAD9" opacity="0.5" cx="29.1176471" cy="29.1402439" rx="10.7843137" ry="10.7926829"></ellipse>
|
||||
<path d="M29.1176471,39.9329268 L29.1176471,18.347561 C23.1616351,18.347561 18.3333333,23.1796097 18.3333333,29.1402439 C18.3333333,35.1008781 23.1616351,39.9329268 29.1176471,39.9329268 Z" id="Oval-2" fill="#BACAD9"></path>
|
||||
<g id="Group-9" opacity="0.45" transform="translate(172.000000, 131.000000)" fill="#E6A1A6">
|
||||
<ellipse id="Oval-2-Copy-2" cx="7.01960784" cy="7.14634146" rx="6.47058824" ry="6.47560976"></ellipse>
|
||||
<path d="M0.549019608,13.6219512 C4.12262681,13.6219512 7.01960784,10.722722 7.01960784,7.14634146 C7.01960784,3.56996095 4.12262681,0.670731707 0.549019608,0.670731707 L0.549019608,13.6219512 Z" id="Oval-2-Copy-2" transform="translate(3.784314, 7.146341) scale(-1, 1) translate(-3.784314, -7.146341) "></path>
|
||||
</g>
|
||||
<ellipse id="Oval-10" fill="#CFDAE6" cx="218.382353" cy="138.685976" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy-2" fill="#E0B4B7" opacity="0.35" cx="179.558824" cy="175.381098" rx="1.61764706" ry="1.61890244"></ellipse>
|
||||
<ellipse id="Oval-10-Copy" fill="#E0B4B7" opacity="0.35" cx="180.098039" cy="102.530488" rx="2.15686275" ry="2.15853659"></ellipse>
|
||||
<path d="M28.9985381,29.9671598 L171.151018,132.876024" id="Path-11" stroke="#CFDAE6" opacity="0.8"></path>
|
||||
</g>
|
||||
<g id="Group-10" opacity="0.799999952" transform="translate(1054.100635, 36.659317) rotate(-11.000000) translate(-1054.100635, -36.659317) translate(1026.600635, 4.659317)">
|
||||
<ellipse id="Oval-7" stroke="#CFDAE6" stroke-width="0.941176471" cx="43.8135593" cy="32" rx="11.1864407" ry="11.2941176"></ellipse>
|
||||
<g id="Group-12" transform="translate(34.596774, 23.111111)" fill="#BACAD9">
|
||||
<ellipse id="Oval-7" opacity="0.45" cx="9.18534718" cy="8.88888889" rx="8.47457627" ry="8.55614973"></ellipse>
|
||||
<path d="M9.18534718,17.4450386 C13.8657264,17.4450386 17.6599235,13.6143199 17.6599235,8.88888889 C17.6599235,4.16345787 13.8657264,0.332739156 9.18534718,0.332739156 L9.18534718,17.4450386 Z" id="Oval-7"></path>
|
||||
</g>
|
||||
<path d="M34.6597385,24.809694 L5.71666084,4.76878945" id="Path-2" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
<ellipse id="Oval" stroke="#CFDAE6" stroke-width="0.941176471" cx="3.26271186" cy="3.29411765" rx="3.26271186" ry="3.29411765"></ellipse>
|
||||
<ellipse id="Oval-Copy" fill="#F7E1AD" cx="2.79661017" cy="61.1764706" rx="2.79661017" ry="2.82352941"></ellipse>
|
||||
<path d="M34.6312443,39.2922712 L5.06366663,59.785082" id="Path-10" stroke="#CFDAE6" stroke-width="0.941176471"></path>
|
||||
</g>
|
||||
<g id="Group-19" opacity="0.33" transform="translate(1282.537219, 446.502867) rotate(-10.000000) translate(-1282.537219, -446.502867) translate(1142.537219, 327.502867)">
|
||||
<g id="Group-17" transform="translate(141.333539, 104.502742) rotate(275.000000) translate(-141.333539, -104.502742) translate(129.333539, 92.502742)" fill="#BACAD9">
|
||||
<circle id="Oval-4" opacity="0.45" cx="11.6666667" cy="11.6666667" r="11.6666667"></circle>
|
||||
<path d="M23.3333333,23.3333333 C23.3333333,16.8900113 18.1099887,11.6666667 11.6666667,11.6666667 C5.22334459,11.6666667 0,16.8900113 0,23.3333333 L23.3333333,23.3333333 Z" id="Oval-4" transform="translate(11.666667, 17.500000) scale(-1, -1) translate(-11.666667, -17.500000) "></path>
|
||||
</g>
|
||||
<circle id="Oval-5-Copy-6" fill="#CFDAE6" cx="201.833333" cy="87.5" r="5.83333333"></circle>
|
||||
<path d="M143.5,88.8126685 L155.070501,17.6038544" id="Path-17" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M17.5,37.3333333 L127.466252,97.6449735" id="Path-18" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<polyline id="Path-19" stroke="#CFDAE6" stroke-width="1.16666667" points="143.902597 120.302281 174.935455 231.571342 38.5 147.510847 126.366941 110.833333"></polyline>
|
||||
<path d="M159.833333,99.7453842 L195.416667,89.25" id="Path-20" stroke="#E0B4B7" stroke-width="1.16666667" opacity="0.6"></path>
|
||||
<path d="M205.333333,82.1372105 L238.719406,36.1666667" id="Path-24" stroke="#BACAD9" stroke-width="1.16666667"></path>
|
||||
<path d="M266.723424,132.231988 L207.083333,90.4166667" id="Path-25" stroke="#CFDAE6" stroke-width="1.16666667"></path>
|
||||
<circle id="Oval-5" fill="#C1D1E0" cx="156.916667" cy="8.75" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-3" fill="#C1D1E0" cx="39.0833333" cy="148.75" r="5.25"></circle>
|
||||
<circle id="Oval-5-Copy-2" fill-opacity="0.6" fill="#D1DEED" cx="8.75" cy="33.25" r="8.75"></circle>
|
||||
<circle id="Oval-5-Copy-4" fill-opacity="0.6" fill="#D1DEED" cx="243.833333" cy="30.3333333" r="5.83333333"></circle>
|
||||
<circle id="Oval-5-Copy-5" fill="#E0B4B7" cx="175.583333" cy="232.75" r="5.25"></circle>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.7 KiB |
|
@ -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="1551058675966" class="icon" style="" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7872" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M85.333333 512h85.333334a340.736 340.736 0 0 1 99.712-241.621333 337.493333 337.493333 0 0 1 108.458666-72.96 346.453333 346.453333 0 0 1 261.546667-1.749334A106.154667 106.154667 0 0 0 746.666667 298.666667C805.802667 298.666667 853.333333 251.136 853.333333 192S805.802667 85.333333 746.666667 85.333333c-29.397333 0-55.978667 11.776-75.221334 30.933334-103.722667-41.514667-222.848-40.874667-325.76 2.517333a423.594667 423.594667 0 0 0-135.68 91.264 423.253333 423.253333 0 0 0-91.306666 135.637333A426.88 426.88 0 0 0 85.333333 512z m741.248 133.205333c-17.109333 40.618667-41.685333 77.141333-72.96 108.416s-67.797333 55.850667-108.458666 72.96a346.453333 346.453333 0 0 1-261.546667 1.749334A106.154667 106.154667 0 0 0 277.333333 725.333333C218.197333 725.333333 170.666667 772.864 170.666667 832S218.197333 938.666667 277.333333 938.666667c29.397333 0 55.978667-11.776 75.221334-30.933334A425.173333 425.173333 0 0 0 512 938.666667a425.941333 425.941333 0 0 0 393.258667-260.352A426.325333 426.325333 0 0 0 938.666667 512h-85.333334a341.034667 341.034667 0 0 1-26.752 133.205333z" p-id="7873"></path><path d="M512 318.378667c-106.752 0-193.621333 86.869333-193.621333 193.621333S405.248 705.621333 512 705.621333s193.621333-86.869333 193.621333-193.621333S618.752 318.378667 512 318.378667z m0 301.909333c-59.690667 0-108.288-48.597333-108.288-108.288S452.309333 403.712 512 403.712s108.288 48.597333 108.288 108.288-48.597333 108.288-108.288 108.288z" p-id="7874"></path></svg>
|
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 54 KiB |
|
@ -0,0 +1,404 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="378px" height="428px" viewBox="0 0 378 428" enable-background="new 0 0 378 428" xml:space="preserve"> <image id="image0" width="378" height="428" x="0" y="0"
|
||||
xlink:href="data:image/png;base64,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
|
||||
hE97GYqEUEtDIFHmlSMsQMub/wt2mUwWRXH2h46+p2sSCLt9U09QImR95iCvhvgdb7vYY7//qAag
|
||||
3z10VKdoZg10RbsO7PwuT8z8uug8HPHndn6DIG1gMOYlq9dHUjmfk4Ccy03bFCF2wfjwfN/qNSGh
|
||||
0Bib1+kON2yPVv6F7kldKJdc1hhzj50zqfMfti7drKNBED1oeCKM4ERUizc73FsyjeOJ+LE9/3wX
|
||||
xmkH96DTW9oRMImxgRNSqN/S1qyDf3d6W9Rqe+GW3bqnJ2hfj4SkUd9Nzur3tA/6pNE+6JNG+6BP
|
||||
Gu2DPmm0D/qk0T7ok0b7oE8a7YM+abQP+qTRPuiTRvugTxrtgz5ptA/6pNE+6JNG+6BPGv0/ZU+s
|
||||
wShjyJYAAAAldEVYdGRhdGU6Y3JlYXRlADIwMTktMDQtMjdUMTE6NDY6MzArMDE6MDDf0iPvAAAA
|
||||
JXRFWHRkYXRlOm1vZGlmeQAyMDE5LTA0LTI3VDExOjQxOjMwKzAxOjAwTFOAKgAAACh0RVh0aWNj
|
||||
OmNvcHlyaWdodABDb3B5cmlnaHQgQXBwbGUgSW5jLiwgMjAxOC9MBUEAAAAXdEVYdGljYzpkZXNj
|
||||
cmlwdGlvbgBEaXNwbGF5FxuVuAAAABh0RVh0aWNjOm1hbnVmYWN0dXJlcgBEaXNwbGF5mRrp2QAA
|
||||
ABF0RVh0aWNjOm1vZGVsAERpc3BsYXn4nJwgAAAAAElFTkSuQmCC" />
|
||||
</svg>
|
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 20 KiB |
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg viewBox="0 0 128 128" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 52.6 (67491) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>Vue</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs>
|
||||
<linearGradient x1="69.644116%" y1="0%" x2="69.644116%" y2="100%" id="linearGradient-1">
|
||||
<stop stop-color="#29CDFF" offset="0%"></stop>
|
||||
<stop stop-color="#148EFF" offset="37.8600687%"></stop>
|
||||
<stop stop-color="#0A60FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="-19.8191553%" y1="-36.7931464%" x2="138.57919%" y2="157.637507%" id="linearGradient-2">
|
||||
<stop stop-color="#29CDFF" offset="0%"></stop>
|
||||
<stop stop-color="#0F78FF" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
<linearGradient x1="68.1279872%" y1="-35.6905737%" x2="30.4400914%" y2="114.942679%" id="linearGradient-3">
|
||||
<stop stop-color="#FA8E7D" offset="0%"></stop>
|
||||
<stop stop-color="#F74A5C" offset="51.2635191%"></stop>
|
||||
<stop stop-color="#F51D2C" offset="100%"></stop>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="Vue" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
|
||||
<g id="Group" transform="translate(19.000000, 9.000000)">
|
||||
<path d="M89.96,90.48 C78.58,93.48 68.33,83.36 67.62,82.48 L46.6604487,62.2292258 C45.5023849,61.1103236 44.8426845,59.5728835 44.8296987,57.9626396 L44.5035564,17.5209948 C44.4948861,16.4458744 44.0537714,15.4195095 43.2796864,14.6733517 L29.6459999,1.53153737 C28.055475,-0.00160504005 25.5232423,0.0449126588 23.9900999,1.63543756 C23.2715121,2.38092066 22.87,3.37600834 22.87,4.41143746 L22.87,64.3864751 C22.87,67.0807891 23.9572233,69.6611067 25.885409,71.5429748 L63.6004615,108.352061 C65.9466323,110.641873 69.6963584,110.624605 72.0213403,108.313281" id="Path-Copy" fill="url(#linearGradient-1)" fill-rule="nonzero" transform="translate(56.415000, 54.831157) scale(-1, 1) translate(-56.415000, -54.831157) "></path>
|
||||
<path d="M68,90.1163122 C56.62,93.1163122 45.46,83.36 44.75,82.48 L23.7904487,62.2292258 C22.6323849,61.1103236 21.9726845,59.5728835 21.9596987,57.9626396 L21.6335564,17.5209948 C21.6248861,16.4458744 21.1837714,15.4195095 20.4096864,14.6733517 L6.7759999,1.53153737 C5.185475,-0.00160504005 2.65324232,0.0449126588 1.12009991,1.63543756 C0.401512125,2.38092066 3.90211878e-13,3.37600834 3.90798505e-13,4.41143746 L3.94351218e-13,64.3864751 C3.94681177e-13,67.0807891 1.08722326,69.6611067 3.01540903,71.5429748 L40.7807092,108.401101 C43.1069304,110.671444 46.8180151,110.676525 49.1504445,108.412561" id="Path" fill="url(#linearGradient-2)" fill-rule="nonzero"></path>
|
||||
<path d="M43.2983488,19.0991931 L27.5566079,3.88246244 C26.7624281,3.11476967 26.7409561,1.84862177 27.5086488,1.05444194 C27.8854826,0.664606611 28.4044438,0.444472651 28.9466386,0.444472651 L60.3925021,0.444472651 C61.4970716,0.444472651 62.3925021,1.33990315 62.3925021,2.44447265 C62.3925021,2.9858375 62.1730396,3.50407742 61.7842512,3.88079942 L46.0801285,19.0975301 C45.3051579,19.8484488 44.0742167,19.8491847 43.2983488,19.0991931 Z" id="Path" fill="url(#linearGradient-3)"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<div class="antd-pro-components-article-list-content-index-listContent">
|
||||
<div class="description">
|
||||
<slot>
|
||||
{{ description }}
|
||||
</slot>
|
||||
</div>
|
||||
<div class="extra">
|
||||
<a-avatar :src="avatar" size="small" />
|
||||
<a :href="href">{{ owner }}</a> 发布在 <a :href="href">{{ href }}</a>
|
||||
<em>{{ updateAt | moment }}</em>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ArticleListContent',
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'antd-pro-components-article-list-content-index-listContent'
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
owner: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
avatar: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
href: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
updateAt: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import '../index.less';
|
||||
|
||||
.antd-pro-components-article-list-content-index-listContent {
|
||||
.description {
|
||||
max-width: 720px;
|
||||
line-height: 22px;
|
||||
}
|
||||
.extra {
|
||||
margin-top: 16px;
|
||||
color: @text-color-secondary;
|
||||
line-height: 22px;
|
||||
|
||||
& /deep/ .ant-avatar {
|
||||
position: relative;
|
||||
top: 1px;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-right: 8px;
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
& > em {
|
||||
margin-left: 16px;
|
||||
color: @disabled-color;
|
||||
font-style: normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-xs) {
|
||||
.antd-pro-components-article-list-content-index-listContent {
|
||||
.extra {
|
||||
& > em {
|
||||
display: block;
|
||||
margin-top: 8px;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
import ArticleListContent from './ArticleListContent'
|
||||
|
||||
export default ArticleListContent
|
|
@ -0,0 +1,46 @@
|
|||
<template>
|
||||
<tooltip v-if="tips !== ''">
|
||||
<template slot="title">{{ tips }}</template>
|
||||
<avatar :size="avatarSize" :src="src" />
|
||||
</tooltip>
|
||||
<avatar v-else :size="avatarSize" :src="src" />
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Avatar from 'ant-design-vue/es/avatar'
|
||||
import Tooltip from 'ant-design-vue/es/tooltip'
|
||||
|
||||
export default {
|
||||
name: 'AvatarItem',
|
||||
components: {
|
||||
Avatar,
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
tips: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
src: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
size: this.$parent.size
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
avatarSize () {
|
||||
return this.size !== 'mini' && this.size || 20
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$parent.size' (val) {
|
||||
this.size = val
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,99 @@
|
|||
<!--
|
||||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<ul>
|
||||
<slot></slot>
|
||||
<template v-for="item in filterEmpty($slots.default).slice(0, 3)"></template>
|
||||
|
||||
<template v-if="maxLength > 0 && filterEmpty($slots.default).length > maxLength">
|
||||
<avatar-item :size="size">
|
||||
<avatar :size="size !== 'mini' && size || 20" :style="excessItemsStyle">{{ `+${maxLength}` }}</avatar>
|
||||
</avatar-item>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
-->
|
||||
|
||||
<script>
|
||||
import Avatar from 'ant-design-vue/es/avatar'
|
||||
import AvatarItem from './Item'
|
||||
import { filterEmpty } from '@/components/_util/util'
|
||||
|
||||
export default {
|
||||
AvatarItem,
|
||||
name: 'AvatarList',
|
||||
components: {
|
||||
Avatar,
|
||||
AvatarItem
|
||||
},
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-avatar-list'
|
||||
},
|
||||
/**
|
||||
* 头像大小 类型: large、small 、mini, default
|
||||
* 默认值: default
|
||||
*/
|
||||
size: {
|
||||
type: [String, Number],
|
||||
default: 'default'
|
||||
},
|
||||
/**
|
||||
* 要显示的最大项目
|
||||
*/
|
||||
maxLength: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
/**
|
||||
* 多余的项目风格
|
||||
*/
|
||||
excessItemsStyle: {
|
||||
type: Object,
|
||||
default: () => {
|
||||
return {
|
||||
color: '#f56a00',
|
||||
backgroundColor: '#fde3cf'
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
},
|
||||
methods: {
|
||||
getItems (items) {
|
||||
const classString = {
|
||||
[`${this.prefixCls}-item`]: true,
|
||||
[`${this.size}`]: true
|
||||
}
|
||||
|
||||
if (this.maxLength > 0) {
|
||||
items = items.slice(0, this.maxLength)
|
||||
items.push((<Avatar size={ this.size } style={ this.excessItemsStyle }>{`+${this.maxLength}`}</Avatar>))
|
||||
}
|
||||
const itemList = items.map((item) => (
|
||||
<li class={ classString }>{ item }</li>
|
||||
))
|
||||
return itemList
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { prefixCls, size } = this.$props
|
||||
const classString = {
|
||||
[`${prefixCls}`]: true,
|
||||
[`${size}`]: true
|
||||
}
|
||||
const items = filterEmpty(this.$slots.default)
|
||||
const itemsDom = items && items.length ? <ul class={`${prefixCls}-items`}>{ this.getItems(items) }</ul> : null
|
||||
|
||||
return (
|
||||
<div class={ classString }>
|
||||
{ itemsDom }
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,4 @@
|
|||
import AvatarList from './List'
|
||||
import './index.less'
|
||||
|
||||
export default AvatarList
|
|
@ -0,0 +1,60 @@
|
|||
@import "../index";
|
||||
|
||||
@avatar-list-prefix-cls: ~"@{ant-pro-prefix}-avatar-list";
|
||||
@avatar-list-item-prefix-cls: ~"@{ant-pro-prefix}-avatar-list-item";
|
||||
|
||||
.@{avatar-list-prefix-cls} {
|
||||
display: inline-block;
|
||||
|
||||
ul {
|
||||
list-style: none;
|
||||
display: inline-block;
|
||||
padding: 0;
|
||||
margin: 0 0 0 8px;
|
||||
font-size: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.@{avatar-list-item-prefix-cls} {
|
||||
display: inline-block;
|
||||
font-size: @font-size-base;
|
||||
margin-left: -8px;
|
||||
width: @avatar-size-base;
|
||||
height: @avatar-size-base;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
border: 1px solid #fff;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
width: @avatar-size-lg;
|
||||
height: @avatar-size-lg;
|
||||
}
|
||||
|
||||
&.small {
|
||||
width: @avatar-size-sm;
|
||||
height: @avatar-size-sm;
|
||||
}
|
||||
|
||||
&.mini {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
|
||||
:global {
|
||||
.ant-avatar {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
|
||||
.ant-avatar-string {
|
||||
font-size: 12px;
|
||||
line-height: 18px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
# AvatarList 用户头像列表
|
||||
|
||||
|
||||
一组用户头像,常用在项目/团队成员列表。可通过设置 `size` 属性来指定头像大小。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import AvatarList from '@/components/AvatarList'
|
||||
const AvatarListItem = AvatarList.AvatarItem
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AvatarList,
|
||||
AvatarListItem
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<avatar-list size="mini">
|
||||
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
|
||||
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
</avatar-list>
|
||||
```
|
||||
或
|
||||
```html
|
||||
<avatar-list :max-length="3">
|
||||
<avatar-list-item tips="Jake" src="https://gw.alipayobjects.com/zos/rmsportal/zOsKZmFRdUtvpqCImOVY.png" />
|
||||
<avatar-list-item tips="Andy" src="https://gw.alipayobjects.com/zos/rmsportal/sfjbOqnsXXJgNCjCzDBL.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
<avatar-list-item tips="Niko" src="https://gw.alipayobjects.com/zos/rmsportal/kZzEzemZyKLKFsojXItE.png" />
|
||||
</avatar-list>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
### AvatarList
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ---------------- | -------- | ---------------------------------- | --------- |
|
||||
| size | 头像大小 | `large`、`small` 、`mini`, `default` | `default` |
|
||||
| maxLength | 要显示的最大项目 | number | - |
|
||||
| excessItemsStyle | 多余的项目风格 | CSSProperties | - |
|
||||
|
||||
### AvatarList.Item
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
| ---- | ------ | --------- | --- |
|
||||
| tips | 头像展示文案 | string | - |
|
||||
| src | 头像图片连接 | string | - |
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
<v-chart
|
||||
height="254"
|
||||
:data="data"
|
||||
:forceFit="true"
|
||||
:padding="['auto', 'auto', '40', '50']">
|
||||
<v-tooltip />
|
||||
<v-axis />
|
||||
<v-bar position="x*y"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const data = []
|
||||
for (let i = 0; i < 12; i += 1) {
|
||||
data.push({
|
||||
x: `${i + 1}月`,
|
||||
y: Math.floor(Math.random() * 1000) + 200
|
||||
})
|
||||
}
|
||||
const tooltip = [
|
||||
'x*y',
|
||||
(x, y) => ({
|
||||
name: x,
|
||||
value: y
|
||||
})
|
||||
]
|
||||
const scale = [{
|
||||
dataKey: 'x',
|
||||
min: 2
|
||||
}, {
|
||||
dataKey: 'y',
|
||||
title: '时间',
|
||||
min: 1,
|
||||
max: 22
|
||||
}]
|
||||
|
||||
export default {
|
||||
name: 'Bar',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
data,
|
||||
scale,
|
||||
tooltip
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,120 @@
|
|||
<template>
|
||||
<a-card :loading="loading" :body-style="{ padding: '20px 24px 8px' }" :bordered="false">
|
||||
<div class="chart-card-header">
|
||||
<div class="meta">
|
||||
<span class="chart-card-title">
|
||||
<slot name="title">
|
||||
{{ title }}
|
||||
</slot>
|
||||
</span>
|
||||
<span class="chart-card-action">
|
||||
<slot name="action"></slot>
|
||||
</span>
|
||||
</div>
|
||||
<div class="total">
|
||||
<slot name="total">
|
||||
<span>{{ typeof total === 'function' && total() || total }}</span>
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-card-content">
|
||||
<div class="content-fix">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="chart-card-footer">
|
||||
<div class="field">
|
||||
<slot name="footer"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'ChartCard',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
total: {
|
||||
type: [Function, Number, String],
|
||||
required: false,
|
||||
default: null
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chart-card-header {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
.meta {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
color: rgba(0, 0, 0, .45);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-card-action {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.chart-card-footer {
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding-top: 9px;
|
||||
margin-top: 8px;
|
||||
|
||||
> * {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.field {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.chart-card-content {
|
||||
margin-bottom: 12px;
|
||||
position: relative;
|
||||
height: 46px;
|
||||
width: 100%;
|
||||
|
||||
.content-fix {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.total {
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
color: #000;
|
||||
margin-top: 4px;
|
||||
margin-bottom: 0;
|
||||
font-size: 30px;
|
||||
line-height: 38px;
|
||||
height: 38px;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,67 @@
|
|||
<template>
|
||||
<div>
|
||||
<v-chart
|
||||
:forceFit="true"
|
||||
:height="height"
|
||||
:width="width"
|
||||
:data="data"
|
||||
:scale="scale"
|
||||
:padding="0">
|
||||
<v-tooltip />
|
||||
<v-interval
|
||||
:shape="['liquid-fill-gauge']"
|
||||
position="transfer*value"
|
||||
color=""
|
||||
:v-style="{
|
||||
lineWidth: 10,
|
||||
opacity: 0.75
|
||||
}"
|
||||
:tooltip="[
|
||||
'transfer*value',
|
||||
(transfer, value) => {
|
||||
return {
|
||||
name: transfer,
|
||||
value,
|
||||
};
|
||||
},
|
||||
]"
|
||||
></v-interval>
|
||||
<v-guide
|
||||
v-for="(row, index) in data"
|
||||
:key="index"
|
||||
type="text"
|
||||
:top="true"
|
||||
:position="{
|
||||
gender: row.transfer,
|
||||
value: 45
|
||||
}"
|
||||
:content="row.value + '%'"
|
||||
:v-style="{
|
||||
fontSize: 100,
|
||||
textAlign: 'center',
|
||||
opacity: 0.75,
|
||||
}"
|
||||
/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Liquid',
|
||||
props: {
|
||||
height: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,56 @@
|
|||
<template>
|
||||
<div class="antv-chart-mini">
|
||||
<div class="chart-wrapper" :style="{ height: 46 }">
|
||||
<v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 0, 18, 0]">
|
||||
<v-tooltip />
|
||||
<v-smooth-area position="x*y" />
|
||||
</v-chart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import moment from 'moment'
|
||||
const data = []
|
||||
const beginDay = new Date().getTime()
|
||||
|
||||
for (let i = 0; i < 10; i++) {
|
||||
data.push({
|
||||
x: moment(new Date(beginDay + 1000 * 60 * 60 * 24 * i)).format('YYYY-MM-DD'),
|
||||
y: Math.round(Math.random() * 10)
|
||||
})
|
||||
}
|
||||
|
||||
const tooltip = [
|
||||
'x*y',
|
||||
(x, y) => ({
|
||||
name: x,
|
||||
value: y
|
||||
})
|
||||
]
|
||||
const scale = [{
|
||||
dataKey: 'x',
|
||||
min: 2
|
||||
}, {
|
||||
dataKey: 'y',
|
||||
title: '时间',
|
||||
min: 1,
|
||||
max: 22
|
||||
}]
|
||||
|
||||
export default {
|
||||
name: 'MiniArea',
|
||||
data () {
|
||||
return {
|
||||
data,
|
||||
tooltip,
|
||||
scale,
|
||||
height: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import "chart";
|
||||
</style>
|
|
@ -0,0 +1,49 @@
|
|||
<template>
|
||||
<div class="antv-chart-mini">
|
||||
<div class="chart-wrapper" :style="{ height: 46 }">
|
||||
<v-chart :force-fit="true" :height="height" :data="data" :padding="[36, 5, 18, 5]">
|
||||
<v-tooltip />
|
||||
<v-bar position="x*y" />
|
||||
</v-chart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
const tooltip = [
|
||||
'x*y',
|
||||
(x, y) => ({
|
||||
name: x,
|
||||
value: y
|
||||
})
|
||||
]
|
||||
|
||||
const scale = [{
|
||||
dataKey: 'x',
|
||||
min: 2
|
||||
}, {
|
||||
dataKey: 'y',
|
||||
title: 'Date',
|
||||
min: 1,
|
||||
max: 7
|
||||
}]
|
||||
|
||||
export default {
|
||||
name: 'MiniBar',
|
||||
data () {
|
||||
return {
|
||||
tooltip,
|
||||
scale,
|
||||
height: 100
|
||||
}
|
||||
},
|
||||
props: {
|
||||
data: Array
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import "chart";
|
||||
</style>
|
|
@ -0,0 +1,75 @@
|
|||
<template>
|
||||
<div class="chart-mini-progress">
|
||||
<div class="target" :style="{ left: target + '%'}">
|
||||
<span :style="{ backgroundColor: color }" />
|
||||
<span :style="{ backgroundColor: color }"/>
|
||||
</div>
|
||||
<div class="progress-wrapper">
|
||||
<div class="progress" :style="{ backgroundColor: color, width: percentage + '%', height: height }"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MiniProgress',
|
||||
props: {
|
||||
target: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
height: {
|
||||
type: String,
|
||||
default: '10px'
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#13C2C2'
|
||||
},
|
||||
percentage: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chart-mini-progress {
|
||||
padding: 5px 0;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.target {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
|
||||
span {
|
||||
border-radius: 100px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 4px;
|
||||
width: 2px;
|
||||
|
||||
&:last-child {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
.progress-wrapper {
|
||||
background-color: #f5f5f5;
|
||||
position: relative;
|
||||
|
||||
.progress {
|
||||
transition: all .4s cubic-bezier(.08,.82,.17,1) 0s;
|
||||
border-radius: 1px 0 0 1px;
|
||||
background-color: #1890ff;
|
||||
width: 0;
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,40 @@
|
|||
<template>
|
||||
<div :class="prefixCls">
|
||||
<div class="chart-wrapper" :style="{ height: 46 }">
|
||||
<v-chart :force-fit="true" :height="100" :data="dataSource" :scale="scale" :padding="[36, 0, 18, 0]">
|
||||
<v-tooltip />
|
||||
<v-smooth-line position="x*y" :size="2" />
|
||||
<v-smooth-area position="x*y" />
|
||||
</v-chart>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MiniSmoothArea',
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-smooth-area'
|
||||
},
|
||||
scale: {
|
||||
type: [Object, Array],
|
||||
required: true
|
||||
},
|
||||
dataSource: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
height: 100
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import "smooth.area.less";
|
||||
</style>
|
|
@ -0,0 +1,68 @@
|
|||
<template>
|
||||
<v-chart :forceFit="true" height="400" :data="data" :padding="[20, 20, 95, 20]" :scale="scale">
|
||||
<v-tooltip></v-tooltip>
|
||||
<v-axis :dataKey="axis1Opts.dataKey" :line="axis1Opts.line" :tickLine="axis1Opts.tickLine" :grid="axis1Opts.grid" />
|
||||
<v-axis :dataKey="axis2Opts.dataKey" :line="axis2Opts.line" :tickLine="axis2Opts.tickLine" :grid="axis2Opts.grid" />
|
||||
<v-legend dataKey="user" marker="circle" :offset="30" />
|
||||
<v-coord type="polar" radius="0.8" />
|
||||
<v-line position="item*score" color="user" :size="2" />
|
||||
<v-point position="item*score" color="user" :size="4" shape="circle" />
|
||||
</v-chart>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const axis1Opts = {
|
||||
dataKey: 'item',
|
||||
line: null,
|
||||
tickLine: null,
|
||||
grid: {
|
||||
lineStyle: {
|
||||
lineDash: null
|
||||
},
|
||||
hideFirstLine: false
|
||||
}
|
||||
}
|
||||
const axis2Opts = {
|
||||
dataKey: 'score',
|
||||
line: null,
|
||||
tickLine: null,
|
||||
grid: {
|
||||
type: 'polygon',
|
||||
lineStyle: {
|
||||
lineDash: null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const scale = [
|
||||
{
|
||||
dataKey: 'score',
|
||||
min: 0,
|
||||
max: 80
|
||||
}, {
|
||||
dataKey: 'user',
|
||||
alias: '类型'
|
||||
}
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'Radar',
|
||||
props: {
|
||||
data: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
axis1Opts,
|
||||
axis2Opts,
|
||||
scale
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,77 @@
|
|||
<template>
|
||||
<div class="rank">
|
||||
<h4 class="title">{{ title }}</h4>
|
||||
<ul class="list">
|
||||
<li :key="index" v-for="(item, index) in list">
|
||||
<span :class="index < 3 ? 'active' : null">{{ index + 1 }}</span>
|
||||
<span>{{ item.name }}</span>
|
||||
<span>{{ item.total }}</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'RankList',
|
||||
// ['title', 'list']
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.rank {
|
||||
padding: 0 32px 32px 72px;
|
||||
|
||||
.list {
|
||||
margin: 25px 0 0;
|
||||
padding: 0;
|
||||
list-style: none;
|
||||
|
||||
li {
|
||||
margin-top: 16px;
|
||||
|
||||
span {
|
||||
color: rgba(0, 0, 0, .65);
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
|
||||
&:first-child {
|
||||
background-color: #f5f5f5;
|
||||
border-radius: 20px;
|
||||
display: inline-block;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
margin-right: 24px;
|
||||
height: 20px;
|
||||
line-height: 20px;
|
||||
width: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
&.active {
|
||||
background-color: #314659;
|
||||
color: #fff;
|
||||
}
|
||||
&:last-child {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile .rank {
|
||||
padding: 0 32px 32px 32px;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,113 @@
|
|||
<template>
|
||||
<v-chart :width="width" :height="height" :padding="[0]" :data="data" :scale="scale">
|
||||
<v-tooltip :show-title="false" />
|
||||
<v-coord type="rect" direction="TL" />
|
||||
<v-point position="x*y" color="category" shape="cloud" tooltip="value*category" />
|
||||
</v-chart>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { registerShape } from 'viser-vue'
|
||||
const DataSet = require('@antv/data-set')
|
||||
|
||||
const imgUrl = 'https://gw.alipayobjects.com/zos/rmsportal/gWyeGLCdFFRavBGIDzWk.png'
|
||||
|
||||
const scale = [
|
||||
{ dataKey: 'x', nice: false },
|
||||
{ dataKey: 'y', nice: false }
|
||||
]
|
||||
|
||||
registerShape('point', 'cloud', {
|
||||
draw (cfg, container) {
|
||||
return container.addShape('text', {
|
||||
attrs: {
|
||||
fillOpacity: cfg.opacity,
|
||||
fontSize: cfg.origin._origin.size,
|
||||
rotate: cfg.origin._origin.rotate,
|
||||
text: cfg.origin._origin.text,
|
||||
textAlign: 'center',
|
||||
fontFamily: cfg.origin._origin.font,
|
||||
fill: cfg.color,
|
||||
textBaseline: 'Alphabetic',
|
||||
...cfg.style,
|
||||
x: cfg.x,
|
||||
y: cfg.y
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
export default {
|
||||
name: 'TagCloud',
|
||||
props: {
|
||||
tagList: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
height: {
|
||||
type: Number,
|
||||
default: 400
|
||||
},
|
||||
width: {
|
||||
type: Number,
|
||||
default: 640
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
data: [],
|
||||
scale
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
tagList: function (val) {
|
||||
if (val.length > 0) {
|
||||
this.initTagCloud(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
if (this.tagList.length > 0) {
|
||||
this.initTagCloud(this.tagList)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initTagCloud (dataSource) {
|
||||
const { height, width } = this
|
||||
|
||||
const dv = new DataSet.View().source(dataSource)
|
||||
const range = dv.range('value')
|
||||
const min = range[0]
|
||||
const max = range[1]
|
||||
const imageMask = new Image()
|
||||
imageMask.crossOrigin = ''
|
||||
imageMask.src = imgUrl
|
||||
imageMask.onload = () => {
|
||||
dv.transform({
|
||||
type: 'tag-cloud',
|
||||
fields: ['name', 'value'],
|
||||
size: [width, height],
|
||||
imageMask,
|
||||
font: 'Verdana',
|
||||
padding: 0,
|
||||
timeInterval: 5000, // max execute time
|
||||
rotate () {
|
||||
let random = ~~(Math.random() * 4) % 4
|
||||
if (random === 2) {
|
||||
random = 0
|
||||
}
|
||||
return random * 90 // 0, 90, 270
|
||||
},
|
||||
fontSize (d) {
|
||||
if (d.value) {
|
||||
return ((d.value - min) / (max - min)) * (32 - 8) + 8
|
||||
}
|
||||
return 0
|
||||
}
|
||||
})
|
||||
this.data = dv.rows
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,64 @@
|
|||
<template>
|
||||
<div :style="{ padding: '0 0 32px 32px' }">
|
||||
<h4 :style="{ marginBottom: '20px' }">{{ title }}</h4>
|
||||
<v-chart
|
||||
height="254"
|
||||
:data="data"
|
||||
:scale="scale"
|
||||
:forceFit="true"
|
||||
:padding="['auto', 'auto', '40', '50']">
|
||||
<v-tooltip />
|
||||
<v-axis />
|
||||
<v-bar position="x*y"/>
|
||||
</v-chart>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const tooltip = [
|
||||
'x*y',
|
||||
(x, y) => ({
|
||||
name: x,
|
||||
value: y
|
||||
})
|
||||
]
|
||||
const scale = [{
|
||||
dataKey: 'x',
|
||||
title: '日期(天)',
|
||||
alias: '日期(天)',
|
||||
min: 2
|
||||
}, {
|
||||
dataKey: 'y',
|
||||
title: '流量(Gb)',
|
||||
alias: '流量(Gb)',
|
||||
min: 1
|
||||
}]
|
||||
|
||||
export default {
|
||||
name: 'Bar',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
data: [],
|
||||
scale,
|
||||
tooltip
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.getMonthBar()
|
||||
},
|
||||
methods: {
|
||||
getMonthBar () {
|
||||
this.$http.get('/analysis/month-bar')
|
||||
.then(res => {
|
||||
this.data = res.result
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,82 @@
|
|||
<template>
|
||||
<div class="chart-trend">
|
||||
{{ term }}
|
||||
<span>{{ rate }}%</span>
|
||||
<span :class="['trend-icon', trend]"><a-icon :type="'caret-' + trend"/></span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'Trend',
|
||||
props: {
|
||||
term: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: true
|
||||
},
|
||||
percentage: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
type: {
|
||||
type: Boolean,
|
||||
default: null
|
||||
},
|
||||
target: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
value: {
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
fixed: {
|
||||
type: Number,
|
||||
default: 2
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
trend: this.type && 'up' || 'down',
|
||||
rate: this.percentage
|
||||
}
|
||||
},
|
||||
created () {
|
||||
const type = this.type === null ? this.value >= this.target : this.type
|
||||
this.trend = type ? 'up' : 'down'
|
||||
this.rate = (this.percentage === null ? Math.abs(this.value - this.target) * 100 / this.target : this.percentage).toFixed(this.fixed)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.chart-trend {
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
|
||||
.trend-icon {
|
||||
font-size: 12px;
|
||||
|
||||
&.up, &.down {
|
||||
margin-left: 4px;
|
||||
position: relative;
|
||||
top: 1px;
|
||||
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(.83);
|
||||
}
|
||||
}
|
||||
|
||||
&.up {
|
||||
color: #f5222d;
|
||||
}
|
||||
&.down {
|
||||
color: #52c41a;
|
||||
top: -1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,13 @@
|
|||
.antv-chart-mini {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.chart-wrapper {
|
||||
position: absolute;
|
||||
bottom: -28px;
|
||||
width: 100%;
|
||||
|
||||
/* margin: 0 -5px;
|
||||
overflow: hidden;*/
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
@import "../index";
|
||||
|
||||
@smoothArea-prefix-cls: ~"@{ant-pro-prefix}-smooth-area";
|
||||
|
||||
.@{smoothArea-prefix-cls} {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
|
||||
.chart-wrapper {
|
||||
position: absolute;
|
||||
bottom: -28px;
|
||||
width: 100%;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
<template>
|
||||
<span>
|
||||
{{ lastTime | format }}
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
function fixedZero (val) {
|
||||
return val * 1 < 10 ? `0${val}` : val
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'CountDown',
|
||||
props: {
|
||||
format: {
|
||||
type: Function,
|
||||
default: undefined
|
||||
},
|
||||
target: {
|
||||
type: [Date, Number],
|
||||
required: true
|
||||
},
|
||||
onEnd: {
|
||||
type: Function,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
dateTime: '0',
|
||||
originTargetTime: 0,
|
||||
lastTime: 0,
|
||||
timer: 0,
|
||||
interval: 1000
|
||||
}
|
||||
},
|
||||
filters: {
|
||||
format (time) {
|
||||
const hours = 60 * 60 * 1000
|
||||
const minutes = 60 * 1000
|
||||
|
||||
const h = Math.floor(time / hours)
|
||||
const m = Math.floor((time - h * hours) / minutes)
|
||||
const s = Math.floor((time - h * hours - m * minutes) / 1000)
|
||||
return `${fixedZero(h)}:${fixedZero(m)}:${fixedZero(s)}`
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.initTime()
|
||||
this.tick()
|
||||
},
|
||||
methods: {
|
||||
initTime () {
|
||||
let lastTime = 0
|
||||
let targetTime = 0
|
||||
this.originTargetTime = this.target
|
||||
try {
|
||||
if (Object.prototype.toString.call(this.target) === '[object Date]') {
|
||||
targetTime = this.target
|
||||
} else {
|
||||
targetTime = new Date(this.target).getTime()
|
||||
}
|
||||
} catch (e) {
|
||||
throw new Error('invalid target prop')
|
||||
}
|
||||
|
||||
lastTime = targetTime - new Date().getTime()
|
||||
|
||||
this.lastTime = lastTime < 0 ? 0 : lastTime
|
||||
},
|
||||
tick () {
|
||||
const { onEnd } = this
|
||||
|
||||
this.timer = setTimeout(() => {
|
||||
if (this.lastTime < this.interval) {
|
||||
clearTimeout(this.timer)
|
||||
this.lastTime = 0
|
||||
if (typeof onEnd === 'function') {
|
||||
onEnd()
|
||||
}
|
||||
} else {
|
||||
this.lastTime -= this.interval
|
||||
this.tick()
|
||||
}
|
||||
}, this.interval)
|
||||
}
|
||||
},
|
||||
beforeUpdate () {
|
||||
if (this.originTargetTime !== this.target) {
|
||||
this.initTime()
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
clearTimeout(this.timer)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
import CountDown from './CountDown'
|
||||
|
||||
export default CountDown
|
|
@ -0,0 +1,34 @@
|
|||
# CountDown 倒计时
|
||||
|
||||
倒计时组件。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import CountDown from '@/components/CountDown/CountDown'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CountDown
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<count-down :target="new Date().getTime() + 3000000" :on-end="onEndHandle" />
|
||||
```
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 |
|
||||
|----------|------------------------------------------|-------------|-------|
|
||||
| target | 目标时间 | Date | - |
|
||||
| onEnd | 倒计时结束回调 | funtion | -|
|
|
@ -0,0 +1,153 @@
|
|||
<template>
|
||||
<div :class="['description-list', size, layout === 'vertical' ? 'vertical': 'horizontal']">
|
||||
<div v-if="title" class="title">{{ title }}</div>
|
||||
<a-row>
|
||||
<slot></slot>
|
||||
</a-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Col } from 'ant-design-vue/es/grid/'
|
||||
|
||||
const Item = {
|
||||
name: 'DetailListItem',
|
||||
props: {
|
||||
term: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
}
|
||||
},
|
||||
inject: {
|
||||
col: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
render () {
|
||||
return (
|
||||
<Col {...{ props: responsive[this.col] }}>
|
||||
<div class="term">{this.$props.term}</div>
|
||||
<div class="content">{this.$slots.default}</div>
|
||||
</Col>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
const responsive = {
|
||||
1: { xs: 24 },
|
||||
2: { xs: 24, sm: 12 },
|
||||
3: { xs: 24, sm: 12, md: 8 },
|
||||
4: { xs: 24, sm: 12, md: 6 }
|
||||
}
|
||||
|
||||
export default {
|
||||
name: 'DetailList',
|
||||
Item: Item,
|
||||
components: {
|
||||
Col
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
col: {
|
||||
type: Number,
|
||||
required: false,
|
||||
default: 3
|
||||
},
|
||||
size: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'large'
|
||||
},
|
||||
layout: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'horizontal'
|
||||
}
|
||||
},
|
||||
provide () {
|
||||
return {
|
||||
col: this.col > 4 ? 4 : this.col
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.description-list {
|
||||
|
||||
.title {
|
||||
color: rgba(0,0,0,.85);
|
||||
font-size: 14px;
|
||||
font-weight: 500;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
/deep/ .term {
|
||||
color: rgba(0,0,0,.85);
|
||||
display: table-cell;
|
||||
line-height: 20px;
|
||||
margin-right: 8px;
|
||||
padding-bottom: 16px;
|
||||
white-space: nowrap;
|
||||
|
||||
&:not(:empty):after {
|
||||
content: ":";
|
||||
margin: 0 8px 0 2px;
|
||||
position: relative;
|
||||
top: -.5px;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .content {
|
||||
color: rgba(0,0,0,.65);
|
||||
display: table-cell;
|
||||
min-height: 22px;
|
||||
line-height: 22px;
|
||||
padding-bottom: 16px;
|
||||
width: 100%;
|
||||
&:empty {
|
||||
content: ' ';
|
||||
height: 38px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.small {
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, .65);
|
||||
font-weight: normal;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
/deep/ .term, .content {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
/deep/ .term, .content {
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&.vertical {
|
||||
.term {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
/deep/ .term, .content {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import DescriptionList from './DescriptionList'
|
||||
export default DescriptionList
|
|
@ -0,0 +1,64 @@
|
|||
<script>
|
||||
import Tooltip from 'ant-design-vue/es/tooltip'
|
||||
import { cutStrByFullLength, getStrFullLength } from '@/components/_util/util'
|
||||
/*
|
||||
const isSupportLineClamp = document.body.style.webkitLineClamp !== undefined;
|
||||
|
||||
const TooltipOverlayStyle = {
|
||||
overflowWrap: 'break-word',
|
||||
wordWrap: 'break-word',
|
||||
};
|
||||
*/
|
||||
|
||||
export default {
|
||||
name: 'Ellipsis',
|
||||
components: {
|
||||
Tooltip
|
||||
},
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-ellipsis'
|
||||
},
|
||||
tooltip: {
|
||||
type: Boolean
|
||||
},
|
||||
length: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
lines: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
fullWidthRecognition: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getStrDom (str, fullLength) {
|
||||
return (
|
||||
<span>{ cutStrByFullLength(str, this.length) + (fullLength > this.length ? '...' : '') }</span>
|
||||
)
|
||||
},
|
||||
getTooltip (fullStr, fullLength) {
|
||||
return (
|
||||
<Tooltip>
|
||||
<template slot="title">{ fullStr }</template>
|
||||
{ this.getStrDom(fullStr, fullLength) }
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { tooltip, length } = this.$props
|
||||
const str = this.$slots.default.map(vNode => vNode.text).join('')
|
||||
const fullLength = getStrFullLength(str)
|
||||
const strDom = tooltip && fullLength > length ? this.getTooltip(str, fullLength) : this.getStrDom(str, fullLength)
|
||||
return (
|
||||
strDom
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,3 @@
|
|||
import Ellipsis from './Ellipsis'
|
||||
|
||||
export default Ellipsis
|
|
@ -0,0 +1,38 @@
|
|||
# Ellipsis 文本自动省略号
|
||||
|
||||
文本过长自动处理省略号,支持按照文本长度和最大行数两种方式截取。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import Ellipsis from '@/components/Ellipsis'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Ellipsis
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<ellipsis :length="100" tooltip>
|
||||
There were injuries alleged in three cases in 2015, and a
|
||||
fourth incident in September, according to the safety recall report. After meeting with US regulators in October, the firm decided to issue a voluntary recall.
|
||||
</ellipsis>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
|
||||
参数 | 说明 | 类型 | 默认值
|
||||
----|------|-----|------
|
||||
tooltip | 移动到文本展示完整内容的提示 | boolean | -
|
||||
length | 在按照长度截取下的文本最大字符数,超过则截取省略 | number | -
|
|
@ -0,0 +1,130 @@
|
|||
<template>
|
||||
<div class="exception">
|
||||
<div class="imgBlock">
|
||||
<div class="imgEle" :style="{backgroundImage: `url(${config[type].img})`}">
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
<h1>{{ config[type].title }}</h1>
|
||||
<div class="desc">{{ config[type].desc }}</div>
|
||||
<div class="actions">
|
||||
<a-button type="primary" @click="handleToHome">Take me back home!</a-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import types from './type'
|
||||
|
||||
export default {
|
||||
name: 'Exception',
|
||||
props: {
|
||||
type: {
|
||||
type: String,
|
||||
default: '404'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
config: types
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleToHome () {
|
||||
this.$router.push({ name: 'dashboard' })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style lang="less">
|
||||
@import "~ant-design-vue/lib/style/index";
|
||||
|
||||
.exception {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 80%;
|
||||
min-height: 500px;
|
||||
|
||||
.imgBlock {
|
||||
flex: 0 0 62.5%;
|
||||
width: 62.5%;
|
||||
padding-right: 152px;
|
||||
zoom: 1;
|
||||
&::before,
|
||||
&::after {
|
||||
content: ' ';
|
||||
display: table;
|
||||
}
|
||||
&::after {
|
||||
clear: both;
|
||||
height: 0;
|
||||
font-size: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
.imgEle {
|
||||
float: right;
|
||||
width: 100%;
|
||||
max-width: 430px;
|
||||
height: 360px;
|
||||
background-repeat: no-repeat;
|
||||
background-position: 50% 50%;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: auto;
|
||||
|
||||
h1 {
|
||||
margin-bottom: 24px;
|
||||
color: #434e59;
|
||||
font-weight: 600;
|
||||
font-size: 72px;
|
||||
line-height: 72px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
margin-bottom: 16px;
|
||||
color: @text-color-secondary;
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
}
|
||||
|
||||
.actions {
|
||||
button:not(:last-child) {
|
||||
margin-right: 8px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-xl) {
|
||||
.exception {
|
||||
.imgBlock {
|
||||
padding-right: 88px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-sm) {
|
||||
.exception {
|
||||
display: block;
|
||||
text-align: center;
|
||||
.imgBlock {
|
||||
margin: 0 auto 24px;
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: @screen-xs) {
|
||||
.exception {
|
||||
.imgBlock {
|
||||
margin-bottom: -24px;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import ExceptionPage from './ExceptionPage.vue'
|
||||
export default ExceptionPage
|
|
@ -0,0 +1,19 @@
|
|||
const types = {
|
||||
403: {
|
||||
img: 'https://gw.alipayobjects.com/zos/rmsportal/wZcnGqRDyhPOEYFcZDnb.svg',
|
||||
title: '403',
|
||||
desc: 'Not authorized.'
|
||||
},
|
||||
404: {
|
||||
img: 'https://gw.alipayobjects.com/zos/rmsportal/KpnpchXsobRgLElEozzI.svg',
|
||||
title: '404',
|
||||
desc: 'Lost? Page not found :|'
|
||||
},
|
||||
500: {
|
||||
img: 'https://gw.alipayobjects.com/zos/rmsportal/RVRUAYdCGeYNBWoKiIwB.svg',
|
||||
title: '500',
|
||||
desc: 'Auch, server error!'
|
||||
}
|
||||
}
|
||||
|
||||
export default types
|
|
@ -0,0 +1,30 @@
|
|||
<template>
|
||||
<div :class="prefixCls">
|
||||
<div style="float: left">
|
||||
<slot name="extra">{{ extra }}</slot>
|
||||
</div>
|
||||
<div style="float: right">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'FooterToolBar',
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-footer-toolbar'
|
||||
},
|
||||
extra: {
|
||||
type: [String, Object],
|
||||
default: ''
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
|
@ -0,0 +1,4 @@
|
|||
import FooterToolBar from './FooterToolBar'
|
||||
import './index.less'
|
||||
|
||||
export default FooterToolBar
|
|
@ -0,0 +1,23 @@
|
|||
@import "../index";
|
||||
|
||||
@footer-toolbar-prefix-cls: ~"@{ant-pro-prefix}-footer-toolbar";
|
||||
|
||||
.@{footer-toolbar-prefix-cls} {
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
height: 56px;
|
||||
line-height: 56px;
|
||||
box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.03);
|
||||
background: #fff;
|
||||
border-top: 1px solid #e8e8e8;
|
||||
padding: 0 24px;
|
||||
z-index: 9;
|
||||
|
||||
&:after {
|
||||
content: "";
|
||||
display: block;
|
||||
clear: both;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
# FooterToolbar 底部工具栏
|
||||
|
||||
固定在底部的工具栏。
|
||||
|
||||
|
||||
|
||||
## 何时使用
|
||||
|
||||
固定在内容区域的底部,不随滚动条移动,常用于长页面的数据搜集和提交工作。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import FooterToolBar from '@/components/FooterToolbar'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
FooterToolBar
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示
|
||||
|
||||
```html
|
||||
<footer-tool-bar>
|
||||
<a-button type="primary" @click="validate" :loading="loading">提交</a-button>
|
||||
</footer-tool-bar>
|
||||
```
|
||||
或
|
||||
```html
|
||||
<footer-tool-bar extra="扩展信息提示">
|
||||
<a-button type="primary" @click="validate" :loading="loading">提交</a-button>
|
||||
</footer-tool-bar>
|
||||
```
|
||||
|
||||
|
||||
## API
|
||||
|
||||
参数 | 说明 | 类型 | 默认值
|
||||
----|------|-----|------
|
||||
children (slot) | 工具栏内容,向右对齐 | - | -
|
||||
extra | 额外信息,向左对齐 | String, Object | -
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div class="footer">
|
||||
<div class="links">
|
||||
<a
|
||||
href="https://github.com/keel-hq/keel"
|
||||
target="_blank"
|
||||
>
|
||||
<a-icon type="github" />
|
||||
</a>
|
||||
</div>
|
||||
<div class="copyright">
|
||||
Copyright
|
||||
<a-icon type="copyright" /> 2019 <span>Keel</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'GlobalFooter',
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.footer {
|
||||
padding: 0 16px;
|
||||
margin: 48px 0 24px;
|
||||
text-align: center;
|
||||
|
||||
.links {
|
||||
margin-bottom: 8px;
|
||||
|
||||
a {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
|
||||
&:hover {
|
||||
color: rgba(0, 0, 0, 0.65);
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-right: 40px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.copyright {
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import GlobalFooter from './GlobalFooter'
|
||||
export default GlobalFooter
|
|
@ -0,0 +1,123 @@
|
|||
<template>
|
||||
<transition name="showHeader">
|
||||
<div v-if="visible" class="header-animat">
|
||||
<a-layout-header
|
||||
v-if="visible"
|
||||
:class="[fixedHeader && 'ant-header-fixedHeader', sidebarOpened ? 'ant-header-side-opened' : 'ant-header-side-closed', ]"
|
||||
:style="{ padding: '0' }">
|
||||
<div v-if="mode === 'sidemenu'" class="header">
|
||||
<a-icon v-if="device==='mobile'" class="trigger" :type="collapsed ? 'menu-fold' : 'menu-unfold'" @click="toggle"/>
|
||||
<a-icon v-else class="trigger" :type="collapsed ? 'menu-unfold' : 'menu-fold'" @click="toggle"/>
|
||||
<user-menu></user-menu>
|
||||
</div>
|
||||
<div v-else :class="['top-nav-header-index', theme]">
|
||||
<div class="header-index-wide">
|
||||
<div class="header-index-left">
|
||||
<logo class="top-nav-header" :show-title="device !== 'mobile'"/>
|
||||
<s-menu v-if="device !== 'mobile'" mode="horizontal" :menu="menus" :theme="theme" />
|
||||
<a-icon v-else class="trigger" :type="collapsed ? 'menu-fold' : 'menu-unfold'" @click="toggle" />
|
||||
</div>
|
||||
<user-menu class="header-index-right"></user-menu>
|
||||
</div>
|
||||
</div>
|
||||
</a-layout-header>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UserMenu from '../tools/UserMenu'
|
||||
import SMenu from '../Menu/'
|
||||
import Logo from '../tools/Logo'
|
||||
import { mixin } from '@/utils/mixin'
|
||||
|
||||
export default {
|
||||
name: 'GlobalHeader',
|
||||
components: {
|
||||
UserMenu,
|
||||
SMenu,
|
||||
Logo
|
||||
},
|
||||
mixins: [mixin],
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
// sidemenu, topmenu
|
||||
default: 'sidemenu'
|
||||
},
|
||||
menus: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
device: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'desktop'
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
visible: true,
|
||||
oldScrollTop: 0
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
document.body.addEventListener('scroll', this.handleScroll, { passive: true })
|
||||
},
|
||||
methods: {
|
||||
handleScroll () {
|
||||
if (!this.autoHideHeader) {
|
||||
return
|
||||
}
|
||||
|
||||
const scrollTop = document.body.scrollTop + document.documentElement.scrollTop
|
||||
if (!this.ticking) {
|
||||
this.ticking = true
|
||||
requestAnimationFrame(() => {
|
||||
if (this.oldScrollTop > scrollTop) {
|
||||
this.visible = true
|
||||
} else if (scrollTop > 300 && this.visible) {
|
||||
this.visible = false
|
||||
} else if (scrollTop < 300 && !this.visible) {
|
||||
this.visible = true
|
||||
}
|
||||
this.oldScrollTop = scrollTop
|
||||
this.ticking = false
|
||||
})
|
||||
}
|
||||
},
|
||||
toggle () {
|
||||
this.$emit('toggle')
|
||||
}
|
||||
},
|
||||
beforeDestroy () {
|
||||
document.body.removeEventListener('scroll', this.handleScroll, true)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less">
|
||||
.header-animat{
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
.showHeader-enter-active {
|
||||
transition: all 0.25s ease;
|
||||
}
|
||||
.showHeader-leave-active {
|
||||
transition: all 0.5s ease;
|
||||
}
|
||||
.showHeader-enter, .showHeader-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import GlobalHeader from './GlobalHeader'
|
||||
export default GlobalHeader
|
|
@ -0,0 +1,53 @@
|
|||
<template>
|
||||
<div>
|
||||
<a-tabs>
|
||||
<a-tab-pane v-for="(v, i) in icons" :tab="v.title" :key="i">
|
||||
<ul>
|
||||
<li v-for="(icon, key) in v.icons" :key="`${v.title}-${key}`" :class="{ 'active': selectedIcon==icon }">
|
||||
<a-icon :type="icon" :style="{ fontSize: '36px' }" @click="handleSelectedIcon(icon)" />
|
||||
</li>
|
||||
</ul>
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import icons from './icons'
|
||||
|
||||
export default {
|
||||
name: 'IconSelect',
|
||||
data () {
|
||||
return {
|
||||
selectedIcon: '',
|
||||
icons
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleSelectedIcon (icon) {
|
||||
this.selectedIcon = icon
|
||||
this.$emit('change', icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
ul{
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
overflow-y: scroll;
|
||||
height: 250px;
|
||||
li{
|
||||
display: inline-block;
|
||||
padding:5px;
|
||||
margin:5px;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
&.active{
|
||||
box-shadow: 0px 0px 5px 2px #888888;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,48 @@
|
|||
IconSelector
|
||||
====
|
||||
|
||||
> 图标选择组件,常用于为某一个数据设定一个图标时使用
|
||||
> eg: 设定菜单列表时,为每个菜单设定一个图标
|
||||
|
||||
该组件由 [@Saraka](https://github.com/saraka-tsukai) 封装
|
||||
|
||||
|
||||
|
||||
### 使用方式
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<icon-selector @change="handleIconChange"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import IconSelector from '@/components/IconSelector'
|
||||
|
||||
export default {
|
||||
name: 'YourView',
|
||||
components: {
|
||||
IconSelector
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleIconChange (icon) {
|
||||
console.log('change Icon', icon)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
|
||||
|
||||
### 事件
|
||||
|
||||
|
||||
| 名称 | 说明 | 类型 | 默认值 |
|
||||
| ------ | -------------------------- | ------ | ------ |
|
||||
| change | 当改变了 `icon` 选中项触发 | String | - |
|
|
@ -0,0 +1,26 @@
|
|||
export default [
|
||||
{
|
||||
title: '方向性图标',
|
||||
icons: ['step-backward', 'step-forward', 'fast-backward', 'fast-forward', 'shrink', 'arrows-alt', 'down', 'up', 'left', 'right', 'caret-up', 'caret-down', 'caret-left', 'caret-right', 'up-circle', 'down-circle', 'left-circle', 'right-circle', 'double-right', 'double-left', 'vertical-left', 'vertical-right', 'forward', 'backward', 'rollback', 'enter', 'retweet', 'swap', 'swap-left', 'swap-right', 'arrow-up', 'arrow-down', 'arrow-left', 'arrow-right', 'play-circle', 'up-square', 'down-square', 'left-square', 'right-square', 'login', 'logout', 'menu-fold', 'menu-unfold', 'border-bottom', 'border-horizontal', 'border-inner', 'border-left', 'border-right', 'border-top', 'border-verticle', 'pic-center', 'pic-left', 'pic-right', 'radius-bottomleft', 'radius-bottomright', 'radius-upleft', 'fullscreen', 'fullscreen-exit']
|
||||
},
|
||||
{
|
||||
title: '提示建议性图标',
|
||||
icons: ['question', 'question-circle', 'plus', 'plus-circle', 'pause', 'pause-circle', 'minus', 'minus-circle', 'plus-square', 'minus-square', 'info', 'info-circle', 'exclamation', 'exclamation-circle', 'close', 'close-circle', 'close-square', 'check', 'check-circle', 'check-square', 'clock-circle', 'warning', 'issues-close', 'stop']
|
||||
},
|
||||
{
|
||||
title: '编辑类图标',
|
||||
icons: ['edit', 'form', 'copy', 'scissor', 'delete', 'snippets', 'diff', 'highlight', 'align-center', 'align-left', 'align-right', 'bg-colors', 'bold', 'italic', 'underline', 'strikethrough', 'redo', 'undo', 'zoom-in', 'zoom-out', 'font-colors', 'font-size', 'line-height', 'colum-height', 'dash', 'small-dash', 'sort-ascending', 'sort-descending', 'drag', 'ordered-list', 'radius-setting']
|
||||
},
|
||||
{
|
||||
title: '数据类图标',
|
||||
icons: ['area-chart', 'pie-chart', 'bar-chart', 'dot-chart', 'line-chart', 'radar-chart', 'heat-map', 'fall', 'rise', 'stock', 'box-plot', 'fund', 'sliders']
|
||||
},
|
||||
{
|
||||
title: '网站通用图标',
|
||||
icons: ['lock', 'unlock', 'bars', 'book', 'calendar', 'cloud', 'cloud-download', 'code', 'copy', 'credit-card', 'delete', 'desktop', 'download', 'ellipsis', 'file', 'file-text', 'file-unknown', 'file-pdf', 'file-word', 'file-excel', 'file-jpg', 'file-ppt', 'file-markdown', 'file-add', 'folder', 'folder-open', 'folder-add', 'hdd', 'frown', 'meh', 'smile', 'inbox', 'laptop', 'appstore', 'link', 'mail', 'mobile', 'notification', 'paper-clip', 'picture', 'poweroff', 'reload', 'search', 'setting', 'share-alt', 'shopping-cart', 'tablet', 'tag', 'tags', 'to-top', 'upload', 'user', 'video-camera', 'home', 'loading', 'loading-3-quarters', 'cloud-upload', 'star', 'heart', 'environment', 'eye', 'camera', 'save', 'team', 'solution', 'phone', 'filter', 'exception', 'export', 'customer-service', 'qrcode', 'scan', 'like', 'dislike', 'message', 'pay-circle', 'calculator', 'pushpin', 'bulb', 'select', 'switcher', 'rocket', 'bell', 'disconnect', 'database', 'compass', 'barcode', 'hourglass', 'key', 'flag', 'layout', 'printer', 'sound', 'usb', 'skin', 'tool', 'sync', 'wifi', 'car', 'schedule', 'user-add', 'user-delete', 'usergroup-add', 'usergroup-delete', 'man', 'woman', 'shop', 'gift', 'idcard', 'medicine-box', 'red-envelope', 'coffee', 'copyright', 'trademark', 'safety', 'wallet', 'bank', 'trophy', 'contacts', 'global', 'shake', 'api', 'fork', 'dashboard', 'table', 'profile', 'alert', 'audit', 'branches', 'build', 'border', 'crown', 'experiment', 'fire', 'money-collect', 'property-safety', 'read', 'reconciliation', 'rest', 'security-scan', 'insurance', 'interation', 'safety-certificate', 'project', 'thunderbolt', 'block', 'cluster', 'deployment-unit', 'dollar', 'euro', 'pound', 'file-done', 'file-exclamation', 'file-protect', 'file-search', 'file-sync', 'gateway', 'gold', 'robot', 'shopping']
|
||||
},
|
||||
{
|
||||
title: '品牌和标识',
|
||||
icons: ['android', 'apple', 'windows', 'ie', 'chrome', 'github', 'aliwangwang', 'dingding', 'weibo-square', 'weibo-circle', 'taobao-circle', 'html5', 'weibo', 'twitter', 'wechat', 'youtube', 'alipay-circle', 'taobao', 'skype', 'qq', 'medium-workmark', 'gitlab', 'medium', 'linkedin', 'google-plus', 'dropbox', 'facebook', 'codepen', 'code-sandbox', 'amazon', 'google', 'codepen-circle', 'alipay', 'ant-design', 'aliyun', 'zhihu', 'slack', 'slack-square', 'behance', 'behance-square', 'dribbble', 'dribbble-square', 'instagram', 'yuque', 'alibaba', 'yahoo']
|
||||
}
|
||||
]
|
|
@ -0,0 +1,2 @@
|
|||
import IconSelector from './IconSelector'
|
||||
export default IconSelector
|
|
@ -0,0 +1,61 @@
|
|||
<template>
|
||||
<a-layout-sider
|
||||
:class="['sider', isDesktop() ? null : 'shadow', theme, fixSiderbar ? 'ant-fixed-sidemenu' : null ]"
|
||||
width="256px"
|
||||
:collapsible="collapsible"
|
||||
v-model="collapsed"
|
||||
:trigger="null">
|
||||
<logo />
|
||||
<s-menu
|
||||
:collapsed="collapsed"
|
||||
:menu="menus"
|
||||
:theme="theme"
|
||||
:mode="mode"
|
||||
@select="onSelect"
|
||||
style="padding: 16px 0px;"></s-menu>
|
||||
</a-layout-sider>
|
||||
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Logo from '@/components/tools/Logo'
|
||||
import SMenu from './index'
|
||||
import { mixin, mixinDevice } from '@/utils/mixin'
|
||||
|
||||
export default {
|
||||
name: 'SideMenu',
|
||||
components: { Logo, SMenu },
|
||||
mixins: [mixin, mixinDevice],
|
||||
props: {
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inline'
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
},
|
||||
collapsible: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
},
|
||||
menus: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onSelect (obj) {
|
||||
this.$emit('menuSelect', obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,2 @@
|
|||
import SMenu from './menu'
|
||||
export default SMenu
|
|
@ -0,0 +1,180 @@
|
|||
import Menu from 'ant-design-vue/es/menu'
|
||||
import Icon from 'ant-design-vue/es/icon'
|
||||
|
||||
const { Item, SubMenu } = Menu
|
||||
|
||||
export default {
|
||||
name: 'SMenu',
|
||||
props: {
|
||||
menu: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inline'
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
openKeys: [],
|
||||
selectedKeys: [],
|
||||
cachedOpenKeys: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rootSubmenuKeys: vm => {
|
||||
const keys = []
|
||||
vm.menu.forEach(item => keys.push(item.path))
|
||||
return keys
|
||||
}
|
||||
},
|
||||
mounted () {
|
||||
this.updateMenu()
|
||||
},
|
||||
watch: {
|
||||
collapsed (val) {
|
||||
if (val) {
|
||||
this.cachedOpenKeys = this.openKeys.concat()
|
||||
this.openKeys = []
|
||||
} else {
|
||||
this.openKeys = this.cachedOpenKeys
|
||||
}
|
||||
},
|
||||
$route: function () {
|
||||
this.updateMenu()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// select menu item
|
||||
onOpenChange (openKeys) {
|
||||
// 在水平模式下时执行,并且不再执行后续
|
||||
if (this.mode === 'horizontal') {
|
||||
this.openKeys = openKeys
|
||||
return
|
||||
}
|
||||
// 非水平模式时
|
||||
const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
|
||||
if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
|
||||
this.openKeys = openKeys
|
||||
} else {
|
||||
this.openKeys = latestOpenKey ? [latestOpenKey] : []
|
||||
}
|
||||
},
|
||||
updateMenu () {
|
||||
const routes = this.$route.matched.concat()
|
||||
const { hidden } = this.$route.meta
|
||||
if (routes.length >= 3 && hidden) {
|
||||
routes.pop()
|
||||
this.selectedKeys = [routes[routes.length - 1].path]
|
||||
} else {
|
||||
this.selectedKeys = [routes.pop().path]
|
||||
}
|
||||
const openKeys = []
|
||||
if (this.mode === 'inline') {
|
||||
routes.forEach(item => {
|
||||
openKeys.push(item.path)
|
||||
})
|
||||
}
|
||||
|
||||
this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
|
||||
},
|
||||
|
||||
// render
|
||||
renderItem (menu) {
|
||||
if (!menu.hidden) {
|
||||
return menu.children && !menu.hideChildrenInMenu ? this.renderSubMenu(menu) : this.renderMenuItem(menu)
|
||||
}
|
||||
return null
|
||||
},
|
||||
renderMenuItem (menu) {
|
||||
const target = menu.meta.target || null
|
||||
const tag = target && 'a' || 'router-link'
|
||||
const props = { to: { name: menu.name } }
|
||||
const attrs = { href: menu.path, target: menu.meta.target }
|
||||
|
||||
if (menu.children && menu.hideChildrenInMenu) {
|
||||
// 把有子菜单的 并且 父菜单是要隐藏子菜单的
|
||||
// 都给子菜单增加一个 hidden 属性
|
||||
// 用来给刷新页面时, selectedKeys 做控制用
|
||||
menu.children.forEach(item => {
|
||||
item.meta = Object.assign(item.meta, { hidden: true })
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<Item {...{ key: menu.path }}>
|
||||
<tag {...{ props, attrs }}>
|
||||
{this.renderIcon(menu.meta.icon)}
|
||||
<span>{menu.meta.title}</span>
|
||||
</tag>
|
||||
</Item>
|
||||
)
|
||||
},
|
||||
renderSubMenu (menu) {
|
||||
const itemArr = []
|
||||
if (!menu.hideChildrenInMenu) {
|
||||
menu.children.forEach(item => itemArr.push(this.renderItem(item)))
|
||||
}
|
||||
return (
|
||||
<SubMenu {...{ key: menu.path }}>
|
||||
<span slot="title">
|
||||
{this.renderIcon(menu.meta.icon)}
|
||||
<span>{menu.meta.title}</span>
|
||||
</span>
|
||||
{itemArr}
|
||||
</SubMenu>
|
||||
)
|
||||
},
|
||||
renderIcon (icon) {
|
||||
if (icon === 'none' || icon === undefined) {
|
||||
return null
|
||||
}
|
||||
const props = {}
|
||||
typeof (icon) === 'object' ? props.component = icon : props.type = icon
|
||||
return (
|
||||
<Icon {... { props } }/>
|
||||
)
|
||||
}
|
||||
},
|
||||
|
||||
render () {
|
||||
const { mode, theme, menu } = this
|
||||
const props = {
|
||||
mode: mode,
|
||||
theme: theme,
|
||||
openKeys: this.openKeys
|
||||
}
|
||||
const on = {
|
||||
select: obj => {
|
||||
this.selectedKeys = obj.selectedKeys
|
||||
this.$emit('select', obj)
|
||||
},
|
||||
openChange: this.onOpenChange
|
||||
}
|
||||
|
||||
const menuTree = menu.map(item => {
|
||||
if (item.hidden) {
|
||||
return null
|
||||
}
|
||||
return this.renderItem(item)
|
||||
})
|
||||
// {...{ props, on: on }}
|
||||
return (
|
||||
<Menu vModel={this.selectedKeys} {...{ props, on: on }}>
|
||||
{menuTree}
|
||||
</Menu>
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,156 @@
|
|||
import Menu from 'ant-design-vue/es/menu'
|
||||
import Icon from 'ant-design-vue/es/icon'
|
||||
|
||||
const { Item, SubMenu } = Menu
|
||||
|
||||
export default {
|
||||
name: 'SMenu',
|
||||
props: {
|
||||
menu: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
theme: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'dark'
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
required: false,
|
||||
default: 'inline'
|
||||
},
|
||||
collapsed: {
|
||||
type: Boolean,
|
||||
required: false,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
openKeys: [],
|
||||
selectedKeys: [],
|
||||
cachedOpenKeys: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
rootSubmenuKeys: vm => {
|
||||
const keys = []
|
||||
vm.menu.forEach(item => keys.push(item.path))
|
||||
return keys
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.updateMenu()
|
||||
},
|
||||
watch: {
|
||||
collapsed (val) {
|
||||
if (val) {
|
||||
this.cachedOpenKeys = this.openKeys.concat()
|
||||
this.openKeys = []
|
||||
} else {
|
||||
this.openKeys = this.cachedOpenKeys
|
||||
}
|
||||
},
|
||||
$route: function () {
|
||||
this.updateMenu()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
renderIcon: function (h, icon) {
|
||||
if (icon === 'none' || icon === undefined) {
|
||||
return null
|
||||
}
|
||||
const props = {}
|
||||
typeof (icon) === 'object' ? props.component = icon : props.type = icon
|
||||
return h(Icon, { props: { ...props } })
|
||||
},
|
||||
renderMenuItem: function (h, menu, pIndex, index) {
|
||||
const target = menu.meta.target || null
|
||||
return h(Item, { key: menu.path ? menu.path : 'item_' + pIndex + '_' + index }, [
|
||||
h('router-link', { attrs: { to: { name: menu.name }, target: target } }, [
|
||||
this.renderIcon(h, menu.meta.icon),
|
||||
h('span', [menu.meta.title])
|
||||
])
|
||||
])
|
||||
},
|
||||
renderSubMenu: function (h, menu, pIndex, index) {
|
||||
const this2_ = this
|
||||
const subItem = [h('span', { slot: 'title' }, [this.renderIcon(h, menu.meta.icon), h('span', [menu.meta.title])])]
|
||||
const itemArr = []
|
||||
const pIndex_ = pIndex + '_' + index
|
||||
console.log('menu', menu)
|
||||
if (!menu.hideChildrenInMenu) {
|
||||
menu.children.forEach(function (item, i) {
|
||||
itemArr.push(this2_.renderItem(h, item, pIndex_, i))
|
||||
})
|
||||
}
|
||||
return h(SubMenu, { key: menu.path ? menu.path : 'submenu_' + pIndex + '_' + index }, subItem.concat(itemArr))
|
||||
},
|
||||
renderItem: function (h, menu, pIndex, index) {
|
||||
if (!menu.hidden) {
|
||||
return menu.children && !menu.hideChildrenInMenu
|
||||
? this.renderSubMenu(h, menu, pIndex, index)
|
||||
: this.renderMenuItem(h, menu, pIndex, index)
|
||||
}
|
||||
},
|
||||
renderMenu: function (h, menuTree) {
|
||||
const this2_ = this
|
||||
const menuArr = []
|
||||
menuTree.forEach(function (menu, i) {
|
||||
if (!menu.hidden) {
|
||||
menuArr.push(this2_.renderItem(h, menu, '0', i))
|
||||
}
|
||||
})
|
||||
return menuArr
|
||||
},
|
||||
onOpenChange (openKeys) {
|
||||
const latestOpenKey = openKeys.find(key => !this.openKeys.includes(key))
|
||||
if (!this.rootSubmenuKeys.includes(latestOpenKey)) {
|
||||
this.openKeys = openKeys
|
||||
} else {
|
||||
this.openKeys = latestOpenKey ? [latestOpenKey] : []
|
||||
}
|
||||
},
|
||||
updateMenu () {
|
||||
const routes = this.$route.matched.concat()
|
||||
|
||||
if (routes.length >= 4 && this.$route.meta.hidden) {
|
||||
routes.pop()
|
||||
this.selectedKeys = [routes[2].path]
|
||||
} else {
|
||||
this.selectedKeys = [routes.pop().path]
|
||||
}
|
||||
|
||||
const openKeys = []
|
||||
if (this.mode === 'inline') {
|
||||
routes.forEach(item => {
|
||||
openKeys.push(item.path)
|
||||
})
|
||||
}
|
||||
|
||||
this.collapsed ? (this.cachedOpenKeys = openKeys) : (this.openKeys = openKeys)
|
||||
}
|
||||
},
|
||||
render (h) {
|
||||
return h(
|
||||
Menu,
|
||||
{
|
||||
props: {
|
||||
theme: this.$props.theme,
|
||||
mode: this.$props.mode,
|
||||
openKeys: this.openKeys,
|
||||
selectedKeys: this.selectedKeys
|
||||
},
|
||||
on: {
|
||||
openChange: this.onOpenChange,
|
||||
select: obj => {
|
||||
this.selectedKeys = obj.selectedKeys
|
||||
this.$emit('select', obj)
|
||||
}
|
||||
}
|
||||
},
|
||||
this.renderMenu(h, this.menu)
|
||||
)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
<!--
|
||||
<template>
|
||||
<div style="margin: -23px -24px 24px -24px">
|
||||
<!–<a-dropdown :trigger="['contextmenu']" overlayClassName="multi-tab-menu-wrapper">
|
||||
<a-menu slot="overlay">
|
||||
<a-menu-item key="1">1st menu item</a-menu-item>
|
||||
<a-menu-item key="2">2nd menu item</a-menu-item>
|
||||
<a-menu-item key="3">3rd menu item</a-menu-item>
|
||||
</a-menu>
|
||||
</a-dropdown>–>
|
||||
<a-tabs
|
||||
hideAdd
|
||||
v-model="activeKey"
|
||||
type="editable-card"
|
||||
:tabBarStyle="{ background: '#FFF', margin: 0, paddingLeft: '16px', paddingTop: '1px' }"
|
||||
@edit="onEdit"
|
||||
>
|
||||
<a-tab-pane v-for="page in pages" :style="{ height: 0 }" :tab="page.meta.title" :key="page.fullPath" :closable="pages.length > 1">
|
||||
</a-tab-pane>
|
||||
<template slot="renderTabBar" slot-scope="props, DefaultTabBar">
|
||||
<component :is="DefaultTabBar" {...props} />
|
||||
</template>
|
||||
</a-tabs>
|
||||
</div>
|
||||
</template>
|
||||
-->
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'MultiTab',
|
||||
data () {
|
||||
return {
|
||||
fullPathList: [],
|
||||
pages: [],
|
||||
activeKey: '',
|
||||
newTabIndex: 0
|
||||
}
|
||||
},
|
||||
created () {
|
||||
this.pages.push(this.$route)
|
||||
this.fullPathList.push(this.$route.fullPath)
|
||||
this.selectedLastPath()
|
||||
},
|
||||
methods: {
|
||||
onEdit (targetKey, action) {
|
||||
this[action](targetKey)
|
||||
},
|
||||
remove (targetKey) {
|
||||
this.pages = this.pages.filter(page => page.fullPath !== targetKey)
|
||||
this.fullPathList = this.fullPathList.filter(path => path !== targetKey)
|
||||
// 判断当前标签是否关闭,若关闭则跳转到最后一个还存在的标签页
|
||||
if (!this.fullPathList.includes(this.activeKey)) {
|
||||
this.selectedLastPath()
|
||||
}
|
||||
},
|
||||
selectedLastPath () {
|
||||
this.activeKey = this.fullPathList[this.fullPathList.length - 1]
|
||||
},
|
||||
|
||||
// content menu
|
||||
closeThat (e) {
|
||||
this.remove(e)
|
||||
},
|
||||
closeLeft (e) {
|
||||
const currentIndex = this.fullPathList.indexOf(e)
|
||||
if (currentIndex > 0) {
|
||||
this.fullPathList.forEach((item, index) => {
|
||||
if (index < currentIndex) {
|
||||
this.remove(item)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.info('左侧没有标签')
|
||||
}
|
||||
},
|
||||
closeRight (e) {
|
||||
const currentIndex = this.fullPathList.indexOf(e)
|
||||
if (currentIndex < (this.fullPathList.length - 1)) {
|
||||
this.fullPathList.forEach((item, index) => {
|
||||
if (index > currentIndex) {
|
||||
this.remove(item)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.$message.info('右侧没有标签')
|
||||
}
|
||||
},
|
||||
closeAll (e) {
|
||||
const currentIndex = this.fullPathList.indexOf(e)
|
||||
this.fullPathList.forEach((item, index) => {
|
||||
if (index !== currentIndex) {
|
||||
this.remove(item)
|
||||
}
|
||||
})
|
||||
},
|
||||
closeMenuClick ({ key, item, domEvent }) {
|
||||
const vkey = domEvent.target.getAttribute('data-vkey')
|
||||
switch (key) {
|
||||
case 'close-right':
|
||||
this.closeRight(vkey)
|
||||
break
|
||||
case 'close-left':
|
||||
this.closeLeft(vkey)
|
||||
break
|
||||
case 'close-all':
|
||||
this.closeAll(vkey)
|
||||
break
|
||||
default:
|
||||
case 'close-that':
|
||||
this.closeThat(vkey)
|
||||
break
|
||||
}
|
||||
},
|
||||
renderTabPaneMenu (e) {
|
||||
return (
|
||||
<a-menu {...{ on: { click: this.closeMenuClick } }}>
|
||||
<a-menu-item key="close-that" data-vkey={e}>关闭当前标签</a-menu-item>
|
||||
<a-menu-item key="close-right" data-vkey={e}>关闭右侧</a-menu-item>
|
||||
<a-menu-item key="close-left" data-vkey={e}>关闭左侧</a-menu-item>
|
||||
<a-menu-item key="close-all" data-vkey={e}>关闭全部</a-menu-item>
|
||||
</a-menu>
|
||||
)
|
||||
},
|
||||
// render
|
||||
renderTabPane (title, keyPath) {
|
||||
const menu = this.renderTabPaneMenu(keyPath)
|
||||
|
||||
return (
|
||||
<a-dropdown overlay={menu} trigger={['contextmenu']}>
|
||||
<span style={{ userSelect: 'none' }}>{ title }</span>
|
||||
</a-dropdown>
|
||||
)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'$route': function (newVal) {
|
||||
this.activeKey = newVal.fullPath
|
||||
if (this.fullPathList.indexOf(newVal.fullPath) < 0) {
|
||||
this.fullPathList.push(newVal.fullPath)
|
||||
this.pages.push(newVal)
|
||||
}
|
||||
},
|
||||
activeKey: function (newPathKey) {
|
||||
this.$router.push({ path: newPathKey })
|
||||
}
|
||||
},
|
||||
render () {
|
||||
const { onEdit, $data: { pages } } = this
|
||||
const panes = pages.map(page => {
|
||||
return (
|
||||
<a-tab-pane
|
||||
style={{ height: 0 }}
|
||||
tab={this.renderTabPane(page.meta.title, page.fullPath)}
|
||||
key={page.fullPath} closable={pages.length > 1}
|
||||
>
|
||||
</a-tab-pane>)
|
||||
})
|
||||
|
||||
return (
|
||||
<div class="ant-pro-multi-tab">
|
||||
<div class="ant-pro-multi-tab-wrapper">
|
||||
<a-tabs
|
||||
hideAdd
|
||||
type={'editable-card'}
|
||||
v-model={this.activeKey}
|
||||
tabBarStyle={{ background: '#FFF', margin: 0, paddingLeft: '16px', paddingTop: '1px' }}
|
||||
{...{ on: { edit: onEdit } }}>
|
||||
{panes}
|
||||
</a-tabs>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,4 @@
|
|||
import MultiTab from './MultiTab'
|
||||
import './index.less'
|
||||
|
||||
export default MultiTab
|
|
@ -0,0 +1,25 @@
|
|||
@import '../index';
|
||||
|
||||
@multi-tab-prefix-cls: ~"@{ant-pro-prefix}-multi-tab";
|
||||
@multi-tab-wrapper-prefix-cls: ~"@{ant-pro-prefix}-multi-tab-wrapper";
|
||||
|
||||
/*
|
||||
.topmenu .@{multi-tab-prefix-cls} {
|
||||
max-width: 1200px;
|
||||
margin: -23px auto 24px auto;
|
||||
}
|
||||
*/
|
||||
.@{multi-tab-prefix-cls} {
|
||||
margin: -23px -24px 24px -24px;
|
||||
background: #fff;
|
||||
}
|
||||
|
||||
.topmenu .@{multi-tab-wrapper-prefix-cls} {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.topmenu.content-width-Fluid .@{multi-tab-wrapper-prefix-cls} {
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
<template>
|
||||
<a-popover
|
||||
v-model="visible"
|
||||
trigger="click"
|
||||
placement="bottomRight"
|
||||
overlayClassName="header-notice-wrapper"
|
||||
:autoAdjustOverflow="true"
|
||||
:arrowPointAtCenter="true"
|
||||
:overlayStyle="{ width: '300px', top: '50px' }"
|
||||
>
|
||||
<template slot="content">
|
||||
<a-spin :spinning="loadding">
|
||||
<a-tabs>
|
||||
<a-tab-pane tab="通知" key="1">
|
||||
<a-list>
|
||||
<a-list-item>
|
||||
<a-list-item-meta title="你收到了 14 份新周报" description="一年前">
|
||||
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/ThXAXghbEsBCCSDihZxY.png"/>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<a-list-item-meta title="你推荐的 曲妮妮 已通过第三轮面试" description="一年前">
|
||||
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/OKJXDXrmkNshAMvwtvhu.png"/>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<a-list-item-meta title="这种模板可以区分多种通知类型" description="一年前">
|
||||
<a-avatar style="background-color: white" slot="avatar" src="https://gw.alipayobjects.com/zos/rmsportal/kISTdvpyTAhtGxpovNWd.png"/>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="消息" key="2">
|
||||
123
|
||||
</a-tab-pane>
|
||||
<a-tab-pane tab="待办" key="3">
|
||||
123
|
||||
</a-tab-pane>
|
||||
</a-tabs>
|
||||
</a-spin>
|
||||
</template>
|
||||
<span @click="fetchNotice" class="header-notice">
|
||||
<a-badge count="12">
|
||||
<a-icon style="font-size: 16px; padding: 4px" type="bell" />
|
||||
</a-badge>
|
||||
</span>
|
||||
</a-popover>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HeaderNotice',
|
||||
data () {
|
||||
return {
|
||||
loadding: false,
|
||||
visible: false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
fetchNotice () {
|
||||
if (!this.visible) {
|
||||
this.loadding = true
|
||||
setTimeout(() => {
|
||||
this.loadding = false
|
||||
}, 2000)
|
||||
} else {
|
||||
this.loadding = false
|
||||
}
|
||||
this.visible = !this.visible
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css">
|
||||
.header-notice-wrapper {
|
||||
top: 50px !important;
|
||||
}
|
||||
</style>
|
||||
<style lang="less" scoped>
|
||||
.header-notice{
|
||||
display: inline-block;
|
||||
transition: all 0.3s;
|
||||
|
||||
span {
|
||||
vertical-align: initial;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import NoticeIcon from './NoticeIcon'
|
||||
export default NoticeIcon
|
|
@ -0,0 +1,54 @@
|
|||
<template>
|
||||
<div :class="[prefixCls]">
|
||||
<slot name="subtitle">
|
||||
<div :class="[`${prefixCls}-subtitle`]">{{ typeof subTitle === 'string' ? subTitle : subTitle() }}</div>
|
||||
</slot>
|
||||
<div class="number-info-value">
|
||||
<span>{{ total }}</span>
|
||||
<span class="sub-total">
|
||||
{{ subTotal }}
|
||||
<icon :type="`caret-${status}`" />
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Icon from 'ant-design-vue/es/icon'
|
||||
|
||||
export default {
|
||||
name: 'NumberInfo',
|
||||
props: {
|
||||
prefixCls: {
|
||||
type: String,
|
||||
default: 'ant-pro-number-info'
|
||||
},
|
||||
total: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
subTotal: {
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
subTitle: {
|
||||
type: [String, Function],
|
||||
default: ''
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: 'up'
|
||||
}
|
||||
},
|
||||
components: {
|
||||
Icon
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@import "index";
|
||||
</style>
|
|
@ -0,0 +1,3 @@
|
|||
import NumberInfo from './NumberInfo'
|
||||
|
||||
export default NumberInfo
|
|
@ -0,0 +1,55 @@
|
|||
@import "../index";
|
||||
|
||||
@numberInfo-prefix-cls: ~"@{ant-pro-prefix}-number-info";
|
||||
|
||||
.@{numberInfo-prefix-cls} {
|
||||
|
||||
.ant-pro-number-info-subtitle {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-base;
|
||||
height: 22px;
|
||||
line-height: 22px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.number-info-value {
|
||||
margin-top: 4px;
|
||||
font-size: 0;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
word-break: break-all;
|
||||
white-space: nowrap;
|
||||
|
||||
& > span {
|
||||
color: @heading-color;
|
||||
display: inline-block;
|
||||
line-height: 32px;
|
||||
height: 32px;
|
||||
font-size: 24px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
|
||||
.sub-total {
|
||||
color: @text-color-secondary;
|
||||
font-size: @font-size-lg;
|
||||
vertical-align: top;
|
||||
margin-right: 0;
|
||||
i {
|
||||
font-size: 12px;
|
||||
transform: scale(0.82);
|
||||
margin-left: 4px;
|
||||
}
|
||||
:global {
|
||||
.anticon-caret-up {
|
||||
color: @red-6;
|
||||
}
|
||||
.anticon-caret-down {
|
||||
color: @green-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
# NumberInfo 数据文本
|
||||
|
||||
常用在数据卡片中,用于突出展示某个业务数据。
|
||||
|
||||
|
||||
|
||||
引用方式:
|
||||
|
||||
```javascript
|
||||
import NumberInfo from '@/components/NumberInfo'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
NumberInfo
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||
## 代码演示 [demo](https://pro.loacg.com/test/home)
|
||||
|
||||
```html
|
||||
<number-info
|
||||
:sub-title="() => { return 'Visits this week' }"
|
||||
:total="12321"
|
||||
status="up"
|
||||
:sub-total="17.1"></number-info>
|
||||
```
|
||||
|
||||
|
||||
|
||||
## API
|
||||
|
||||
参数 | 说明 | 类型 | 默认值
|
||||
----|------|-----|------
|
||||
title | 标题 | ReactNode\|string | -
|
||||
subTitle | 子标题 | ReactNode\|string | -
|
||||
total | 总量 | ReactNode\|string | -
|
||||
subTotal | 子总量 | ReactNode\|string | -
|
||||
status | 增加状态 | 'up \| down' | -
|
||||
theme | 状态样式 | string | 'light'
|
||||
gap | 设置数字和描述之间的间距(像素)| number | 8
|
|
@ -0,0 +1,202 @@
|
|||
<template>
|
||||
<div class="page-header">
|
||||
<div class="page-header-index-wide">
|
||||
<s-breadcrumb />
|
||||
<div class="detail">
|
||||
<div class="main" v-if="!$route.meta.hiddenHeaderContent">
|
||||
<div class="row">
|
||||
<img v-if="logo" :src="logo" class="logo"/>
|
||||
<h1 v-if="title" class="title">{{ title }}</h1>
|
||||
<div class="action">
|
||||
<slot name="action"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div v-if="avatar" class="avatar">
|
||||
<a-avatar :src="avatar" />
|
||||
</div>
|
||||
<div v-if="this.$slots.content" class="headerContent">
|
||||
<slot name="content"></slot>
|
||||
</div>
|
||||
<div v-if="this.$slots.extra" class="extra">
|
||||
<slot name="extra"></slot>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<slot name="pageMenu"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Breadcrumb from '@/components/tools/Breadcrumb'
|
||||
|
||||
export default {
|
||||
name: 'PageHeader',
|
||||
components: {
|
||||
's-breadcrumb': Breadcrumb
|
||||
},
|
||||
props: {
|
||||
title: {
|
||||
type: [String, Boolean],
|
||||
default: true,
|
||||
required: false
|
||||
},
|
||||
logo: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
},
|
||||
avatar: {
|
||||
type: String,
|
||||
default: '',
|
||||
required: false
|
||||
}
|
||||
},
|
||||
data () {
|
||||
return {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.page-header {
|
||||
background: #fff;
|
||||
padding: 16px 32px 0;
|
||||
border-bottom: 1px solid #e8e8e8;
|
||||
|
||||
.breadcrumb {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.detail {
|
||||
display: flex;
|
||||
/*margin-bottom: 16px;*/
|
||||
|
||||
.avatar {
|
||||
flex: 0 1 72px;
|
||||
margin: 0 24px 8px 0;
|
||||
|
||||
& > span {
|
||||
border-radius: 72px;
|
||||
display: block;
|
||||
width: 72px;
|
||||
height: 72px;
|
||||
}
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 100%;
|
||||
flex: 0 1 auto;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.avatar {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 20px;
|
||||
font-weight: 500;
|
||||
|
||||
font-size: 20px;
|
||||
line-height: 28px;
|
||||
font-weight: 500;
|
||||
color: rgba(0, 0, 0, 0.85);
|
||||
margin-bottom: 16px;
|
||||
flex: auto;
|
||||
}
|
||||
.logo {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
border-radius: 4px;
|
||||
margin-right: 16px;
|
||||
}
|
||||
.content,
|
||||
.headerContent {
|
||||
flex: auto;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
line-height: 22px;
|
||||
|
||||
.link {
|
||||
margin-top: 16px;
|
||||
line-height: 24px;
|
||||
|
||||
a {
|
||||
font-size: 14px;
|
||||
margin-right: 32px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.extra {
|
||||
flex: 0 1 auto;
|
||||
margin-left: 88px;
|
||||
min-width: 242px;
|
||||
text-align: right;
|
||||
}
|
||||
.action {
|
||||
margin-left: 56px;
|
||||
min-width: 266px;
|
||||
flex: 0 1 auto;
|
||||
text-align: right;
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.mobile .page-header {
|
||||
.main {
|
||||
.row {
|
||||
flex-wrap: wrap;
|
||||
|
||||
.avatar {
|
||||
flex: 0 1 25%;
|
||||
margin: 0 2% 8px 0;
|
||||
}
|
||||
|
||||
.content,
|
||||
.headerContent {
|
||||
flex: 0 1 70%;
|
||||
|
||||
.link {
|
||||
margin-top: 16px;
|
||||
line-height: 24px;
|
||||
|
||||
a {
|
||||
font-size: 14px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.extra {
|
||||
flex: 1 1 auto;
|
||||
margin-left: 0;
|
||||
min-width: 0;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.action {
|
||||
margin-left: unset;
|
||||
min-width: 266px;
|
||||
flex: 0 1 auto;
|
||||
text-align: left;
|
||||
margin-bottom: 12px;
|
||||
|
||||
&:empty {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import PageHeader from './PageHeader'
|
||||
export default PageHeader
|
|
@ -0,0 +1,10 @@
|
|||
import { Spin } from 'ant-design-vue'
|
||||
|
||||
export default {
|
||||
name: 'PageLoading',
|
||||
render () {
|
||||
return (<div style={{ paddingTop: 100, textAlign: 'center' }}>
|
||||
<Spin size="large" />
|
||||
</div>)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<div class="result">
|
||||
<div>
|
||||
<a-icon :class="{ 'icon': true, [`${type}`]: true }" :type="localIsSuccess ? 'check-circle' : 'close-circle'"/>
|
||||
</div>
|
||||
<div class="title">
|
||||
<slot name="title">
|
||||
{{ title }}
|
||||
</slot>
|
||||
</div>
|
||||
<div class="description">
|
||||
<slot name="description">
|
||||
{{ description }}
|
||||
</slot>
|
||||
</div>
|
||||
<div class="extra" v-if="$slots.default">
|
||||
<slot></slot>
|
||||
</div>
|
||||
<div class="action" v-if="$slots.action">
|
||||
<slot name="action"></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const resultEnum = ['success', 'error']
|
||||
|
||||
export default {
|
||||
name: 'Result',
|
||||
props: {
|
||||
/** @Deprecated */
|
||||
isSuccess: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
default: resultEnum[0],
|
||||
validator (val) {
|
||||
return (val) => resultEnum.includes(val)
|
||||
}
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
localIsSuccess: function () {
|
||||
return this.type === resultEnum[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.result {
|
||||
text-align: center;
|
||||
width: 72%;
|
||||
margin: 0 auto;
|
||||
padding: 24px 0 8px;
|
||||
|
||||
.icon {
|
||||
font-size: 72px;
|
||||
line-height: 72px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.success {
|
||||
color: #52c41a;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
.title {
|
||||
font-size: 24px;
|
||||
color: rgba(0, 0, 0, .85);
|
||||
font-weight: 500;
|
||||
line-height: 32px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.description {
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: rgba(0, 0, 0, 0.45);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.extra {
|
||||
background: #fafafa;
|
||||
padding: 24px 40px;
|
||||
border-radius: 2px;
|
||||
text-align: left;
|
||||
}
|
||||
.action {
|
||||
margin-top: 32px;
|
||||
}
|
||||
}
|
||||
|
||||
.mobile {
|
||||
.result {
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
padding: unset;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import Result from './Result.vue'
|
||||
export default Result
|
|
@ -0,0 +1,372 @@
|
|||
<template>
|
||||
<div class="setting-drawer" ref="settingDrawer">
|
||||
<a-drawer
|
||||
width="300"
|
||||
placement="right"
|
||||
@close="onClose"
|
||||
:closable="false"
|
||||
:visible="visible"
|
||||
:getContainer="() => $refs.settingDrawer"
|
||||
:style="{}"
|
||||
>
|
||||
<div class="setting-drawer-index-content">
|
||||
|
||||
<div :style="{ marginBottom: '24px' }">
|
||||
<h3 class="setting-drawer-index-title">Overall Style</h3>
|
||||
|
||||
<div class="setting-drawer-index-blockChecbox">
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
Dark Menu Style
|
||||
</template>
|
||||
<div class="setting-drawer-index-item" @click="handleMenuTheme('dark')">
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/LCkqqYNmvBEbokSDscrm.svg" alt="dark">
|
||||
<div class="setting-drawer-index-selectIcon" v-if="navTheme === 'dark'">
|
||||
<a-icon type="check"/>
|
||||
</div>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
Light Menu Style
|
||||
</template>
|
||||
<div class="setting-drawer-index-item" @click="handleMenuTheme('light')">
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/jpRkZQMyYRryryPNtyIC.svg" alt="light">
|
||||
<div class="setting-drawer-index-selectIcon" v-if="navTheme !== 'dark'">
|
||||
<a-icon type="check"/>
|
||||
</div>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div :style="{ marginBottom: '24px' }">
|
||||
<h3 class="setting-drawer-index-title">Theme Color</h3>
|
||||
|
||||
<div style="height: 20px">
|
||||
<a-tooltip class="setting-drawer-theme-color-colorBlock" v-for="(item, index) in colorList" :key="index">
|
||||
<template slot="title">
|
||||
{{ item.key }}
|
||||
</template>
|
||||
<a-tag :color="item.color" @click="changeColor(item.color)">
|
||||
<a-icon type="check" v-if="item.color === primaryColor"></a-icon>
|
||||
</a-tag>
|
||||
</a-tooltip>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<a-divider />
|
||||
|
||||
<div :style="{ marginBottom: '24px' }">
|
||||
<h3 class="setting-drawer-index-title">Navigation Mode</h3>
|
||||
|
||||
<div class="setting-drawer-index-blockChecbox">
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
Sidebar Navigation
|
||||
</template>
|
||||
<div class="setting-drawer-index-item" @click="handleLayout('sidemenu')">
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/JopDzEhOqwOjeNTXkoje.svg" alt="sidemenu">
|
||||
<div class="setting-drawer-index-selectIcon" v-if="layoutMode === 'sidemenu'">
|
||||
<a-icon type="check"/>
|
||||
</div>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
|
||||
<a-tooltip>
|
||||
<template slot="title">
|
||||
Top Bar Navigation
|
||||
</template>
|
||||
<div class="setting-drawer-index-item" @click="handleLayout('topmenu')">
|
||||
<img src="https://gw.alipayobjects.com/zos/rmsportal/KDNDBbriJhLwuqMoxcAr.svg" alt="topmenu">
|
||||
<div class="setting-drawer-index-selectIcon" v-if="layoutMode !== 'sidemenu'">
|
||||
<a-icon type="check"/>
|
||||
</div>
|
||||
</div>
|
||||
</a-tooltip>
|
||||
</div>
|
||||
<div :style="{ marginTop: '24px' }">
|
||||
<a-list :split="false">
|
||||
<a-list-item>
|
||||
<a-tooltip slot="actions">
|
||||
<template slot="title">
|
||||
This setting is valid only for top bar navigation]
|
||||
</template>
|
||||
<a-select size="small" style="width: 80px;" :defaultValue="contentWidth" @change="handleContentWidthChange">
|
||||
<a-select-option value="Fixed">Fixed</a-select-option>
|
||||
<a-select-option value="Fluid" v-if="layoutMode !== 'sidemenu'">Fluid</a-select-option>
|
||||
</a-select>
|
||||
</a-tooltip>
|
||||
<a-list-item-meta>
|
||||
<div slot="title">Content Area Width</div>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<a-switch slot="actions" size="small" :defaultChecked="fixedHeader" @change="handleFixedHeader" />
|
||||
<a-list-item-meta>
|
||||
<div slot="title">fixed header</div>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<a-switch slot="actions" size="small" :disabled="!fixedHeader" :defaultChecked="autoHideHeader" @change="handleFixedHeaderHidden" />
|
||||
<a-list-item-meta>
|
||||
<a-tooltip slot="title" placement="left">
|
||||
<template slot="title">Hide header when sliding</template>
|
||||
<div :style="{ opacity: !fixedHeader ? '0.5' : '1' }">Hide header when scrolling down</div>
|
||||
</a-tooltip>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
<a-list-item >
|
||||
<a-switch slot="actions" size="small" :disabled="(layoutMode === 'topmenu')" :defaultChecked="fixSiderbar" @change="handleFixSiderbar" />
|
||||
<a-list-item-meta>
|
||||
<div slot="title" :style="{ textDecoration: layoutMode === 'topmenu' ? 'line-through' : 'unset' }">Fixed side menu</div>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider />
|
||||
|
||||
<div :style="{ marginBottom: '24px' }">
|
||||
<h3 class="setting-drawer-index-title">Other Settings</h3>
|
||||
<div>
|
||||
<a-list :split="false">
|
||||
<a-list-item>
|
||||
<a-switch slot="actions" size="small" :defaultChecked="colorWeak" @change="onColorWeak" />
|
||||
<a-list-item-meta>
|
||||
<div slot="title">Night Mode</div>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
<a-list-item>
|
||||
<a-switch slot="actions" size="small" :defaultChecked="multiTab" @change="onMultiTab" />
|
||||
<a-list-item-meta>
|
||||
<div slot="title">Multi-Page Mode</div>
|
||||
</a-list-item-meta>
|
||||
</a-list-item>
|
||||
</a-list>
|
||||
</div>
|
||||
</div>
|
||||
<a-divider />
|
||||
<div :style="{ marginBottom: '24px' }">
|
||||
<a-button
|
||||
@click="doCopy"
|
||||
icon="copy"
|
||||
block
|
||||
>Copy Settings</a-button>
|
||||
<a-alert type="warning" :style="{ marginTop: '24px' }">
|
||||
<span slot="message">
|
||||
The configuration bar is only used in the development environment for preview,
|
||||
the production environment will not be displayed,
|
||||
please manually modify the configuration file.
|
||||
<a href="https://github.com/sendya/ant-design-pro-vue/blob/master/src/config/defaultSettings.js" target="_blank">src/config/defaultSettings.js</a>
|
||||
</span>
|
||||
</a-alert>
|
||||
</div>
|
||||
</div>
|
||||
<div class="setting-drawer-index-handle" @click="toggle">
|
||||
<a-icon type="setting" v-if="!visible"/>
|
||||
<a-icon type="close" v-else/>
|
||||
</div>
|
||||
</a-drawer>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { DetailList } from '@/components'
|
||||
import SettingItem from './SettingItem'
|
||||
import config from '@/config/defaultSettings'
|
||||
import { updateTheme, updateColorWeak, colorList } from './settingConfig'
|
||||
import { mixin, mixinDevice } from '@/utils/mixin'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
DetailList,
|
||||
SettingItem
|
||||
},
|
||||
mixins: [mixin, mixinDevice],
|
||||
data () {
|
||||
return {
|
||||
visible: true,
|
||||
colorList,
|
||||
baseConfig: Object.assign({}, config)
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
mounted () {
|
||||
const vm = this
|
||||
setTimeout(() => {
|
||||
vm.visible = false
|
||||
}, 16)
|
||||
// 当主题色不是默认色时,才进行主题编译
|
||||
if (this.primaryColor !== config.primaryColor) {
|
||||
updateTheme(this.primaryColor)
|
||||
}
|
||||
if (this.colorWeak !== config.colorWeak) {
|
||||
updateColorWeak(this.colorWeak)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showDrawer () {
|
||||
this.visible = true
|
||||
},
|
||||
onClose () {
|
||||
this.visible = false
|
||||
},
|
||||
toggle () {
|
||||
this.visible = !this.visible
|
||||
},
|
||||
onColorWeak (checked) {
|
||||
this.baseConfig.colorWeak = checked
|
||||
this.$store.dispatch('ToggleWeak', checked)
|
||||
updateColorWeak(checked)
|
||||
},
|
||||
onMultiTab (checked) {
|
||||
this.baseConfig.multiTab = checked
|
||||
this.$store.dispatch('ToggleMultiTab', checked)
|
||||
},
|
||||
handleMenuTheme (theme) {
|
||||
this.baseConfig.navTheme = theme
|
||||
this.$store.dispatch('ToggleTheme', theme)
|
||||
},
|
||||
doCopy () {
|
||||
const text = `export default {
|
||||
primaryColor: '${this.baseConfig.primaryColor}', // primary color of ant design
|
||||
navTheme: '${this.baseConfig.navTheme}', // theme for nav menu
|
||||
layout: '${this.baseConfig.layout}', // nav menu position: sidemenu or topmenu
|
||||
contentWidth: '${this.baseConfig.contentWidth}', // layout of content: Fluid or Fixed, only works when layout is topmenu
|
||||
fixedHeader: ${this.baseConfig.fixedHeader}, // sticky header
|
||||
fixSiderbar: ${this.baseConfig.fixSiderbar}, // sticky siderbar
|
||||
autoHideHeader: ${this.baseConfig.autoHideHeader}, // auto hide header
|
||||
colorWeak: ${this.baseConfig.colorWeak},
|
||||
multiTab: ${this.baseConfig.multiTab},
|
||||
production: process.env.NODE_ENV === 'production' && process.env.VUE_APP_PREVIEW !== 'true',
|
||||
// vue-ls options
|
||||
storageOptions: {
|
||||
namespace: 'pro__',
|
||||
name: 'ls',
|
||||
storage: 'local',
|
||||
}
|
||||
}`
|
||||
this.$copyText(text).then(message => {
|
||||
console.log('copy', message)
|
||||
this.$message.success('复制完毕')
|
||||
}).catch(err => {
|
||||
console.log('copy.err', err)
|
||||
this.$message.error('复制失败')
|
||||
})
|
||||
},
|
||||
handleLayout (mode) {
|
||||
this.baseConfig.layout = mode
|
||||
this.$store.dispatch('ToggleLayoutMode', mode)
|
||||
// 因为顶部菜单不能固定左侧菜单栏,所以强制关闭
|
||||
//
|
||||
this.handleFixSiderbar(false)
|
||||
},
|
||||
handleContentWidthChange (type) {
|
||||
this.baseConfig.contentWidth = type
|
||||
this.$store.dispatch('ToggleContentWidth', type)
|
||||
},
|
||||
changeColor (color) {
|
||||
this.baseConfig.primaryColor = color
|
||||
if (this.primaryColor !== color) {
|
||||
this.$store.dispatch('ToggleColor', color)
|
||||
updateTheme(color)
|
||||
}
|
||||
},
|
||||
handleFixedHeader (fixed) {
|
||||
this.baseConfig.fixedHeader = fixed
|
||||
this.$store.dispatch('ToggleFixedHeader', fixed)
|
||||
},
|
||||
handleFixedHeaderHidden (autoHidden) {
|
||||
this.baseConfig.autoHideHeader = autoHidden
|
||||
this.$store.dispatch('ToggleFixedHeaderHidden', autoHidden)
|
||||
},
|
||||
handleFixSiderbar (fixed) {
|
||||
if (this.layoutMode === 'topmenu') {
|
||||
this.baseConfig.fixSiderbar = false
|
||||
this.$store.dispatch('ToggleFixSiderbar', false)
|
||||
return
|
||||
}
|
||||
this.baseConfig.fixSiderbar = fixed
|
||||
this.$store.dispatch('ToggleFixSiderbar', fixed)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.setting-drawer-index-content {
|
||||
|
||||
.setting-drawer-index-blockChecbox {
|
||||
display: flex;
|
||||
|
||||
.setting-drawer-index-item {
|
||||
margin-right: 16px;
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
|
||||
img {
|
||||
width: 48px;
|
||||
}
|
||||
|
||||
.setting-drawer-index-selectIcon {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
width: 100%;
|
||||
padding-top: 15px;
|
||||
padding-left: 24px;
|
||||
height: 100%;
|
||||
color: #1890ff;
|
||||
font-size: 14px;
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
.setting-drawer-theme-color-colorBlock {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
border-radius: 2px;
|
||||
float: left;
|
||||
cursor: pointer;
|
||||
margin-right: 8px;
|
||||
padding-left: 0px;
|
||||
padding-right: 0px;
|
||||
text-align: center;
|
||||
color: #fff;
|
||||
font-weight: 700;
|
||||
|
||||
i {
|
||||
font-size: 14px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting-drawer-index-handle {
|
||||
position: absolute;
|
||||
top: 240px;
|
||||
background: #1890ff;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
right: 300px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
pointer-events: auto;
|
||||
z-index: 1001;
|
||||
text-align: center;
|
||||
font-size: 16px;
|
||||
border-radius: 4px 0 0 4px;
|
||||
|
||||
i {
|
||||
color: rgb(255, 255, 255);
|
||||
font-size: 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,38 @@
|
|||
<template>
|
||||
<div class="setting-drawer-index-item">
|
||||
<h3 class="setting-drawer-index-title">{{ title }}</h3>
|
||||
<slot></slot>
|
||||
<a-divider v-if="divider"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'SettingItem',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
divider: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
.setting-drawer-index-item {
|
||||
margin-bottom: 24px;
|
||||
|
||||
.setting-drawer-index-title {
|
||||
font-size: 14px;
|
||||
color: rgba(0, 0, 0, .85);
|
||||
line-height: 22px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,2 @@
|
|||
import SettingDrawer from './SettingDrawer'
|
||||
export default SettingDrawer
|
|
@ -0,0 +1,95 @@
|
|||
import { message } from 'ant-design-vue/es'
|
||||
// import defaultSettings from '../defaultSettings';
|
||||
|
||||
let lessNodesAppended
|
||||
|
||||
const colorList = [
|
||||
{
|
||||
key: 'dusk', color: '#F5222D'
|
||||
},
|
||||
{
|
||||
key: 'volcanic', color: '#FA541C'
|
||||
},
|
||||
{
|
||||
key: 'sundial', color: '#FAAD14'
|
||||
},
|
||||
{
|
||||
key: 'mingqing', color: '#13C2C2'
|
||||
},
|
||||
{
|
||||
key: 'aurora green', color: '#52C41A'
|
||||
},
|
||||
{
|
||||
key: 'light blue', color: '#1890FF'
|
||||
},
|
||||
{
|
||||
key: 'blue', color: '#2F54EB'
|
||||
},
|
||||
{
|
||||
key: 'purple', color: '#722ED1'
|
||||
}
|
||||
]
|
||||
|
||||
const updateTheme = primaryColor => {
|
||||
// Don't compile less in production!
|
||||
/* if (process.env.NODE_ENV === 'production') {
|
||||
return;
|
||||
} */
|
||||
// Determine if the component is remounted
|
||||
if (!primaryColor) {
|
||||
return
|
||||
}
|
||||
const hideMessage = message.loading('Compiling theme!', 0)
|
||||
function buildIt () {
|
||||
if (!window.less) {
|
||||
return
|
||||
}
|
||||
setTimeout(() => {
|
||||
window.less
|
||||
.modifyVars({
|
||||
'@primary-color': primaryColor
|
||||
})
|
||||
.then(() => {
|
||||
hideMessage()
|
||||
})
|
||||
.catch(() => {
|
||||
message.error('Failed to update theme')
|
||||
hideMessage()
|
||||
})
|
||||
}, 200)
|
||||
}
|
||||
if (!lessNodesAppended) {
|
||||
// insert less.js and color.less
|
||||
const lessStyleNode = document.createElement('link')
|
||||
const lessConfigNode = document.createElement('script')
|
||||
const lessScriptNode = document.createElement('script')
|
||||
lessStyleNode.setAttribute('rel', 'stylesheet/less')
|
||||
lessStyleNode.setAttribute('href', '/color.less')
|
||||
lessConfigNode.innerHTML = `
|
||||
window.less = {
|
||||
async: true,
|
||||
env: 'production',
|
||||
javascriptEnabled: true
|
||||
};
|
||||
`
|
||||
lessScriptNode.src = 'https://gw.alipayobjects.com/os/lib/less.js/3.8.1/less.min.js'
|
||||
lessScriptNode.async = true
|
||||
lessScriptNode.onload = () => {
|
||||
buildIt()
|
||||
lessScriptNode.onload = null
|
||||
}
|
||||
document.body.appendChild(lessStyleNode)
|
||||
document.body.appendChild(lessConfigNode)
|
||||
document.body.appendChild(lessScriptNode)
|
||||
lessNodesAppended = true
|
||||
} else {
|
||||
buildIt()
|
||||
}
|
||||
}
|
||||
|
||||
const updateColorWeak = colorWeak => {
|
||||
// document.body.className = colorWeak ? 'colorWeak' : '';
|
||||
colorWeak ? document.body.classList.add('colorWeak') : document.body.classList.remove('colorWeak')
|
||||
}
|
||||
|
||||
export { updateTheme, colorList, updateColorWeak }
|