test: 测试: 添加docker和一些基础配置

This commit is contained in:
bunny 2024-02-27 14:51:41 +08:00
commit 28f0cd9227
73 changed files with 16440 additions and 0 deletions

4
.browserslistrc Normal file
View File

@ -0,0 +1,4 @@
> 1%
last 2 versions
not dead
not ie 11

14
.editorconfig Normal file
View File

@ -0,0 +1,14 @@
# http://editorconfig.org
root = true
[*] # 表示所有文件适用
charset = utf-8 # 设置文件字符集为 utf-8
end_of_line = lf # 控制换行类型(lf | cr | crlf)
insert_final_newline = false # 始终在文件末尾插入一个新行
indent_style = tab # 缩进风格tab | space
indent_size = 2 # 缩进大小
max_line_length = 130 # 最大行长度
[*.md] # 表示仅 md 文件适用以下规则
max_line_length = off # 关闭最大行长度限制
trim_trailing_whitespace = false # 关闭末尾空格修剪

5
.eslintignore Normal file
View File

@ -0,0 +1,5 @@
vue.config.js
list
.prettierrc.js
.stylelintrc.js
src/utils/request.js

16
.eslintrc.js Normal file
View File

@ -0,0 +1,16 @@
module.exports = {
root: true,
env: {
node: true,
},
extends: ['plugin:vue/vue3-essential', 'eslint:recommended', '@vue/typescript/recommended', 'plugin:prettier/recommended'],
parserOptions: {
ecmaVersion: 2020,
},
rules: {
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'vue/multi-word-component-names': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

4
.husky/commit-msg Normal file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install commitlint --edit $1

4
.husky/pre-commit Normal file
View File

@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint:lint-staged

1
.prettierignore Normal file
View File

@ -0,0 +1 @@
list

39
.prettierrc.js Normal file
View File

@ -0,0 +1,39 @@
// @see: https://www.prettier.cn
module.exports = {
// 超过最大值换行
printWidth: 130,
// 缩进字节数
tabWidth: 1,
// 使用制表符而不是空格缩进行
useTabs: true,
// 结尾不用分号(true有false没有)
semi: true,
// 使用单引号(true单引号false双引号)
singleQuote: true,
// 更改引用对象属性的时间 可选值"<as-needed|consistent|preserve>"
quoteProps: 'as-needed',
// 在对象,数组括号与文字之间加空格 "{ foo: bar }"
bracketSpacing: true,
// 多行时尽可能打印尾随逗号。(例如,单行数组永远不会出现逗号结尾。) 可选值"<none|es5|all>"默认none
trailingComma: 'all',
// 在JSX中使用单引号而不是双引号
jsxSingleQuote: true,
// (x) => {} 箭头函数参数只有一个时是否要有小括号。avoid省略括号 ,always不省略括号
arrowParens: 'avoid',
// 如果文件顶部已经有一个 doclock这个选项将新建一行注释并打上@format标记。
insertPragma: false,
// 指定要使用的解析器,不需要写文件开头的 @prettier
requirePragma: false,
// 默认值。因为使用了一些折行敏感型的渲染器如GitHub comment而按照markdown文本样式进行折行
proseWrap: 'preserve',
// 在html中空格是否是敏感的 "css" - 遵守CSS显示属性的默认值 "strict" - 空格被认为是敏感的 "ignore" - 空格被认为是不敏感的
htmlWhitespaceSensitivity: 'css',
// 换行符使用 lf 结尾是 可选值"<auto|lf|crlf|cr>"
endOfLine: 'auto',
// 这两个选项可用于格式化以给定字符偏移量(分别包括和不包括)开始和结束的代码
rangeStart: 0,
rangeEnd: Infinity,
vueIndentScriptAndStyle: false, // Vue文件脚本和样式标签缩进
};

1
.stylelintignore Normal file
View File

@ -0,0 +1 @@
build

49
.stylelintrc.js Normal file
View File

@ -0,0 +1,49 @@
// npm i stylelint-config-standard stylelint-config-standard-scss stylelint-config-recess-order stylelint-config-prettier
// npm i stylelint-config-html stylelint-config-recommended-vue
// @see: https://stylelint.io
module.exports = {
/* 继承某些已有的规则 */
extends: [
'stylelint-config-standard', // 配置stylelint拓展插件
'stylelint-config-html/vue', // 配置 vue 中 template 样式格式化
'stylelint-config-standard-scss', // 配置stylelint scss插件
'stylelint-config-recommended-vue/scss', // 配置 vue 中 scss 样式格式化
'stylelint-config-recess-order', // 配置stylelint css属性书写顺序插件,
'stylelint-config-prettier', // 配置stylelint和prettier兼容
],
overrides: [
// 扫描 .vue/html 文件中的<style>标签内的样式
{
files: ['**/*.{vue,html}'],
customSyntax: 'postcss-html',
},
],
/**
* null => 关闭该规则
*/
rules: {
'value-keyword-case': null, // 在 css 中使用 v-bind不报错
'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器
'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)"
'string-quotes': 'double', // 指定字符串使用单引号或双引号
'unit-case': null, // 指定单位的大小写 "lower(全小写)"|"upper(全大写)"
'color-hex-case': 'lower', // 指定 16 进制颜色的大小写 "lower(全小写)"|"upper(全大写)"
'color-hex-length': 'long', // 指定 16 进制颜色的简写或扩写 "short(16进制简写)"|"long(16进制扩写)"
'rule-empty-line-before': 'never', // 要求或禁止在规则之前的空行 "always(规则之前必须始终有一个空行)"|"never(规则前绝不能有空行)"|"always-multi-line(多行规则之前必须始终有一个空行)"|"never-multi-line(多行规则之前绝不能有空行。)"
'font-family-no-missing-generic-family-keyword': null, // 禁止在字体族名称列表中缺少通用字体族关键字
'block-opening-brace-space-before': 'always', // 要求在块的开大括号之前必须有一个空格或不能有空白符 "always(大括号前必须始终有一个空格)"|"never(左大括号之前绝不能有空格)"|"always-single-line(在单行块中的左大括号之前必须始终有一个空格)"|"never-single-line(在单行块中的左大括号之前绝不能有空格)"|"always-multi-line(在多行块中,左大括号之前必须始终有一个空格)"|"never-multi-line(多行块中的左大括号之前绝不能有空格)"
'property-no-unknown': null, // 禁止未知的属性(true 为不允许)
'no-empty-source': null, // 禁止空源码
'declaration-block-trailing-semicolon': null, // 要求或不允许在声明块中使用尾随分号 string"always(必须始终有一个尾随分号)"|"never(不得有尾随分号)"
'selector-class-pattern': null, // 强制选择器类名的格式
'scss/at-import-partial-extension': null, // 解决不能引入scss文件
'value-no-vendor-prefix': null, // 关闭 vendor-prefix(为了解决多行省略 -webkit-box)
'selector-pseudo-class-no-unknown': [
true,
{
ignorePseudoClasses: ['global', 'v-deep', 'deep'],
},
],
},
};

16
README.md Normal file
View File

@ -0,0 +1,16 @@
# vue-pinia看板rem布局
欢迎使用bunny-cli。
这个项目模板只涉及rem不涉及其它内容。
## 注意事项
### 打包成apk
1. 如果需要打包成apk要将路由改为hash路由
2. 打包成apk将公共路径改为`./`
3. 打包成apk需要考虑跨域跨域由于打包时没有NGINX做代理所以无法完成只能后端做跨域否则接口访问不到。
4. 要设置APPID因为HBuilderX必须要获取。
### docker配置
默认配置中已经集成了NGINX和dockfile文件后面自动化部署等直接用即可

3
babel.config.js Normal file
View File

@ -0,0 +1,3 @@
module.exports = {
presets: ["@vue/cli-plugin-babel/preset"],
};

106
commitlint.config.js Normal file
View File

@ -0,0 +1,106 @@
// @see: https://cz-git.qbenben.com/zh/guide
/** @type {import('cz-git').UserConfig} */
module.exports = {
ignores: [commit => commit === 'init'],
extends: ['@commitlint/config-conventional'],
rules: {
// @see: https://commitlint.js.org/#/reference-rules
'body-leading-blank': [2, 'always'],
'footer-leading-blank': [1, 'always'],
'header-max-length': [2, 'always', 108],
'subject-empty': [2, 'never'],
'type-empty': [2, 'never'],
'subject-case': [0],
'type-enum': [
2,
'always',
[
'init',
'feat',
'page',
'completepage',
'fix',
'fixbug',
'docs',
'style',
'refactor',
'perf',
'test',
'build',
'ci',
'chore',
'revert',
'wip',
'workflow',
'types',
'release',
'optimize',
],
],
},
prompt: {
messages: {
type: '选择你要提交的类型 :',
scope: '选择一个提交范围(可选):',
customScope: '请输入自定义的提交范围 :',
subject: '填写简短精炼的变更描述 :\n',
body: '填写更加详细的变更描述(可选)。使用 "|" 换行 :\n',
breaking: '列举非兼容性重大的变更(可选)。使用 "|" 换行 :\n',
footerPrefixsSelect: '选择关联issue前缀可选:',
customFooterPrefixs: '输入自定义issue前缀 :',
footer: '列举关联issue (可选) 例如: #31, #I3244 :\n',
confirmCommit: '是否提交或修改commit ?',
},
types: [
{ value: 'init: 初始化', name: '初始化: ⏳ 初始化项目', emoji: '⏳' },
{ value: 'optimize: 优化代码', name: '优化代码: ♻️ 优化项目代码', emoji: '♻️' },
{ value: 'feat: 新增功能', name: '新增: 🚀 新增功能', emoji: '🚀' },
{ value: 'page: 新增页面', name: '页面: 📄 新增页面', emoji: '📄' },
{ value: 'completepage: 完成页面', name: '完成页面: 🍻 完成页面', emoji: '🍻' },
{ value: 'fixbug: 修改bug', name: 'bug: 🐛 修改bug', emoji: '🐛' },
{ value: 'fix: 修复', name: '修复: 🧩 修复缺陷', emoji: '🧩' },
{ value: 'docs: 文档', name: '文档: 📚 文档变更', emoji: '📚' },
{ value: 'style: 格式', name: '格式: 🎨 代码格式(不影响功能,例如空格、分号等格式修正)', emoji: '🎨' },
{ value: 'refactor: 重构', name: '重构: 〽️ 代码重构(不包括 bug 修复、功能新增)', emoji: '〽️' },
{ value: 'perf: 性能', name: '性能: ⚡️ 性能优化', emoji: '⚡️' },
{ value: 'test: 测试', name: '测试: ✅ 添加疏漏测试或已有测试改动', emoji: '✅' },
{
value: 'chore: 构建',
name: '构建: 📦️ 构建流程、外部依赖变更(如升级 npm 包、修改 webpack 配置等)',
emoji: '📦️',
},
{ value: 'ci: 集成', name: '集成: 🎡 修改 CI 配置、脚本', emoji: '🎡' },
{ value: 'revert: 回退', name: '回退: ⏪️ 回滚 commit', emoji: '⏪️' },
{ value: 'build: 打包', name: '打包: 🔨 项目打包发布', emoji: '🔨' },
],
useEmoji: true,
themeColorCode: '',
scopes: [],
allowCustomScopes: true,
allowEmptyScopes: true,
customScopesAlign: 'bottom',
customScopesAlias: 'custom',
emptyScopesAlias: 'empty',
upperCaseSubject: false,
allowBreakingChanges: ['feat', 'fix'],
breaklineNumber: 100,
breaklineChar: '|',
skipQuestions: [],
issuePrefixs: [{ value: 'closed', name: 'closed: ISSUES has been processed' }],
customIssuePrefixsAlign: 'top',
emptyIssuePrefixsAlias: 'skip',
customIssuePrefixsAlias: 'custom',
allowCustomIssuePrefixs: true,
allowEmptyIssuePrefixs: true,
confirmColorize: true,
maxHeaderLength: Infinity,
maxSubjectLength: Infinity,
minSubjectLength: 0,
scopeOverrides: undefined,
defaultBody: '',
defaultIssues: '',
defaultScope: '',
defaultSubject: '',
},
};

23
docker/dockerfile Normal file
View File

@ -0,0 +1,23 @@
# 使用官方的 Nginx 镜像作为基础镜像
FROM nginx
# 删除默认的 Nginx 配置文件
RUN rm /etc/nginx/conf.d/default.conf
# 将自定义的 Nginx 配置文件复制到容器中
COPY nginx.conf /etc/nginx/conf.d/
# 创建一个目录来存放前端项目文件
WORKDIR /usr/share/nginx/html
# 将前端项目打包文件复制到 Nginx 的默认静态文件目录
COPY dist/ /usr/share/nginx/html
# 复制到nginx目录下
COPY dist/ /etc/nginx/html
# 暴露 Nginx 的默认端口
EXPOSE 80
# 自动启动 Nginx
CMD ["nginx", "-g", "daemon off;"]

22
docker/nginx.conf Normal file
View File

@ -0,0 +1,22 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /etc/nginx/html;
index index.html index.htm;
try_files $uri /index.html;
}
# 后端跨域请求
location ~/api/ {
proxy_pass http://192.168.3.98:1001;
}
error_page 404 404.html;
location = /50x.html {
root html;
}
}

7
lint-staged.config.js Normal file
View File

@ -0,0 +1,7 @@
module.exports = {
'*.{js,jsx,ts,tsx,vue}': ['eslint --fix', 'prettier --write'],
'{!(package)*.json,*.code-snippets,.!(browserslist)*rc}': ['prettier --write--parser json'],
'package.json': ['prettier --write'],
'*.{scss,less,styl,html,vue}': ['stylelint --fix', 'prettier --write'],
'*.md': ['prettier --write'],
};

15526
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

74
package.json Normal file
View File

@ -0,0 +1,74 @@
{
"name": "vue_ts_pina",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint",
"lint:eslint": "eslint --fix --ext .js,.ts,.vue ./src",
"lint:prettier": "prettier --write --loglevel warn \"src/**/*.{js,ts,json,tsx,css,less,scss,vue,html,md}\"",
"lint:stylelint": "stylelint --cache --fix \"**/*.{vue,less,postcss,css,scss}\" --cache --cache-location node_modules/.cache/stylelint/",
"lint:lint-staged": "lint-staged",
"prepare": "husky install",
"release": "standard-version",
"commit": "git status && git add -A && git-cz"
},
"dependencies": {
"axios": "^1.6.2",
"core-js": "^3.8.3",
"dayjs": "^1.11.10",
"echarts": "^5.5.0",
"loadsh": "^0.0.4",
"pinia": "^2.1.7",
"postcss-pxtorem": "^6.1.0",
"stylelint-config-recess-order": "^4.6.0",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^36.0.0",
"stylelint-config-standard-scss": "^13.0.0",
"uuid": "^9.0.1",
"vue": "^3.2.13",
"vue-cookies": "^1.8.3",
"vue-echarts": "^6.6.9",
"vue-lazyload": "^3.0.0",
"vue-router": "^4.0.3",
"webpackbar": "^6.0.0"
},
"devDependencies": {
"@commitlint/cli": "^18.4.3",
"@commitlint/config-conventional": "^18.4.3",
"@typescript-eslint/eslint-plugin": "^5.4.0",
"@typescript-eslint/parser": "^5.4.0",
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-eslint": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"@vue/eslint-config-typescript": "^9.1.0",
"commitizen": "^4.3.0",
"cz-git": "^1.8.0",
"eslint": "^7.32.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^8.0.3",
"husky": "^8.0.3",
"lint-staged": "^11.2.6",
"postcss": "^8.4.32",
"postcss-html": "^1.5.0",
"prettier": "^2.4.1",
"sass": "^1.71.0",
"sass-loader": "^12.0.0",
"stylelint": "^14.16.1",
"stylelint-config-html": "^1.1.0",
"stylelint-config-prettier": "^9.0.5",
"typescript": "~4.5.5"
},
"gitHooks": {
"pre-commit": "lint-staged"
},
"config": {
"commitizen": {
"path": "node_modules/cz-git"
}
}
}

6
postcss.config.js Normal file
View File

@ -0,0 +1,6 @@
const autoprefixer = require('autoprefixer');
const px2rem = require('postcss-pxtorem');
module.exports = {
plugins: [autoprefixer(), px2rem({ rootValue: 80, unitPrecision: 5, propList: ['*'] })],
};

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

17
public/index.html Normal file
View File

@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>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>

24
src/App.vue Normal file
View File

@ -0,0 +1,24 @@
<template>
<router-view />
</template>
<script lang="ts" setup>
const debounce = (callback: (...args: any[]) => void, delay: number) => {
let tid: any;
return function (...args: any[]) {
const ctx = self;
tid && clearTimeout(tid);
tid = setTimeout(() => {
callback.apply(ctx, args);
}, delay);
};
};
const _ = (window as any).ResizeObserver;
(window as any).ResizeObserver = class ResizeObserver extends _ {
constructor(callback: (...args: any[]) => void) {
callback = debounce(callback, 20);
super(callback);
}
};
</script>
<style lang="scss"></style>

8
src/api/test.ts Normal file
View File

@ -0,0 +1,8 @@
import Request from '@/utils/request';
export const reqGetLoadBoard = () => {
return Request({
url: '/board/loadBoard',
method: 'GET',
});
};

3
src/assets/css/index.css Normal file
View File

@ -0,0 +1,3 @@
body {
background-color: #000;
}

82
src/assets/css/reset.css Normal file
View File

@ -0,0 +1,82 @@
/* 选中文字颜色 */
*::selection {
color: #1f1f1f;
background: #b3d4fc;
}
/*定义滚动条高宽及背景高宽分别对应横竖滚动条的尺寸*/
::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: #f5f5f5;
}
/*定义滚动条轨道内阴影+圆角*/
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px #ccc;
border-radius: 5px;
background-color: #f5f5f5;
}
/*定义滑块内阴影+圆角*/
::-webkit-scrollbar-thumb {
border-radius: 5px;
-webkit-box-shadow: inset 0 0 6px #ccc;
background-color: #ccc;
}
html,body{height:100%;}
html,body,h1,h2,h3,h4,h5,h6,div,dl,dt,dd,ul,ol,li,p,blockquote,pre,hr,figure,table,caption,th,td,form,fieldset,legend,input,button,textarea,menu{margin:0;padding:0;}
header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:block;}
table{border-collapse:collapse;border-spacing:0;}
caption,th{text-align:left;font-weight:normal;}
html,body,fieldset,img,iframe,abbr{border:0;}
i,cite,em,var,address,dfn{font-style:normal;}
[hidefocus],summary{outline:0;}
li{list-style:none;}
h1,h2,h3,h4,h5,h6,small{font-size:100%;}
sup,sub{font-size:83%;}
pre,code,kbd,samp{font-family:inherit;}
q:before,q:after{content:none;}
textarea{overflow:auto;resize:none;}
label,summary{cursor:default;}
a,button{cursor:pointer;}
h1,h2,h3,h4,h5,h6,em,strong,b{font-weight:bold;}
del,ins,u,s,a,a:hover{text-decoration:none;}
body,textarea,input,button,select,keygen,legend{font: Microsoft YaHei,arial,\5b8b\4f53;color:#333;outline:0;}
body{background:#fff;}
a,a:hover{color:#333;}
*{box-sizing: border-box;}
/* 去除input默认填充的背景颜色 */
input:-webkit-autofill {
-webkit-box-shadow: 0 0 0px 1000px white inset;
}
/* 清除input[type=number]的默认样式 */
input[type=number] {
-moz-appearance:textfield;
}
input[type=number]::-webkit-inner-spin-button,
input[type=number]::-webkit-outer-spin-button {
-webkit-appearance: none;
margin: 0;
}
/* 清除移动端 a 标签等点击区域变色 */
*{
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}
/* 清除移动端 input 样式 */
input{
border: none;
-moz-appearance:none;
-webkit-appearance : none ; /*解决ios上按钮的圆角问题*/
border-radius: 0; /*解决ios上输入框圆角问题*/
outline:medium; /*去掉鼠标点击的默认黄色边框*/
background-color: transparent;
}
/* 避免ios滑动滚动条卡顿 */
*{
-webkit-overflow-scrolling : touch
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 133 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

14
src/main.ts Normal file
View File

@ -0,0 +1,14 @@
import 'echarts';
import { createPinia } from 'pinia';
import { createApp } from 'vue';
import ECharts from 'vue-echarts';
import App from './App.vue';
import './assets/css/reset.css';
import router from './router';
import './utils/lib-flexible.js';
import './utils/rem';
const app = createApp(App);
app.component('VChart', ECharts);
app.use(router).use(createPinia()).mount('#app');

20
src/router/index.ts Normal file
View File

@ -0,0 +1,20 @@
import { createRouter, createWebHashHistory, createWebHistory, RouteRecordRaw } from 'vue-router';
const routes: Array<RouteRecordRaw> = [
{
path: '/',
name: 'layout',
component: () => import(/* webpackChunkName: "layout" */ '@/views/layout.vue'),
},
];
/**
* appHash路由createWebHashHistory
* createWebHistory
*/
const router = createRouter({
history: createWebHashHistory(process.env.BASE_URL),
routes,
});
export default router;

6
src/shims-vue.d.ts vendored Normal file
View File

@ -0,0 +1,6 @@
/* eslint-disable */
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
}

11
src/store/test.ts Normal file
View File

@ -0,0 +1,11 @@
import { defineStore } from 'pinia';
export const testStore = defineStore('testStore', {
state: () => {
return {
count: 0,
};
},
getters: {},
actions: {},
});

135
src/utils/lib-flexible.js Normal file
View File

@ -0,0 +1,135 @@
(function (win, lib) {
var doc = win.document;
var docEl = doc.documentElement;
var metaEl = doc.querySelector('meta[name="viewport"]');
var flexibleEl = doc.querySelector('meta[name="flexible"]');
var dpr = 0;
var scale = 0;
var tid;
var flexible = lib.flexible || (lib.flexible = {});
if (metaEl) {
console.warn('将根据已有的meta标签来设置缩放比例');
var match = metaEl
.getAttribute('content')
// eslint-disable-next-line no-useless-escape
.match(/initial\-scale=([\d\.]+)/);
if (match) {
scale = parseFloat(match[1]);
dpr = parseInt(1 / scale);
}
} else if (flexibleEl) {
var content = flexibleEl.getAttribute('content');
if (content) {
// eslint-disable-next-line no-useless-escape
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/);
// eslint-disable-next-line no-useless-escape
var maximumDpr = content.match(/maximum\-dpr=([\d\.]+)/);
if (initialDpr) {
dpr = parseFloat(initialDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
if (maximumDpr) {
dpr = parseFloat(maximumDpr[1]);
scale = parseFloat((1 / dpr).toFixed(2));
}
}
}
if (!dpr && !scale) {
// var isAndroid = win.navigator.appVersion.match(/android/gi);
var isIPhone = win.navigator.appVersion.match(/iphone/gi);
var devicePixelRatio = win.devicePixelRatio;
if (isIPhone) {
// iOS下对于2和3的屏用2倍的方案其余的用1倍方案
if (devicePixelRatio >= 3 && (!dpr || dpr >= 3)) {
dpr = 3;
} else if (devicePixelRatio >= 2 && (!dpr || dpr >= 2)) {
dpr = 2;
} else {
dpr = 1;
}
} else {
// 其他设备下仍旧使用1倍的方案
dpr = 1;
}
scale = 1 / dpr;
}
docEl.setAttribute('data-dpr', dpr);
if (!metaEl) {
metaEl = doc.createElement('meta');
metaEl.setAttribute('name', 'viewport');
metaEl.setAttribute(
'content',
'initial-scale=' + scale + ', maximum-scale=' + scale + ', minimum-scale=' + scale + ', user-scalable=no',
);
if (docEl.firstElementChild) {
docEl.firstElementChild.appendChild(metaEl);
} else {
var wrap = doc.createElement('div');
wrap.appendChild(metaEl);
doc.write(wrap.innerHTML);
}
}
function refreshRem() {
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = width * dpr;
}
var rem = width / 24;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
win.addEventListener(
'resize',
function () {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
},
false,
);
win.addEventListener(
'pageshow',
function (e) {
if (e.persisted) {
clearTimeout(tid);
tid = setTimeout(refreshRem, 300);
}
},
false,
);
if (doc.readyState === 'complete') {
doc.body.style.fontSize = 12 * dpr + 'px';
} else {
doc.addEventListener(
'DOMContentLoaded',
function () {
doc.body.style.fontSize = 12 * dpr + 'px';
},
false,
);
}
refreshRem();
flexible.dpr = win.dpr = dpr;
flexible.refreshRem = refreshRem;
flexible.rem2px = function (d) {
var val = parseFloat(d) * this.rem;
if (typeof d === 'string' && d.match(/rem$/)) {
val += 'px';
}
return val;
};
flexible.px2rem = function (d) {
var val = parseFloat(d) / this.rem;
if (typeof d === 'string' && d.match(/px$/)) {
val += 'rem';
}
return val;
};
})(window, window['lib'] || (window['lib'] = {}));

12
src/utils/rem.ts Normal file
View File

@ -0,0 +1,12 @@
(function init(screenRatioByDesign = 16 / 9) {
const docEle = document.documentElement;
function setHtmlFontSize() {
const screenRatio = docEle.clientWidth / docEle.clientHeight;
const fontSize = ((screenRatio > screenRatioByDesign ? screenRatioByDesign / screenRatio : 1) * docEle.clientWidth) / 24;
docEle.style.fontSize = fontSize.toFixed(3) + 'px';
}
setHtmlFontSize();
window.addEventListener('resize', setHtmlFontSize);
})();

23
src/utils/request.ts Normal file
View File

@ -0,0 +1,23 @@
import axios from 'axios';
const request = axios.create({
baseURL: '/api',
timeout: 10000,
});
// 请求拦截器
request.interceptors.request.use(config => {
return config;
});
// 响应拦截器
request.interceptors.response.use(
response => {
return response.data;
},
error => {
return Promise.reject(new Error('网络错误'));
},
);
export default request;

90
src/views/layout.vue Normal file
View File

@ -0,0 +1,90 @@
<template>
成功
<div class="box"></div>
<div class="charts">
<ECharts :option="option" autoresize theme="dark" />
</div>
</template>
<script lang="ts" setup>
import { reactive } from 'vue';
import ECharts from 'vue-echarts';
const option = reactive({
title: {
text: 'Rainfall vs Evaporation',
subtext: 'Fake Data',
},
tooltip: {
trigger: 'axis',
},
legend: {
data: ['Rainfall', 'Evaporation'],
},
toolbox: {
show: true,
feature: {
dataView: { show: true, readOnly: false },
magicType: { show: true, type: ['line', 'bar'] },
restore: { show: true },
saveAsImage: { show: true },
},
},
calculable: true,
xAxis: [
{
type: 'category',
// prettier-ignore
data: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
},
],
yAxis: [
{
type: 'value',
},
],
series: [
{
name: 'Rainfall',
type: 'bar',
data: [2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3],
markPoint: {
data: [
{ type: 'max', name: 'Max' },
{ type: 'min', name: 'Min' },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
{
name: 'Evaporation',
type: 'bar',
data: [2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3],
markPoint: {
data: [
{ name: 'Max', value: 182.2, xAxis: 7, yAxis: 183 },
{ name: 'Min', value: 2.3, xAxis: 11, yAxis: 3 },
],
},
markLine: {
data: [{ type: 'average', name: 'Avg' }],
},
},
],
});
</script>
<style scoped lang="scss">
.box {
width: 100px;
height: 100px;
background-color: #e54;
}
.charts {
margin: 0 auto;
width: 800px;
height: 500px;
}
</style>

40
tsconfig.json Normal file
View File

@ -0,0 +1,40 @@
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"jsx": "preserve",
"moduleResolution": "node",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"forceConsistentCasingInFileNames": true,
"useDefineForClassFields": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.tsx",
"src/**/*.vue",
"tests/**/*.ts",
"tests/**/*.tsx"
],
"exclude": [
"node_modules"
]
}

12
vue.config.js Normal file
View File

@ -0,0 +1,12 @@
const { defineConfig } = require('@vue/cli-service');
const WebpackBar = require('webpackbar');
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [
// 设置进度条颜色
new WebpackBar({ color: '#F6DCE0', profile: true }),
],
},
publicPath: process.env.NODE_ENV === 'production' ? './' : './',
});