feat: 整体布局完成
2
.env
|
@ -1,5 +1,5 @@
|
|||
# 应用名称
|
||||
VITE_APP_TITLE="Vite 模板"
|
||||
VITE_APP_TITLE="车辆监控中心"
|
||||
|
||||
# 平台本地运行端口号
|
||||
VITE_PORT=7000
|
||||
|
|
|
@ -1,46 +1,46 @@
|
|||
module.exports = {
|
||||
// (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always)
|
||||
arrowParens: "always",
|
||||
// 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false
|
||||
bracketSameLine: false,
|
||||
// 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar})
|
||||
bracketSpacing: true,
|
||||
// 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto)
|
||||
embeddedLanguageFormatting: "auto",
|
||||
// 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css)
|
||||
htmlWhitespaceSensitivity: "ignore",
|
||||
// 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false
|
||||
insertPragma: false,
|
||||
// 在 JSX 中使用单引号替代双引号,默认false
|
||||
jsxSingleQuote: false,
|
||||
// 每行最多字符数量,超出换行(默认100)
|
||||
printWidth: 100,
|
||||
// 超出打印宽度 (always | never | preserve )
|
||||
proseWrap: "preserve",
|
||||
// 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;)
|
||||
quoteProps: "as-needed",
|
||||
// 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false
|
||||
requirePragma: false,
|
||||
// 结尾添加分号
|
||||
semi: true,
|
||||
// 使用单引号 (true:单引号;false:双引号)
|
||||
singleQuote: false,
|
||||
// 缩进空格数,默认2个空格
|
||||
tabWidth: 2,
|
||||
// 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号
|
||||
trailingComma: "es5",
|
||||
// 指定缩进方式,空格或tab,默认false,即使用空格
|
||||
useTabs: false,
|
||||
// vue 文件中是否缩进 <style> 和 <script> 标签,默认 false
|
||||
vueIndentScriptAndStyle: false,
|
||||
export default {
|
||||
// (x)=>{},单个参数箭头函数是否显示小括号。(always:始终显示;avoid:省略括号。默认:always)
|
||||
arrowParens: "always",
|
||||
// 开始标签的右尖括号是否跟随在最后一行属性末尾,默认false
|
||||
bracketSameLine: false,
|
||||
// 对象字面量的括号之间打印空格 (true - Example: { foo: bar } ; false - Example: {foo:bar})
|
||||
bracketSpacing: true,
|
||||
// 是否格式化一些文件中被嵌入的代码片段的风格(auto|off;默认auto)
|
||||
embeddedLanguageFormatting: "auto",
|
||||
// 指定 HTML 文件的空格敏感度 (css|strict|ignore;默认css)
|
||||
htmlWhitespaceSensitivity: "ignore",
|
||||
// 当文件已经被 Prettier 格式化之后,是否会在文件顶部插入一个特殊的 @format 标记,默认false
|
||||
insertPragma: false,
|
||||
// 在 JSX 中使用单引号替代双引号,默认false
|
||||
jsxSingleQuote: false,
|
||||
// 每行最多字符数量,超出换行(默认100)
|
||||
printWidth: 100,
|
||||
// 超出打印宽度 (always | never | preserve )
|
||||
proseWrap: "preserve",
|
||||
// 对象属性是否使用引号(as-needed | consistent | preserve;默认as-needed:对象的属性需要加引号才添加;)
|
||||
quoteProps: "as-needed",
|
||||
// 是否只格式化在文件顶部包含特定注释(@prettier| @format)的文件,默认false
|
||||
requirePragma: false,
|
||||
// 结尾添加分号
|
||||
semi: true,
|
||||
// 使用单引号 (true:单引号;false:双引号)
|
||||
singleQuote: false,
|
||||
// 缩进空格数,默认2个空格
|
||||
tabWidth: 2,
|
||||
// 元素末尾是否加逗号,默认es5: ES5中的 objects, arrays 等会添加逗号,TypeScript 中的 type 后不加逗号
|
||||
trailingComma: "es5",
|
||||
// 指定缩进方式,空格或tab,默认false,即使用空格
|
||||
useTabs: false,
|
||||
// vue 文件中是否缩进 <style> 和 <script> 标签,默认 false
|
||||
vueIndentScriptAndStyle: false,
|
||||
|
||||
endOfLine: "auto",
|
||||
overrides: [
|
||||
{
|
||||
files: "*.html",
|
||||
options: {
|
||||
parser: "html",
|
||||
},
|
||||
},
|
||||
],
|
||||
endOfLine: "auto",
|
||||
overrides: [
|
||||
{
|
||||
files: "*.html",
|
||||
options: {
|
||||
parser: "html",
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
|
|
|
@ -1,51 +1,51 @@
|
|||
import type { BuildOptions } from 'vite';
|
||||
import { pathResolve } from './utils';
|
||||
import type { BuildOptions } from "vite";
|
||||
import { pathResolve } from "./utils";
|
||||
|
||||
export const buildEnv = (): BuildOptions => {
|
||||
return {
|
||||
target: 'es2015',
|
||||
assetsInlineLimit: 20000,
|
||||
// 构建输出的目录,默认值为"dist"
|
||||
outDir: 'docker/dist',
|
||||
// 用于指定使用的代码压缩工具。在这里,minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser
|
||||
// esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log
|
||||
minify: 'terser', // "esbuild"
|
||||
// 用于配置 Terser 的选项
|
||||
terserOptions: {
|
||||
// 用于配置压缩选项
|
||||
compress: {
|
||||
drop_console: true, // 是否删除代码中的 console 语句, 默认值false
|
||||
drop_debugger: true, // 是否删除代码中的 debugger 语句, 默认值false
|
||||
},
|
||||
},
|
||||
// 禁用 gzip 压缩大小报告,可略微减少打包时间
|
||||
reportCompressedSize: false,
|
||||
// 用于指定是否生成源映射文件。源映射文件可以帮助调试和定位源代码中的错误。当设置为false时,构建过程不会生成源映射文件
|
||||
sourcemap: false,
|
||||
// 用于配置 CommonJS 模块的选项
|
||||
commonjsOptions: {
|
||||
// 用于指定是否忽略 CommonJS 模块中的 try-catch 语句。当设置为false时,构建过程会保留 CommonJS 模块中的 try-catch 语句
|
||||
ignoreTryCatch: false,
|
||||
},
|
||||
// 规定触发警告的 chunk 大小, 当某个代码分块的大小超过该限制时,Vite 会发出警告
|
||||
chunkSizeWarningLimit: 2000,
|
||||
rollupOptions: {
|
||||
external: ['md-editor-v3', 'echarts'],
|
||||
input: {
|
||||
index: pathResolve('../index.html', import.meta.url),
|
||||
},
|
||||
// 静态资源分类打包
|
||||
output: {
|
||||
chunkFileNames: 'static/js/[name]-[hash].js',
|
||||
entryFileNames: 'static/js/[name]-[hash].js',
|
||||
assetFileNames: 'static/[ext]/[name]-[hash].[ext]',
|
||||
manualChunks: id => {
|
||||
// 如果是包含在包中则打包成 vendor
|
||||
if (id.includes('node_modules')) {
|
||||
return `vendor`;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
return {
|
||||
target: "es2015",
|
||||
assetsInlineLimit: 20000,
|
||||
// 构建输出的目录,默认值为"dist"
|
||||
outDir: "docker/dist",
|
||||
// 用于指定使用的代码压缩工具。在这里,minify 被设置为 'terser',表示使用 Terser 进行代码压缩。默认值terser
|
||||
// esbuild 打包更快,但是不能去除 console.log,terser打包慢,但能去除 console.log
|
||||
minify: "terser", // "esbuild"
|
||||
// 用于配置 Terser 的选项
|
||||
terserOptions: {
|
||||
// 用于配置压缩选项
|
||||
compress: {
|
||||
drop_console: true, // 是否删除代码中的 console 语句, 默认值false
|
||||
drop_debugger: true, // 是否删除代码中的 debugger 语句, 默认值false
|
||||
},
|
||||
},
|
||||
// 禁用 gzip 压缩大小报告,可略微减少打包时间
|
||||
reportCompressedSize: false,
|
||||
// 用于指定是否生成源映射文件。源映射文件可以帮助调试和定位源代码中的错误。当设置为false时,构建过程不会生成源映射文件
|
||||
sourcemap: false,
|
||||
// 用于配置 CommonJS 模块的选项
|
||||
commonjsOptions: {
|
||||
// 用于指定是否忽略 CommonJS 模块中的 try-catch 语句。当设置为false时,构建过程会保留 CommonJS 模块中的 try-catch 语句
|
||||
ignoreTryCatch: false,
|
||||
},
|
||||
// 规定触发警告的 chunk 大小, 当某个代码分块的大小超过该限制时,Vite 会发出警告
|
||||
chunkSizeWarningLimit: 2000,
|
||||
rollupOptions: {
|
||||
external: ["md-editor-v3", "echarts"],
|
||||
input: {
|
||||
index: pathResolve("../index.html", import.meta.url),
|
||||
},
|
||||
// 静态资源分类打包
|
||||
output: {
|
||||
chunkFileNames: "static/js/[name]-[hash].js",
|
||||
entryFileNames: "static/js/[name]-[hash].js",
|
||||
assetFileNames: "static/[ext]/[name]-[hash].[ext]",
|
||||
manualChunks: (id) => {
|
||||
// 如果是包含在包中则打包成 vendor
|
||||
if (id.includes("node_modules")) {
|
||||
return `vendor`;
|
||||
}
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
112
build/cdn.ts
|
@ -1,5 +1,5 @@
|
|||
import { Plugin as importToCDN } from 'vite-plugin-cdn-import';
|
||||
import { wrapperEnv } from './utils';
|
||||
import { Plugin as importToCDN } from "vite-plugin-cdn-import";
|
||||
import { wrapperEnv } from "./utils";
|
||||
|
||||
/**
|
||||
* @description 打包时采用`cdn`模式,仅限外网使用(默认不采用,如果需要采用cdn模式,请在 .env.production 文件,将 VITE_CDN 设置成true)
|
||||
|
@ -7,61 +7,61 @@ import { wrapperEnv } from './utils';
|
|||
* 注意:上面提到的仅限外网使用也不是完全肯定的,如果你们公司内网部署的有相关js、css文件,也可以将下面配置对应改一下,整一套内网版cdn
|
||||
*/
|
||||
export const cdn = importToCDN({
|
||||
//(prodUrl解释: name: 对应下面modules的name,version: 自动读取本地package.json中dependencies依赖中对应包的版本号,path: 对应下面modules的path,当然也可写完整路径,会替换prodUrl)
|
||||
// prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
|
||||
prodUrl: 'https://unpkg.com/{name}@{version}/{path}',
|
||||
modules: [
|
||||
{
|
||||
name: 'vue',
|
||||
var: 'Vue',
|
||||
path: 'dist/vue.global.prod.js',
|
||||
},
|
||||
{
|
||||
name: 'vue-router',
|
||||
var: 'VueRouter',
|
||||
path: 'dist/vue-router.global.js',
|
||||
},
|
||||
// {
|
||||
// name: 'vue-i18n',
|
||||
// var: 'VueI18n',
|
||||
// path: 'dist/vue-i18n.global.prod.js',
|
||||
// },
|
||||
// {
|
||||
// name: 'vue-demi',
|
||||
// var: 'VueDemi',
|
||||
// path: 'lib/index.iife.js',
|
||||
// },
|
||||
{
|
||||
name: 'pinia',
|
||||
var: 'Pinia',
|
||||
path: 'dist/pinia.iife.js',
|
||||
},
|
||||
// {
|
||||
// name: 'element-plus',
|
||||
// var: 'ElementPlus',
|
||||
// path: 'dist/index.full.js',
|
||||
// css: 'dist/index.css',
|
||||
// },
|
||||
{
|
||||
name: 'axios',
|
||||
var: 'axios',
|
||||
path: 'dist/axios.min.js',
|
||||
},
|
||||
{
|
||||
name: 'dayjs',
|
||||
var: 'dayjs',
|
||||
path: 'dayjs.min.js',
|
||||
},
|
||||
{
|
||||
name: 'echarts',
|
||||
var: 'echarts',
|
||||
path: 'dist/echarts.min.js',
|
||||
},
|
||||
],
|
||||
//(prodUrl解释: name: 对应下面modules的name,version: 自动读取本地package.json中dependencies依赖中对应包的版本号,path: 对应下面modules的path,当然也可写完整路径,会替换prodUrl)
|
||||
// prodUrl: 'https://cdn.bootcdn.net/ajax/libs/{name}/{version}/{path}',
|
||||
prodUrl: "https://unpkg.com/{name}@{version}/{path}",
|
||||
modules: [
|
||||
{
|
||||
name: "vue",
|
||||
var: "Vue",
|
||||
path: "dist/vue.global.prod.js",
|
||||
},
|
||||
{
|
||||
name: "vue-router",
|
||||
var: "VueRouter",
|
||||
path: "dist/vue-router.global.js",
|
||||
},
|
||||
// {
|
||||
// name: 'vue-i18n',
|
||||
// var: 'VueI18n',
|
||||
// path: 'dist/vue-i18n.global.prod.js',
|
||||
// },
|
||||
// {
|
||||
// name: 'vue-demi',
|
||||
// var: 'VueDemi',
|
||||
// path: 'lib/index.iife.js',
|
||||
// },
|
||||
{
|
||||
name: "pinia",
|
||||
var: "Pinia",
|
||||
path: "dist/pinia.iife.js",
|
||||
},
|
||||
// {
|
||||
// name: 'element-plus',
|
||||
// var: 'ElementPlus',
|
||||
// path: 'dist/index.full.js',
|
||||
// css: 'dist/index.css',
|
||||
// },
|
||||
{
|
||||
name: "axios",
|
||||
var: "axios",
|
||||
path: "dist/axios.min.js",
|
||||
},
|
||||
{
|
||||
name: "dayjs",
|
||||
var: "dayjs",
|
||||
path: "dayjs.min.js",
|
||||
},
|
||||
{
|
||||
name: "echarts",
|
||||
var: "echarts",
|
||||
path: "dist/echarts.min.js",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
/* 是否使用CDN加速 */
|
||||
export const useCDN = mode => {
|
||||
const env = wrapperEnv(mode, 'VITE');
|
||||
return env.VITE_CDN ? cdn : null;
|
||||
export const useCDN = (mode) => {
|
||||
const env = wrapperEnv(mode, "VITE");
|
||||
return env.VITE_CDN ? cdn : null;
|
||||
};
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
import dayjs from 'dayjs';
|
||||
import { dependencies, devDependencies, engines, name, version } from '../package.json';
|
||||
import dayjs from "dayjs";
|
||||
import { dependencies, devDependencies, engines, name, version } from "../package.json";
|
||||
|
||||
const __APP_INFO__ = {
|
||||
pkg: { name, version, engines, dependencies, devDependencies },
|
||||
lastBuildTime: dayjs(new Date()).format('YYYY-MM-DD HH:mm:ss'),
|
||||
pkg: { name, version, engines, dependencies, devDependencies },
|
||||
lastBuildTime: dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss"),
|
||||
};
|
||||
|
||||
export const define = () => {
|
||||
return {
|
||||
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||
};
|
||||
return {
|
||||
__APP_INFO__: JSON.stringify(__APP_INFO__),
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,50 +1,55 @@
|
|||
import { wrapperEnv } from './utils';
|
||||
import dayjs, { type Dayjs } from 'dayjs';
|
||||
import gradientString from 'gradient-string';
|
||||
import duration from 'dayjs/plugin/duration';
|
||||
import boxen, { type Options as BoxenOptions } from 'boxen';
|
||||
import { wrapperEnv } from "./utils";
|
||||
import dayjs, { type Dayjs } from "dayjs";
|
||||
import gradientString from "gradient-string";
|
||||
import duration from "dayjs/plugin/duration";
|
||||
import boxen, { type Options as BoxenOptions } from "boxen";
|
||||
|
||||
dayjs.extend(duration);
|
||||
|
||||
const boxenOptions: BoxenOptions = {
|
||||
padding: 0.94,
|
||||
borderColor: 'cyan',
|
||||
borderStyle: 'round',
|
||||
textAlignment: 'left',
|
||||
padding: 0.94,
|
||||
borderColor: "cyan",
|
||||
borderStyle: "round",
|
||||
textAlignment: "left",
|
||||
};
|
||||
|
||||
/* 输出日志信息 */
|
||||
const printLogMessage = (VITE_PORT: number) => {
|
||||
return gradientString('cyan', 'magenta').multiline(
|
||||
`保存成功!服务器重新启动
|
||||
return gradientString("cyan", "magenta").multiline(
|
||||
`保存成功!服务器重新启动
|
||||
项目访问地址如下:
|
||||
http://localhost:${VITE_PORT}`,
|
||||
);
|
||||
http://localhost:${VITE_PORT}`
|
||||
);
|
||||
};
|
||||
|
||||
export const viteConsoleLog = mode => {
|
||||
const { VITE_PORT } = wrapperEnv(mode);
|
||||
export const viteConsoleLog = (mode) => {
|
||||
const { VITE_PORT } = wrapperEnv(mode);
|
||||
|
||||
let config: { command: string };
|
||||
let startTime: Dayjs;
|
||||
let endTime: Dayjs;
|
||||
return {
|
||||
name: 'vite:buildInfo',
|
||||
configResolved(resolvedConfig) {
|
||||
config = resolvedConfig;
|
||||
},
|
||||
buildStart() {
|
||||
console.log(boxen(printLogMessage(VITE_PORT), boxenOptions));
|
||||
if (config.command === 'build') {
|
||||
startTime = dayjs(new Date());
|
||||
}
|
||||
},
|
||||
closeBundle() {
|
||||
if (config.command === 'build') {
|
||||
endTime = dayjs(new Date());
|
||||
const format = dayjs.duration(endTime.diff(startTime)).format('mm分ss秒');
|
||||
console.log(boxen(gradientString('cyan', 'magenta').multiline(`🎉 恭喜打包完成(总用时${format})`), boxenOptions));
|
||||
}
|
||||
},
|
||||
};
|
||||
let config: { command: string };
|
||||
let startTime: Dayjs;
|
||||
let endTime: Dayjs;
|
||||
return {
|
||||
name: "vite:buildInfo",
|
||||
configResolved(resolvedConfig) {
|
||||
config = resolvedConfig;
|
||||
},
|
||||
buildStart() {
|
||||
console.log(boxen(printLogMessage(VITE_PORT), boxenOptions));
|
||||
if (config.command === "build") {
|
||||
startTime = dayjs(new Date());
|
||||
}
|
||||
},
|
||||
closeBundle() {
|
||||
if (config.command === "build") {
|
||||
endTime = dayjs(new Date());
|
||||
const format = dayjs.duration(endTime.diff(startTime)).format("mm分ss秒");
|
||||
console.log(
|
||||
boxen(
|
||||
gradientString("cyan", "magenta").multiline(`🎉 恭喜打包完成(总用时${format})`),
|
||||
boxenOptions
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* 尤其当您禁用浏览器缓存时(这种情况只应该发生在调试阶段)必须将对应模块加入到 include里,否则会遇到开发环境切换页面卡顿的问题(vite 会认为它是一个新的依赖包会重新加载并强制刷新页面),因为它既无法使用浏览器缓存,又没有在本地 node_modules/.vite 里缓存
|
||||
* 温馨提示:如果您使用的第三方库是全局引入,也就是引入到 src/main.ts 文件里,就不需要再添加到 include 里了,因为 vite 会自动将它们缓存到 node_modules/.vite
|
||||
*/
|
||||
const include = ['vue', 'vue-router', 'dayjs', 'axios', 'pinia', 'vue-types', 'js-cookie'];
|
||||
const include = ["vue", "vue-router", "dayjs", "axios", "pinia", "vue-types", "js-cookie"];
|
||||
|
||||
/**
|
||||
* 在预构建中强制排除的依赖项
|
||||
|
|
|
@ -1,44 +1,44 @@
|
|||
import vue from '@vitejs/plugin-vue';
|
||||
import type { PluginOption } from 'vite';
|
||||
import vueJsx from '@vitejs/plugin-vue-jsx';
|
||||
import Inspector from 'vite-plugin-vue-inspector';
|
||||
import { compressPack, report } from './utils';
|
||||
import removeConsole from 'vite-plugin-remove-console';
|
||||
import { useCDN } from './cdn';
|
||||
import { viteConsoleLog } from './info';
|
||||
import UnoCSS from 'unocss/vite';
|
||||
import { presetIcons, presetUno } from 'unocss';
|
||||
import UnoCssIcons from '@unocss/preset-icons';
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import type { PluginOption } from "vite";
|
||||
import vueJsx from "@vitejs/plugin-vue-jsx";
|
||||
import Inspector from "vite-plugin-vue-inspector";
|
||||
import { compressPack, report } from "./utils";
|
||||
import removeConsole from "vite-plugin-remove-console";
|
||||
import { useCDN } from "./cdn";
|
||||
import { viteConsoleLog } from "./info";
|
||||
import UnoCSS from "unocss/vite";
|
||||
import { presetIcons, presetUno } from "unocss";
|
||||
import UnoCssIcons from "@unocss/preset-icons";
|
||||
|
||||
export const plugins = (mode): PluginOption[] => {
|
||||
return [
|
||||
vue(),
|
||||
vueJsx(),
|
||||
Inspector(),
|
||||
report(),
|
||||
removeConsole(),
|
||||
useCDN(mode),
|
||||
viteConsoleLog(mode),
|
||||
UnoCSS({
|
||||
hmrTopLevelAwait: false,
|
||||
|
||||
presets: [
|
||||
presetIcons({
|
||||
extraProperties: {
|
||||
display: 'inline-block',
|
||||
'vertical-align': 'middle',
|
||||
},
|
||||
}),
|
||||
UnoCssIcons({
|
||||
// 其他选项
|
||||
prefix: 'i-',
|
||||
extraProperties: {
|
||||
display: 'inline-block',
|
||||
},
|
||||
}),
|
||||
presetUno(),
|
||||
],
|
||||
}),
|
||||
compressPack(mode),
|
||||
];
|
||||
return [
|
||||
vue(),
|
||||
vueJsx(),
|
||||
Inspector(),
|
||||
report(),
|
||||
removeConsole(),
|
||||
useCDN(mode),
|
||||
viteConsoleLog(mode),
|
||||
UnoCSS({
|
||||
hmrTopLevelAwait: false,
|
||||
inspector: true, // 控制台是否打印 UnoCSS inspector
|
||||
presets: [
|
||||
presetIcons({
|
||||
extraProperties: {
|
||||
display: "inline-block",
|
||||
"vertical-align": "middle",
|
||||
},
|
||||
}),
|
||||
UnoCssIcons({
|
||||
// 其他选项
|
||||
prefix: "i-",
|
||||
extraProperties: {
|
||||
display: "inline-block",
|
||||
},
|
||||
}),
|
||||
presetUno(),
|
||||
],
|
||||
}),
|
||||
compressPack(mode),
|
||||
];
|
||||
};
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import { pathResolve } from './utils';
|
||||
import { pathResolve } from "./utils";
|
||||
|
||||
export const resolve = () => {
|
||||
return {
|
||||
alias: {
|
||||
'@': pathResolve('../src'),
|
||||
'@build': pathResolve(),
|
||||
},
|
||||
};
|
||||
return {
|
||||
alias: {
|
||||
"@": pathResolve("../src"),
|
||||
"@build": pathResolve(),
|
||||
},
|
||||
};
|
||||
};
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
import type { ServerOptions } from 'vite';
|
||||
import { wrapperEnv } from './utils';
|
||||
import type { ServerOptions } from "vite";
|
||||
import { wrapperEnv } from "./utils";
|
||||
|
||||
/* 开发服务配置 */
|
||||
export const server = mode => {
|
||||
const { VITE_PORT, VITE_APP_URL, VITE_STRICT_PORT } = wrapperEnv(mode);
|
||||
export const server = (mode) => {
|
||||
const { VITE_PORT, VITE_APP_URL, VITE_STRICT_PORT } = wrapperEnv(mode);
|
||||
|
||||
const options: ServerOptions = {
|
||||
strictPort: VITE_STRICT_PORT,
|
||||
port: VITE_PORT,
|
||||
host: '0.0.0.0',
|
||||
open: true,
|
||||
cors: true,
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: VITE_APP_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/admin/, '/api'),
|
||||
},
|
||||
'/mock': {
|
||||
target: VITE_APP_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/mock/, '/mock'),
|
||||
},
|
||||
},
|
||||
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
||||
warmup: {
|
||||
clientFiles: ['./index.html', './src/{views,components}/*'],
|
||||
},
|
||||
};
|
||||
const options: ServerOptions = {
|
||||
strictPort: VITE_STRICT_PORT,
|
||||
port: VITE_PORT,
|
||||
host: "0.0.0.0",
|
||||
open: true,
|
||||
cors: true,
|
||||
proxy: {
|
||||
"/api": {
|
||||
target: VITE_APP_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/admin/, "/api"),
|
||||
},
|
||||
"/mock": {
|
||||
target: VITE_APP_URL,
|
||||
changeOrigin: true,
|
||||
rewrite: (path: string) => path.replace(/^\/mock/, "/mock"),
|
||||
},
|
||||
},
|
||||
// 预热文件以提前转换和缓存结果,降低启动期间的初始页面加载时长并防止转换瀑布
|
||||
warmup: {
|
||||
clientFiles: ["./index.html", "./src/{views,components}/*"],
|
||||
},
|
||||
};
|
||||
|
||||
return options;
|
||||
return options;
|
||||
};
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { loadEnv } from 'vite';
|
||||
import { visualizer } from 'rollup-plugin-visualizer';
|
||||
import viteCompression from 'vite-plugin-compression';
|
||||
import { dirname, resolve } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
import { loadEnv } from "vite";
|
||||
import { visualizer } from "rollup-plugin-visualizer";
|
||||
import viteCompression from "vite-plugin-compression";
|
||||
|
||||
export const root: string = process.cwd();
|
||||
|
||||
|
@ -11,20 +11,20 @@ export const root: string = process.cwd();
|
|||
* @param dir 路径片段,默认`build`
|
||||
* @param metaUrl 模块的完整`url`,如果在`build`目录外调用必传`import.meta.url`
|
||||
*/
|
||||
export const pathResolve = (dir = '.', metaUrl = import.meta.url) => {
|
||||
// 当前文件目录的绝对路径
|
||||
const currentFileDir = dirname(fileURLToPath(metaUrl));
|
||||
// build 目录的绝对路径
|
||||
const buildDir = resolve(currentFileDir, 'build');
|
||||
// 解析的绝对路径
|
||||
const resolvedPath = resolve(currentFileDir, dir);
|
||||
// 检查解析的绝对路径是否在 build 目录内
|
||||
if (resolvedPath.startsWith(buildDir)) {
|
||||
// 在 build 目录内,返回当前文件路径
|
||||
return fileURLToPath(metaUrl);
|
||||
}
|
||||
// 不在 build 目录内,返回解析后的绝对路径
|
||||
return resolvedPath;
|
||||
export const pathResolve = (dir = ".", metaUrl = import.meta.url) => {
|
||||
// 当前文件目录的绝对路径
|
||||
const currentFileDir = dirname(fileURLToPath(metaUrl));
|
||||
// build 目录的绝对路径
|
||||
const buildDir = resolve(currentFileDir, "build");
|
||||
// 解析的绝对路径
|
||||
const resolvedPath = resolve(currentFileDir, dir);
|
||||
// 检查解析的绝对路径是否在 build 目录内
|
||||
if (resolvedPath.startsWith(buildDir)) {
|
||||
// 在 build 目录内,返回当前文件路径
|
||||
return fileURLToPath(metaUrl);
|
||||
}
|
||||
// 不在 build 目录内,返回解析后的绝对路径
|
||||
return resolvedPath;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -33,32 +33,34 @@ export const pathResolve = (dir = '.', metaUrl = import.meta.url) => {
|
|||
* @param prefix 需要过滤的前缀
|
||||
* @link 参考:https://cn.vite.dev/config/#using-environment-variables-in-config
|
||||
*/
|
||||
export const wrapperEnv = (mode, prefix = ''): ViteEnv => {
|
||||
const env = loadEnv(mode, root, prefix);
|
||||
export const wrapperEnv = (mode, prefix = ""): ViteEnv => {
|
||||
const env = loadEnv(mode, root, prefix);
|
||||
|
||||
// 将变量转换指定类型
|
||||
for (const envName of Object.keys(env)) {
|
||||
let realName = env[envName].replace(/\\n/g, '\n');
|
||||
realName = realName === 'true' ? true : realName === 'false' ? false : realName;
|
||||
// 将变量转换指定类型
|
||||
for (const envName of Object.keys(env)) {
|
||||
let realName = env[envName].replace(/\\n/g, "\n");
|
||||
realName = realName === "true" ? true : realName === "false" ? false : realName;
|
||||
|
||||
if (envName === 'VITE_PORT') {
|
||||
realName = Number(realName);
|
||||
}
|
||||
env[envName] = realName;
|
||||
process.env[envName] = realName;
|
||||
}
|
||||
return env;
|
||||
if (envName === "VITE_PORT") {
|
||||
realName = Number(realName);
|
||||
}
|
||||
env[envName] = realName;
|
||||
process.env[envName] = realName;
|
||||
}
|
||||
return env;
|
||||
};
|
||||
|
||||
/* 打包分析 */
|
||||
export const report = () => {
|
||||
const lifecycle = process.env.npm_lifecycle_event;
|
||||
return lifecycle === 'report' ? visualizer({ open: true, brotliSize: true, filename: 'report.html' }) : (null as any);
|
||||
const lifecycle = process.env.npm_lifecycle_event;
|
||||
return lifecycle === "report"
|
||||
? visualizer({ open: true, brotliSize: true, filename: "report.html" })
|
||||
: (null as any);
|
||||
};
|
||||
|
||||
/* 启用gzip压缩 */
|
||||
export const compressPack = mode => {
|
||||
const { VITE_COMPRESSION } = wrapperEnv(mode);
|
||||
export const compressPack = (mode) => {
|
||||
const { VITE_COMPRESSION } = wrapperEnv(mode);
|
||||
|
||||
return VITE_COMPRESSION == 'gzip' ? viteCompression({ threshold: 1024000 }) : null;
|
||||
return VITE_COMPRESSION == "gzip" ? viteCompression({ threshold: 1024000 }) : null;
|
||||
};
|
||||
|
|
342
eslint.config.js
|
@ -1,174 +1,174 @@
|
|||
import js from '@eslint/js';
|
||||
import pluginVue from 'eslint-plugin-vue';
|
||||
import * as parserVue from 'vue-eslint-parser';
|
||||
import configPrettier from 'eslint-config-prettier';
|
||||
import pluginPrettier from 'eslint-plugin-prettier';
|
||||
import { defineFlatConfig } from 'eslint-define-config';
|
||||
import * as parserTypeScript from '@typescript-eslint/parser';
|
||||
import pluginTypeScript from '@typescript-eslint/eslint-plugin';
|
||||
import js from "@eslint/js";
|
||||
import pluginVue from "eslint-plugin-vue";
|
||||
import * as parserVue from "vue-eslint-parser";
|
||||
import configPrettier from "eslint-config-prettier";
|
||||
import pluginPrettier from "eslint-plugin-prettier";
|
||||
import { defineFlatConfig } from "eslint-define-config";
|
||||
import * as parserTypeScript from "@typescript-eslint/parser";
|
||||
import pluginTypeScript from "@typescript-eslint/eslint-plugin";
|
||||
|
||||
export default defineFlatConfig([
|
||||
{
|
||||
...js.configs.recommended,
|
||||
ignores: ['**/.*', 'dist/*', '*.d.ts', 'public/*', 'src/assets/**', 'src/**/iconfont/**'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
// index.d.ts
|
||||
RefType: 'readonly',
|
||||
EmitType: 'readonly',
|
||||
TargetContext: 'readonly',
|
||||
ComponentRef: 'readonly',
|
||||
ElRef: 'readonly',
|
||||
ForDataType: 'readonly',
|
||||
AnyFunction: 'readonly',
|
||||
PropType: 'readonly',
|
||||
Writable: 'readonly',
|
||||
Nullable: 'readonly',
|
||||
NonNullable: 'readonly',
|
||||
Recordable: 'readonly',
|
||||
ReadonlyRecordable: 'readonly',
|
||||
Indexable: 'readonly',
|
||||
DeepPartial: 'readonly',
|
||||
Without: 'readonly',
|
||||
Exclusive: 'readonly',
|
||||
TimeoutHandle: 'readonly',
|
||||
IntervalHandle: 'readonly',
|
||||
Effect: 'readonly',
|
||||
ChangeEvent: 'readonly',
|
||||
WheelEvent: 'readonly',
|
||||
ImportMetaEnv: 'readonly',
|
||||
Fn: 'readonly',
|
||||
PromiseFn: 'readonly',
|
||||
ComponentElRef: 'readonly',
|
||||
parseInt: 'readonly',
|
||||
parseFloat: 'readonly',
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
prettier: pluginPrettier,
|
||||
},
|
||||
rules: {
|
||||
...configPrettier.rules,
|
||||
...pluginPrettier.configs.recommended.rules,
|
||||
'no-debugger': 'off',
|
||||
'no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
'prettier/prettier': [
|
||||
'error',
|
||||
{
|
||||
endOfLine: 'auto',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.?([cm])ts', '**/*.?([cm])tsx'],
|
||||
languageOptions: {
|
||||
parser: parserTypeScript,
|
||||
parserOptions: {
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
'@typescript-eslint': pluginTypeScript,
|
||||
},
|
||||
rules: {
|
||||
...pluginTypeScript.configs.strict.rules,
|
||||
'@typescript-eslint/ban-types': 'off',
|
||||
'@typescript-eslint/no-redeclare': 'error',
|
||||
'@typescript-eslint/ban-ts-comment': 'off',
|
||||
'@typescript-eslint/no-explicit-any': 'off',
|
||||
'@typescript-eslint/prefer-as-const': 'warn',
|
||||
'@typescript-eslint/no-empty-function': 'off',
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
'@typescript-eslint/no-import-type-side-effects': 'error',
|
||||
'@typescript-eslint/prefer-literal-enum-member': 'off',
|
||||
'@typescript-eslint/explicit-module-boundary-types': 'off',
|
||||
'@typescript-eslint/consistent-type-imports': [
|
||||
'error',
|
||||
{
|
||||
disallowTypeAnnotations: false,
|
||||
fixStyle: 'inline-type-imports',
|
||||
},
|
||||
],
|
||||
'@typescript-eslint/no-unused-vars': [
|
||||
'error',
|
||||
{
|
||||
argsIgnorePattern: '^_',
|
||||
varsIgnorePattern: '^_',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.d.ts'],
|
||||
rules: {
|
||||
'eslint-comments/no-unlimited-disable': 'off',
|
||||
'import/no-duplicates': 'off',
|
||||
'unused-imports/no-unused-vars': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.?([cm])js'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-require-imports': 'off',
|
||||
'@typescript-eslint/no-var-requires': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.vue'],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
$: 'readonly',
|
||||
$$: 'readonly',
|
||||
$computed: 'readonly',
|
||||
$customRef: 'readonly',
|
||||
$ref: 'readonly',
|
||||
$shallowRef: 'readonly',
|
||||
$toRef: 'readonly',
|
||||
},
|
||||
parser: parserVue,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true,
|
||||
},
|
||||
extraFileExtensions: ['.vue'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
sourceType: 'module',
|
||||
},
|
||||
},
|
||||
plugins: {
|
||||
vue: pluginVue,
|
||||
},
|
||||
processor: pluginVue.processors['.vue'],
|
||||
rules: {
|
||||
...pluginVue.configs.base.rules,
|
||||
...pluginVue.configs['vue3-essential'].rules,
|
||||
...pluginVue.configs['vue3-recommended'].rules,
|
||||
'no-undef': 'off',
|
||||
'no-unused-vars': 'off',
|
||||
'vue/no-v-html': 'off',
|
||||
'vue/require-default-prop': 'off',
|
||||
'vue/require-explicit-emits': 'off',
|
||||
'vue/multi-word-component-names': 'off',
|
||||
'vue/no-setup-props-reactivity-loss': 'off',
|
||||
'vue/html-self-closing': [
|
||||
'error',
|
||||
{
|
||||
html: {
|
||||
void: 'always',
|
||||
normal: 'always',
|
||||
component: 'always',
|
||||
},
|
||||
svg: 'always',
|
||||
math: 'always',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
...js.configs.recommended,
|
||||
ignores: ["**/.*", "dist/*", "*.d.ts", "public/*", "src/assets/**", "src/**/iconfont/**"],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
// index.d.ts
|
||||
RefType: "readonly",
|
||||
EmitType: "readonly",
|
||||
TargetContext: "readonly",
|
||||
ComponentRef: "readonly",
|
||||
ElRef: "readonly",
|
||||
ForDataType: "readonly",
|
||||
AnyFunction: "readonly",
|
||||
PropType: "readonly",
|
||||
Writable: "readonly",
|
||||
Nullable: "readonly",
|
||||
NonNullable: "readonly",
|
||||
Recordable: "readonly",
|
||||
ReadonlyRecordable: "readonly",
|
||||
Indexable: "readonly",
|
||||
DeepPartial: "readonly",
|
||||
Without: "readonly",
|
||||
Exclusive: "readonly",
|
||||
TimeoutHandle: "readonly",
|
||||
IntervalHandle: "readonly",
|
||||
Effect: "readonly",
|
||||
ChangeEvent: "readonly",
|
||||
WheelEvent: "readonly",
|
||||
ImportMetaEnv: "readonly",
|
||||
Fn: "readonly",
|
||||
PromiseFn: "readonly",
|
||||
ComponentElRef: "readonly",
|
||||
parseInt: "readonly",
|
||||
parseFloat: "readonly"
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
prettier: pluginPrettier
|
||||
},
|
||||
rules: {
|
||||
...configPrettier.rules,
|
||||
...pluginPrettier.configs.recommended.rules,
|
||||
"no-debugger": "off",
|
||||
"no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_"
|
||||
}
|
||||
],
|
||||
"prettier/prettier": [
|
||||
"error",
|
||||
{
|
||||
endOfLine: "auto"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ["**/*.?([cm])ts", "**/*.?([cm])tsx"],
|
||||
languageOptions: {
|
||||
parser: parserTypeScript,
|
||||
parserOptions: {
|
||||
sourceType: "module"
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
"@typescript-eslint": pluginTypeScript
|
||||
},
|
||||
rules: {
|
||||
...pluginTypeScript.configs.strict.rules,
|
||||
"@typescript-eslint/ban-types": "off",
|
||||
"@typescript-eslint/no-redeclare": "error",
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-explicit-any": "off",
|
||||
"@typescript-eslint/prefer-as-const": "warn",
|
||||
"@typescript-eslint/no-empty-function": "off",
|
||||
"@typescript-eslint/no-non-null-assertion": "off",
|
||||
"@typescript-eslint/no-import-type-side-effects": "error",
|
||||
"@typescript-eslint/prefer-literal-enum-member": "off",
|
||||
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"error",
|
||||
{
|
||||
disallowTypeAnnotations: false,
|
||||
fixStyle: "inline-type-imports"
|
||||
}
|
||||
],
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{
|
||||
argsIgnorePattern: "^_",
|
||||
varsIgnorePattern: "^_"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ["**/*.d.ts"],
|
||||
rules: {
|
||||
"eslint-comments/no-unlimited-disable": "off",
|
||||
"import/no-duplicates": "off",
|
||||
"unused-imports/no-unused-vars": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ["**/*.?([cm])js"],
|
||||
rules: {
|
||||
"@typescript-eslint/no-require-imports": "off",
|
||||
"@typescript-eslint/no-var-requires": "off"
|
||||
}
|
||||
},
|
||||
{
|
||||
files: ["**/*.vue"],
|
||||
languageOptions: {
|
||||
globals: {
|
||||
$: "readonly",
|
||||
$$: "readonly",
|
||||
$computed: "readonly",
|
||||
$customRef: "readonly",
|
||||
$ref: "readonly",
|
||||
$shallowRef: "readonly",
|
||||
$toRef: "readonly"
|
||||
},
|
||||
parser: parserVue,
|
||||
parserOptions: {
|
||||
ecmaFeatures: {
|
||||
jsx: true
|
||||
},
|
||||
extraFileExtensions: [".vue"],
|
||||
parser: "@typescript-eslint/parser",
|
||||
sourceType: "module"
|
||||
}
|
||||
},
|
||||
plugins: {
|
||||
vue: pluginVue
|
||||
},
|
||||
processor: pluginVue.processors[".vue"],
|
||||
rules: {
|
||||
...pluginVue.configs.base.rules,
|
||||
...pluginVue.configs["vue3-essential"].rules,
|
||||
...pluginVue.configs["vue3-recommended"].rules,
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"vue/no-v-html": "off",
|
||||
"vue/require-default-prop": "off",
|
||||
"vue/require-explicit-emits": "off",
|
||||
"vue/multi-word-component-names": "off",
|
||||
"vue/no-setup-props-reactivity-loss": "off",
|
||||
"vue/html-self-closing": [
|
||||
"error",
|
||||
{
|
||||
html: {
|
||||
void: "always",
|
||||
normal: "always",
|
||||
component: "always"
|
||||
},
|
||||
svg: "always",
|
||||
math: "always"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "dashboard-template",
|
||||
"name": "vehicle-monitor",
|
||||
"private": true,
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
|
@ -12,6 +12,7 @@
|
|||
"lint": "pnpm lint:eslint && pnpm lint:prettier && pnpm lint:stylelint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@eslint/js": "^9.21.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.24.1",
|
||||
"@typescript-eslint/parser": "^8.24.1",
|
||||
"@unocss/preset-icons": "^66.0.0",
|
||||
|
@ -22,7 +23,7 @@
|
|||
"boxen": "^8.0.1",
|
||||
"dayjs": "^1.11.13",
|
||||
"echarts": "^5.5.1",
|
||||
"eslint": "^9.9.1",
|
||||
"eslint": "^9.21.0",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-define-config": "^2.1.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
|
@ -33,6 +34,9 @@
|
|||
"nprogress": "^0.2.0",
|
||||
"pinia": "^2.3.1",
|
||||
"pinia-plugin-persistedstate": "^3.2.3",
|
||||
"postcss": "^8.5.3",
|
||||
"postcss-loader": "^8.1.1",
|
||||
"postcss-px-to-viewport-8-plugin": "^1.2.5",
|
||||
"prettier": "^3.3.3",
|
||||
"rimraf": "^5.0.10",
|
||||
"rollup-plugin-visualizer": "^5.14.0",
|
||||
|
@ -48,6 +52,7 @@
|
|||
"vite-plugin-remove-console": "^2.2.0",
|
||||
"vite-plugin-vue-inspector": "^5.3.1",
|
||||
"vue": "^3.5.13",
|
||||
"vue-eslint-parser": "^9.4.3",
|
||||
"vue-router": "^4.4.3",
|
||||
"vue-types": "^6.0.0"
|
||||
},
|
||||
|
|
145
pnpm-lock.yaml
|
@ -8,6 +8,9 @@ importers:
|
|||
|
||||
.:
|
||||
dependencies:
|
||||
'@eslint/js':
|
||||
specifier: ^9.21.0
|
||||
version: 9.21.0
|
||||
'@typescript-eslint/eslint-plugin':
|
||||
specifier: ^8.24.1
|
||||
version: 8.24.1(@typescript-eslint/parser@8.24.1(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.21.0(jiti@2.4.2))(typescript@5.7.3)
|
||||
|
@ -39,20 +42,20 @@ importers:
|
|||
specifier: ^5.5.1
|
||||
version: 5.6.0
|
||||
eslint:
|
||||
specifier: ^9.9.1
|
||||
specifier: ^9.21.0
|
||||
version: 9.21.0(jiti@2.4.2)
|
||||
eslint-config-prettier:
|
||||
specifier: ^9.1.0
|
||||
version: 9.1.0(eslint@9.21.0)
|
||||
version: 9.1.0(eslint@9.21.0(jiti@2.4.2))
|
||||
eslint-define-config:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0
|
||||
eslint-plugin-prettier:
|
||||
specifier: ^5.2.1
|
||||
version: 5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0))(eslint@9.21.0)(prettier@3.5.2)
|
||||
version: 5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2))(prettier@3.5.2)
|
||||
eslint-plugin-vue:
|
||||
specifier: ^9.27.0
|
||||
version: 9.32.0(eslint@9.21.0)
|
||||
version: 9.32.0(eslint@9.21.0(jiti@2.4.2))
|
||||
gradient-string:
|
||||
specifier: ^3.0.0
|
||||
version: 3.0.0
|
||||
|
@ -71,6 +74,15 @@ importers:
|
|||
pinia-plugin-persistedstate:
|
||||
specifier: ^3.2.3
|
||||
version: 3.2.3(pinia@2.3.1(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3)))
|
||||
postcss:
|
||||
specifier: ^8.5.3
|
||||
version: 8.5.3
|
||||
postcss-loader:
|
||||
specifier: ^8.1.1
|
||||
version: 8.1.1(postcss@8.5.3)(typescript@5.7.3)
|
||||
postcss-px-to-viewport-8-plugin:
|
||||
specifier: ^1.2.5
|
||||
version: 1.2.5
|
||||
prettier:
|
||||
specifier: ^3.3.3
|
||||
version: 3.5.2
|
||||
|
@ -116,6 +128,9 @@ importers:
|
|||
vue:
|
||||
specifier: ^3.5.13
|
||||
version: 3.5.13(typescript@5.7.3)
|
||||
vue-eslint-parser:
|
||||
specifier: ^9.4.3
|
||||
version: 9.4.3(eslint@9.21.0(jiti@2.4.2))
|
||||
vue-router:
|
||||
specifier: ^4.4.3
|
||||
version: 4.5.0(vue@3.5.13(typescript@5.7.3))
|
||||
|
@ -128,7 +143,7 @@ importers:
|
|||
version: 2.2.310
|
||||
'@vitejs/plugin-vue':
|
||||
specifier: ^5.2.1
|
||||
version: 5.2.1(vite@6.1.1(sass@1.85.0))(vue@3.5.13(typescript@5.7.3))
|
||||
version: 5.2.1(vite@6.1.1(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@5.7.3))
|
||||
'@vue/tsconfig':
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0(typescript@5.7.3)(vue@3.5.13(typescript@5.7.3))
|
||||
|
@ -1705,6 +1720,10 @@ packages:
|
|||
jackspeak@3.4.3:
|
||||
resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
|
||||
|
||||
jiti@1.21.7:
|
||||
resolution: {integrity: sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==}
|
||||
hasBin: true
|
||||
|
||||
jiti@2.4.2:
|
||||
resolution: {integrity: sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==}
|
||||
hasBin: true
|
||||
|
@ -1890,6 +1909,10 @@ packages:
|
|||
nth-check@2.1.1:
|
||||
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
|
||||
|
||||
object-assign@4.1.1:
|
||||
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
ofetch@1.4.1:
|
||||
resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==}
|
||||
|
||||
|
@ -1983,9 +2006,25 @@ packages:
|
|||
resolution: {integrity: sha512-5mMeb1TgLWoRKxZ0Xh9RZDfwUUIqRrcxO2uXO+Ezl1N5lqpCiSU5Gk6+1kZediBfBHFtPCdopr2UZ2SgUsKcgQ==}
|
||||
engines: {node: ^12 || >=14}
|
||||
|
||||
postcss-loader@8.1.1:
|
||||
resolution: {integrity: sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==}
|
||||
engines: {node: '>= 18.12.0'}
|
||||
peerDependencies:
|
||||
'@rspack/core': 0.x || 1.x
|
||||
postcss: ^7.0.0 || ^8.0.1
|
||||
webpack: ^5.0.0
|
||||
peerDependenciesMeta:
|
||||
'@rspack/core':
|
||||
optional: true
|
||||
webpack:
|
||||
optional: true
|
||||
|
||||
postcss-media-query-parser@0.2.3:
|
||||
resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==}
|
||||
|
||||
postcss-px-to-viewport-8-plugin@1.2.5:
|
||||
resolution: {integrity: sha512-+yc69+q/euV7iKh5fGXY6C/lpepmVx2DGFHeYj5BpzIFyBBpdACDjZyrZ8AV0kCg+J0bplBv4ZA1QTzgaK0rGg==}
|
||||
|
||||
postcss-resolve-nested-selector@0.1.6:
|
||||
resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==}
|
||||
|
||||
|
@ -2849,11 +2888,6 @@ snapshots:
|
|||
eslint: 9.21.0(jiti@2.4.2)
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/eslint-utils@4.4.1(eslint@9.21.0)':
|
||||
dependencies:
|
||||
eslint: 9.21.0
|
||||
eslint-visitor-keys: 3.4.3
|
||||
|
||||
'@eslint-community/regexpp@4.12.1': {}
|
||||
|
||||
'@eslint/config-array@0.19.2':
|
||||
|
@ -3342,9 +3376,9 @@ snapshots:
|
|||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
'@vitejs/plugin-vue@5.2.1(vite@6.1.1(sass@1.85.0))(vue@3.5.13(typescript@5.7.3))':
|
||||
'@vitejs/plugin-vue@5.2.1(vite@6.1.1(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0))(vue@3.5.13(typescript@5.7.3))':
|
||||
dependencies:
|
||||
vite: 6.1.1(sass@1.85.0)
|
||||
vite: 6.1.1(jiti@2.4.2)(sass@1.85.0)(terser@5.39.0)
|
||||
vue: 3.5.13(typescript@5.7.3)
|
||||
|
||||
'@volar/language-core@2.4.11':
|
||||
|
@ -3797,31 +3831,31 @@ snapshots:
|
|||
|
||||
escape-string-regexp@4.0.0: {}
|
||||
|
||||
eslint-config-prettier@9.1.0(eslint@9.21.0):
|
||||
eslint-config-prettier@9.1.0(eslint@9.21.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
eslint: 9.21.0
|
||||
eslint: 9.21.0(jiti@2.4.2)
|
||||
|
||||
eslint-define-config@2.1.0: {}
|
||||
|
||||
eslint-plugin-prettier@5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0))(eslint@9.21.0)(prettier@3.5.2):
|
||||
eslint-plugin-prettier@5.2.3(eslint-config-prettier@9.1.0(eslint@9.21.0(jiti@2.4.2)))(eslint@9.21.0(jiti@2.4.2))(prettier@3.5.2):
|
||||
dependencies:
|
||||
eslint: 9.21.0
|
||||
eslint: 9.21.0(jiti@2.4.2)
|
||||
prettier: 3.5.2
|
||||
prettier-linter-helpers: 1.0.0
|
||||
synckit: 0.9.2
|
||||
optionalDependencies:
|
||||
eslint-config-prettier: 9.1.0(eslint@9.21.0)
|
||||
eslint-config-prettier: 9.1.0(eslint@9.21.0(jiti@2.4.2))
|
||||
|
||||
eslint-plugin-vue@9.32.0(eslint@9.21.0):
|
||||
eslint-plugin-vue@9.32.0(eslint@9.21.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0)
|
||||
eslint: 9.21.0
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.2))
|
||||
eslint: 9.21.0(jiti@2.4.2)
|
||||
globals: 13.24.0
|
||||
natural-compare: 1.4.0
|
||||
nth-check: 2.1.1
|
||||
postcss-selector-parser: 6.1.2
|
||||
semver: 7.7.1
|
||||
vue-eslint-parser: 9.4.3(eslint@9.21.0)
|
||||
vue-eslint-parser: 9.4.3(eslint@9.21.0(jiti@2.4.2))
|
||||
xml-name-validator: 4.0.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
@ -3840,45 +3874,6 @@ snapshots:
|
|||
|
||||
eslint-visitor-keys@4.2.0: {}
|
||||
|
||||
eslint@9.21.0:
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0)
|
||||
'@eslint-community/regexpp': 4.12.1
|
||||
'@eslint/config-array': 0.19.2
|
||||
'@eslint/core': 0.12.0
|
||||
'@eslint/eslintrc': 3.3.0
|
||||
'@eslint/js': 9.21.0
|
||||
'@eslint/plugin-kit': 0.2.7
|
||||
'@humanfs/node': 0.16.6
|
||||
'@humanwhocodes/module-importer': 1.0.1
|
||||
'@humanwhocodes/retry': 0.4.2
|
||||
'@types/estree': 1.0.6
|
||||
'@types/json-schema': 7.0.15
|
||||
ajv: 6.12.6
|
||||
chalk: 4.1.2
|
||||
cross-spawn: 7.0.6
|
||||
debug: 4.4.0
|
||||
escape-string-regexp: 4.0.0
|
||||
eslint-scope: 8.2.0
|
||||
eslint-visitor-keys: 4.2.0
|
||||
espree: 10.3.0
|
||||
esquery: 1.6.0
|
||||
esutils: 2.0.3
|
||||
fast-deep-equal: 3.1.3
|
||||
file-entry-cache: 8.0.0
|
||||
find-up: 5.0.0
|
||||
glob-parent: 6.0.2
|
||||
ignore: 5.3.2
|
||||
imurmurhash: 0.1.4
|
||||
is-glob: 4.0.3
|
||||
json-stable-stringify-without-jsonify: 1.0.1
|
||||
lodash.merge: 4.6.2
|
||||
minimatch: 3.1.2
|
||||
natural-compare: 1.4.0
|
||||
optionator: 0.9.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
eslint@9.21.0(jiti@2.4.2):
|
||||
dependencies:
|
||||
'@eslint-community/eslint-utils': 4.4.1(eslint@9.21.0(jiti@2.4.2))
|
||||
|
@ -4198,6 +4193,8 @@ snapshots:
|
|||
optionalDependencies:
|
||||
'@pkgjs/parseargs': 0.11.0
|
||||
|
||||
jiti@1.21.7: {}
|
||||
|
||||
jiti@2.4.2: {}
|
||||
|
||||
js-cookie@3.0.5: {}
|
||||
|
@ -4347,6 +4344,8 @@ snapshots:
|
|||
dependencies:
|
||||
boolbase: 1.0.0
|
||||
|
||||
object-assign@4.1.1: {}
|
||||
|
||||
ofetch@1.4.1:
|
||||
dependencies:
|
||||
destr: 2.0.3
|
||||
|
@ -4443,8 +4442,21 @@ snapshots:
|
|||
postcss: 8.5.3
|
||||
postcss-safe-parser: 6.0.0(postcss@8.5.3)
|
||||
|
||||
postcss-loader@8.1.1(postcss@8.5.3)(typescript@5.7.3):
|
||||
dependencies:
|
||||
cosmiconfig: 9.0.0(typescript@5.7.3)
|
||||
jiti: 1.21.7
|
||||
postcss: 8.5.3
|
||||
semver: 7.7.1
|
||||
transitivePeerDependencies:
|
||||
- typescript
|
||||
|
||||
postcss-media-query-parser@0.2.3: {}
|
||||
|
||||
postcss-px-to-viewport-8-plugin@1.2.5:
|
||||
dependencies:
|
||||
object-assign: 4.1.1
|
||||
|
||||
postcss-resolve-nested-selector@0.1.6: {}
|
||||
|
||||
postcss-safe-parser@6.0.0(postcss@8.5.3):
|
||||
|
@ -4924,25 +4936,16 @@ snapshots:
|
|||
sass: 1.85.0
|
||||
terser: 5.39.0
|
||||
|
||||
vite@6.1.1(sass@1.85.0):
|
||||
dependencies:
|
||||
esbuild: 0.24.2
|
||||
postcss: 8.5.3
|
||||
rollup: 4.34.8
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.3
|
||||
sass: 1.85.0
|
||||
|
||||
vscode-uri@3.1.0: {}
|
||||
|
||||
vue-demi@0.14.10(vue@3.5.13(typescript@5.7.3)):
|
||||
dependencies:
|
||||
vue: 3.5.13(typescript@5.7.3)
|
||||
|
||||
vue-eslint-parser@9.4.3(eslint@9.21.0):
|
||||
vue-eslint-parser@9.4.3(eslint@9.21.0(jiti@2.4.2)):
|
||||
dependencies:
|
||||
debug: 4.4.0
|
||||
eslint: 9.21.0
|
||||
eslint: 9.21.0(jiti@2.4.2)
|
||||
eslint-scope: 7.2.2
|
||||
eslint-visitor-keys: 3.4.3
|
||||
espree: 9.6.1
|
||||
|
|
22
src/App.vue
|
@ -1,22 +1,10 @@
|
|||
<script lang="ts" setup></script>
|
||||
|
||||
<template>
|
||||
<router-view />
|
||||
<router-view />
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.logo {
|
||||
height: 6em;
|
||||
padding: 1.5em;
|
||||
will-change: filter;
|
||||
transition: filter 300ms;
|
||||
}
|
||||
|
||||
.logo:hover {
|
||||
filter: drop-shadow(0 0 2em #646cffaa);
|
||||
}
|
||||
|
||||
.logo.vue:hover {
|
||||
filter: drop-shadow(0 0 2em #42b883aa);
|
||||
<style>
|
||||
#app {
|
||||
width: 100%;
|
||||
height: 1080px;
|
||||
}
|
||||
</style>
|
||||
|
|
After Width: | Height: | Size: 66 KiB |
After Width: | Height: | Size: 308 KiB |
After Width: | Height: | Size: 195 KiB |
After Width: | Height: | Size: 232 KiB |
After Width: | Height: | Size: 3.9 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 2.2 KiB |
|
@ -0,0 +1,38 @@
|
|||
<script lang="ts" setup></script>
|
||||
|
||||
<template>
|
||||
<main class="mt-[78px] mx-auto flex-center w-[1620px] h-[650px]">
|
||||
<div class="left mr-[28px]">左边</div>
|
||||
|
||||
<div class="middle">中间</div>
|
||||
|
||||
<div class="right ml-[28px]">右边</div>
|
||||
</main>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-main {
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.left,
|
||||
.right {
|
||||
width: 380px;
|
||||
height: 650px;
|
||||
background: url("@/assets/images/bg-side.png") no-repeat center;
|
||||
background-size: cover;
|
||||
transition: transform 0.8s;
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.left {
|
||||
transform: rotateY(180deg);
|
||||
}
|
||||
|
||||
.middle {
|
||||
width: 824px;
|
||||
height: 650px;
|
||||
background: url("@/assets/images/bg-middle.png") no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,25 @@
|
|||
<script lang="ts" setup></script>
|
||||
|
||||
<template>
|
||||
<footer class="mt-[66px] mx-auto w-[772px] h-[125px]">
|
||||
<ul class="flex-x-around">
|
||||
<li
|
||||
v-for="index in new Array(5)"
|
||||
:key="index"
|
||||
class="rectangle w-[138px] h-[125px] flex-y-center bg-[#0E094D55]"
|
||||
>
|
||||
<img alt="车辆管理" src="@/assets/images/footer-39.png" />
|
||||
<span class="c-white font-100">车辆管理</span>
|
||||
</li>
|
||||
</ul>
|
||||
</footer>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.rectangle {
|
||||
img {
|
||||
width: 67px;
|
||||
height: 67px;
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,54 @@
|
|||
<script lang="ts" setup></script>
|
||||
|
||||
<template>
|
||||
<header class="h-[105px]">
|
||||
<div class="time ml-[41px] c-[#027AFF]">2025年2月25日22:45:14</div>
|
||||
|
||||
<div class="title">
|
||||
<h1 class="c-white text-align-center">智慧智能监管中心</h1>
|
||||
<h2 class="text-align-center">车辆监控中心</h2>
|
||||
</div>
|
||||
|
||||
<div class="bar-op flex items-center h-[36px]">
|
||||
<ul class="float-left flex-x-around w-[148px]">
|
||||
<li><img alt="icon-1" src="@/assets/images/icon-1.png" /></li>
|
||||
<li><img alt="icon-2" src="@/assets/images/icon-2.png" /></li>
|
||||
<li><img alt="icon-3" src="@/assets/images/icon-3.png" /></li>
|
||||
</ul>
|
||||
<span class="float-left c-[#027AFF]">王菠萝</span>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
header {
|
||||
position: relative;
|
||||
background: url("@/assets/images/bg-header.png") no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.time {
|
||||
position: absolute;
|
||||
line-height: 60px;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.title {
|
||||
h1 {
|
||||
font-size: 42px;
|
||||
line-height: 60px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
line-height: 45px;
|
||||
color: #00ffff;
|
||||
}
|
||||
}
|
||||
|
||||
.bar-op {
|
||||
position: absolute;
|
||||
top: 11px;
|
||||
right: 20px;
|
||||
}
|
||||
</style>
|
|
@ -1,26 +1,22 @@
|
|||
<script lang="ts" setup></script>
|
||||
<script lang="ts" setup>
|
||||
import AppMain from "@/layout/components/AppMain/index.vue";
|
||||
import NavBar from "@/layout/components/NavBar/index.vue";
|
||||
import Footer from "@/layout/components/Footer/index.vue";
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="w-full flex items-center justify-center flex-wrap gap-x-4 text-4xl p-2 mt-4">
|
||||
<div class="w-full flex items-center justify-center mb-4">
|
||||
<button>清除默认样式的按钮</button>
|
||||
</div>
|
||||
<div class="i-ph-anchor-simple-thin" />
|
||||
<!-- 来自 Phosphor 图标的基本锚点图标 -->
|
||||
<div class="i-ph-anchor-simple-thin" />
|
||||
<!-- 来自 Material Design Icons 的一个橙色闹钟 -->
|
||||
<div class="i-mdi-alarm text-orange-400" />
|
||||
<!-- 一个大尺寸的 Vue 标志 -->
|
||||
<div class="i-logos-vue text-3xl" />
|
||||
<!-- 太阳在亮模式,月亮在暗模式,来自 Carbon -->
|
||||
<button class="i-carbon-sun dark:i-carbon-moon" />
|
||||
<!-- Twemoji 笑脸,悬停时变成流泪表情 -->
|
||||
<div class="i-twemoji-grinning-face-with-smiling-eyes hover:i-twemoji-face-with-tears-of-joy" />
|
||||
<div class="i-vscode-icons:file-type-light-pnpm" />
|
||||
<div class="i-vscode-icons:file-type-light-pnpm?mask text-red-300" />
|
||||
<span class="i-ic:baseline-16mp" />
|
||||
<span class="i-vscode-icons:file-type-java" />
|
||||
</div>
|
||||
<div class="layout w-full h-full">
|
||||
<NavBar />
|
||||
<AppMain />
|
||||
<Footer />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
<style scoped>
|
||||
.layout {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: url("@/assets/images/bg.png") no-repeat center;
|
||||
background-size: cover;
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,232 +1,237 @@
|
|||
<script lang="ts" setup>
|
||||
import { useRouter } from 'vue-router';
|
||||
import { useRouter } from "vue-router";
|
||||
|
||||
const router = useRouter();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="page-container">
|
||||
<div class="pic-404">
|
||||
<img alt="404" class="pic-404__parent" src="@/assets/images/404.png" />
|
||||
<img alt="404" class="pic-404__child left" src="@/assets/images/404_cloud.png" />
|
||||
<img alt="404" class="pic-404__child mid" src="@/assets/images/404_cloud.png" />
|
||||
<img alt="404" class="pic-404__child right" src="@/assets/images/404_cloud.png" />
|
||||
</div>
|
||||
<div class="bullshit">
|
||||
<div class="bullshit__oops">OOPS!</div>
|
||||
<div class="bullshit__info">
|
||||
All rights reserved
|
||||
<a href="https://wallstreetcn.com" style="color: #20a0ff" target="_blank">wallstreetcn</a>
|
||||
</div>
|
||||
<div class="bullshit__headline">The webmaster said that you can not enter this page...</div>
|
||||
<div class="bullshit__info">Please check that the URL you entered is correct, or click the button below to return to the homepage.</div>
|
||||
<a class="bullshit__return-home" href="/" @click.prevent="router.replace('/')"> Back to home </a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="page-container">
|
||||
<div class="pic-404">
|
||||
<img alt="404" class="pic-404__parent" src="@/assets/images/404.png" />
|
||||
<img alt="404" class="pic-404__child left" src="@/assets/images/404_cloud.png" />
|
||||
<img alt="404" class="pic-404__child mid" src="@/assets/images/404_cloud.png" />
|
||||
<img alt="404" class="pic-404__child right" src="@/assets/images/404_cloud.png" />
|
||||
</div>
|
||||
<div class="bullshit">
|
||||
<div class="bullshit__oops">OOPS!</div>
|
||||
<div class="bullshit__info">
|
||||
All rights reserved
|
||||
<a href="https://wallstreetcn.com" style="color: #20a0ff" target="_blank">wallstreetcn</a>
|
||||
</div>
|
||||
<div class="bullshit__headline">The webmaster said that you can not enter this page...</div>
|
||||
<div class="bullshit__info">
|
||||
Please check that the URL you entered is correct, or click the button below to return to the
|
||||
homepage.
|
||||
</div>
|
||||
<a class="bullshit__return-home" href="/" @click.prevent="router.replace('/')">
|
||||
Back to home
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.page-container {
|
||||
display: flex;
|
||||
padding: 100px;
|
||||
display: flex;
|
||||
padding: 100px;
|
||||
|
||||
.pic-404 {
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
.pic-404 {
|
||||
width: 600px;
|
||||
overflow: hidden;
|
||||
|
||||
&__parent {
|
||||
width: 100%;
|
||||
}
|
||||
&__parent {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
&__child {
|
||||
&.left {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
width: 80px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__child {
|
||||
&.left {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
width: 80px;
|
||||
opacity: 0;
|
||||
animation-name: cloudLeft;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&.mid {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
width: 46px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&.mid {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
width: 46px;
|
||||
opacity: 0;
|
||||
animation-name: cloudMid;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&.right {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
width: 62px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&.right {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
width: 62px;
|
||||
opacity: 0;
|
||||
animation-name: cloudRight;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-delay: 1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
@keyframes cloudLeft {
|
||||
0% {
|
||||
top: 17px;
|
||||
left: 220px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
20% {
|
||||
top: 33px;
|
||||
left: 188px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 81px;
|
||||
left: 92px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
100% {
|
||||
top: 97px;
|
||||
left: 60px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
@keyframes cloudMid {
|
||||
0% {
|
||||
top: 10px;
|
||||
left: 420px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
20% {
|
||||
top: 40px;
|
||||
left: 360px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
70% {
|
||||
top: 130px;
|
||||
left: 180px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
100% {
|
||||
top: 160px;
|
||||
left: 120px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
@keyframes cloudRight {
|
||||
0% {
|
||||
top: 100px;
|
||||
left: 500px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
20% {
|
||||
top: 120px;
|
||||
left: 460px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
80% {
|
||||
top: 180px;
|
||||
left: 340px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
100% {
|
||||
top: 200px;
|
||||
left: 300px;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.bullshit {
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
.bullshit {
|
||||
width: 300px;
|
||||
padding: 30px 0;
|
||||
overflow: hidden;
|
||||
|
||||
&__oops {
|
||||
margin-bottom: 20px;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: #1482f0;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__oops {
|
||||
margin-bottom: 20px;
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
line-height: 40px;
|
||||
color: #1482f0;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&__headline {
|
||||
margin-bottom: 10px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__headline {
|
||||
margin-bottom: 10px;
|
||||
font-size: 20px;
|
||||
font-weight: bold;
|
||||
line-height: 24px;
|
||||
color: #222;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.1s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&__info {
|
||||
margin-bottom: 30px;
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: grey;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__info {
|
||||
margin-bottom: 30px;
|
||||
font-size: 13px;
|
||||
line-height: 21px;
|
||||
color: grey;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.2s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
&__return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: #1482f0;
|
||||
border-radius: 100px;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
&__return-home {
|
||||
display: block;
|
||||
float: left;
|
||||
width: 110px;
|
||||
height: 36px;
|
||||
font-size: 14px;
|
||||
line-height: 36px;
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
cursor: pointer;
|
||||
background: #1482f0;
|
||||
border-radius: 100px;
|
||||
opacity: 0;
|
||||
animation-name: slideUp;
|
||||
animation-duration: 0.5s;
|
||||
animation-delay: 0.3s;
|
||||
animation-fill-mode: forwards;
|
||||
}
|
||||
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(60px);
|
||||
}
|
||||
@keyframes slideUp {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform: translateY(60px);
|
||||
}
|
||||
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<template>
|
||||
<div />
|
||||
<div />
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { useRoute, useRouter } from 'vue-router';
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
|
@ -11,5 +11,5 @@ const router = useRouter();
|
|||
const { params, query } = route;
|
||||
const { path } = params;
|
||||
|
||||
router.replace({ path: '/' + path, query });
|
||||
router.replace({ path: "/" + path, query });
|
||||
</script>
|
||||
|
|
|
@ -1,33 +1,36 @@
|
|||
import {
|
||||
defineConfig,
|
||||
presetAttributify,
|
||||
presetIcons,
|
||||
presetTypography,
|
||||
presetUno,
|
||||
presetWebFonts,
|
||||
transformerDirectives,
|
||||
transformerVariantGroup,
|
||||
} from 'unocss';
|
||||
defineConfig,
|
||||
presetAttributify,
|
||||
presetIcons,
|
||||
presetTypography,
|
||||
presetUno,
|
||||
presetWebFonts,
|
||||
transformerDirectives,
|
||||
transformerVariantGroup,
|
||||
} from "unocss";
|
||||
|
||||
export default defineConfig({
|
||||
shortcuts: [
|
||||
// ...
|
||||
],
|
||||
theme: {
|
||||
colors: {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
presetUno(),
|
||||
presetAttributify(),
|
||||
presetIcons(),
|
||||
presetTypography(),
|
||||
presetWebFonts({
|
||||
fonts: {
|
||||
// ...
|
||||
},
|
||||
}),
|
||||
],
|
||||
transformers: [transformerDirectives(), transformerVariantGroup()],
|
||||
shortcuts: {
|
||||
"flex-center": "flex justify-center items-center",
|
||||
"flex-x-between": "flex items-center justify-between",
|
||||
"flex-x-around": "flex items-center justify-around",
|
||||
"flex-y-center": "flex flex-col flex-wrap justify-center items-center",
|
||||
},
|
||||
theme: {
|
||||
colors: {
|
||||
// ...
|
||||
},
|
||||
},
|
||||
presets: [
|
||||
presetUno(),
|
||||
presetAttributify(),
|
||||
presetIcons(),
|
||||
presetTypography(),
|
||||
presetWebFonts({
|
||||
fonts: {
|
||||
// ...
|
||||
},
|
||||
}),
|
||||
],
|
||||
transformers: [transformerDirectives(), transformerVariantGroup()],
|
||||
});
|
||||
|
|
|
@ -1,33 +1,57 @@
|
|||
import { defineConfig } from 'vite';
|
||||
import { plugins } from './build/plugins';
|
||||
import { resolve } from './build/resolve';
|
||||
import { buildEnv } from './build/buildEnv';
|
||||
import { define } from './build/define';
|
||||
import { root, wrapperEnv } from './build/utils';
|
||||
import { server } from './build/server';
|
||||
import { exclude, include } from './build/optimize';
|
||||
import { defineConfig } from "vite";
|
||||
import { plugins } from "./build/plugins";
|
||||
import { resolve } from "./build/resolve";
|
||||
import { buildEnv } from "./build/buildEnv";
|
||||
import { define } from "./build/define";
|
||||
import { root, wrapperEnv } from "./build/utils";
|
||||
import { server } from "./build/server";
|
||||
import { exclude, include } from "./build/optimize";
|
||||
import postCssPxToViewport8plugin from "postcss-px-to-viewport-8-plugin";
|
||||
|
||||
// https://vite.dev/config/
|
||||
export default defineConfig(({ command, mode, isSsrBuild, isPreview }) => {
|
||||
const env = wrapperEnv(mode, 'VITE');
|
||||
const env = wrapperEnv(mode, "VITE");
|
||||
|
||||
return {
|
||||
root,
|
||||
base: env.VITE_PUBLIC_PATH,
|
||||
define: define(),
|
||||
plugins: plugins(mode),
|
||||
resolve: resolve(),
|
||||
esbuild: {
|
||||
jsxFactory: 'h',
|
||||
jsxFragment: 'Fragment',
|
||||
jsxInject: "import { h } from 'vue';",
|
||||
},
|
||||
logLevel: 'info',
|
||||
// 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
|
||||
clearScreen: false,
|
||||
build: buildEnv(),
|
||||
server: server(mode),
|
||||
preview: server(mode),
|
||||
optimizeDeps: { include, exclude },
|
||||
};
|
||||
return {
|
||||
root,
|
||||
base: env.VITE_PUBLIC_PATH,
|
||||
define: define(),
|
||||
plugins: plugins(mode),
|
||||
resolve: resolve(),
|
||||
esbuild: {
|
||||
jsxFactory: "h",
|
||||
jsxFragment: "Fragment",
|
||||
jsxInject: "import { h } from 'vue';",
|
||||
},
|
||||
css: {
|
||||
postcss: {
|
||||
plugins: [
|
||||
postCssPxToViewport8plugin({
|
||||
unitToConvert: "px",
|
||||
viewportWidth: 1920, // 设计稿的宽度
|
||||
unitPrecision: 5, // 单位转换后保留的精度
|
||||
propList: ["*"], // 能转化为vw的属性列表
|
||||
viewportUnit: "vw", // 希望使用的视口单位
|
||||
fontViewportUnit: "vw", // 字体使用的视口单位
|
||||
selectorBlackList: [], // 需要忽略的CSS选择器,不会转为视口单位,使用原有的px等单位。
|
||||
minPixelValue: 1, // 设置最小的转换数值,如果为1的话,只有大于1的值会被转换
|
||||
mediaQuery: true, // 媒体查询里的单位是否需要转换单位
|
||||
replace: true, // 是否直接更换属性值,而不添加备用属性
|
||||
exclude: [/node_modules/], // 忽略某些文件夹下的文件或特定文件,例如 'node_modules' 下的文件
|
||||
include: [], // 如果设置了include,那将只有匹配到的文件才会被转换
|
||||
landscape: false, // 是否添加根据 landscapeWidth 生成的媒体查询条件 @media (orientation: landscape)
|
||||
landscapeUnit: "vw", // 横屏时使用的单位
|
||||
landscapeWidth: 1024, // 横屏时使用的视口宽度
|
||||
}),
|
||||
],
|
||||
},
|
||||
},
|
||||
logLevel: "info",
|
||||
// 设为 false 可以避免 Vite 清屏而错过在终端中打印某些关键信息
|
||||
clearScreen: false,
|
||||
build: buildEnv(),
|
||||
server: server(mode),
|
||||
preview: server(mode),
|
||||
optimizeDeps: { include, exclude },
|
||||
};
|
||||
});
|
||||
|
|