@ -0,0 +1,5 @@ |
|||||
|
|
||||
|
# port |
||||
|
VITE_PORT = 8100 |
||||
|
|
||||
|
|
||||
@ -0,0 +1,5 @@ |
|||||
|
# 本地环境 |
||||
|
NODE_ENV = 'development' |
||||
|
|
||||
|
# 本地环境接口地址 |
||||
|
VUE_APP_BASE_API = '/api' |
||||
@ -0,0 +1,5 @@ |
|||||
|
# 线上环境 |
||||
|
NODE_ENV = "production" |
||||
|
|
||||
|
# 线上环境接口地址 |
||||
|
VUE_APP_BASE_API = '/api' |
||||
@ -0,0 +1,6 @@ |
|||||
|
# 测试环境 |
||||
|
NODE_ENV = "test" |
||||
|
|
||||
|
|
||||
|
# 测试环境接口地址 |
||||
|
VUE_APP_BASE_API = '/api' |
||||
@ -0,0 +1,15 @@ |
|||||
|
|
||||
|
*.sh |
||||
|
node_modules |
||||
|
*.md |
||||
|
*.woff |
||||
|
*.ttf |
||||
|
.vscode |
||||
|
.idea |
||||
|
dist |
||||
|
/public |
||||
|
/docs |
||||
|
.husky |
||||
|
.local |
||||
|
/bin |
||||
|
Dockerfile |
||||
@ -0,0 +1,25 @@ |
|||||
|
module.exports = { |
||||
|
"env": { |
||||
|
"browser": true, |
||||
|
"es2021": true, |
||||
|
"node":true |
||||
|
}, |
||||
|
"extends": [ |
||||
|
"eslint:recommended", |
||||
|
"plugin:vue/vue3-essential", |
||||
|
"plugin:@typescript-eslint/recommended", |
||||
|
'plugin:prettier/recommended' |
||||
|
], |
||||
|
"parser": "vue-eslint-parser", |
||||
|
"parserOptions": { |
||||
|
"ecmaVersion": "latest", |
||||
|
"parser": "@typescript-eslint/parser", |
||||
|
"sourceType": "module" |
||||
|
}, |
||||
|
"plugins": [ |
||||
|
"vue", |
||||
|
"@typescript-eslint" |
||||
|
], |
||||
|
"rules": { |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,9 @@ |
|||||
|
/dist/* |
||||
|
.local |
||||
|
.output.js |
||||
|
/node_modules/** |
||||
|
|
||||
|
**/*.svg |
||||
|
**/*.sh |
||||
|
|
||||
|
/public/* |
||||
@ -0,0 +1,122 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en" > |
||||
|
<head> |
||||
|
<meta charset="UTF-8" /> |
||||
|
<link rel="icon" href="/favicon.ico"> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
|
<title>Vue admin perfect</title> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div id="app"> |
||||
|
<style> |
||||
|
.first-loading-wrp { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
height: 90vh; |
||||
|
min-height: 90vh; |
||||
|
} |
||||
|
.first-loading-wrp > h1 { |
||||
|
font-size: 30px; |
||||
|
font-weight: bolder; |
||||
|
} |
||||
|
.first-loading-wrp .loading-wrp { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 98px; |
||||
|
} |
||||
|
.dot { |
||||
|
position: relative; |
||||
|
box-sizing: border-box; |
||||
|
display: inline-block; |
||||
|
width: 64px; |
||||
|
height: 64px; |
||||
|
font-size: 64px; |
||||
|
transform: rotate(45deg); |
||||
|
animation: antRotate 1.2s infinite linear; |
||||
|
} |
||||
|
|
||||
|
.dot i { |
||||
|
position: absolute; |
||||
|
display: block; |
||||
|
width: 28px; |
||||
|
height: 28px; |
||||
|
background-color: #1890ff; |
||||
|
border-radius: 100%; |
||||
|
opacity: 0.3; |
||||
|
transform: scale(0.75); |
||||
|
transform-origin: 50% 50%; |
||||
|
animation: antSpinMove 1s infinite linear alternate; |
||||
|
} |
||||
|
|
||||
|
.dot i:nth-child(1) { |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
.dot i:nth-child(2) { |
||||
|
top: 0; |
||||
|
right: 0; |
||||
|
-webkit-animation-delay: 0.4s; |
||||
|
animation-delay: 0.4s; |
||||
|
} |
||||
|
|
||||
|
.dot i:nth-child(3) { |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
-webkit-animation-delay: 0.8s; |
||||
|
animation-delay: 0.8s; |
||||
|
} |
||||
|
|
||||
|
.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> |
||||
|
<div id="vue-admin-perfect"> |
||||
|
<div class="first-loading-wrp"> |
||||
|
<div class="loading-wrp"> |
||||
|
<span class="dot dot-spin"> |
||||
|
<i></i> |
||||
|
<i></i> |
||||
|
<i></i> |
||||
|
<i></i> |
||||
|
</span> |
||||
|
</div> |
||||
|
<h1>vue-admin-perfect</h1> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<script type="module" src="/src/main.ts"></script> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,81 @@ |
|||||
|
{ |
||||
|
"name": "vue-admin-perfect", |
||||
|
"private": true, |
||||
|
"version": "0.0.0", |
||||
|
"scripts": { |
||||
|
"dev": "vite", |
||||
|
"build:dev": "vite build --mode development", |
||||
|
"build:test": "vite build --mode test", |
||||
|
"build:prod": "vite build --mode production", |
||||
|
"build": "vite build", |
||||
|
"preview": "vite preview", |
||||
|
"build:ts": "vue-tsc --noEmit --skipLibCheck && vite build", |
||||
|
"lint": "eslint . --ext .vue,.js,.ts,.jsx,.tsx --fix", |
||||
|
"lint:prettier": "prettier --write \"src/**/*.{js,json,tsx,css,less,scss,vue,html,md}\"" |
||||
|
}, |
||||
|
"dependencies": { |
||||
|
"@better-scroll/core": "^2.4.2", |
||||
|
"@vueuse/core": "^9.1.1", |
||||
|
"@wangeditor/editor": "^5.1.14", |
||||
|
"@wangeditor/editor-for-vue": "^5.1.12", |
||||
|
"axios": "^0.27.2", |
||||
|
"clipboard": "^2.0.10", |
||||
|
"codemirror": "^5.65.9", |
||||
|
"core-js": "^3.6.5", |
||||
|
"dayjs": "^1.11.4", |
||||
|
"default-passive-events": "^2.0.0", |
||||
|
"echarts": "^5.3.1", |
||||
|
"echarts-liquidfill": "^3.1.0", |
||||
|
"element-plus": "^2.2.21", |
||||
|
"exceljs": "^4.3.0", |
||||
|
"file-saver": "^2.0.5", |
||||
|
"fuse.js": "^6.6.2", |
||||
|
"jszip": "^3.9.1", |
||||
|
"mavon-editor": "^2.10.4", |
||||
|
"md-editor-v3": "^1.11.3", |
||||
|
"nprogress": "^0.2.0", |
||||
|
"path-browserify": "^1.0.1", |
||||
|
"path-to-regexp": "^6.2.0", |
||||
|
"pinia": "^2.0.21", |
||||
|
"pinia-persistedstate-plugin": "^0.1.0", |
||||
|
"pinia-plugin-persistedstate": "^2.1.1", |
||||
|
"print-js": "^1.6.0", |
||||
|
"sass": "^1.54.0", |
||||
|
"splitpanes": "^3.1.1", |
||||
|
"svg-sprite-loader": "^6.0.11", |
||||
|
"vue": "^3.2.39", |
||||
|
"vue-cropper": "^1.0.3", |
||||
|
"vue-cropperjs": "^5.0.0", |
||||
|
"vue-fuse": "^4.1.1", |
||||
|
"vue-mugen-scroll": "^0.2.6", |
||||
|
"vue-qr": "^4.0.6", |
||||
|
"vue-router": "^4.1.6", |
||||
|
"vue-splitpane": "^1.0.6", |
||||
|
"vuedraggable": "^4.1.0", |
||||
|
"vuex": "^4.0.0-0", |
||||
|
"xlsx": "^0.18.5" |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"@typescript-eslint/eslint-plugin": "^5.32.0", |
||||
|
"@typescript-eslint/parser": "^5.32.0", |
||||
|
"@vitejs/plugin-vue": "^3.0.0", |
||||
|
"consola": "^2.15.3", |
||||
|
"dart-sass": "^1.25.0", |
||||
|
"eslint": "^8.21.0", |
||||
|
"eslint-config-prettier": "^8.5.0", |
||||
|
"eslint-plugin-prettier": "^4.2.1", |
||||
|
"eslint-plugin-vue": "^9.3.0", |
||||
|
"fast-glob": "^3.2.11", |
||||
|
"prettier": "^2.7.1", |
||||
|
"typescript": "^4.6.4", |
||||
|
"unplugin-auto-import": "^0.10.3", |
||||
|
"unplugin-vue-components": "^0.21.2", |
||||
|
"unplugin-vue-define-options": "^0.7.3", |
||||
|
"vite": "^3.0.0", |
||||
|
"vite-plugin-compression": "^0.5.1", |
||||
|
"vite-plugin-style-import": "^2.0.0", |
||||
|
"vite-plugin-svg-icons": "^2.0.1", |
||||
|
"vite-plugin-vue-setup-extend": "^0.4.0", |
||||
|
"vue-tsc": "^0.38.4" |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,14 @@ |
|||||
|
module.exports = { |
||||
|
// 一行的字符数,如果超过会进行换行,默认为80
|
||||
|
printWidth: 100, |
||||
|
// 行位是否使用分号,默认为true
|
||||
|
semi: false, |
||||
|
vueIndentScriptAndStyle: true, |
||||
|
// 字符串是否使用单引号,默认为false,使用双引号
|
||||
|
singleQuote: true, |
||||
|
// 是否使用尾逗号,有三个可选值"<none|es5|all>"
|
||||
|
trailingComma: 'all', |
||||
|
proseWrap: 'never', |
||||
|
htmlWhitespaceSensitivity: 'strict', |
||||
|
endOfLine: 'auto', |
||||
|
}; |
||||
|
After Width: | Height: | Size: 4.2 KiB |
@ -0,0 +1,17 @@ |
|||||
|
<!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="/favicon.ico"> |
||||
|
<title><%= htmlWebpackPlugin.options.title %></title> |
||||
|
</head> |
||||
|
<body> |
||||
|
<noscript> |
||||
|
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong> |
||||
|
</noscript> |
||||
|
<div id="app"></div> |
||||
|
<!-- built files will be auto injected --> |
||||
|
</body> |
||||
|
</html> |
||||
|
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,37 @@ |
|||||
|
<template> |
||||
|
<el-config-provider :size="globalComSize" :locale="zhCn"> |
||||
|
<router-view></router-view> |
||||
|
</el-config-provider> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import {computed} from "vue"; |
||||
|
import {useSettingStore} from "@/store/modules/setting" |
||||
|
// 配置element中文 |
||||
|
import zhCn from 'element-plus/es/locale/lang/zh-cn' |
||||
|
|
||||
|
const SettingStore = useSettingStore() |
||||
|
// 配置全局组件大小 |
||||
|
const globalComSize = computed(():string=>SettingStore.themeConfig.globalComSize) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss"> |
||||
|
#app { |
||||
|
position: relative; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
font-family: Avenir, sans-serif; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
color: #2c3e50; |
||||
|
} |
||||
|
.el-pager li:focus { |
||||
|
border: none; |
||||
|
} |
||||
|
.el-dropdown:focus { |
||||
|
border: none; |
||||
|
} |
||||
|
.svg-icon:focus { |
||||
|
border: none; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,108 @@ |
|||||
|
``` |
||||
|
export interface AxiosRequestConfig { |
||||
|
// `url` 是用于请求的服务器 URL |
||||
|
url?: string; |
||||
|
|
||||
|
// `method` 是创建请求时使用的方法 |
||||
|
method?: Method; |
||||
|
|
||||
|
// `baseURL` 将自动加在 `url` 前面,除非 `url` 是一个绝对 URL。 |
||||
|
// 它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL |
||||
|
baseURL?: string; |
||||
|
|
||||
|
// `transformRequest` 允许在向服务器发送前,修改请求数据 |
||||
|
// 只能用在 'PUT', 'POST' 和 'PATCH' 这几个请求方法 |
||||
|
// 后面数组中的函数必须返回一个字符串,或 ArrayBuffer,或 Stream |
||||
|
transformRequest?: AxiosTransformer | AxiosTransformer[]; |
||||
|
|
||||
|
// `transformResponse` 在传递给 then/catch 前,允许修改响应数据 |
||||
|
transformResponse?: AxiosTransformer | AxiosTransformer[]; |
||||
|
|
||||
|
// `headers` 是即将被发送的自定义请求头 |
||||
|
headers?: any; |
||||
|
|
||||
|
// `params` 是即将与请求一起发送的 URL 参数 |
||||
|
// 必须是一个无格式对象(plain object)或 URLSearchParams 对象 |
||||
|
params?: any; |
||||
|
|
||||
|
// `paramsSerializer` 是一个负责 `params` 序列化的函数 |
||||
|
paramsSerializer?: (params: any) => string; |
||||
|
|
||||
|
// `data` 是作为请求主体被发送的数据 |
||||
|
// 只适用于这些请求方法 'PUT', 'POST', 和 'PATCH' |
||||
|
// 在没有设置 `transformRequest` 时,必须是以下类型之一: |
||||
|
// - string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams |
||||
|
// - 浏览器专属:FormData, File, Blob |
||||
|
// - Node 专属: Stream |
||||
|
data?: any; |
||||
|
|
||||
|
// `timeout` 指定请求超时的毫秒数(0 表示无超时时间) |
||||
|
// 如果请求话费了超过 `timeout` 的时间,请求将被中断 |
||||
|
timeout?: number; |
||||
|
|
||||
|
// 超时提示消息 |
||||
|
timeoutErrorMessage?: string; |
||||
|
|
||||
|
// `withCredentials` 表示跨域请求时是否需要使用凭证 |
||||
|
withCredentials?: boolean; |
||||
|
|
||||
|
// `adapter` 允许自定义处理请求,以使测试更轻松 |
||||
|
adapter?: AxiosAdapter; |
||||
|
|
||||
|
// `auth` 表示应该使用 HTTP 基础验证,并提供凭据 |
||||
|
auth?: AxiosBasicCredentials; |
||||
|
|
||||
|
// `responseType` 表示服务器响应的数据类型,可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' |
||||
|
responseType?: ResponseType; |
||||
|
|
||||
|
// `xsrfCookieName` 是用作 xsrf token 的值的cookie的名称 |
||||
|
xsrfCookieName?: string; |
||||
|
|
||||
|
// `xsrfHeaderName` 是携带 xsrf 令牌值的 http 标头的名称 |
||||
|
xsrfHeaderName?: string; |
||||
|
|
||||
|
// `onUploadProgress` 允许为上传处理进度事件 |
||||
|
onUploadProgress?: (progressEvent: any) => void; |
||||
|
|
||||
|
// `onDownloadProgress` 允许为下载处理进度事件 |
||||
|
onDownloadProgress?: (progressEvent: any) => void; |
||||
|
|
||||
|
// `maxContentLength` 定义允许的响应内容的最大尺寸 |
||||
|
maxContentLength?: number; |
||||
|
|
||||
|
// `validateStatus` 定义对于给定的HTTP 响应状态码是 resolve 或 reject promise 。 |
||||
|
// 如果 `validateStatus` 返回 `true` (或者设置为 `null` 或 `undefined`), |
||||
|
// promise 将被 resolve; 否则,promise 将被 rejecte |
||||
|
validateStatus?: ((status: number) => boolean) | null; |
||||
|
|
||||
|
// 请求体最大尺寸 |
||||
|
maxBodyLength?: number; |
||||
|
|
||||
|
// `maxRedirects` 定义在 node.js 中 follow 的最大重定向数目 |
||||
|
// 如果设置为0,将不会 follow 任何重定向 |
||||
|
maxRedirects?: number; |
||||
|
|
||||
|
// `socketPath` 定义了一个在 node.js 中使用的 UNIX Socket。 |
||||
|
// 只能指定 `socketPath` 或 `proxy`。 |
||||
|
// 如果两者都指定,则使用 `socketPath`。 |
||||
|
socketPath?: string | null; |
||||
|
|
||||
|
// `httpAgent` 和 `httpsAgent` 分别在 node.js 中用于定义在执行 http 和 https 时使用的自定义代理。 |
||||
|
httpAgent?: any; |
||||
|
httpsAgent?: any; |
||||
|
|
||||
|
// 'proxy' 定义代理服务器的主机名称和端口 |
||||
|
proxy?: AxiosProxyConfig | false; |
||||
|
|
||||
|
// `cancelToken` 指定用于取消请求的 cancel token |
||||
|
cancelToken?: CancelToken; |
||||
|
|
||||
|
// 将其设置为`false`,它将不会解压缩您的响应,而是保留原始的Content-Encoding头。 |
||||
|
// 默认是true |
||||
|
decompress?: boolean; |
||||
|
|
||||
|
// 控制响应数据是否转换 |
||||
|
transitional?: TransitionalOptions |
||||
|
} |
||||
|
|
||||
|
``` |
||||
@ -0,0 +1,44 @@ |
|||||
|
export const errorCodeType = function(code:string):string{ |
||||
|
let errMessage:string = "未知错误" |
||||
|
switch (code) { |
||||
|
case 400: |
||||
|
errMessage = '请求失败!请您稍后重试' |
||||
|
break |
||||
|
case 401: |
||||
|
errMessage = '未授权,请重新登录' |
||||
|
break |
||||
|
case 403: |
||||
|
errMessage = '当前账号无权限访问!' |
||||
|
break |
||||
|
case 404: |
||||
|
errMessage = '你所访问的资源不存在!' |
||||
|
break |
||||
|
case 405: |
||||
|
errMessage = '请求方式错误!请您稍后重试' |
||||
|
break |
||||
|
case 408: |
||||
|
errMessage = '请求超时!请您稍后重试' |
||||
|
break |
||||
|
case 500: |
||||
|
errMessage = '服务器端出错' |
||||
|
break |
||||
|
case 501: |
||||
|
errMessage = '网络未实现' |
||||
|
break |
||||
|
case 502: |
||||
|
errMessage = '网络错误' |
||||
|
break |
||||
|
case 503: |
||||
|
errMessage = '服务不可用' |
||||
|
break |
||||
|
case 504: |
||||
|
errMessage = '网络超时' |
||||
|
break |
||||
|
case 505: |
||||
|
errMessage = 'http版本不支持该请求' |
||||
|
break |
||||
|
default: |
||||
|
errMessage = `其他连接错误 --${code}` |
||||
|
} |
||||
|
return errMessage |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios' |
||||
|
import { ElMessage } from "element-plus"; |
||||
|
import {useUserStore} from "@/store/modules/user" |
||||
|
// 创建axios实例 进行基本参数配置
|
||||
|
const service = axios.create({ |
||||
|
// 默认请求地址,根据环境的不同可在.env 文件中进行修改
|
||||
|
baseURL: import.meta.env.VUE_APP_BASE_API, |
||||
|
// 设置接口访问超时时间
|
||||
|
timeout: 3000000, // request timeout,
|
||||
|
// 跨域时候允许携带凭证
|
||||
|
withCredentials: true |
||||
|
}) |
||||
|
|
||||
|
// request interceptor 接口请求拦截
|
||||
|
service.interceptors.request.use((config:AxiosRequestConfig)=>{ |
||||
|
/** |
||||
|
* 用户登录之后获取服务端返回的token,后面每次请求都在请求头中带上token进行JWT校验 |
||||
|
* token 存储在本地储存中(storage)、vuex、pinia |
||||
|
*/ |
||||
|
const userStore = useUserStore(); |
||||
|
const token: string = userStore.token; |
||||
|
// 自定义请求头
|
||||
|
if(token){ config.headers['Authorization'] = token} |
||||
|
return config |
||||
|
},(error: AxiosError) => { |
||||
|
// 请求错误,这里可以用全局提示框进行提示
|
||||
|
return Promise.reject(error); |
||||
|
}) |
||||
|
|
||||
|
// response interceptor 接口响应拦截
|
||||
|
service.interceptors.response.use((response: AxiosResponse) =>{ |
||||
|
// 直接返回res,当然你也可以只返回res.data
|
||||
|
// 系统如果有自定义code也可以在这里处理
|
||||
|
return response |
||||
|
|
||||
|
|
||||
|
},(error: AxiosError) => { |
||||
|
return Promise.reject(error) |
||||
|
}) |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* @description 显示错误消息 |
||||
|
* opt 传入参数 |
||||
|
* err 错误信息 |
||||
|
* type 消息类型 |
||||
|
* duration 消息持续时间 |
||||
|
*/ |
||||
|
function showErrMessage (opt, err, type:any= 'error', duration:number = 5000){ |
||||
|
ElMessage({ |
||||
|
message: err.msg, |
||||
|
type:type, |
||||
|
duration: duration |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
export default service |
||||
@ -0,0 +1,9 @@ |
|||||
|
import request from './request' |
||||
|
|
||||
|
export function login(data) { |
||||
|
return request({ |
||||
|
url: '/vue-element-perfect/user/login', |
||||
|
method: 'post', |
||||
|
data |
||||
|
}) |
||||
|
} |
||||
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
@ -0,0 +1,539 @@ |
|||||
|
/* Logo 字体 */ |
||||
|
@font-face { |
||||
|
font-family: "iconfont logo"; |
||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834'); |
||||
|
src: url('https://at.alicdn.com/t/font_985780_km7mi63cihi.eot?t=1545807318834#iefix') format('embedded-opentype'), |
||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.woff?t=1545807318834') format('woff'), |
||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.ttf?t=1545807318834') format('truetype'), |
||||
|
url('https://at.alicdn.com/t/font_985780_km7mi63cihi.svg?t=1545807318834#iconfont') format('svg'); |
||||
|
} |
||||
|
|
||||
|
.logo { |
||||
|
font-family: "iconfont logo"; |
||||
|
font-size: 160px; |
||||
|
font-style: normal; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
|
||||
|
/* tabs */ |
||||
|
.nav-tabs { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
.nav-tabs .nav-more { |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
height: 42px; |
||||
|
line-height: 42px; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
#tabs { |
||||
|
border-bottom: 1px solid #eee; |
||||
|
} |
||||
|
|
||||
|
#tabs li { |
||||
|
cursor: pointer; |
||||
|
width: 100px; |
||||
|
height: 40px; |
||||
|
line-height: 40px; |
||||
|
text-align: center; |
||||
|
font-size: 16px; |
||||
|
border-bottom: 2px solid transparent; |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
margin-bottom: -1px; |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#tabs .active { |
||||
|
border-bottom-color: #f00; |
||||
|
color: #222; |
||||
|
} |
||||
|
|
||||
|
.tab-container .content { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
/* 页面布局 */ |
||||
|
.main { |
||||
|
padding: 30px 100px; |
||||
|
width: 960px; |
||||
|
margin: 0 auto; |
||||
|
} |
||||
|
|
||||
|
.main .logo { |
||||
|
color: #333; |
||||
|
text-align: left; |
||||
|
margin-bottom: 30px; |
||||
|
line-height: 1; |
||||
|
height: 110px; |
||||
|
margin-top: -50px; |
||||
|
overflow: hidden; |
||||
|
*zoom: 1; |
||||
|
} |
||||
|
|
||||
|
.main .logo a { |
||||
|
font-size: 160px; |
||||
|
color: #333; |
||||
|
} |
||||
|
|
||||
|
.helps { |
||||
|
margin-top: 40px; |
||||
|
} |
||||
|
|
||||
|
.helps pre { |
||||
|
padding: 20px; |
||||
|
margin: 10px 0; |
||||
|
border: solid 1px #e7e1cd; |
||||
|
background-color: #fffdef; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
|
||||
|
.icon_lists { |
||||
|
width: 100% !important; |
||||
|
overflow: hidden; |
||||
|
*zoom: 1; |
||||
|
} |
||||
|
|
||||
|
.icon_lists li { |
||||
|
width: 100px; |
||||
|
margin-bottom: 10px; |
||||
|
margin-right: 20px; |
||||
|
text-align: center; |
||||
|
list-style: none !important; |
||||
|
cursor: default; |
||||
|
} |
||||
|
|
||||
|
.icon_lists li .code-name { |
||||
|
line-height: 1.2; |
||||
|
} |
||||
|
|
||||
|
.icon_lists .icon { |
||||
|
display: block; |
||||
|
height: 100px; |
||||
|
line-height: 100px; |
||||
|
font-size: 42px; |
||||
|
margin: 10px auto; |
||||
|
color: #333; |
||||
|
-webkit-transition: font-size 0.25s linear, width 0.25s linear; |
||||
|
-moz-transition: font-size 0.25s linear, width 0.25s linear; |
||||
|
transition: font-size 0.25s linear, width 0.25s linear; |
||||
|
} |
||||
|
|
||||
|
.icon_lists .icon:hover { |
||||
|
font-size: 100px; |
||||
|
} |
||||
|
|
||||
|
.icon_lists .svg-icon { |
||||
|
/* 通过设置 font-size 来改变图标大小 */ |
||||
|
width: 1em; |
||||
|
/* 图标和文字相邻时,垂直对齐 */ |
||||
|
vertical-align: -0.15em; |
||||
|
/* 通过设置 color 来改变 SVG 的颜色/fill */ |
||||
|
fill: currentColor; |
||||
|
/* path 和 stroke 溢出 viewBox 部分在 IE 下会显示 |
||||
|
normalize.css 中也包含这行 */ |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
|
||||
|
.icon_lists li .name, |
||||
|
.icon_lists li .code-name { |
||||
|
color: #666; |
||||
|
} |
||||
|
|
||||
|
/* markdown 样式 */ |
||||
|
.markdown { |
||||
|
color: #666; |
||||
|
font-size: 14px; |
||||
|
line-height: 1.8; |
||||
|
} |
||||
|
|
||||
|
.highlight { |
||||
|
line-height: 1.5; |
||||
|
} |
||||
|
|
||||
|
.markdown img { |
||||
|
vertical-align: middle; |
||||
|
max-width: 100%; |
||||
|
} |
||||
|
|
||||
|
.markdown h1 { |
||||
|
color: #404040; |
||||
|
font-weight: 500; |
||||
|
line-height: 40px; |
||||
|
margin-bottom: 24px; |
||||
|
} |
||||
|
|
||||
|
.markdown h2, |
||||
|
.markdown h3, |
||||
|
.markdown h4, |
||||
|
.markdown h5, |
||||
|
.markdown h6 { |
||||
|
color: #404040; |
||||
|
margin: 1.6em 0 0.6em 0; |
||||
|
font-weight: 500; |
||||
|
clear: both; |
||||
|
} |
||||
|
|
||||
|
.markdown h1 { |
||||
|
font-size: 28px; |
||||
|
} |
||||
|
|
||||
|
.markdown h2 { |
||||
|
font-size: 22px; |
||||
|
} |
||||
|
|
||||
|
.markdown h3 { |
||||
|
font-size: 16px; |
||||
|
} |
||||
|
|
||||
|
.markdown h4 { |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
.markdown h5 { |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.markdown h6 { |
||||
|
font-size: 12px; |
||||
|
} |
||||
|
|
||||
|
.markdown hr { |
||||
|
height: 1px; |
||||
|
border: 0; |
||||
|
background: #e9e9e9; |
||||
|
margin: 16px 0; |
||||
|
clear: both; |
||||
|
} |
||||
|
|
||||
|
.markdown p { |
||||
|
margin: 1em 0; |
||||
|
} |
||||
|
|
||||
|
.markdown>p, |
||||
|
.markdown>blockquote, |
||||
|
.markdown>.highlight, |
||||
|
.markdown>ol, |
||||
|
.markdown>ul { |
||||
|
width: 80%; |
||||
|
} |
||||
|
|
||||
|
.markdown ul>li { |
||||
|
list-style: circle; |
||||
|
} |
||||
|
|
||||
|
.markdown>ul li, |
||||
|
.markdown blockquote ul>li { |
||||
|
margin-left: 20px; |
||||
|
padding-left: 4px; |
||||
|
} |
||||
|
|
||||
|
.markdown>ul li p, |
||||
|
.markdown>ol li p { |
||||
|
margin: 0.6em 0; |
||||
|
} |
||||
|
|
||||
|
.markdown ol>li { |
||||
|
list-style: decimal; |
||||
|
} |
||||
|
|
||||
|
.markdown>ol li, |
||||
|
.markdown blockquote ol>li { |
||||
|
margin-left: 20px; |
||||
|
padding-left: 4px; |
||||
|
} |
||||
|
|
||||
|
.markdown code { |
||||
|
margin: 0 3px; |
||||
|
padding: 0 5px; |
||||
|
background: #eee; |
||||
|
border-radius: 3px; |
||||
|
} |
||||
|
|
||||
|
.markdown strong, |
||||
|
.markdown b { |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.markdown>table { |
||||
|
border-collapse: collapse; |
||||
|
border-spacing: 0px; |
||||
|
empty-cells: show; |
||||
|
border: 1px solid #e9e9e9; |
||||
|
width: 95%; |
||||
|
margin-bottom: 24px; |
||||
|
} |
||||
|
|
||||
|
.markdown>table th { |
||||
|
white-space: nowrap; |
||||
|
color: #333; |
||||
|
font-weight: 600; |
||||
|
} |
||||
|
|
||||
|
.markdown>table th, |
||||
|
.markdown>table td { |
||||
|
border: 1px solid #e9e9e9; |
||||
|
padding: 8px 16px; |
||||
|
text-align: left; |
||||
|
} |
||||
|
|
||||
|
.markdown>table th { |
||||
|
background: #F7F7F7; |
||||
|
} |
||||
|
|
||||
|
.markdown blockquote { |
||||
|
font-size: 90%; |
||||
|
color: #999; |
||||
|
border-left: 4px solid #e9e9e9; |
||||
|
padding-left: 0.8em; |
||||
|
margin: 1em 0; |
||||
|
} |
||||
|
|
||||
|
.markdown blockquote p { |
||||
|
margin: 0; |
||||
|
} |
||||
|
|
||||
|
.markdown .anchor { |
||||
|
opacity: 0; |
||||
|
transition: opacity 0.3s ease; |
||||
|
margin-left: 8px; |
||||
|
} |
||||
|
|
||||
|
.markdown .waiting { |
||||
|
color: #ccc; |
||||
|
} |
||||
|
|
||||
|
.markdown h1:hover .anchor, |
||||
|
.markdown h2:hover .anchor, |
||||
|
.markdown h3:hover .anchor, |
||||
|
.markdown h4:hover .anchor, |
||||
|
.markdown h5:hover .anchor, |
||||
|
.markdown h6:hover .anchor { |
||||
|
opacity: 1; |
||||
|
display: inline-block; |
||||
|
} |
||||
|
|
||||
|
.markdown>br, |
||||
|
.markdown>p>br { |
||||
|
clear: both; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
.hljs { |
||||
|
display: block; |
||||
|
background: white; |
||||
|
padding: 0.5em; |
||||
|
color: #333333; |
||||
|
overflow-x: auto; |
||||
|
} |
||||
|
|
||||
|
.hljs-comment, |
||||
|
.hljs-meta { |
||||
|
color: #969896; |
||||
|
} |
||||
|
|
||||
|
.hljs-string, |
||||
|
.hljs-variable, |
||||
|
.hljs-template-variable, |
||||
|
.hljs-strong, |
||||
|
.hljs-emphasis, |
||||
|
.hljs-quote { |
||||
|
color: #df5000; |
||||
|
} |
||||
|
|
||||
|
.hljs-keyword, |
||||
|
.hljs-selector-tag, |
||||
|
.hljs-type { |
||||
|
color: #a71d5d; |
||||
|
} |
||||
|
|
||||
|
.hljs-literal, |
||||
|
.hljs-symbol, |
||||
|
.hljs-bullet, |
||||
|
.hljs-attribute { |
||||
|
color: #0086b3; |
||||
|
} |
||||
|
|
||||
|
.hljs-section, |
||||
|
.hljs-name { |
||||
|
color: #63a35c; |
||||
|
} |
||||
|
|
||||
|
.hljs-tag { |
||||
|
color: #333333; |
||||
|
} |
||||
|
|
||||
|
.hljs-title, |
||||
|
.hljs-attr, |
||||
|
.hljs-selector-id, |
||||
|
.hljs-selector-class, |
||||
|
.hljs-selector-attr, |
||||
|
.hljs-selector-pseudo { |
||||
|
color: #795da3; |
||||
|
} |
||||
|
|
||||
|
.hljs-addition { |
||||
|
color: #55a532; |
||||
|
background-color: #eaffea; |
||||
|
} |
||||
|
|
||||
|
.hljs-deletion { |
||||
|
color: #bd2c00; |
||||
|
background-color: #ffecec; |
||||
|
} |
||||
|
|
||||
|
.hljs-link { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
|
||||
|
/* 代码高亮 */ |
||||
|
/* PrismJS 1.15.0 |
||||
|
https://prismjs.com/download.html#themes=prism&languages=markup+css+clike+javascript */ |
||||
|
/** |
||||
|
* prism.js default theme for JavaScript, CSS and HTML |
||||
|
* Based on dabblet (http://dabblet.com) |
||||
|
* @author Lea Verou |
||||
|
*/ |
||||
|
code[class*="language-"], |
||||
|
pre[class*="language-"] { |
||||
|
color: black; |
||||
|
background: none; |
||||
|
text-shadow: 0 1px white; |
||||
|
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; |
||||
|
text-align: left; |
||||
|
white-space: pre; |
||||
|
word-spacing: normal; |
||||
|
word-break: normal; |
||||
|
word-wrap: normal; |
||||
|
line-height: 1.5; |
||||
|
|
||||
|
-moz-tab-size: 4; |
||||
|
-o-tab-size: 4; |
||||
|
tab-size: 4; |
||||
|
|
||||
|
-webkit-hyphens: none; |
||||
|
-moz-hyphens: none; |
||||
|
-ms-hyphens: none; |
||||
|
hyphens: none; |
||||
|
} |
||||
|
|
||||
|
pre[class*="language-"]::-moz-selection, |
||||
|
pre[class*="language-"] ::-moz-selection, |
||||
|
code[class*="language-"]::-moz-selection, |
||||
|
code[class*="language-"] ::-moz-selection { |
||||
|
text-shadow: none; |
||||
|
background: #b3d4fc; |
||||
|
} |
||||
|
|
||||
|
pre[class*="language-"]::selection, |
||||
|
pre[class*="language-"] ::selection, |
||||
|
code[class*="language-"]::selection, |
||||
|
code[class*="language-"] ::selection { |
||||
|
text-shadow: none; |
||||
|
background: #b3d4fc; |
||||
|
} |
||||
|
|
||||
|
@media print { |
||||
|
|
||||
|
code[class*="language-"], |
||||
|
pre[class*="language-"] { |
||||
|
text-shadow: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/* Code blocks */ |
||||
|
pre[class*="language-"] { |
||||
|
padding: 1em; |
||||
|
margin: .5em 0; |
||||
|
overflow: auto; |
||||
|
} |
||||
|
|
||||
|
:not(pre)>code[class*="language-"], |
||||
|
pre[class*="language-"] { |
||||
|
background: #f5f2f0; |
||||
|
} |
||||
|
|
||||
|
/* Inline code */ |
||||
|
:not(pre)>code[class*="language-"] { |
||||
|
padding: .1em; |
||||
|
border-radius: .3em; |
||||
|
white-space: normal; |
||||
|
} |
||||
|
|
||||
|
.token.comment, |
||||
|
.token.prolog, |
||||
|
.token.doctype, |
||||
|
.token.cdata { |
||||
|
color: slategray; |
||||
|
} |
||||
|
|
||||
|
.token.punctuation { |
||||
|
color: #999; |
||||
|
} |
||||
|
|
||||
|
.namespace { |
||||
|
opacity: .7; |
||||
|
} |
||||
|
|
||||
|
.token.property, |
||||
|
.token.tag, |
||||
|
.token.boolean, |
||||
|
.token.number, |
||||
|
.token.constant, |
||||
|
.token.symbol, |
||||
|
.token.deleted { |
||||
|
color: #905; |
||||
|
} |
||||
|
|
||||
|
.token.selector, |
||||
|
.token.attr-name, |
||||
|
.token.string, |
||||
|
.token.char, |
||||
|
.token.builtin, |
||||
|
.token.inserted { |
||||
|
color: #690; |
||||
|
} |
||||
|
|
||||
|
.token.operator, |
||||
|
.token.entity, |
||||
|
.token.url, |
||||
|
.language-css .token.string, |
||||
|
.style .token.string { |
||||
|
color: #9a6e3a; |
||||
|
background: hsla(0, 0%, 100%, .5); |
||||
|
} |
||||
|
|
||||
|
.token.atrule, |
||||
|
.token.attr-value, |
||||
|
.token.keyword { |
||||
|
color: #07a; |
||||
|
} |
||||
|
|
||||
|
.token.function, |
||||
|
.token.class-name { |
||||
|
color: #DD4A68; |
||||
|
} |
||||
|
|
||||
|
.token.regex, |
||||
|
.token.important, |
||||
|
.token.variable { |
||||
|
color: #e90; |
||||
|
} |
||||
|
|
||||
|
.token.important, |
||||
|
.token.bold { |
||||
|
font-weight: bold; |
||||
|
} |
||||
|
|
||||
|
.token.italic { |
||||
|
font-style: italic; |
||||
|
} |
||||
|
|
||||
|
.token.entity { |
||||
|
cursor: help; |
||||
|
} |
||||
@ -0,0 +1,763 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html> |
||||
|
<head> |
||||
|
<meta charset="utf-8"/> |
||||
|
<title>iconfont Demo</title> |
||||
|
<link rel="shortcut icon" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg" type="image/x-icon"/> |
||||
|
<link rel="icon" type="image/svg+xml" href="//img.alicdn.com/imgextra/i4/O1CN01Z5paLz1O0zuCC7osS_!!6000000001644-55-tps-83-82.svg"/> |
||||
|
<link rel="stylesheet" href="https://g.alicdn.com/thx/cube/1.3.2/cube.min.css"> |
||||
|
<link rel="stylesheet" href="demo.css"> |
||||
|
<link rel="stylesheet" href="iconfont.css"> |
||||
|
<script src="iconfont.js"></script> |
||||
|
<!-- jQuery --> |
||||
|
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/7bfddb60-08e8-11e9-9b04-53e73bb6408b.js"></script> |
||||
|
<!-- 代码高亮 --> |
||||
|
<script src="https://a1.alicdn.com/oss/uploads/2018/12/26/a3f714d0-08e6-11e9-8a15-ebf944d7534c.js"></script> |
||||
|
<style> |
||||
|
.main .logo { |
||||
|
margin-top: 0; |
||||
|
height: auto; |
||||
|
} |
||||
|
|
||||
|
.main .logo a { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
} |
||||
|
|
||||
|
.main .logo .sub-title { |
||||
|
margin-left: 0.5em; |
||||
|
font-size: 22px; |
||||
|
color: #fff; |
||||
|
background: linear-gradient(-45deg, #3967FF, #B500FE); |
||||
|
-webkit-background-clip: text; |
||||
|
-webkit-text-fill-color: transparent; |
||||
|
} |
||||
|
</style> |
||||
|
</head> |
||||
|
<body> |
||||
|
<div class="main"> |
||||
|
<h1 class="logo"><a href="https://www.iconfont.cn/" title="iconfont 首页" target="_blank"> |
||||
|
<img width="200" src="https://img.alicdn.com/imgextra/i3/O1CN01Mn65HV1FfSEzR6DKv_!!6000000000514-55-tps-228-59.svg"> |
||||
|
|
||||
|
</a></h1> |
||||
|
<div class="nav-tabs"> |
||||
|
<ul id="tabs" class="dib-box"> |
||||
|
<li class="dib active"><span>Unicode</span></li> |
||||
|
<li class="dib"><span>Font class</span></li> |
||||
|
<li class="dib"><span>Symbol</span></li> |
||||
|
</ul> |
||||
|
|
||||
|
<a href="https://www.iconfont.cn/manage/index?manage_type=myprojects&projectId=3641732" target="_blank" class="nav-more">查看项目</a> |
||||
|
|
||||
|
</div> |
||||
|
<div class="tab-container"> |
||||
|
<div class="content unicode" style="display: block;"> |
||||
|
<ul class="icon_lists dib-box"> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">阴</div> |
||||
|
<div class="code-name">&#xe6a0;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">大暴雨</div> |
||||
|
<div class="code-name">&#xe6a7;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">刷新</div> |
||||
|
<div class="code-name">&#xe627;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">刷新</div> |
||||
|
<div class="code-name">&#xe629;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">多云-2-copy</div> |
||||
|
<div class="code-name">&#xe68d;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">多云-1</div> |
||||
|
<div class="code-name">&#xe679;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">大雪</div> |
||||
|
<div class="code-name">&#xe67a;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">大雨</div> |
||||
|
<div class="code-name">&#xe67b;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">风</div> |
||||
|
<div class="code-name">&#xe67c;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">多云-3</div> |
||||
|
<div class="code-name">&#xe67d;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">多云-2</div> |
||||
|
<div class="code-name">&#xe67e;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">雷雨交加</div> |
||||
|
<div class="code-name">&#xe67f;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">多云</div> |
||||
|
<div class="code-name">&#xe680;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">中雨</div> |
||||
|
<div class="code-name">&#xe681;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">雾</div> |
||||
|
<div class="code-name">&#xe682;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">小雨</div> |
||||
|
<div class="code-name">&#xe683;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">小雪</div> |
||||
|
<div class="code-name">&#xe684;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">闪电</div> |
||||
|
<div class="code-name">&#xe685;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">雪</div> |
||||
|
<div class="code-name">&#xe686;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">中雪</div> |
||||
|
<div class="code-name">&#xe687;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">扬尘</div> |
||||
|
<div class="code-name">&#xe688;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">月亮</div> |
||||
|
<div class="code-name">&#xe689;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">雨夹雪</div> |
||||
|
<div class="code-name">&#xe68a;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">晴</div> |
||||
|
<div class="code-name">&#xe68b;</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont"></span> |
||||
|
<div class="name">霾</div> |
||||
|
<div class="code-name">&#xe68c;</div> |
||||
|
</li> |
||||
|
|
||||
|
</ul> |
||||
|
<div class="article markdown"> |
||||
|
<h2 id="unicode-">Unicode 引用</h2> |
||||
|
<hr> |
||||
|
|
||||
|
<p>Unicode 是字体在网页端最原始的应用方式,特点是:</p> |
||||
|
<ul> |
||||
|
<li>支持按字体的方式去动态调整图标大小,颜色等等。</li> |
||||
|
<li>默认情况下不支持多色,直接添加多色图标会自动去色。</li> |
||||
|
</ul> |
||||
|
<blockquote> |
||||
|
<p>注意:新版 iconfont 支持两种方式引用多色图标:SVG symbol 引用方式和彩色字体图标模式。(使用彩色字体图标需要在「编辑项目」中开启「彩色」选项后并重新生成。)</p> |
||||
|
</blockquote> |
||||
|
<p>Unicode 使用步骤如下:</p> |
||||
|
<h3 id="-font-face">第一步:拷贝项目下面生成的 <code>@font-face</code></h3> |
||||
|
<pre><code class="language-css" |
||||
|
>@font-face { |
||||
|
font-family: 'iconfont'; |
||||
|
src: url('iconfont.woff2?t=1663216428515') format('woff2'), |
||||
|
url('iconfont.woff?t=1663216428515') format('woff'), |
||||
|
url('iconfont.ttf?t=1663216428515') format('truetype'); |
||||
|
} |
||||
|
</code></pre> |
||||
|
<h3 id="-iconfont-">第二步:定义使用 iconfont 的样式</h3> |
||||
|
<pre><code class="language-css" |
||||
|
>.iconfont { |
||||
|
font-family: "iconfont" !important; |
||||
|
font-size: 16px; |
||||
|
font-style: normal; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
</code></pre> |
||||
|
<h3 id="-">第三步:挑选相应图标并获取字体编码,应用于页面</h3> |
||||
|
<pre> |
||||
|
<code class="language-html" |
||||
|
><span class="iconfont">&#x33;</span> |
||||
|
</code></pre> |
||||
|
<blockquote> |
||||
|
<p>"iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p> |
||||
|
</blockquote> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="content font-class"> |
||||
|
<ul class="icon_lists dib-box"> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-yin"></span> |
||||
|
<div class="name"> |
||||
|
阴 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-yin |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-dabaoyu"></span> |
||||
|
<div class="name"> |
||||
|
大暴雨 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-dabaoyu |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-shuaxin1"></span> |
||||
|
<div class="name"> |
||||
|
刷新 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-shuaxin1 |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-shuaxin"></span> |
||||
|
<div class="name"> |
||||
|
刷新 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-shuaxin |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-duoyun-2-copy"></span> |
||||
|
<div class="name"> |
||||
|
多云-2-copy |
||||
|
</div> |
||||
|
<div class="code-name">.icon-duoyun-2-copy |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-duoyun-1"></span> |
||||
|
<div class="name"> |
||||
|
多云-1 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-duoyun-1 |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-daxue"></span> |
||||
|
<div class="name"> |
||||
|
大雪 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-daxue |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-dayu"></span> |
||||
|
<div class="name"> |
||||
|
大雨 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-dayu |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-feng"></span> |
||||
|
<div class="name"> |
||||
|
风 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-feng |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-duoyun-3"></span> |
||||
|
<div class="name"> |
||||
|
多云-3 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-duoyun-3 |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-duoyun-2"></span> |
||||
|
<div class="name"> |
||||
|
多云-2 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-duoyun-2 |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-leiyujiaojia"></span> |
||||
|
<div class="name"> |
||||
|
雷雨交加 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-leiyujiaojia |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-duoyun"></span> |
||||
|
<div class="name"> |
||||
|
多云 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-duoyun |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-zhongyu"></span> |
||||
|
<div class="name"> |
||||
|
中雨 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-zhongyu |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-wu"></span> |
||||
|
<div class="name"> |
||||
|
雾 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-wu |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-xiaoyu"></span> |
||||
|
<div class="name"> |
||||
|
小雨 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-xiaoyu |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-xiaoxue"></span> |
||||
|
<div class="name"> |
||||
|
小雪 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-xiaoxue |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-shandian"></span> |
||||
|
<div class="name"> |
||||
|
闪电 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-shandian |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-xue"></span> |
||||
|
<div class="name"> |
||||
|
雪 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-xue |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-zhongxue"></span> |
||||
|
<div class="name"> |
||||
|
中雪 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-zhongxue |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-yangchen"></span> |
||||
|
<div class="name"> |
||||
|
扬尘 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-yangchen |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-yueliang"></span> |
||||
|
<div class="name"> |
||||
|
月亮 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-yueliang |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-yujiaxue"></span> |
||||
|
<div class="name"> |
||||
|
雨夹雪 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-yujiaxue |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-qing"></span> |
||||
|
<div class="name"> |
||||
|
晴 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-qing |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<span class="icon iconfont icon-mai"></span> |
||||
|
<div class="name"> |
||||
|
霾 |
||||
|
</div> |
||||
|
<div class="code-name">.icon-mai |
||||
|
</div> |
||||
|
</li> |
||||
|
|
||||
|
</ul> |
||||
|
<div class="article markdown"> |
||||
|
<h2 id="font-class-">font-class 引用</h2> |
||||
|
<hr> |
||||
|
|
||||
|
<p>font-class 是 Unicode 使用方式的一种变种,主要是解决 Unicode 书写不直观,语意不明确的问题。</p> |
||||
|
<p>与 Unicode 使用方式相比,具有如下特点:</p> |
||||
|
<ul> |
||||
|
<li>相比于 Unicode 语意明确,书写更直观。可以很容易分辨这个 icon 是什么。</li> |
||||
|
<li>因为使用 class 来定义图标,所以当要替换图标时,只需要修改 class 里面的 Unicode 引用。</li> |
||||
|
</ul> |
||||
|
<p>使用步骤如下:</p> |
||||
|
<h3 id="-fontclass-">第一步:引入项目下面生成的 fontclass 代码:</h3> |
||||
|
<pre><code class="language-html"><link rel="stylesheet" href="./iconfont.css"> |
||||
|
</code></pre> |
||||
|
<h3 id="-">第二步:挑选相应图标并获取类名,应用于页面:</h3> |
||||
|
<pre><code class="language-html"><span class="iconfont icon-xxx"></span> |
||||
|
</code></pre> |
||||
|
<blockquote> |
||||
|
<p>" |
||||
|
iconfont" 是你项目下的 font-family。可以通过编辑项目查看,默认是 "iconfont"。</p> |
||||
|
</blockquote> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="content symbol"> |
||||
|
<ul class="icon_lists dib-box"> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-yin"></use> |
||||
|
</svg> |
||||
|
<div class="name">阴</div> |
||||
|
<div class="code-name">#icon-yin</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-dabaoyu"></use> |
||||
|
</svg> |
||||
|
<div class="name">大暴雨</div> |
||||
|
<div class="code-name">#icon-dabaoyu</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-shuaxin1"></use> |
||||
|
</svg> |
||||
|
<div class="name">刷新</div> |
||||
|
<div class="code-name">#icon-shuaxin1</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-shuaxin"></use> |
||||
|
</svg> |
||||
|
<div class="name">刷新</div> |
||||
|
<div class="code-name">#icon-shuaxin</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-duoyun-2-copy"></use> |
||||
|
</svg> |
||||
|
<div class="name">多云-2-copy</div> |
||||
|
<div class="code-name">#icon-duoyun-2-copy</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-duoyun-1"></use> |
||||
|
</svg> |
||||
|
<div class="name">多云-1</div> |
||||
|
<div class="code-name">#icon-duoyun-1</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-daxue"></use> |
||||
|
</svg> |
||||
|
<div class="name">大雪</div> |
||||
|
<div class="code-name">#icon-daxue</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-dayu"></use> |
||||
|
</svg> |
||||
|
<div class="name">大雨</div> |
||||
|
<div class="code-name">#icon-dayu</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-feng"></use> |
||||
|
</svg> |
||||
|
<div class="name">风</div> |
||||
|
<div class="code-name">#icon-feng</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-duoyun-3"></use> |
||||
|
</svg> |
||||
|
<div class="name">多云-3</div> |
||||
|
<div class="code-name">#icon-duoyun-3</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-duoyun-2"></use> |
||||
|
</svg> |
||||
|
<div class="name">多云-2</div> |
||||
|
<div class="code-name">#icon-duoyun-2</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-leiyujiaojia"></use> |
||||
|
</svg> |
||||
|
<div class="name">雷雨交加</div> |
||||
|
<div class="code-name">#icon-leiyujiaojia</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-duoyun"></use> |
||||
|
</svg> |
||||
|
<div class="name">多云</div> |
||||
|
<div class="code-name">#icon-duoyun</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-zhongyu"></use> |
||||
|
</svg> |
||||
|
<div class="name">中雨</div> |
||||
|
<div class="code-name">#icon-zhongyu</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-wu"></use> |
||||
|
</svg> |
||||
|
<div class="name">雾</div> |
||||
|
<div class="code-name">#icon-wu</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-xiaoyu"></use> |
||||
|
</svg> |
||||
|
<div class="name">小雨</div> |
||||
|
<div class="code-name">#icon-xiaoyu</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-xiaoxue"></use> |
||||
|
</svg> |
||||
|
<div class="name">小雪</div> |
||||
|
<div class="code-name">#icon-xiaoxue</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-shandian"></use> |
||||
|
</svg> |
||||
|
<div class="name">闪电</div> |
||||
|
<div class="code-name">#icon-shandian</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-xue"></use> |
||||
|
</svg> |
||||
|
<div class="name">雪</div> |
||||
|
<div class="code-name">#icon-xue</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-zhongxue"></use> |
||||
|
</svg> |
||||
|
<div class="name">中雪</div> |
||||
|
<div class="code-name">#icon-zhongxue</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-yangchen"></use> |
||||
|
</svg> |
||||
|
<div class="name">扬尘</div> |
||||
|
<div class="code-name">#icon-yangchen</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-yueliang"></use> |
||||
|
</svg> |
||||
|
<div class="name">月亮</div> |
||||
|
<div class="code-name">#icon-yueliang</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-yujiaxue"></use> |
||||
|
</svg> |
||||
|
<div class="name">雨夹雪</div> |
||||
|
<div class="code-name">#icon-yujiaxue</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-qing"></use> |
||||
|
</svg> |
||||
|
<div class="name">晴</div> |
||||
|
<div class="code-name">#icon-qing</div> |
||||
|
</li> |
||||
|
|
||||
|
<li class="dib"> |
||||
|
<svg class="icon svg-icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-mai"></use> |
||||
|
</svg> |
||||
|
<div class="name">霾</div> |
||||
|
<div class="code-name">#icon-mai</div> |
||||
|
</li> |
||||
|
|
||||
|
</ul> |
||||
|
<div class="article markdown"> |
||||
|
<h2 id="symbol-">Symbol 引用</h2> |
||||
|
<hr> |
||||
|
|
||||
|
<p>这是一种全新的使用方式,应该说这才是未来的主流,也是平台目前推荐的用法。相关介绍可以参考这篇<a href="">文章</a> |
||||
|
这种用法其实是做了一个 SVG 的集合,与另外两种相比具有如下特点:</p> |
||||
|
<ul> |
||||
|
<li>支持多色图标了,不再受单色限制。</li> |
||||
|
<li>通过一些技巧,支持像字体那样,通过 <code>font-size</code>, <code>color</code> 来调整样式。</li> |
||||
|
<li>兼容性较差,支持 IE9+,及现代浏览器。</li> |
||||
|
<li>浏览器渲染 SVG 的性能一般,还不如 png。</li> |
||||
|
</ul> |
||||
|
<p>使用步骤如下:</p> |
||||
|
<h3 id="-symbol-">第一步:引入项目下面生成的 symbol 代码:</h3> |
||||
|
<pre><code class="language-html"><script src="./iconfont.js"></script> |
||||
|
</code></pre> |
||||
|
<h3 id="-css-">第二步:加入通用 CSS 代码(引入一次就行):</h3> |
||||
|
<pre><code class="language-html"><style> |
||||
|
.icon { |
||||
|
width: 1em; |
||||
|
height: 1em; |
||||
|
vertical-align: -0.15em; |
||||
|
fill: currentColor; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
</style> |
||||
|
</code></pre> |
||||
|
<h3 id="-">第三步:挑选相应图标并获取类名,应用于页面:</h3> |
||||
|
<pre><code class="language-html"><svg class="icon" aria-hidden="true"> |
||||
|
<use xlink:href="#icon-xxx"></use> |
||||
|
</svg> |
||||
|
</code></pre> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
<script> |
||||
|
$(document).ready(function () { |
||||
|
$('.tab-container .content:first').show() |
||||
|
|
||||
|
$('#tabs li').click(function (e) { |
||||
|
var tabContent = $('.tab-container .content') |
||||
|
var index = $(this).index() |
||||
|
|
||||
|
if ($(this).hasClass('active')) { |
||||
|
return |
||||
|
} else { |
||||
|
$('#tabs li').removeClass('active') |
||||
|
$(this).addClass('active') |
||||
|
|
||||
|
tabContent.hide().eq(index).fadeIn() |
||||
|
} |
||||
|
}) |
||||
|
}) |
||||
|
</script> |
||||
|
</body> |
||||
|
</html> |
||||
@ -0,0 +1,115 @@ |
|||||
|
@font-face { |
||||
|
font-family: "iconfont"; /* Project id 3641732 */ |
||||
|
src: url('./iconfont.woff2?t=1663216428515') format('woff2'), |
||||
|
url('./iconfont.woff?t=1663216428515') format('woff'), |
||||
|
url('./iconfont.ttf?t=1663216428515') format('truetype'); |
||||
|
} |
||||
|
|
||||
|
.iconfont { |
||||
|
font-family: "iconfont" !important; |
||||
|
font-size: 16px; |
||||
|
font-style: normal; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
|
||||
|
.icon-yin:before { |
||||
|
content: "\e6a0"; |
||||
|
} |
||||
|
|
||||
|
.icon-dabaoyu:before { |
||||
|
content: "\e6a7"; |
||||
|
} |
||||
|
|
||||
|
.icon-shuaxin1:before { |
||||
|
content: "\e627"; |
||||
|
} |
||||
|
|
||||
|
.icon-shuaxin:before { |
||||
|
content: "\e629"; |
||||
|
} |
||||
|
|
||||
|
.icon-duoyun-2-copy:before { |
||||
|
content: "\e68d"; |
||||
|
} |
||||
|
|
||||
|
.icon-duoyun-1:before { |
||||
|
content: "\e679"; |
||||
|
} |
||||
|
|
||||
|
.icon-daxue:before { |
||||
|
content: "\e67a"; |
||||
|
} |
||||
|
|
||||
|
.icon-dayu:before { |
||||
|
content: "\e67b"; |
||||
|
} |
||||
|
|
||||
|
.icon-feng:before { |
||||
|
content: "\e67c"; |
||||
|
} |
||||
|
|
||||
|
.icon-duoyun-3:before { |
||||
|
content: "\e67d"; |
||||
|
} |
||||
|
|
||||
|
.icon-duoyun-2:before { |
||||
|
content: "\e67e"; |
||||
|
} |
||||
|
|
||||
|
.icon-leiyujiaojia:before { |
||||
|
content: "\e67f"; |
||||
|
} |
||||
|
|
||||
|
.icon-duoyun:before { |
||||
|
content: "\e680"; |
||||
|
} |
||||
|
|
||||
|
.icon-zhongyu:before { |
||||
|
content: "\e681"; |
||||
|
} |
||||
|
|
||||
|
.icon-wu:before { |
||||
|
content: "\e682"; |
||||
|
} |
||||
|
|
||||
|
.icon-xiaoyu:before { |
||||
|
content: "\e683"; |
||||
|
} |
||||
|
|
||||
|
.icon-xiaoxue:before { |
||||
|
content: "\e684"; |
||||
|
} |
||||
|
|
||||
|
.icon-shandian:before { |
||||
|
content: "\e685"; |
||||
|
} |
||||
|
|
||||
|
.icon-xue:before { |
||||
|
content: "\e686"; |
||||
|
} |
||||
|
|
||||
|
.icon-zhongxue:before { |
||||
|
content: "\e687"; |
||||
|
} |
||||
|
|
||||
|
.icon-yangchen:before { |
||||
|
content: "\e688"; |
||||
|
} |
||||
|
|
||||
|
.icon-yueliang:before { |
||||
|
content: "\e689"; |
||||
|
} |
||||
|
|
||||
|
.icon-yujiaxue:before { |
||||
|
content: "\e68a"; |
||||
|
} |
||||
|
|
||||
|
.icon-qing:before { |
||||
|
content: "\e68b"; |
||||
|
} |
||||
|
|
||||
|
.icon-mai:before { |
||||
|
content: "\e68c"; |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,184 @@ |
|||||
|
{ |
||||
|
"id": "3641732", |
||||
|
"name": "weather", |
||||
|
"font_family": "iconfont", |
||||
|
"css_prefix_text": "icon-", |
||||
|
"description": "", |
||||
|
"glyphs": [ |
||||
|
{ |
||||
|
"icon_id": "28557556", |
||||
|
"name": "阴", |
||||
|
"font_class": "yin", |
||||
|
"unicode": "e6a0", |
||||
|
"unicode_decimal": 59040 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "28557770", |
||||
|
"name": "大暴雨", |
||||
|
"font_class": "dabaoyu", |
||||
|
"unicode": "e6a7", |
||||
|
"unicode_decimal": 59047 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "7724796", |
||||
|
"name": "刷新", |
||||
|
"font_class": "shuaxin1", |
||||
|
"unicode": "e627", |
||||
|
"unicode_decimal": 58919 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "6999224", |
||||
|
"name": "刷新", |
||||
|
"font_class": "shuaxin", |
||||
|
"unicode": "e629", |
||||
|
"unicode_decimal": 58921 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "31772217", |
||||
|
"name": "多云-2-copy", |
||||
|
"font_class": "duoyun-2-copy", |
||||
|
"unicode": "e68d", |
||||
|
"unicode_decimal": 59021 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265274", |
||||
|
"name": "多云-1", |
||||
|
"font_class": "duoyun-1", |
||||
|
"unicode": "e679", |
||||
|
"unicode_decimal": 59001 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265275", |
||||
|
"name": "大雪", |
||||
|
"font_class": "daxue", |
||||
|
"unicode": "e67a", |
||||
|
"unicode_decimal": 59002 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265276", |
||||
|
"name": "大雨", |
||||
|
"font_class": "dayu", |
||||
|
"unicode": "e67b", |
||||
|
"unicode_decimal": 59003 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265277", |
||||
|
"name": "风", |
||||
|
"font_class": "feng", |
||||
|
"unicode": "e67c", |
||||
|
"unicode_decimal": 59004 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265278", |
||||
|
"name": "多云-3", |
||||
|
"font_class": "duoyun-3", |
||||
|
"unicode": "e67d", |
||||
|
"unicode_decimal": 59005 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265279", |
||||
|
"name": "多云-2", |
||||
|
"font_class": "duoyun-2", |
||||
|
"unicode": "e67e", |
||||
|
"unicode_decimal": 59006 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265280", |
||||
|
"name": "雷雨交加", |
||||
|
"font_class": "leiyujiaojia", |
||||
|
"unicode": "e67f", |
||||
|
"unicode_decimal": 59007 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265281", |
||||
|
"name": "多云", |
||||
|
"font_class": "duoyun", |
||||
|
"unicode": "e680", |
||||
|
"unicode_decimal": 59008 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265282", |
||||
|
"name": "中雨", |
||||
|
"font_class": "zhongyu", |
||||
|
"unicode": "e681", |
||||
|
"unicode_decimal": 59009 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265283", |
||||
|
"name": "雾", |
||||
|
"font_class": "wu", |
||||
|
"unicode": "e682", |
||||
|
"unicode_decimal": 59010 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265284", |
||||
|
"name": "小雨", |
||||
|
"font_class": "xiaoyu", |
||||
|
"unicode": "e683", |
||||
|
"unicode_decimal": 59011 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265285", |
||||
|
"name": "小雪", |
||||
|
"font_class": "xiaoxue", |
||||
|
"unicode": "e684", |
||||
|
"unicode_decimal": 59012 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265286", |
||||
|
"name": "闪电", |
||||
|
"font_class": "shandian", |
||||
|
"unicode": "e685", |
||||
|
"unicode_decimal": 59013 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265287", |
||||
|
"name": "雪", |
||||
|
"font_class": "xue", |
||||
|
"unicode": "e686", |
||||
|
"unicode_decimal": 59014 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265288", |
||||
|
"name": "中雪", |
||||
|
"font_class": "zhongxue", |
||||
|
"unicode": "e687", |
||||
|
"unicode_decimal": 59015 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265289", |
||||
|
"name": "扬尘", |
||||
|
"font_class": "yangchen", |
||||
|
"unicode": "e688", |
||||
|
"unicode_decimal": 59016 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265290", |
||||
|
"name": "月亮", |
||||
|
"font_class": "yueliang", |
||||
|
"unicode": "e689", |
||||
|
"unicode_decimal": 59017 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265291", |
||||
|
"name": "雨夹雪", |
||||
|
"font_class": "yujiaxue", |
||||
|
"unicode": "e68a", |
||||
|
"unicode_decimal": 59018 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265292", |
||||
|
"name": "晴", |
||||
|
"font_class": "qing", |
||||
|
"unicode": "e68b", |
||||
|
"unicode_decimal": 59019 |
||||
|
}, |
||||
|
{ |
||||
|
"icon_id": "29265293", |
||||
|
"name": "霾", |
||||
|
"font_class": "mai", |
||||
|
"unicode": "e68c", |
||||
|
"unicode_decimal": 59020 |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
After Width: | Height: | Size: 533 B |
|
After Width: | Height: | Size: 5.9 KiB |
|
After Width: | Height: | Size: 202 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 160 KiB |
|
After Width: | Height: | Size: 89 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 182 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 496 B |
@ -0,0 +1,86 @@ |
|||||
|
<template> |
||||
|
<vue-cropper |
||||
|
ref="cropper" |
||||
|
:img="avatarUrl" |
||||
|
:output-size="defaultOptions.outputSize" |
||||
|
:output-type="defaultOptions.outputType" |
||||
|
:info="defaultOptions.info" |
||||
|
:full="defaultOptions.full" |
||||
|
:fixed="defaultOptions.fixed" |
||||
|
:autoCropWidth="defaultOptions.autoCropWidth" |
||||
|
:autoCropHeight="defaultOptions.autoCropHeight" |
||||
|
:fixed-box="defaultOptions.fixedBox" |
||||
|
:auto-crop="defaultOptions.autoCrop" |
||||
|
:center-box="defaultOptions.centerBox" |
||||
|
@real-time="realTime" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import {defineExpose, reactive, ref} from 'vue' |
||||
|
import { VueCropper } from 'vue-cropper' |
||||
|
import 'vue-cropper/dist/index.css' |
||||
|
|
||||
|
const emit = defineEmits(['change']) |
||||
|
let props = defineProps({ |
||||
|
avatarUrl:{ |
||||
|
type:String |
||||
|
}, |
||||
|
options:{ |
||||
|
type:Object, |
||||
|
default:()=>{} |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
let cropper = ref() |
||||
|
|
||||
|
const defaultOptions = reactive({ |
||||
|
outputSize:0.8, // 裁剪生成图片的质量 |
||||
|
outputType: 'png', // 生成图片的格式 |
||||
|
info: true, // 裁剪框的大小信息 |
||||
|
fixed: true, // 是否开启截图框宽高固定比例 |
||||
|
autoCrop: true, // 是否默认生成截图框 |
||||
|
anMoveBox: true, // 截图框能否拖动 |
||||
|
original: false, // 上传图片按照原始比例渲染 |
||||
|
autoCropWidth: 300, // 默认生成截图框宽度 |
||||
|
autoCropHeight: 300, // 默认生成截图框高度 |
||||
|
// 只有自动截图开启 宽度高度才生效 |
||||
|
centerBox: false, // 截图框是否被限制在图片里面 |
||||
|
high: true, // 是否按照dpr设备比例图片 |
||||
|
fixedBox: false, // 固定截图框大小 不允许改变 |
||||
|
full: false, // 是否输出原图比例的截图 |
||||
|
...props.options |
||||
|
}) |
||||
|
|
||||
|
const getBase64 = ()=>{ |
||||
|
return new Promise(resolve => { |
||||
|
cropper.value.getCropData((data) => { |
||||
|
resolve(data) |
||||
|
}) |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const rotateLeft = () => { |
||||
|
cropper.value.rotateLeft() |
||||
|
} |
||||
|
const rotateRight = () => { |
||||
|
cropper.value.rotateRight() |
||||
|
} |
||||
|
|
||||
|
const zoom = (percent) => { |
||||
|
cropper.value.changeScale(percent) |
||||
|
} |
||||
|
|
||||
|
// 实时预览图片 |
||||
|
const realTime = (data)=>{ |
||||
|
emit('change',data) |
||||
|
} |
||||
|
|
||||
|
|
||||
|
defineExpose({ |
||||
|
getBase64, |
||||
|
rotateLeft, |
||||
|
rotateRight, |
||||
|
zoom |
||||
|
}) |
||||
|
</script> |
||||
@ -0,0 +1,162 @@ |
|||||
|
<template> |
||||
|
<div :id="id" :class="className" :style="{ height: height, width: width }" /> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import echarts from 'echarts' |
||||
|
import resize from './mixins/resize' |
||||
|
|
||||
|
export default { |
||||
|
mixins: [resize], |
||||
|
props: { |
||||
|
className: { |
||||
|
type: String, |
||||
|
default: 'chart', |
||||
|
}, |
||||
|
id: { |
||||
|
type: String, |
||||
|
default: 'chart', |
||||
|
}, |
||||
|
width: { |
||||
|
type: String, |
||||
|
default: '200px', |
||||
|
}, |
||||
|
height: { |
||||
|
type: String, |
||||
|
default: '200px', |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
chart: null, |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.initChart() |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
if (!this.chart) { |
||||
|
return |
||||
|
} |
||||
|
this.chart.dispose() |
||||
|
this.chart = null |
||||
|
}, |
||||
|
methods: { |
||||
|
initChart() { |
||||
|
this.chart = echarts.init(document.getElementById(this.id)) |
||||
|
|
||||
|
const xAxisData = [] |
||||
|
const data = [] |
||||
|
const data2 = [] |
||||
|
for (let i = 0; i < 50; i++) { |
||||
|
xAxisData.push(i) |
||||
|
data.push((Math.sin(i / 5) * (i / 5 - 10) + i / 6) * 5) |
||||
|
data2.push((Math.sin(i / 5) * (i / 5 + 10) + i / 6) * 3) |
||||
|
} |
||||
|
this.chart.setOption({ |
||||
|
backgroundColor: '#08263a', |
||||
|
grid: { |
||||
|
left: '5%', |
||||
|
right: '5%', |
||||
|
}, |
||||
|
xAxis: [ |
||||
|
{ |
||||
|
show: false, |
||||
|
data: xAxisData, |
||||
|
}, |
||||
|
{ |
||||
|
show: false, |
||||
|
data: xAxisData, |
||||
|
}, |
||||
|
], |
||||
|
visualMap: { |
||||
|
show: false, |
||||
|
min: 0, |
||||
|
max: 50, |
||||
|
dimension: 0, |
||||
|
inRange: { |
||||
|
color: ['#4a657a', '#308e92', '#b1cfa5', '#f5d69f', '#f5898b', '#ef5055'], |
||||
|
}, |
||||
|
}, |
||||
|
yAxis: { |
||||
|
axisLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
textStyle: { |
||||
|
color: '#4a657a', |
||||
|
}, |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: true, |
||||
|
lineStyle: { |
||||
|
color: '#08263f', |
||||
|
}, |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false, |
||||
|
}, |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
name: 'back', |
||||
|
type: 'bar', |
||||
|
data: data2, |
||||
|
z: 1, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
opacity: 0.4, |
||||
|
barBorderRadius: 5, |
||||
|
shadowBlur: 3, |
||||
|
shadowColor: '#111', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Simulate Shadow', |
||||
|
type: 'line', |
||||
|
data, |
||||
|
z: 2, |
||||
|
showSymbol: false, |
||||
|
animationDelay: 0, |
||||
|
animationEasing: 'linear', |
||||
|
animationDuration: 1200, |
||||
|
lineStyle: { |
||||
|
normal: { |
||||
|
color: 'transparent', |
||||
|
}, |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
normal: { |
||||
|
color: '#08263a', |
||||
|
shadowBlur: 50, |
||||
|
shadowColor: '#000', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'front', |
||||
|
type: 'bar', |
||||
|
data, |
||||
|
xAxisIndex: 1, |
||||
|
z: 3, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
barBorderRadius: 5, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
animationEasing: 'elasticOut', |
||||
|
animationEasingUpdate: 'elasticOut', |
||||
|
animationDelay(idx) { |
||||
|
return idx * 20 |
||||
|
}, |
||||
|
animationDelayUpdate(idx) { |
||||
|
return idx * 20 |
||||
|
}, |
||||
|
}) |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,274 @@ |
|||||
|
<template> |
||||
|
<div :id="id" :class="className" :style="{ height: height, width: width }" /> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import * as echarts from 'echarts' |
||||
|
import { computed, nextTick, onMounted, ref, watch } from 'vue' |
||||
|
import { EChartsType } from 'echarts/core' |
||||
|
let props = defineProps({ |
||||
|
className: { |
||||
|
type: String, |
||||
|
default: 'chart', |
||||
|
}, |
||||
|
id: { |
||||
|
type: String, |
||||
|
default: 'chart', |
||||
|
}, |
||||
|
width: { |
||||
|
type: String, |
||||
|
default: '200px', |
||||
|
}, |
||||
|
height: { |
||||
|
type: String, |
||||
|
default: '200px', |
||||
|
}, |
||||
|
}) |
||||
|
const isCollapse = computed(() => { |
||||
|
return store.state.app.isCollapse |
||||
|
}) |
||||
|
|
||||
|
let chart: EChartsType |
||||
|
|
||||
|
const initChart = () => { |
||||
|
let chart = echarts.init(document.getElementById(props.id)) |
||||
|
chart.setOption({ |
||||
|
backgroundColor: '#394056', |
||||
|
title: { |
||||
|
top: 20, |
||||
|
text: 'Requests', |
||||
|
textStyle: { |
||||
|
fontWeight: 'normal', |
||||
|
fontSize: 16, |
||||
|
color: '#F1F1F3', |
||||
|
}, |
||||
|
left: '1%', |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
axisPointer: { |
||||
|
lineStyle: { |
||||
|
color: '#57617B', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
legend: { |
||||
|
top: 20, |
||||
|
icon: 'rect', |
||||
|
itemWidth: 14, |
||||
|
itemHeight: 5, |
||||
|
itemGap: 13, |
||||
|
data: ['CMCC', 'CTCC', 'CUCC'], |
||||
|
right: '4%', |
||||
|
textStyle: { |
||||
|
fontSize: 12, |
||||
|
color: '#F1F1F3', |
||||
|
}, |
||||
|
}, |
||||
|
grid: { |
||||
|
top: 100, |
||||
|
left: '2%', |
||||
|
right: '2%', |
||||
|
bottom: '2%', |
||||
|
containLabel: true, |
||||
|
}, |
||||
|
xAxis: [ |
||||
|
{ |
||||
|
type: 'category', |
||||
|
boundaryGap: false, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#57617B', |
||||
|
}, |
||||
|
}, |
||||
|
data: [ |
||||
|
'13:00', |
||||
|
'13:05', |
||||
|
'13:10', |
||||
|
'13:15', |
||||
|
'13:20', |
||||
|
'13:25', |
||||
|
'13:30', |
||||
|
'13:35', |
||||
|
'13:40', |
||||
|
'13:45', |
||||
|
'13:50', |
||||
|
'13:55', |
||||
|
], |
||||
|
}, |
||||
|
], |
||||
|
yAxis: [ |
||||
|
{ |
||||
|
type: 'value', |
||||
|
name: '(%)', |
||||
|
axisTick: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#57617B', |
||||
|
}, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
margin: 10, |
||||
|
textStyle: { |
||||
|
fontSize: 14, |
||||
|
}, |
||||
|
}, |
||||
|
splitLine: { |
||||
|
lineStyle: { |
||||
|
color: '#57617B', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
series: [ |
||||
|
{ |
||||
|
name: 'CMCC', |
||||
|
type: 'line', |
||||
|
smooth: true, |
||||
|
symbol: 'circle', |
||||
|
symbolSize: 5, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
normal: { |
||||
|
width: 1, |
||||
|
}, |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
normal: { |
||||
|
color: new echarts.graphic.LinearGradient( |
||||
|
0, |
||||
|
0, |
||||
|
0, |
||||
|
1, |
||||
|
[ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: 'rgba(137, 189, 27, 0.3)', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 0.8, |
||||
|
color: 'rgba(137, 189, 27, 0)', |
||||
|
}, |
||||
|
], |
||||
|
false, |
||||
|
), |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
||||
|
shadowBlur: 10, |
||||
|
}, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgb(137,189,27)', |
||||
|
borderColor: 'rgba(137,189,2,0.27)', |
||||
|
borderWidth: 12, |
||||
|
}, |
||||
|
}, |
||||
|
data: [220, 182, 191, 134, 150, 120, 110, 125, 145, 122, 165, 122], |
||||
|
}, |
||||
|
{ |
||||
|
name: 'CTCC', |
||||
|
type: 'line', |
||||
|
smooth: true, |
||||
|
symbol: 'circle', |
||||
|
symbolSize: 5, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
normal: { |
||||
|
width: 1, |
||||
|
}, |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
normal: { |
||||
|
color: new echarts.graphic.LinearGradient( |
||||
|
0, |
||||
|
0, |
||||
|
0, |
||||
|
1, |
||||
|
[ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: 'rgba(0, 136, 212, 0.3)', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 0.8, |
||||
|
color: 'rgba(0, 136, 212, 0)', |
||||
|
}, |
||||
|
], |
||||
|
false, |
||||
|
), |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
||||
|
shadowBlur: 10, |
||||
|
}, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgb(0,136,212)', |
||||
|
borderColor: 'rgba(0,136,212,0.2)', |
||||
|
borderWidth: 12, |
||||
|
}, |
||||
|
}, |
||||
|
data: [120, 110, 125, 145, 122, 165, 122, 220, 182, 191, 134, 150], |
||||
|
}, |
||||
|
{ |
||||
|
name: 'CUCC', |
||||
|
type: 'line', |
||||
|
smooth: true, |
||||
|
symbol: 'circle', |
||||
|
symbolSize: 5, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
normal: { |
||||
|
width: 1, |
||||
|
}, |
||||
|
}, |
||||
|
areaStyle: { |
||||
|
normal: { |
||||
|
color: new echarts.graphic.LinearGradient( |
||||
|
0, |
||||
|
0, |
||||
|
0, |
||||
|
1, |
||||
|
[ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: 'rgba(219, 50, 51, 0.3)', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 0.8, |
||||
|
color: 'rgba(219, 50, 51, 0)', |
||||
|
}, |
||||
|
], |
||||
|
false, |
||||
|
), |
||||
|
shadowColor: 'rgba(0, 0, 0, 0.1)', |
||||
|
shadowBlur: 10, |
||||
|
}, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgb(219,50,51)', |
||||
|
borderColor: 'rgba(219,50,51,0.2)', |
||||
|
borderWidth: 12, |
||||
|
}, |
||||
|
}, |
||||
|
data: [220, 182, 125, 145, 122, 191, 134, 150, 120, 110, 165, 122], |
||||
|
}, |
||||
|
], |
||||
|
}) |
||||
|
return chart |
||||
|
} |
||||
|
|
||||
|
watch(isCollapse, () => { |
||||
|
setTimeout(() => { |
||||
|
chart && chart.resize() |
||||
|
}, 300) |
||||
|
}) |
||||
|
|
||||
|
onMounted(() => { |
||||
|
chart = initChart() |
||||
|
window.addEventListener('resize', function () { |
||||
|
chart && chart.resize() |
||||
|
}) |
||||
|
}) |
||||
|
</script> |
||||
@ -0,0 +1,238 @@ |
|||||
|
<template> |
||||
|
<div :id="id" :class="className" :style="{ height: height, width: width }" /> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import echarts from 'echarts' |
||||
|
import resize from './mixins/resize' |
||||
|
|
||||
|
export default { |
||||
|
mixins: [resize], |
||||
|
props: { |
||||
|
className: { |
||||
|
type: String, |
||||
|
default: 'chart', |
||||
|
}, |
||||
|
id: { |
||||
|
type: String, |
||||
|
default: 'chart', |
||||
|
}, |
||||
|
width: { |
||||
|
type: String, |
||||
|
default: '200px', |
||||
|
}, |
||||
|
height: { |
||||
|
type: String, |
||||
|
default: '200px', |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
chart: null, |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.initChart() |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
if (!this.chart) { |
||||
|
return |
||||
|
} |
||||
|
this.chart.dispose() |
||||
|
this.chart = null |
||||
|
}, |
||||
|
methods: { |
||||
|
initChart() { |
||||
|
this.chart = echarts.init(document.getElementById(this.id)) |
||||
|
const xData = (function () { |
||||
|
const data = [] |
||||
|
for (let i = 1; i < 13; i++) { |
||||
|
data.push(i + 'month') |
||||
|
} |
||||
|
return data |
||||
|
})() |
||||
|
this.chart.setOption({ |
||||
|
backgroundColor: '#344b58', |
||||
|
title: { |
||||
|
text: 'statistics', |
||||
|
x: '20', |
||||
|
top: '20', |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
fontSize: '22', |
||||
|
}, |
||||
|
subtextStyle: { |
||||
|
color: '#90979c', |
||||
|
fontSize: '16', |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
axisPointer: { |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
grid: { |
||||
|
left: '5%', |
||||
|
right: '5%', |
||||
|
borderWidth: 0, |
||||
|
top: 150, |
||||
|
bottom: 95, |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
}, |
||||
|
}, |
||||
|
legend: { |
||||
|
x: '5%', |
||||
|
top: '10%', |
||||
|
textStyle: { |
||||
|
color: '#90979c', |
||||
|
}, |
||||
|
data: ['female', 'male', 'average'], |
||||
|
}, |
||||
|
calculable: true, |
||||
|
xAxis: [ |
||||
|
{ |
||||
|
type: 'category', |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#90979c', |
||||
|
}, |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false, |
||||
|
}, |
||||
|
splitArea: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
interval: 0, |
||||
|
}, |
||||
|
data: xData, |
||||
|
}, |
||||
|
], |
||||
|
yAxis: [ |
||||
|
{ |
||||
|
type: 'value', |
||||
|
splitLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#90979c', |
||||
|
}, |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
interval: 0, |
||||
|
}, |
||||
|
splitArea: { |
||||
|
show: false, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
dataZoom: [ |
||||
|
{ |
||||
|
show: true, |
||||
|
height: 30, |
||||
|
xAxisIndex: [0], |
||||
|
bottom: 30, |
||||
|
start: 10, |
||||
|
end: 80, |
||||
|
handleIcon: |
||||
|
'path://M306.1,413c0,2.2-1.8,4-4,4h-59.8c-2.2,0-4-1.8-4-4V200.8c0-2.2,1.8-4,4-4h59.8c2.2,0,4,1.8,4,4V413z', |
||||
|
handleSize: '110%', |
||||
|
handleStyle: { |
||||
|
color: '#d3dee5', |
||||
|
}, |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
}, |
||||
|
borderColor: '#90979c', |
||||
|
}, |
||||
|
{ |
||||
|
type: 'inside', |
||||
|
show: true, |
||||
|
height: 15, |
||||
|
start: 1, |
||||
|
end: 35, |
||||
|
}, |
||||
|
], |
||||
|
series: [ |
||||
|
{ |
||||
|
name: 'female', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
barMaxWidth: 35, |
||||
|
barGap: '10%', |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgba(255,144,128,1)', |
||||
|
label: { |
||||
|
show: true, |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
}, |
||||
|
position: 'insideTop', |
||||
|
formatter(p) { |
||||
|
return p.value > 0 ? p.value : '' |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: [709, 1917, 2455, 2610, 1719, 1433, 1544, 3285, 5208, 3372, 2484, 4078], |
||||
|
}, |
||||
|
|
||||
|
{ |
||||
|
name: 'male', |
||||
|
type: 'bar', |
||||
|
stack: 'total', |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgba(0,191,183,1)', |
||||
|
barBorderRadius: 0, |
||||
|
label: { |
||||
|
show: true, |
||||
|
position: 'top', |
||||
|
formatter(p) { |
||||
|
return p.value > 0 ? p.value : '' |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: [327, 1776, 507, 1200, 800, 482, 204, 1390, 1001, 951, 381, 220], |
||||
|
}, |
||||
|
{ |
||||
|
name: 'average', |
||||
|
type: 'line', |
||||
|
stack: 'total', |
||||
|
symbolSize: 10, |
||||
|
symbol: 'circle', |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: 'rgba(252,230,48,1)', |
||||
|
barBorderRadius: 0, |
||||
|
label: { |
||||
|
show: true, |
||||
|
position: 'top', |
||||
|
formatter(p) { |
||||
|
return p.value > 0 ? p.value : '' |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: [1036, 3693, 2962, 3810, 2519, 1915, 1748, 4675, 6209, 4323, 2865, 4298], |
||||
|
}, |
||||
|
], |
||||
|
}) |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,127 @@ |
|||||
|
|
||||
|
|
||||
|
<template> |
||||
|
<div class="echarts" ref="echarts"></div> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import * as echarts from "echarts"; |
||||
|
|
||||
|
export default { |
||||
|
data(){ |
||||
|
return{ |
||||
|
chart:null |
||||
|
} |
||||
|
}, |
||||
|
methods:{ |
||||
|
initEcharts(){ |
||||
|
let option = { |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'gauge', |
||||
|
startAngle: 180, |
||||
|
endAngle: 0, |
||||
|
center: ['50%', '80%'], |
||||
|
radius: '100%', |
||||
|
min: 0, |
||||
|
max: 1, |
||||
|
z: 5, |
||||
|
splitNumber: 12, |
||||
|
axisLine: { |
||||
|
show: true, |
||||
|
lineStyle: { |
||||
|
width: 6, |
||||
|
color: [ |
||||
|
[0.12, "#d92d4d"], |
||||
|
[0.35, "#eb8349"], |
||||
|
[0.63, "#e6e462"], |
||||
|
[0.8, "#74c7da"], |
||||
|
[1, "#67b45a"], |
||||
|
] |
||||
|
} |
||||
|
}, |
||||
|
axisTick: { |
||||
|
splitNumber: 13, |
||||
|
show: true, |
||||
|
lineStyle: { |
||||
|
color: "auto", |
||||
|
width: 2, |
||||
|
}, |
||||
|
length: 17, |
||||
|
}, |
||||
|
splitLine: { |
||||
|
length: 25, |
||||
|
lineStyle: { |
||||
|
color: 'auto', |
||||
|
width: 8 |
||||
|
} |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
color: '#a0a7b8', |
||||
|
fontSize: 20, |
||||
|
distance: -60, |
||||
|
rotate: 'tangential', |
||||
|
formatter: function (value) { |
||||
|
var value = value.toFixed(2); |
||||
|
if (value == 0.0) { |
||||
|
return "危"; |
||||
|
} else if (value == 0.25) { |
||||
|
return "差"; |
||||
|
} else if (value == 0.5) { |
||||
|
return "中"; |
||||
|
} else if (value == 0.75) { |
||||
|
return "良"; |
||||
|
} else if (value == 1.0) { |
||||
|
return "优"; |
||||
|
} else { |
||||
|
return ""; |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
title: { |
||||
|
offsetCenter: [0, '-10%'], |
||||
|
fontSize: 20 |
||||
|
}, |
||||
|
anchor: { |
||||
|
show: true, |
||||
|
showAbove: true, |
||||
|
size: 25, |
||||
|
itemStyle: { |
||||
|
borderWidth: 10 |
||||
|
} |
||||
|
}, |
||||
|
detail: { |
||||
|
fontSize: 30, |
||||
|
offsetCenter: [0, '-25%'], |
||||
|
valueAnimation: true, |
||||
|
formatter: function (value) { |
||||
|
return Math.round(value * 100); |
||||
|
}, |
||||
|
color: 'auto' |
||||
|
}, |
||||
|
data: [ |
||||
|
{ |
||||
|
value: 0.7, |
||||
|
name: 'Grade Rating' |
||||
|
} |
||||
|
] |
||||
|
} |
||||
|
] |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
this.chart = echarts.init(this.$refs.echarts) |
||||
|
this.chart.setOption(option) |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.initEcharts() |
||||
|
} |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.echarts { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,58 @@ |
|||||
|
import { debounce } from '@/utils/index.js' |
||||
|
|
||||
|
export default { |
||||
|
data() { |
||||
|
return { |
||||
|
$_sidebarElm: null, |
||||
|
$_resizeHandler: null, |
||||
|
} |
||||
|
}, |
||||
|
mounted() { |
||||
|
this.initListener() |
||||
|
}, |
||||
|
activated() { |
||||
|
if (!this.$_resizeHandler) { |
||||
|
// avoid duplication init
|
||||
|
this.initListener() |
||||
|
} |
||||
|
|
||||
|
// when keep-alive chart activated, auto resize
|
||||
|
this.resize() |
||||
|
}, |
||||
|
beforeDestroy() { |
||||
|
this.destroyListener() |
||||
|
}, |
||||
|
deactivated() { |
||||
|
this.destroyListener() |
||||
|
}, |
||||
|
methods: { |
||||
|
// use $_ for mixins properties
|
||||
|
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
|
||||
|
$_sidebarResizeHandler(e) { |
||||
|
if (e.propertyName === 'width') { |
||||
|
this.$_resizeHandler() |
||||
|
} |
||||
|
}, |
||||
|
initListener() { |
||||
|
this.$_resizeHandler = debounce(() => { |
||||
|
this.resize() |
||||
|
}, 100) |
||||
|
window.addEventListener('resize', this.$_resizeHandler) |
||||
|
|
||||
|
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0] |
||||
|
this.$_sidebarElm && |
||||
|
this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler) |
||||
|
}, |
||||
|
destroyListener() { |
||||
|
window.removeEventListener('resize', this.$_resizeHandler) |
||||
|
this.$_resizeHandler = null |
||||
|
|
||||
|
this.$_sidebarElm && |
||||
|
this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler) |
||||
|
}, |
||||
|
resize() { |
||||
|
const { chart } = this |
||||
|
chart && chart.resize() |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
@ -0,0 +1,121 @@ |
|||||
|
<template> |
||||
|
<textarea ref="codeEditor" placeholder="请输入..." ></textarea> |
||||
|
</template> |
||||
|
|
||||
|
<script> |
||||
|
import { defineComponent, onBeforeUnmount, onMounted, ref, toRefs, watch } from "vue"; |
||||
|
// codemirror基础资源引入 |
||||
|
import _CodeMirror from "codemirror"; |
||||
|
import "codemirror/lib/codemirror.css"; |
||||
|
// language |
||||
|
import 'codemirror/mode/javascript/javascript.js' |
||||
|
|
||||
|
// theme css |
||||
|
import 'codemirror/theme/monokai.css' |
||||
|
// 折叠资源引入:开始 |
||||
|
import "codemirror/addon/fold/foldgutter.css"; |
||||
|
import "codemirror/addon/fold/foldcode.js"; |
||||
|
import "codemirror/addon/fold/brace-fold.js"; |
||||
|
import "codemirror/addon/fold/comment-fold.js"; |
||||
|
import "codemirror/addon/fold/indent-fold.js"; |
||||
|
import "codemirror/addon/fold/foldgutter.js"; |
||||
|
// 折叠资源引入:结束 |
||||
|
|
||||
|
// 搜索资源引入:开始 |
||||
|
import "codemirror/addon/scroll/annotatescrollbar.js"; |
||||
|
import "codemirror/addon/search/matchesonscrollbar.js"; |
||||
|
import "codemirror/addon/search/match-highlighter.js"; |
||||
|
import "codemirror/addon/search/jump-to-line.js"; |
||||
|
|
||||
|
import "codemirror/addon/dialog/dialog.js"; |
||||
|
import "codemirror/addon/dialog/dialog.css"; |
||||
|
import "codemirror/addon/search/searchcursor.js"; |
||||
|
import "codemirror/addon/search/search.js"; |
||||
|
// 搜索资源引入:结束 |
||||
|
|
||||
|
// 启用placeholder |
||||
|
import "codemirror/addon/display/placeholder.js"; |
||||
|
|
||||
|
import "codemirror/addon/selection/active-line.js"; //光标行背景高亮,配置里面也需要styleActiveLine设置为true |
||||
|
|
||||
|
const CodeMirror = window.CodeMirror || _CodeMirror; |
||||
|
|
||||
|
export default defineComponent({ |
||||
|
props: { |
||||
|
modelValue: String, |
||||
|
defaultValue: String, |
||||
|
readOnly: { |
||||
|
type: Boolean, |
||||
|
default: false |
||||
|
} |
||||
|
}, |
||||
|
setup(props, context) { |
||||
|
const { modelValue, defaultValue, readOnly } = toRefs(props); |
||||
|
const codeEditor = ref(); |
||||
|
let editor; |
||||
|
watch(modelValue, () => { |
||||
|
if (null != editor && modelValue.value && modelValue.value !== editor.getValue()) { |
||||
|
// 触发v-model的双向绑定 |
||||
|
editor.setValue(modelValue.value); |
||||
|
} |
||||
|
}); |
||||
|
watch(readOnly, () => { |
||||
|
if (null != editor) { |
||||
|
editor.setOption("readOnly", readOnly.value); |
||||
|
} |
||||
|
}); |
||||
|
onMounted(() => { |
||||
|
editor = CodeMirror.fromTextArea(codeEditor.value, { |
||||
|
value: modelValue.value, |
||||
|
// mime: "text/javascript", |
||||
|
mode: "application/json", |
||||
|
indentWithTabs: false, // 在缩进时,是否需要把 n*tab宽度个空格替换成n个tab字符,默认为false |
||||
|
smartIndent: true, // 自动缩进,设置是否根据上下文自动缩进(和上一行相同的缩进量)。默认为true |
||||
|
lineNumbers: true, // 是否在编辑器左侧显示行号 |
||||
|
matchBrackets: true, // 括号匹配 |
||||
|
readOnly: readOnly.value, |
||||
|
// 启用代码折叠相关功能:开始 |
||||
|
foldGutter: true, |
||||
|
lineWrapping: true, //是否自动换行 |
||||
|
gutters: ["CodeMirror-linenumbers", "CodeMirror-foldgutter", "CodeMirror-lint-markers"], |
||||
|
// 启用代码折叠相关功能:结束 |
||||
|
styleActiveLine: false // 光标行高亮 |
||||
|
}); |
||||
|
// 监听编辑器的change事件 |
||||
|
editor.on("change", () => { |
||||
|
// 触发v-model的双向绑定 |
||||
|
context.emit("update:modelValue", editor.getValue()); |
||||
|
}); |
||||
|
if (defaultValue.value) { |
||||
|
editor.setValue(defaultValue.value); |
||||
|
} |
||||
|
}); |
||||
|
onBeforeUnmount(() => { |
||||
|
if (null !== editor) { |
||||
|
editor.toTextArea(); |
||||
|
editor = null; |
||||
|
} |
||||
|
}); |
||||
|
return { codeEditor }; |
||||
|
} |
||||
|
}); |
||||
|
</script> |
||||
|
|
||||
|
<!-- Add "scoped" attribute to limit CSS to this component only --> |
||||
|
<style lang="scss"> |
||||
|
.CodeMirror-wrap{ |
||||
|
height: 100%; |
||||
|
} |
||||
|
|
||||
|
.CodeMirror-gutters { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
z-index: 3; |
||||
|
min-height: 100%; |
||||
|
white-space: nowrap; |
||||
|
background-color: transparent; |
||||
|
border-right: 1px solid #ddd; |
||||
|
} |
||||
|
|
||||
|
</style> |
||||
@ -0,0 +1,5 @@ |
|||||
|
import CountTo from './index.vue' |
||||
|
export default CountTo |
||||
|
if (typeof window !== 'undefined' && window.Vue) { |
||||
|
window.Vue.component('count-to', CountTo) |
||||
|
} |
||||
@ -0,0 +1,202 @@ |
|||||
|
<template> |
||||
|
<span> |
||||
|
{{ displayValue }} |
||||
|
</span> |
||||
|
</template> |
||||
|
<script lang="ts"> |
||||
|
import { requestAnimationFrame, cancelAnimationFrame } from './requestAnimationFrame.js' |
||||
|
export default { |
||||
|
props: { |
||||
|
startVal: { |
||||
|
type: Number, |
||||
|
required: false, |
||||
|
default: 0, |
||||
|
}, |
||||
|
endVal: { |
||||
|
type: Number, |
||||
|
required: false, |
||||
|
default: 2017, |
||||
|
}, |
||||
|
duration: { |
||||
|
type: Number, |
||||
|
required: false, |
||||
|
default: 3000, |
||||
|
}, |
||||
|
autoplay: { |
||||
|
type: Boolean, |
||||
|
required: false, |
||||
|
default: true, |
||||
|
}, |
||||
|
decimals: { |
||||
|
type: Number, |
||||
|
required: false, |
||||
|
default: 0, |
||||
|
validator(value) { |
||||
|
return value >= 0 |
||||
|
}, |
||||
|
}, |
||||
|
decimal: { |
||||
|
type: String, |
||||
|
required: false, |
||||
|
default: '.', |
||||
|
}, |
||||
|
separator: { |
||||
|
type: String, |
||||
|
required: false, |
||||
|
default: ',', |
||||
|
}, |
||||
|
prefix: { |
||||
|
type: String, |
||||
|
required: false, |
||||
|
default: '', |
||||
|
}, |
||||
|
suffix: { |
||||
|
type: String, |
||||
|
required: false, |
||||
|
default: '', |
||||
|
}, |
||||
|
useEasing: { |
||||
|
type: Boolean, |
||||
|
required: false, |
||||
|
default: true, |
||||
|
}, |
||||
|
easingFn: { |
||||
|
type: Function, |
||||
|
default(t, b, c, d) { |
||||
|
return (c * (-Math.pow(2, (-10 * t) / d) + 1) * 1024) / 1023 + b |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
localStartVal: this.startVal, |
||||
|
displayValue: this.formatNumber(this.startVal), |
||||
|
printVal: null, |
||||
|
paused: false, |
||||
|
localDuration: this.duration, |
||||
|
startTime: null, |
||||
|
timestamp: null, |
||||
|
remaining: null, |
||||
|
rAF: null, |
||||
|
} |
||||
|
}, |
||||
|
computed: { |
||||
|
countDown() { |
||||
|
return this.startVal > this.endVal |
||||
|
}, |
||||
|
}, |
||||
|
watch: { |
||||
|
startVal() { |
||||
|
if (this.autoplay) { |
||||
|
this.start() |
||||
|
} |
||||
|
}, |
||||
|
endVal() { |
||||
|
if (this.autoplay) { |
||||
|
this.start() |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
mounted() { |
||||
|
if (this.autoplay) { |
||||
|
this.start() |
||||
|
} |
||||
|
this.$emit('mountedCallback') |
||||
|
}, |
||||
|
methods: { |
||||
|
start() { |
||||
|
this.localStartVal = this.startVal |
||||
|
this.startTime = null |
||||
|
this.localDuration = this.duration |
||||
|
this.paused = false |
||||
|
this.rAF = requestAnimationFrame(this.count) |
||||
|
}, |
||||
|
pauseResume() { |
||||
|
if (this.paused) { |
||||
|
this.resume() |
||||
|
this.paused = false |
||||
|
} else { |
||||
|
this.pause() |
||||
|
this.paused = true |
||||
|
} |
||||
|
}, |
||||
|
pause() { |
||||
|
cancelAnimationFrame(this.rAF) |
||||
|
}, |
||||
|
resume() { |
||||
|
this.startTime = null |
||||
|
this.localDuration = +this.remaining |
||||
|
this.localStartVal = +this.printVal |
||||
|
requestAnimationFrame(this.count) |
||||
|
}, |
||||
|
reset() { |
||||
|
this.startTime = null |
||||
|
cancelAnimationFrame(this.rAF) |
||||
|
this.displayValue = this.formatNumber(this.startVal) |
||||
|
}, |
||||
|
count(timestamp) { |
||||
|
if (!this.startTime) this.startTime = timestamp |
||||
|
this.timestamp = timestamp |
||||
|
const progress = timestamp - this.startTime |
||||
|
this.remaining = this.localDuration - progress |
||||
|
|
||||
|
if (this.useEasing) { |
||||
|
if (this.countDown) { |
||||
|
this.printVal = |
||||
|
this.localStartVal - |
||||
|
this.easingFn(progress, 0, this.localStartVal - this.endVal, this.localDuration) |
||||
|
} else { |
||||
|
this.printVal = this.easingFn( |
||||
|
progress, |
||||
|
this.localStartVal, |
||||
|
this.endVal - this.localStartVal, |
||||
|
this.localDuration, |
||||
|
) |
||||
|
} |
||||
|
} else { |
||||
|
if (this.countDown) { |
||||
|
this.printVal = |
||||
|
this.localStartVal - |
||||
|
(this.localStartVal - this.endVal) * (progress / this.localDuration) |
||||
|
} else { |
||||
|
this.printVal = |
||||
|
this.localStartVal + |
||||
|
(this.endVal - this.localStartVal) * (progress / this.localDuration) |
||||
|
} |
||||
|
} |
||||
|
if (this.countDown) { |
||||
|
this.printVal = this.printVal < this.endVal ? this.endVal : this.printVal |
||||
|
} else { |
||||
|
this.printVal = this.printVal > this.endVal ? this.endVal : this.printVal |
||||
|
} |
||||
|
|
||||
|
this.displayValue = this.formatNumber(this.printVal) |
||||
|
if (progress < this.localDuration) { |
||||
|
this.rAF = requestAnimationFrame(this.count) |
||||
|
} else { |
||||
|
this.$emit('callback') |
||||
|
} |
||||
|
}, |
||||
|
isNumber(val) { |
||||
|
return !isNaN(parseFloat(val)) |
||||
|
}, |
||||
|
formatNumber(num) { |
||||
|
num = num.toFixed(this.decimals) |
||||
|
num += '' |
||||
|
const x = num.split('.') |
||||
|
let x1 = x[0] |
||||
|
const x2 = x.length > 1 ? this.decimal + x[1] : '' |
||||
|
const rgx = /(\d+)(\d{3})/ |
||||
|
if (this.separator && !this.isNumber(this.separator)) { |
||||
|
while (rgx.test(x1)) { |
||||
|
x1 = x1.replace(rgx, '$1' + this.separator + '$2') |
||||
|
} |
||||
|
} |
||||
|
return this.prefix + x1 + x2 + this.suffix |
||||
|
}, |
||||
|
}, |
||||
|
destroyed() { |
||||
|
cancelAnimationFrame(this.rAF) |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
@ -0,0 +1,51 @@ |
|||||
|
let lastTime = 0 |
||||
|
const prefixes = 'webkit moz ms o'.split(' ') // 各浏览器前缀
|
||||
|
|
||||
|
let requestAnimationFrame |
||||
|
let cancelAnimationFrame |
||||
|
|
||||
|
const isServer = typeof window === 'undefined' |
||||
|
if (isServer) { |
||||
|
requestAnimationFrame = function () { |
||||
|
return |
||||
|
} |
||||
|
cancelAnimationFrame = function () { |
||||
|
return |
||||
|
} |
||||
|
} else { |
||||
|
requestAnimationFrame = window.requestAnimationFrame |
||||
|
cancelAnimationFrame = window.cancelAnimationFrame |
||||
|
let prefix |
||||
|
// 通过遍历各浏览器前缀,来得到requestAnimationFrame和cancelAnimationFrame在当前浏览器的实现形式
|
||||
|
for (let i = 0; i < prefixes.length; i++) { |
||||
|
if (requestAnimationFrame && cancelAnimationFrame) { |
||||
|
break |
||||
|
} |
||||
|
prefix = prefixes[i] |
||||
|
requestAnimationFrame = requestAnimationFrame || window[prefix + 'RequestAnimationFrame'] |
||||
|
cancelAnimationFrame = |
||||
|
cancelAnimationFrame || |
||||
|
window[prefix + 'CancelAnimationFrame'] || |
||||
|
window[prefix + 'CancelRequestAnimationFrame'] |
||||
|
} |
||||
|
|
||||
|
// 如果当前浏览器不支持requestAnimationFrame和cancelAnimationFrame,则会退到setTimeout
|
||||
|
if (!requestAnimationFrame || !cancelAnimationFrame) { |
||||
|
requestAnimationFrame = function (callback) { |
||||
|
const currTime = new Date().getTime() |
||||
|
// 为了使setTimteout的尽可能的接近每秒60帧的效果
|
||||
|
const timeToCall = Math.max(0, 16 - (currTime - lastTime)) |
||||
|
const id = window.setTimeout(() => { |
||||
|
callback(currTime + timeToCall) |
||||
|
}, timeToCall) |
||||
|
lastTime = currTime + timeToCall |
||||
|
return id |
||||
|
} |
||||
|
|
||||
|
cancelAnimationFrame = function (id) { |
||||
|
window.clearTimeout(id) |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
export { requestAnimationFrame, cancelAnimationFrame } |
||||
@ -0,0 +1,269 @@ |
|||||
|
<template> |
||||
|
<div ref="chartsRef" class="echarts"/> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import * as echarts from 'echarts' |
||||
|
import { EChartsType } from 'echarts/core' |
||||
|
import { onMounted, ref } from 'vue' |
||||
|
const chartsRef = ref<HTMLElement | null>() |
||||
|
|
||||
|
let colorList = ['#46ea91', '#2ba0ff', '#ed593b', '#7357ff', '#f2d750']; |
||||
|
const options = { |
||||
|
legend: { |
||||
|
icon: 'circle', |
||||
|
top: '5%', |
||||
|
right: '5%', |
||||
|
itemWidth: 6, |
||||
|
itemGap: 5, |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
padding: [3, 0, 0, 0], |
||||
|
}, |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
}, |
||||
|
grid: { |
||||
|
top: '14%', |
||||
|
left: '3%', |
||||
|
right: '4%', |
||||
|
bottom: '10%', |
||||
|
containLabel: true, |
||||
|
}, |
||||
|
xAxis: [ |
||||
|
{ |
||||
|
type: 'category', |
||||
|
data: ['1', '2', '3', '4', '5', '6', '7', '8'], |
||||
|
axisLine: { |
||||
|
lineStyle: { |
||||
|
color: '#33BBFF', |
||||
|
}, |
||||
|
}, |
||||
|
axisTick: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
interval: 0, |
||||
|
textStyle: { |
||||
|
color: '#5FBBEB', |
||||
|
}, |
||||
|
// 默认x轴字体大小 |
||||
|
fontSize: 12, |
||||
|
// margin:文字到x轴的距离 |
||||
|
margin: 10, |
||||
|
}, |
||||
|
axisPointer: { |
||||
|
label: { |
||||
|
// padding: [11, 5, 7], |
||||
|
padding: [0, 0, 0, 0], |
||||
|
// 这里的margin和axisLabel的margin要一致! |
||||
|
margin: 10, |
||||
|
// 移入时的字体大小 |
||||
|
fontSize: 12, |
||||
|
backgroundColor: 'rgba(0,0,0,0)', |
||||
|
}, |
||||
|
}, |
||||
|
boundaryGap: false, |
||||
|
}, |
||||
|
], |
||||
|
yAxis: [ |
||||
|
{ |
||||
|
name: '单位/件', |
||||
|
axisTick: { |
||||
|
show: false, |
||||
|
}, |
||||
|
axisLine: { |
||||
|
show: true, |
||||
|
lineStyle: { |
||||
|
color: '#05D5FF', |
||||
|
}, |
||||
|
}, |
||||
|
axisLabel: { |
||||
|
textStyle: { |
||||
|
color: '#5FBBEB', |
||||
|
}, |
||||
|
}, |
||||
|
splitLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
series: [ |
||||
|
{ |
||||
|
name: '咨询', |
||||
|
type: 'line', |
||||
|
data: [100, 20, 30, 102, 15, 30, 20, 18], |
||||
|
symbolSize: 1, |
||||
|
symbol: 'circle', |
||||
|
smooth: true, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 2, |
||||
|
color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: '#90ffc6', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 1, |
||||
|
color: '#46ea91', |
||||
|
}, |
||||
|
]), |
||||
|
shadowColor: 'rgba(144, 255, 198, .3)', |
||||
|
shadowBlur: 5, |
||||
|
shadowOffsetY: 5, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: colorList[0], |
||||
|
borderColor: colorList[0], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: '求助', |
||||
|
type: 'line', |
||||
|
data: [20, 12, 11, 14, 25, 16, 10, 20], |
||||
|
symbolSize: 1, |
||||
|
symbol: 'circle', |
||||
|
smooth: true, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 2, |
||||
|
color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: '#67bcfc', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 1, |
||||
|
color: '#2ba0ff', |
||||
|
}, |
||||
|
]), |
||||
|
shadowColor: 'rgba(105, 188, 252,.3)', |
||||
|
shadowBlur: 5, |
||||
|
shadowOffsetY: 5, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: colorList[1], |
||||
|
borderColor: colorList[1], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: '无效', |
||||
|
type: 'line', |
||||
|
data: [150, 120, 170, 140, 100, 160, 110, 110], |
||||
|
symbolSize: 1, |
||||
|
symbol: 'circle', |
||||
|
smooth: true, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 2, |
||||
|
color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: '#fc937e ', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 1, |
||||
|
color: '#ed593b', |
||||
|
}, |
||||
|
]), |
||||
|
shadowColor: 'rgb(252, 147, 126,.3)', |
||||
|
shadowBlur: 2, |
||||
|
shadowOffsetY: 2, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: colorList[2], |
||||
|
borderColor: colorList[2], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: '投诉举报', |
||||
|
type: 'line', |
||||
|
data: [200, 80, 100, 30, 60, 50, 110, 20], |
||||
|
symbolSize: 1, |
||||
|
symbol: 'circle', |
||||
|
smooth: true, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 2, |
||||
|
color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: '#a390ff', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 1, |
||||
|
color: '#7357ff', |
||||
|
}, |
||||
|
]), |
||||
|
shadowColor: 'rgba(115, 87, 255, .1)', |
||||
|
shadowBlur: 5, |
||||
|
shadowOffsetY: 5, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: colorList[3], |
||||
|
borderColor: colorList[3], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
name: '建议', |
||||
|
type: 'line', |
||||
|
data: [20, 80, 150, 30, 60, 50, 50, 20], |
||||
|
symbolSize: 1, |
||||
|
symbol: 'circle', |
||||
|
smooth: true, |
||||
|
showSymbol: false, |
||||
|
lineStyle: { |
||||
|
width: 2, |
||||
|
color: new echarts.graphic.LinearGradient(1, 1, 0, 0, [ |
||||
|
{ |
||||
|
offset: 0, |
||||
|
color: '#ffeb86', |
||||
|
}, |
||||
|
{ |
||||
|
offset: 1, |
||||
|
color: '#f2d750', |
||||
|
}, |
||||
|
]), |
||||
|
shadowColor: 'rgba(255, 235, 134, .5)', |
||||
|
shadowBlur: 5, |
||||
|
shadowOffsetY: 5, |
||||
|
}, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
color: colorList[4], |
||||
|
borderColor: colorList[4], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
|
||||
|
let chart: EChartsType |
||||
|
const initChart = () => { |
||||
|
const chart = echarts.init(chartsRef.value) |
||||
|
chart.setOption(options) |
||||
|
return chart |
||||
|
} |
||||
|
onMounted(() => { |
||||
|
chart = initChart() |
||||
|
window.addEventListener('resize', function () { |
||||
|
chart && chart.resize() |
||||
|
}) |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.echarts{ |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,179 @@ |
|||||
|
<template> |
||||
|
<div ref="chartsRef" class="echarts"/> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import * as echarts from 'echarts' |
||||
|
import { EChartsType } from 'echarts/core' |
||||
|
import { onMounted, ref } from 'vue' |
||||
|
const chartsRef = ref<HTMLElement | null>() |
||||
|
var trafficWay = [ |
||||
|
{ |
||||
|
name: 'Ⅰ类', |
||||
|
value: 20, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Ⅱ类', |
||||
|
value: 20, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Ⅲ类', |
||||
|
value: 20, |
||||
|
}, |
||||
|
{ |
||||
|
name: 'Ⅳ类', |
||||
|
value: 20, |
||||
|
}, |
||||
|
{ name: 'Ⅴ类', value: 20 }, |
||||
|
{ name: '劣Ⅴ类', value: 20 }, |
||||
|
]; |
||||
|
|
||||
|
var data = []; |
||||
|
var color = ['#fd566a', '#9787ff', '#fdb36a', '#fdd56a', '#6da7ff', '#63e1f2', '#ff3000']; |
||||
|
for (var i = 0; i < trafficWay.length; i++) { |
||||
|
data.push( |
||||
|
{ |
||||
|
value: trafficWay[i].value, |
||||
|
name: trafficWay[i].name, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
borderWidth: 5, |
||||
|
shadowBlur: 20, |
||||
|
borderColor: color[i], |
||||
|
shadowColor: color[i], |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
{ |
||||
|
value: 2, |
||||
|
name: '', |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
label: { |
||||
|
show: false, |
||||
|
}, |
||||
|
labelLine: { |
||||
|
show: false, |
||||
|
}, |
||||
|
color: 'rgba(0, 0, 0, 0)', |
||||
|
borderColor: 'rgba(0, 0, 0, 0)', |
||||
|
borderWidth: 0, |
||||
|
}, |
||||
|
}, |
||||
|
} |
||||
|
); |
||||
|
} |
||||
|
var seriesOption = [ |
||||
|
{ |
||||
|
name: '', |
||||
|
type: 'pie', |
||||
|
clockWise: false, |
||||
|
radius: [105, 109], |
||||
|
hoverAnimation: false, |
||||
|
itemStyle: { |
||||
|
normal: { |
||||
|
label: { |
||||
|
show: true, |
||||
|
position: 'outside', |
||||
|
|
||||
|
formatter: function (params) { |
||||
|
var percent = 0; |
||||
|
var total = 0; |
||||
|
for (var i = 0; i < trafficWay.length; i++) { |
||||
|
total += trafficWay[i].value; |
||||
|
} |
||||
|
percent = ((params.value / total) * 100).toFixed(0); |
||||
|
if (params.name !== '') { |
||||
|
return params.name + '\t' + percent + '%'; |
||||
|
} else { |
||||
|
return ''; |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
labelLine: { |
||||
|
length: 10, |
||||
|
length2: 20, |
||||
|
show: true, |
||||
|
color: '#00ffff', |
||||
|
}, |
||||
|
}, |
||||
|
}, |
||||
|
data: data, |
||||
|
}, |
||||
|
]; |
||||
|
let options = { |
||||
|
color: color, |
||||
|
title: [{ |
||||
|
text: '水质监测', |
||||
|
top: '44%', |
||||
|
textAlign: 'center', |
||||
|
left: '49.50%', |
||||
|
backgroundColor: '#163253', |
||||
|
borderRadius: 100, |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
fontSize: 20, |
||||
|
fontWeight: '400', |
||||
|
}, |
||||
|
}, { |
||||
|
text: '水环境监测站', |
||||
|
top: '49%', |
||||
|
textAlign: 'center', |
||||
|
left: '49.50%', |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
fontSize: 20, |
||||
|
fontWeight: '400', |
||||
|
}, |
||||
|
}, { |
||||
|
text: '9', |
||||
|
top: '53%', |
||||
|
textAlign: 'center', |
||||
|
left: '48%', |
||||
|
textStyle: { |
||||
|
color: '#f6ea2f', |
||||
|
fontSize: 25, |
||||
|
fontWeight: '800', |
||||
|
fontStyle: 'italic' |
||||
|
}, |
||||
|
}, { |
||||
|
text: '个', |
||||
|
top: '53.5%', |
||||
|
textAlign: 'center', |
||||
|
left: '50.5%', |
||||
|
textStyle: { |
||||
|
color: '#fff', |
||||
|
fontSize: 16, |
||||
|
fontWeight: '400', |
||||
|
}, |
||||
|
}], |
||||
|
tooltip: { |
||||
|
show: false, |
||||
|
}, |
||||
|
|
||||
|
toolbox: { |
||||
|
show: false, |
||||
|
}, |
||||
|
series: seriesOption, |
||||
|
}; |
||||
|
|
||||
|
let chart: EChartsType |
||||
|
const initChart = () => { |
||||
|
const chart = echarts.init(chartsRef.value) |
||||
|
chart.setOption(options) |
||||
|
return chart |
||||
|
} |
||||
|
onMounted(() => { |
||||
|
chart = initChart() |
||||
|
window.addEventListener('resize', function () { |
||||
|
chart && chart.resize() |
||||
|
}) |
||||
|
}) |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.echarts{ |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
|
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,115 @@ |
|||||
|
<template> |
||||
|
<div class="g-right-click-menu" :style="style" v-if="isShow" ref="rightMenu"> |
||||
|
<div |
||||
|
v-for="(item, index) in data" |
||||
|
:key="index" |
||||
|
class="operating" |
||||
|
@click.stop="operatingRightAction($event, item)" |
||||
|
>{{ item.label }}</div |
||||
|
> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts"> |
||||
|
export default { |
||||
|
props: { |
||||
|
data: { |
||||
|
type: Array, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
left: { |
||||
|
type: Number, |
||||
|
default: 0, |
||||
|
}, |
||||
|
type: { |
||||
|
type: Number, |
||||
|
default: 1, |
||||
|
}, |
||||
|
dataInfo: { |
||||
|
type: Object, |
||||
|
default: () => {}, |
||||
|
}, |
||||
|
top: { |
||||
|
type: Number, |
||||
|
default: 0, |
||||
|
}, |
||||
|
isViewInfo: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
}, |
||||
|
watch: { |
||||
|
left: { |
||||
|
handler(newName, oldName) { |
||||
|
if (newName) { |
||||
|
this.isShow = true |
||||
|
} |
||||
|
}, |
||||
|
// 代表在wacth里声明了firstName这个方法之后立即先去执行handler方法 |
||||
|
// immediate: true |
||||
|
}, |
||||
|
}, |
||||
|
computed: { |
||||
|
style() { |
||||
|
let clientHeight = document.body.clientHeight |
||||
|
let y = this.top |
||||
|
if (clientHeight - y < 100) { |
||||
|
return `left:${this.left}px;bottom:${clientHeight - y}px` |
||||
|
} else { |
||||
|
return `left:${this.left}px;top:${this.top}px` |
||||
|
} |
||||
|
}, |
||||
|
}, |
||||
|
data() { |
||||
|
return { |
||||
|
isShow: false, |
||||
|
} |
||||
|
}, |
||||
|
methods: { |
||||
|
/** |
||||
|
* @func 点击操作 |
||||
|
* @param val 1、置顶/取消置顶 2、开启/关闭免打扰 3、开启/关闭星标 4、删除会话 |
||||
|
*/ |
||||
|
operatingRightAction($event, val) { |
||||
|
this.$emit('ok', $event, val) |
||||
|
this.isShow = false |
||||
|
}, |
||||
|
}, |
||||
|
mounted() { |
||||
|
let _self = this |
||||
|
window.addEventListener('click', function () { |
||||
|
_self.isShow = false |
||||
|
}) |
||||
|
window.addEventListener('mousedown', function (e) { |
||||
|
if (e.which === 3) { |
||||
|
_self.isShow = false |
||||
|
} |
||||
|
}) |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.g-right-click-menu { |
||||
|
left: 0; |
||||
|
background: white; |
||||
|
width: 148px; |
||||
|
height: auto; |
||||
|
position: fixed; |
||||
|
//border: 1px solid #c4c4c4; |
||||
|
z-index: 9; |
||||
|
//box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.1); |
||||
|
box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%); |
||||
|
.operating { |
||||
|
font-size: 12px; |
||||
|
padding-left: 23px; |
||||
|
cursor: pointer; |
||||
|
line-height: 27px; |
||||
|
} |
||||
|
.operating:hover { |
||||
|
background: #e2e2e2; |
||||
|
} |
||||
|
|
||||
|
.last-delete { |
||||
|
border-top: 1px solid #ededed; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,119 @@ |
|||||
|
<template> |
||||
|
<div class="advancedForm"> |
||||
|
<el-form |
||||
|
ref="ruleFormRef" |
||||
|
:inline="true" |
||||
|
:label-position="'right'" |
||||
|
:model="formInline" |
||||
|
class="form-inline"> |
||||
|
<el-row |
||||
|
:class="{ |
||||
|
'not-show':byHeight&&!isExpand |
||||
|
}" |
||||
|
:gutter="gutterWidth"> |
||||
|
<el-col :span="item.span" |
||||
|
v-for="item,index in columns" |
||||
|
:key="item.name" |
||||
|
v-show="byHeight?true:(index< (showRow*3)||isExpand)"> |
||||
|
<el-form-item :label="item.title" :label-width="labelWidth" v-if="item.type==='input'"> |
||||
|
<el-input |
||||
|
clearable |
||||
|
v-model="formInline[item.name]" :placeholder="item.placeholder" /> |
||||
|
</el-form-item> |
||||
|
<template v-else-if="item.type==='date'"> |
||||
|
<el-form-item :label="item.title" :label-width="labelWidth" > |
||||
|
<el-date-picker |
||||
|
value-format="YYYY-MM-DD" |
||||
|
v-model="formInline[item.name]" |
||||
|
type="date" |
||||
|
:placeholder="item.placeholder" |
||||
|
/> |
||||
|
</el-form-item> |
||||
|
</template> |
||||
|
</el-col> |
||||
|
</el-row> |
||||
|
</el-form> |
||||
|
<div class="search-btn"> |
||||
|
<el-button type="primary" @click="onSubmit">查询</el-button> |
||||
|
<el-button @click="resetForm(ruleFormRef)">重置</el-button> |
||||
|
<el-button link type="primary" @click="isExpand = !isExpand">{{ isExpand ? '合并' : '展开'}}<el-icon> |
||||
|
<arrow-down v-if="!isExpand" /> |
||||
|
<arrow-up v-else /> </el-icon |
||||
|
></el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import {reactive, ref} from 'vue' |
||||
|
import type { FormInstance, FormRules } from 'element-plus' |
||||
|
const ruleFormRef = ref<FormInstance>() |
||||
|
let props = defineProps({ |
||||
|
// 宽度 |
||||
|
labelWidth: { |
||||
|
default: "100px", |
||||
|
}, |
||||
|
gutterWidth: { |
||||
|
type: Number, |
||||
|
default: 24, |
||||
|
}, |
||||
|
showRow:{ |
||||
|
type: Number, |
||||
|
default: 1, |
||||
|
}, |
||||
|
columns:{ |
||||
|
type:Array, |
||||
|
default:()=>[] |
||||
|
}, |
||||
|
byHeight:{ |
||||
|
type:Boolean, |
||||
|
default:false |
||||
|
} |
||||
|
}) |
||||
|
const emit = defineEmits(['submit','reset']) |
||||
|
// 收缩展开 |
||||
|
const isExpand = ref(false) |
||||
|
|
||||
|
const formInline = reactive({ |
||||
|
}) |
||||
|
|
||||
|
for(let item of props.columns){ |
||||
|
formInline[item.name] = null |
||||
|
} |
||||
|
|
||||
|
const onSubmit = () => { |
||||
|
emit('submit',formInline) |
||||
|
} |
||||
|
|
||||
|
const resetForm = (formEl: FormInstance | undefined) => { |
||||
|
console.log('formEl',formEl) |
||||
|
if (!formEl) return |
||||
|
formEl.resetFields() |
||||
|
const keys = Object.keys(formInline); |
||||
|
keys.forEach(key => { |
||||
|
formInline[key] = null; |
||||
|
}); |
||||
|
emit("reset", formInline); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style lang="scss" scoped> |
||||
|
.advancedForm{ |
||||
|
display: flex; |
||||
|
justify-content: space-between; |
||||
|
.form-inline{ |
||||
|
flex: 1; |
||||
|
} |
||||
|
.el-form--inline .el-form-item{ |
||||
|
width: 100%; |
||||
|
margin-right: 10px; |
||||
|
} |
||||
|
.search-btn{ |
||||
|
margin-left: 40px; |
||||
|
} |
||||
|
.not-show{ |
||||
|
height: 40px; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,35 @@ |
|||||
|
<template> |
||||
|
<svg :class="svgClass" aria-hidden="true"> |
||||
|
<use :xlink:href="iconName"></use> |
||||
|
</svg> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { computed } from 'vue' |
||||
|
export default { |
||||
|
name: 'baseSvgIcon', |
||||
|
props: { |
||||
|
iconClass: { type: String }, |
||||
|
className: { type: String }, |
||||
|
}, |
||||
|
setup(props) { |
||||
|
const iconName = computed(() => { |
||||
|
return props.iconClass ? `#icon-${props.iconClass}` : '#icon' |
||||
|
}) |
||||
|
const svgClass = computed(() => { |
||||
|
return props.className ? 'svg-icon ' + props.className : 'svg-icon' |
||||
|
}) |
||||
|
return { iconName, svgClass } |
||||
|
}, |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped lang="scss"> |
||||
|
.svg-icon { |
||||
|
width: 1em; |
||||
|
height: 1em; |
||||
|
vertical-align: -0.15em; |
||||
|
fill: currentColor; |
||||
|
overflow: hidden; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,26 @@ |
|||||
|
<template> |
||||
|
<el-switch |
||||
|
@change="switchDark" |
||||
|
inline-prompt |
||||
|
v-model="themeConfig.isDark" |
||||
|
:active-icon="Sunny" |
||||
|
:inactive-icon="Moon" |
||||
|
/> |
||||
|
</template> |
||||
|
|
||||
|
<script setup lang="ts" name="switchDark"> |
||||
|
import { Sunny, Moon } from "@element-plus/icons-vue"; |
||||
|
import {computed, ref} from "vue"; |
||||
|
import {useSettingStore} from "@/store/modules/setting" |
||||
|
|
||||
|
const SettingStore = useSettingStore() |
||||
|
// 设置信息 |
||||
|
const themeConfig = computed(()=>SettingStore.themeConfig) |
||||
|
|
||||
|
// 切换暗黑模式 |
||||
|
const switchDark = () => { |
||||
|
const body = document.documentElement as HTMLElement; |
||||
|
if (themeConfig.value.isDark) body.setAttribute("class", "dark"); |
||||
|
else body.setAttribute("class", ""); |
||||
|
}; |
||||
|
</script> |
||||
@ -0,0 +1,304 @@ |
|||||
|
<template> |
||||
|
<div class="m-edit-table"> |
||||
|
<div style="margin-top: 15px; margin-bottom: 15px" v-if="mode !== 'hide' && mode !== 'bottom'"> |
||||
|
<el-button style="width: 100%" @click="add"> |
||||
|
<el-icon style="margin-right: 4px"><plus /></el-icon> 添加一行数据</el-button |
||||
|
> |
||||
|
</div> |
||||
|
<el-table :data="transData" style="width: 100%" row-key="id" border> |
||||
|
<template v-for="item in columns"> |
||||
|
<el-table-column |
||||
|
v-if="item.type" |
||||
|
:type="item.type" |
||||
|
:width="item.width" |
||||
|
:align="item.align" |
||||
|
:fixed="item.fixed" |
||||
|
:label="item.label" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
v-else |
||||
|
:prop="item.name" |
||||
|
:width="item.width" |
||||
|
:align="item.align" |
||||
|
:fixed="item.fixed" |
||||
|
:label="item.label" |
||||
|
> |
||||
|
<template #default="scope"> |
||||
|
<template v-if="!item.slot"> |
||||
|
<template v-if="item.readonly"> |
||||
|
{{ scope.row[item.name] }} |
||||
|
</template> |
||||
|
<template v-else-if="item.valueType === 'select'"> |
||||
|
<el-select |
||||
|
clearable |
||||
|
:placeholder="`请选择`" |
||||
|
v-model="scope.row[item.name]" |
||||
|
v-if="scope.row.edit" |
||||
|
> |
||||
|
<el-option |
||||
|
v-for="ite in item.options" |
||||
|
:key="ite.value" |
||||
|
:label="ite.label" |
||||
|
:value="ite.value" |
||||
|
/> |
||||
|
</el-select> |
||||
|
<span v-else>{{ filterOption(item, scope) }}</span> |
||||
|
</template> |
||||
|
|
||||
|
<template v-else-if="item.valueType === 'date'"> |
||||
|
<el-date-picker |
||||
|
v-model="scope.row[item.name]" |
||||
|
type="date" |
||||
|
value-format="YYYY-MM-DD" |
||||
|
clearable |
||||
|
placeholder="请选择" |
||||
|
v-if="scope.row.edit" |
||||
|
/> |
||||
|
<span v-else>{{ scope.row[item.name] || '--' }}</span> |
||||
|
</template> |
||||
|
<template v-else> |
||||
|
<el-input |
||||
|
clearable |
||||
|
placeholder="请输入" |
||||
|
v-model="scope.row[item.name]" |
||||
|
v-if="scope.row.edit" |
||||
|
></el-input> |
||||
|
<span v-else>{{ scope.row[item.name] || '--' }}</span> |
||||
|
</template> |
||||
|
</template> |
||||
|
<slot v-else :name="item.name" :item="item" :row="scope.row"></slot> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
<el-table-column prop="operator" label="操作" width="250px" fixed="right"> |
||||
|
<template #default="scope"> |
||||
|
<el-button |
||||
|
v-if="scope.row.edit" |
||||
|
type="primary" |
||||
|
size="small" |
||||
|
icon="CircleCheckFilled" |
||||
|
@click="confirmEdit(scope.row)" |
||||
|
> |
||||
|
保存 |
||||
|
</el-button> |
||||
|
<el-button |
||||
|
v-else |
||||
|
type="primary" |
||||
|
size="small" |
||||
|
icon="Edit" |
||||
|
@click="scope.row.edit = !scope.row.edit" |
||||
|
> |
||||
|
编辑 |
||||
|
</el-button> |
||||
|
<el-popover |
||||
|
trigger="click" |
||||
|
v-model:visible="scope.row.visible" |
||||
|
placement="top" |
||||
|
:width="160" |
||||
|
> |
||||
|
<p style="display: flex; align-items: center; margin-bottom: 10px"> |
||||
|
<el-icon color="#faad14" style="margin-right: 10px"><warning-filled /></el-icon> |
||||
|
删除此行?</p |
||||
|
> |
||||
|
<div style="text-align: right; margin: 0"> |
||||
|
<el-button size="small" @click="scope.row.visible = false">取消</el-button> |
||||
|
<el-button size="small" type="primary" @click="deleteAction(scope.row)" |
||||
|
>确定</el-button |
||||
|
> |
||||
|
</div> |
||||
|
<template #reference> |
||||
|
<el-button icon="Delete" @click="deleteCurrent(scope.row)" type="danger" size="small" |
||||
|
>删除</el-button |
||||
|
> |
||||
|
</template> |
||||
|
</el-popover> |
||||
|
<el-button |
||||
|
v-if="scope.row.edit" |
||||
|
type="primary" |
||||
|
size="small" |
||||
|
icon="Edit" |
||||
|
@click="cancelEdit(scope.row)" |
||||
|
> |
||||
|
取消 |
||||
|
</el-button> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</el-table> |
||||
|
<div style="margin-top: 15px" v-if="mode !== 'hide' && mode !== 'top'"> |
||||
|
<el-button style="width: 100%" @click="add"> |
||||
|
<el-icon style="margin-right: 4px"><plus /></el-icon> 添加一行数据</el-button |
||||
|
> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { computed, onMounted, ref, watch } from 'vue' |
||||
|
import { deepObjClone } from '@/utils/index' |
||||
|
import { ElMessage, ElMessageBox } from 'element-plus' |
||||
|
import { reactive } from 'vue' |
||||
|
const emit = defineEmits(['del', 'add', 'onChange']) |
||||
|
let transData = ref([]) |
||||
|
|
||||
|
let props = defineProps({ |
||||
|
columns: { |
||||
|
type: Array, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
data: { |
||||
|
type: Array, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
editableKeys: { |
||||
|
type: Array, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
mode: { |
||||
|
type: String, |
||||
|
default: 'bottom', |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
// 删除当前此行 |
||||
|
const deleteCurrent = (row)=>{ |
||||
|
// console.log('----------',row) |
||||
|
// row.visible = true |
||||
|
} |
||||
|
|
||||
|
const getData = () => { |
||||
|
let arr = deepObjClone(transData.value) |
||||
|
for (let item of arr) { |
||||
|
for (let attr in item) { |
||||
|
if (attr.includes('te__mp')) { |
||||
|
delete item[attr] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
emit('onChange', arr) |
||||
|
} |
||||
|
|
||||
|
let obj = {} |
||||
|
for (let item of props.columns) { |
||||
|
props.data.forEach((it) => { |
||||
|
if (!obj[item.name]) { |
||||
|
obj[item.name] = null |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// 重置数据 |
||||
|
const reset = () => { |
||||
|
transData.value = props.data |
||||
|
for (let item of transData.value) { |
||||
|
if (props.editableKeys.includes(item.id)) { |
||||
|
item.edit = true |
||||
|
} |
||||
|
} |
||||
|
getData() |
||||
|
} |
||||
|
|
||||
|
onMounted(() => { |
||||
|
watch( |
||||
|
() => props.data, |
||||
|
(val) => { |
||||
|
// // 转换数据 |
||||
|
transData.value = deepObjClone(val) |
||||
|
// 存储一个临时变量 |
||||
|
for (let item of transData.value) { |
||||
|
if (props.editableKeys.includes(item.id)) { |
||||
|
item.edit = true |
||||
|
} |
||||
|
for (let attr in item) { |
||||
|
let temp = `${attr}te__mp` |
||||
|
item[temp] = item[attr] |
||||
|
} |
||||
|
} |
||||
|
}, |
||||
|
{ |
||||
|
immediate: true, |
||||
|
deep: true, |
||||
|
}, |
||||
|
) |
||||
|
}) |
||||
|
|
||||
|
const visible = ref(false) |
||||
|
|
||||
|
const handleSizeChange = (val: number) => { |
||||
|
console.log(`${val} items per page`) |
||||
|
} |
||||
|
|
||||
|
const listLoading = ref(false) |
||||
|
|
||||
|
// 保存 |
||||
|
const confirmEdit = (row) => { |
||||
|
row.edit = false |
||||
|
for (let attr in row) { |
||||
|
if (attr.includes('te__mp')) { |
||||
|
row[attr] = row[attr.replace('te__mp', '')] |
||||
|
} |
||||
|
} |
||||
|
getData() |
||||
|
} |
||||
|
// 取消 |
||||
|
const cancelEdit = (row) => { |
||||
|
row.edit = !row.edit |
||||
|
for (let attr in row) { |
||||
|
if (attr !== 'edit') { |
||||
|
if (!attr.includes('te__mp')) { |
||||
|
row[attr] = row[attr + 'te__mp'] |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const deleteAction = (row) => { |
||||
|
row.visible = false |
||||
|
transData.value = transData.value.filter((item) => item.id !== row.id) |
||||
|
emit('del', row) |
||||
|
} |
||||
|
|
||||
|
// 添加 |
||||
|
const add = () => { |
||||
|
let id = ~~(Math.random() * 1000000).toFixed(0) |
||||
|
let obj1 = Object.assign({}, obj, { |
||||
|
id: id, |
||||
|
edit: true, |
||||
|
visible: false, |
||||
|
}) |
||||
|
for (let attr in obj1) { |
||||
|
let temp = `${attr}te__mp` |
||||
|
obj1[temp] = obj1[attr] |
||||
|
} |
||||
|
|
||||
|
if (props.mode === 'bottom') { |
||||
|
transData.value.push(obj1) |
||||
|
} |
||||
|
if (props.mode === 'top') { |
||||
|
transData.value.unshift(obj1) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const filterOption = (item, scope) => { |
||||
|
let obj = item.options.find((ite) => ite.value === scope.row[item.name]) |
||||
|
if (obj) { |
||||
|
return obj.label |
||||
|
} |
||||
|
return '--' |
||||
|
} |
||||
|
|
||||
|
defineExpose({ |
||||
|
reset, |
||||
|
}) |
||||
|
</script> |
||||
|
<style scoped> |
||||
|
.edit-input { |
||||
|
padding-right: 100px; |
||||
|
} |
||||
|
.cancel-btn { |
||||
|
position: absolute; |
||||
|
right: 15px; |
||||
|
top: 10px; |
||||
|
} |
||||
|
.inline-edit-table { |
||||
|
width: 100%; |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,249 @@ |
|||||
|
<template> |
||||
|
<div class="zb-pro-table"> |
||||
|
<div class="header"> |
||||
|
<el-form :inline="true" |
||||
|
class="search-form" |
||||
|
:model="formInline" ref="ruleFormRef" > |
||||
|
<template v-for="(item, index) in formSearchData" :key="index"> |
||||
|
<el-form-item :label="item.label" v-show="isExpand ? isExpand : index < 2"> |
||||
|
<template v-if="item.valueType === 'input'"> |
||||
|
<el-input v-model="formInline[item.name]" :placeholder="`请输入${item.label}`" /> |
||||
|
</template> |
||||
|
<template v-if="item.valueType === 'select'"> |
||||
|
<el-select |
||||
|
style="width: 100%" |
||||
|
v-model="formInline[item.name]" :placeholder="`请选择${item.label}`"> |
||||
|
<el-option |
||||
|
v-for="ite in item.options" |
||||
|
:key="ite.value" |
||||
|
:label="ite.label" |
||||
|
:value="ite.value" |
||||
|
/> |
||||
|
</el-select> |
||||
|
</template> |
||||
|
</el-form-item> |
||||
|
</template> |
||||
|
</el-form> |
||||
|
<div class="search"> |
||||
|
<el-button type="primary" @click="onSubmit" :icon="Search">查询</el-button> |
||||
|
<el-button @click="reset(ruleFormRef)">重置</el-button> |
||||
|
<el-button link type="primary" @click="isExpand = !isExpand">{{ isExpand ? '合并' : '展开'}}<el-icon> |
||||
|
<arrow-down v-if="!isExpand" /> |
||||
|
<arrow-up v-else /> </el-icon |
||||
|
></el-button> |
||||
|
</div> |
||||
|
</div> |
||||
|
<!----------底部----------------------> |
||||
|
<div class="footer"> |
||||
|
<!-----------工具栏操作工具-----------------> |
||||
|
<div class="operator"> |
||||
|
<slot name="btn"></slot> |
||||
|
</div> |
||||
|
<!-- ------------表格---------------> |
||||
|
<div class="table"> |
||||
|
<el-table |
||||
|
class="zb-table" |
||||
|
v-loading="loading" |
||||
|
@selection-change="(val) => emit('selection-change', val)" |
||||
|
:data="list" |
||||
|
:border="true" |
||||
|
> |
||||
|
<template v-for="item in columns"> |
||||
|
<el-table-column |
||||
|
v-if="item.type" |
||||
|
:type="item.type" |
||||
|
:width="item.width" |
||||
|
:align="item.align!=null?item.align:'center'" |
||||
|
:fixed="item.fixed" |
||||
|
:label="item.label" |
||||
|
/> |
||||
|
<el-table-column |
||||
|
v-else |
||||
|
:prop="item.name" |
||||
|
:width="item.width" |
||||
|
:align="item.align!=null?item.align:'center'" |
||||
|
:fixed="item.fixed" |
||||
|
:label="item.label" |
||||
|
> |
||||
|
<template #default="scope"> |
||||
|
<span v-if="!item.slot">{{ scope.row[item.name] }}</span> |
||||
|
<slot v-else :name="item.name" :item="item" :row="scope.row"></slot> |
||||
|
</template> |
||||
|
</el-table-column> |
||||
|
</template> |
||||
|
</el-table> |
||||
|
</div> |
||||
|
<!-- ------------分页---------------> |
||||
|
<div class="pagination"> |
||||
|
<el-pagination |
||||
|
v-model:currentPage="currentPage1" |
||||
|
:page-size="10" |
||||
|
background |
||||
|
layout="total, sizes, prev, pager, next, jumper" |
||||
|
:total="data.length" |
||||
|
@size-change="handleSizeChange" |
||||
|
@current-change="handleCurrentChange" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { computed, ref } from 'vue' |
||||
|
import {Search } from '@element-plus/icons-vue' |
||||
|
import { ElMessage, ElMessageBox } from 'element-plus' |
||||
|
import type { FormInstance } from 'element-plus' |
||||
|
const ruleFormRef = ref<FormInstance>() |
||||
|
const emit = defineEmits(['reset', 'onSubmit', 'selection-change']) |
||||
|
let props = defineProps({ |
||||
|
columns: { |
||||
|
type: Array, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
data: { |
||||
|
type: Array, |
||||
|
default: () => [], |
||||
|
}, |
||||
|
loading: { |
||||
|
type: Boolean, |
||||
|
default: false, |
||||
|
}, |
||||
|
}) |
||||
|
|
||||
|
const currentPage1 = ref(1) |
||||
|
// 收缩展开 |
||||
|
const isExpand = ref(false) |
||||
|
const handleSizeChange = (val: number) => { |
||||
|
console.log(`${val} items per page`) |
||||
|
} |
||||
|
const handleCurrentChange = (val: number) => { |
||||
|
console.log(`current page: ${val}`) |
||||
|
currentPage1.value = val |
||||
|
} |
||||
|
|
||||
|
const list = computed(() => { |
||||
|
let arr = JSON.parse(JSON.stringify(props.data)) |
||||
|
return arr.splice((currentPage1.value - 1) * 10, 10) |
||||
|
}) |
||||
|
|
||||
|
const listLoading = ref(false) |
||||
|
const confirmEdit = (row) => { |
||||
|
row.edit = false |
||||
|
} |
||||
|
const cancelEdit = (row) => { |
||||
|
row.edit = false |
||||
|
} |
||||
|
|
||||
|
import { reactive } from 'vue' |
||||
|
|
||||
|
let obj = {} |
||||
|
let search = [] |
||||
|
for (let item of props.columns) { |
||||
|
if (item.inSearch) { |
||||
|
obj[item.name] = null |
||||
|
} |
||||
|
if (item.inSearch) { |
||||
|
search.push(item) |
||||
|
} |
||||
|
} |
||||
|
const formSearchData = ref(search) |
||||
|
const formInline = reactive(obj) |
||||
|
|
||||
|
const onSubmit = () => { |
||||
|
console.log('submit!', formInline) |
||||
|
emit('onSubmit', formInline) |
||||
|
} |
||||
|
|
||||
|
const reset = (formEl: FormInstance | undefined) => { |
||||
|
formSearchData.value.forEach((item) => { |
||||
|
formInline[item.name] = null |
||||
|
}) |
||||
|
emit('reset') |
||||
|
} |
||||
|
const deleteAction = (row) => { |
||||
|
ElMessageBox.confirm('你确定要删除当前项吗?', '温馨提示', { |
||||
|
confirmButtonText: '确定', |
||||
|
cancelButtonText: '取消', |
||||
|
type: 'warning', |
||||
|
draggable: true, |
||||
|
}) |
||||
|
.then(() => { |
||||
|
list.value = list.value.filter((item) => item.id !== row.id) |
||||
|
ElMessage.success('删除成功') |
||||
|
}) |
||||
|
.catch(() => {}) |
||||
|
} |
||||
|
</script> |
||||
|
<style scoped lang="scss"> |
||||
|
.edit-input { |
||||
|
padding-right: 100px; |
||||
|
} |
||||
|
.cancel-btn { |
||||
|
position: absolute; |
||||
|
right: 15px; |
||||
|
top: 10px; |
||||
|
} |
||||
|
.zb-pro-table { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
display:flex; |
||||
|
flex-direction:column; |
||||
|
|
||||
|
.header{ |
||||
|
display: flex; |
||||
|
padding: 16px 16px 0 16px; |
||||
|
margin-bottom: 16px; |
||||
|
border-radius: 4px; |
||||
|
background: white; |
||||
|
box-shadow: 0 0 12px rgb(0 0 0 / 5%); |
||||
|
.search-form{ |
||||
|
flex: 1; |
||||
|
::v-deep{ |
||||
|
.el-input--default{ |
||||
|
width: 200px; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
.search{ |
||||
|
flex-shrink: 0; |
||||
|
white-space: nowrap; |
||||
|
} |
||||
|
} |
||||
|
.footer{ |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
padding: 16px; |
||||
|
flex-direction: column; |
||||
|
border-radius: 4px; |
||||
|
overflow: hidden; |
||||
|
background: white; |
||||
|
box-shadow: 0 0 12px rgb(0 0 0 / 5%); |
||||
|
min-height: 300px; |
||||
|
.operator{ |
||||
|
margin-bottom: 15px |
||||
|
} |
||||
|
.table{ |
||||
|
position: relative; |
||||
|
flex: 1; |
||||
|
} |
||||
|
.zb-table{ |
||||
|
position: absolute; |
||||
|
height: 100%; |
||||
|
} |
||||
|
} |
||||
|
::v-deep{ |
||||
|
.el-table__header th{ |
||||
|
font-size: 15px; |
||||
|
font-weight: 700; |
||||
|
color: #252525; |
||||
|
} |
||||
|
} |
||||
|
.pagination{ |
||||
|
width: 100%; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
padding-top: 20px; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,88 @@ |
|||||
|
<template> |
||||
|
<el-upload |
||||
|
action="" |
||||
|
:before-upload="beforeUploadAction" |
||||
|
:list-type="listType" |
||||
|
:multiple="multiple" |
||||
|
:on-preview="handlePictureCardPreview" |
||||
|
:on-remove="handleRemove" |
||||
|
:file-list="fileList" |
||||
|
> |
||||
|
<el-icon><Plus /></el-icon> |
||||
|
</el-upload> |
||||
|
|
||||
|
<el-dialog v-model="dialogVisible" width="50%" top="80px"> |
||||
|
<img w-full :src="dialogImageUrl" alt="预览图片" style="width: 100%" /> |
||||
|
</el-dialog> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts" setup> |
||||
|
import { onMounted, ref, watch } from 'vue' |
||||
|
import { Plus } from '@element-plus/icons-vue' |
||||
|
|
||||
|
import type { UploadProps, UploadUserFile } from 'element-plus' |
||||
|
import { ElMessage } from 'element-plus' |
||||
|
let emit = defineEmits(['update']) |
||||
|
let props = defineProps({ |
||||
|
modelValue: Array, |
||||
|
multiple: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
listType: { |
||||
|
type: String, |
||||
|
default: 'picture-card', |
||||
|
}, |
||||
|
showFileList: { |
||||
|
type: Boolean, |
||||
|
default: true, |
||||
|
}, |
||||
|
}) |
||||
|
let fileList = ref([]) |
||||
|
|
||||
|
const dialogImageUrl = ref('') |
||||
|
const dialogVisible = ref(false) |
||||
|
|
||||
|
const handleRemove: UploadProps['onRemove'] = (uploadFile, uploadFiles) => { |
||||
|
console.log(uploadFile, uploadFiles) |
||||
|
} |
||||
|
|
||||
|
const beforeUploadAction = (file, fileLi) => { |
||||
|
return new Promise((resolve, reject) => { |
||||
|
var reader = new FileReader() |
||||
|
let reg = /\.jpg$|\.jpeg$|\.gif$|\.png$/i |
||||
|
reader.readAsDataURL(file) |
||||
|
let name = file.name |
||||
|
if (reg.test(name)) { |
||||
|
reader.onload = (e: FileReader) => { |
||||
|
fileList.value.push({ |
||||
|
name: name, |
||||
|
url: e.target.result, |
||||
|
}) |
||||
|
emit('update', fileList.value) |
||||
|
resolve(e.target.result) |
||||
|
} |
||||
|
} else { |
||||
|
ElMessage.error('请上传图片') |
||||
|
reject() |
||||
|
} |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => { |
||||
|
dialogImageUrl.value = uploadFile.url! |
||||
|
dialogVisible.value = true |
||||
|
} |
||||
|
|
||||
|
onMounted(() => { |
||||
|
watch( |
||||
|
() => props.modelValue, |
||||
|
(value) => { |
||||
|
fileList.value = value |
||||
|
}, |
||||
|
{ |
||||
|
immediate: true, |
||||
|
}, |
||||
|
) |
||||
|
}) |
||||
|
</script> |
||||
@ -0,0 +1,80 @@ |
|||||
|
<template> |
||||
|
<div class="m-wangEditor"> |
||||
|
<Toolbar |
||||
|
style="border-bottom: 1px solid #ccc" |
||||
|
:editor="editorRef" |
||||
|
:defaultConfig="toolbarConfig" |
||||
|
:mode="mode" |
||||
|
/> |
||||
|
<Editor |
||||
|
class="editor-content'" |
||||
|
style="height: 300px; overflow-y: hidden;" |
||||
|
v-model="valueHtml" |
||||
|
:defaultConfig="editorConfig" |
||||
|
:mode="mode" |
||||
|
@onCreated="handleCreated" |
||||
|
/> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
// 引入 wangEditor |
||||
|
import { Editor, Toolbar } from "@wangeditor/editor-for-vue"; |
||||
|
import '@wangeditor/editor/dist/css/style.css' // 引入 css |
||||
|
import {onBeforeUnmount, onMounted, watch, shallowRef, ref, computed} from 'vue' |
||||
|
let editors = null |
||||
|
// 编辑器实例,必须用 shallowRef |
||||
|
const editorRef = shallowRef() |
||||
|
const toolbarConfig = {} |
||||
|
const editorConfig = { placeholder: '请输入内容...' } |
||||
|
|
||||
|
// 内容 HTML |
||||
|
const mode = ref('default') |
||||
|
let emit = defineEmits(['update:modelValue']) |
||||
|
let props = defineProps({ |
||||
|
modelValue: String, |
||||
|
}) |
||||
|
|
||||
|
const getEditorData = () => { |
||||
|
// 通过代码获取编辑器内容 |
||||
|
let data = editors.txt.html() |
||||
|
alert(data) |
||||
|
} |
||||
|
|
||||
|
const handleCreated = (editor) => { |
||||
|
editorRef.value = editor // 记录 editor 实例,重要! |
||||
|
} |
||||
|
|
||||
|
const valueHtml = computed({ |
||||
|
get(){ |
||||
|
return props.modelValue |
||||
|
}, |
||||
|
set(val){ |
||||
|
// 防止富文本内容为空时,校验失败 |
||||
|
if (editorRef.value.isEmpty()) val = ""; |
||||
|
emit('update:modelValue', val) |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// 组件销毁时,也及时销毁编辑器 |
||||
|
onBeforeUnmount(()=>{ |
||||
|
// 调用销毁 API 对当前编辑器实例进行销毁 |
||||
|
const editor = editorRef.value |
||||
|
if (editor == null) { |
||||
|
return |
||||
|
} |
||||
|
editor.destroy() |
||||
|
}) |
||||
|
</script> |
||||
|
<style lang="scss" scoped> |
||||
|
.m-wangEditor{ |
||||
|
z-index: 99; |
||||
|
width: 100%; |
||||
|
border: 1px solid #cccccc; |
||||
|
.editor-toolbar { |
||||
|
border-bottom: 1px solid #cccccc; |
||||
|
} |
||||
|
.editor-content { |
||||
|
overflow-y: hidden; |
||||
|
} |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,8 @@ |
|||||
|
<template> |
||||
|
<div class="zb-pipeline"> |
||||
|
<zb-pipeline-start /> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import ZbPipelineStart from './zb-pipeline-start' |
||||
|
</script> |
||||
@ -0,0 +1,154 @@ |
|||||
|
<template> |
||||
|
<div class="zb-pipeline-start-wrapper"> |
||||
|
<div |
||||
|
class="zb-pipeline-start" |
||||
|
v-bind:class="control === value ? 'active' : ''" |
||||
|
v-on:click="handleClick" |
||||
|
> |
||||
|
<div class="zb-pipeline-start-header"> |
||||
|
<zb-icon type="play-filled" /> |
||||
|
</div> |
||||
|
<div class="zb-pipeline-start-body"> |
||||
|
<div class="zb-pipeline-start-title">开始</div> |
||||
|
<div class="zb-pipeline-start-tooltip"> |
||||
|
<el-tooltip placement="top-start" content="点击进行构建基础设置"> |
||||
|
<el-icon> |
||||
|
<Help /> |
||||
|
</el-icon> |
||||
|
</el-tooltip> |
||||
|
<!-- <zb-tooltip placement="right">--> |
||||
|
<!-- <zb-icon type="help" />--> |
||||
|
<!-- <div slot="content">点击进行构建基础设置</div>--> |
||||
|
<!-- </zb-tooltip>--> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<slot></slot> |
||||
|
</div> |
||||
|
</template> |
||||
|
<script lang="ts" setup> |
||||
|
import { Help } from '@element-plus/icons-vue' |
||||
|
</script> |
||||
|
<style> |
||||
|
/* zb-pipeline-start-wrapper */ |
||||
|
.zb-pipeline-start-wrapper { |
||||
|
position: relative; |
||||
|
padding: 0 40px; |
||||
|
} |
||||
|
|
||||
|
/* zb-pipeline-start */ |
||||
|
.zb-pipeline-start { |
||||
|
cursor: pointer; |
||||
|
user-select: none; |
||||
|
position: relative; |
||||
|
display: flex; |
||||
|
justify-content: flex-start; |
||||
|
align-items: stretch; |
||||
|
width: 200px; |
||||
|
height: 40px; |
||||
|
border-radius: 2px; |
||||
|
background-color: #fff; |
||||
|
} |
||||
|
.zb-pipeline-start:after { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
top: 20px; |
||||
|
right: -40px; |
||||
|
display: block; |
||||
|
width: 40px; |
||||
|
height: 1px; |
||||
|
background-color: #2d8cf0; |
||||
|
} |
||||
|
.zb-pipeline-start .zb-pipeline-start-header { |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
width: 40px; |
||||
|
border-width: 1px 0 1px 1px; |
||||
|
border-style: solid; |
||||
|
border-color: #2d8cf0; |
||||
|
border-radius: 2px 0 0 2px; |
||||
|
background-color: #2d8cf0; |
||||
|
color: #fff; |
||||
|
font-size: 14px; |
||||
|
font-weight: 600; |
||||
|
transition: all 0.2s cubic-bezier(0.23, 1, 0.32, 1); |
||||
|
} |
||||
|
.zb-pipeline-start .zb-pipeline-start-body { |
||||
|
flex: 1; |
||||
|
display: flex; |
||||
|
border-width: 1px 1px 1px 0; |
||||
|
border-style: solid; |
||||
|
border-color: #e3e8f0; |
||||
|
border-radius: 0 2px 2px 0; |
||||
|
padding: 0 8px; |
||||
|
overflow: hidden; |
||||
|
transition: all 0.2s cubic-bezier(0.23, 1, 0.32, 1); |
||||
|
} |
||||
|
.zb-pipeline-start .zb-pipeline-start-title { |
||||
|
flex: 1; |
||||
|
display: block; |
||||
|
overflow: hidden; |
||||
|
color: #262626; |
||||
|
font-size: 14px; |
||||
|
font-weight: 600; |
||||
|
line-height: 38px; |
||||
|
white-space: nowrap; |
||||
|
text-overflow: ellipsis; |
||||
|
} |
||||
|
.zb-pipeline-start .zb-pipeline-start-tooltip { |
||||
|
cursor: pointer; |
||||
|
display: flex; |
||||
|
justify-content: center; |
||||
|
align-items: center; |
||||
|
margin-left: 8px; |
||||
|
} |
||||
|
.zb-pipeline-start .zb-pipeline-start-tooltip .zb-tooltip { |
||||
|
display: block; |
||||
|
} |
||||
|
.zb-pipeline-start .zb-pipeline-start-tooltip .zb-icon { |
||||
|
display: block; |
||||
|
color: #595959; |
||||
|
font-size: 14px; |
||||
|
} |
||||
|
|
||||
|
/* zb-pipeline-start hover */ |
||||
|
.zb-pipeline-start:hover { |
||||
|
} |
||||
|
.zb-pipeline-start:hover:after { |
||||
|
} |
||||
|
.zb-pipeline-start:hover .zb-pipeline-start-header { |
||||
|
border-color: #2d8cf0; |
||||
|
} |
||||
|
.zb-pipeline-start:hover .zb-pipeline-start-body { |
||||
|
border-color: #2d8cf0; |
||||
|
} |
||||
|
.zb-pipeline-start:hover .zb-pipeline-start-title { |
||||
|
} |
||||
|
.zb-pipeline-start:hover .zb-pipeline-start-tooltip { |
||||
|
} |
||||
|
.zb-pipeline-start:hover .zb-pipeline-start-tooltip .zb-tooltip { |
||||
|
} |
||||
|
.zb-pipeline-start:hover .zb-pipeline-start-tooltip .zb-icon { |
||||
|
} |
||||
|
|
||||
|
/* zb-pipeline-start active */ |
||||
|
.zb-pipeline-start.active { |
||||
|
} |
||||
|
.zb-pipeline-start.active:after { |
||||
|
} |
||||
|
.zb-pipeline-start.active .zb-pipeline-start-header { |
||||
|
border-color: #2d8cf0; |
||||
|
} |
||||
|
.zb-pipeline-start.active .zb-pipeline-start-body { |
||||
|
border-color: #2d8cf0; |
||||
|
} |
||||
|
.zb-pipeline-start.active .zb-pipeline-start-title { |
||||
|
} |
||||
|
.zb-pipeline-start.active .zb-pipeline-start-tooltip { |
||||
|
} |
||||
|
.zb-pipeline-start.active .zb-pipeline-start-tooltip .zb-tooltip { |
||||
|
} |
||||
|
.zb-pipeline-start.active .zb-pipeline-start-tooltip .zb-icon { |
||||
|
} |
||||
|
</style> |
||||
@ -0,0 +1,2 @@ |
|||||
|
// * 默认主题颜色
|
||||
|
export const PRIMARY_COLOR: string = "#409eff"; |
||||
@ -0,0 +1,11 @@ |
|||||
|
import Vue from 'vue' |
||||
|
import SvgIcon from '@/components/SvgIcon' // svg component
|
||||
|
|
||||
|
|
||||
|
// const req = require.context('./svg', false, /\.svg$/)
|
||||
|
const req = import.meta.globEager('./svg/*.svg') |
||||
|
|
||||
|
const requireAll = (requireContext) => requireContext.keys().map(requireContext) |
||||
|
requireAll(req) |
||||
|
|
||||
|
export default SvgIcon |
||||
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 831 B |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
After Width: | Height: | Size: 497 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 944 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 421 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 920 B |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 285 B |
|
After Width: | Height: | Size: 821 B |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 623 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 750 B |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 211 B |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 597 B |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 786 B |
|
After Width: | Height: | Size: 980 B |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 440 B |
@ -0,0 +1,22 @@ |
|||||
|
# replace default config |
||||
|
|
||||
|
# multipass: true |
||||
|
# full: true |
||||
|
|
||||
|
plugins: |
||||
|
|
||||
|
# - name |
||||
|
# |
||||
|
# or: |
||||
|
# - name: false |
||||
|
# - name: true |
||||
|
# |
||||
|
# or: |
||||
|
# - name: |
||||
|
# param1: 1 |
||||
|
# param2: 2 |
||||
|
|
||||
|
- removeAttrs: |
||||
|
attrs: |
||||
|
- 'fill' |
||||
|
- 'fill-rule' |
||||