@ -0,0 +1,5 @@ |
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取 |
||||
NODE_ENV = 'development' |
||||
VITE_APP_TITLE = '教学一体化平台' |
||||
VITE_APP_BASE_API = 'http://39.106.16.162:8080' |
||||
# VITE_APP_BASE_API = 'http://127.0.0.1:8080' |
@ -0,0 +1,3 @@ |
||||
NODE_ENV = 'production' |
||||
VITE_APP_TITLE = '教学一体化平台' |
||||
# VITE_APP_BASE_API = '/api' |
@ -0,0 +1,4 @@ |
||||
# 变量必须以 VITE_ 为前缀才能暴露给外部读取 |
||||
NODE_ENV = 'test' |
||||
VITE_APP_TITLE = '教学一体化平台' |
||||
# VITE_APP_BASE_API = '/api' |
@ -0,0 +1,2 @@ |
||||
dist |
||||
node_modules |
@ -0,0 +1,60 @@ |
||||
// @see https://eslint.bootcss.com/docs/rules/ |
||||
|
||||
module.exports = { |
||||
publicPath:"/portal", |
||||
env: { |
||||
browser: true, |
||||
es2021: true, |
||||
node: true, |
||||
jest: true, |
||||
}, |
||||
/* 指定如何解析语法 */ |
||||
parser: 'vue-eslint-parser', |
||||
/** 优先级低于 parse 的语法解析配置 */ |
||||
parserOptions: { |
||||
ecmaVersion: 'latest', |
||||
sourceType: 'module', |
||||
parser: '@typescript-eslint/parser', |
||||
jsxPragma: 'React', |
||||
ecmaFeatures: { |
||||
jsx: true, |
||||
}, |
||||
}, |
||||
/* 继承已有的规则 */ |
||||
extends: [ |
||||
'eslint:recommended', |
||||
'plugin:vue/vue3-essential', |
||||
'plugin:@typescript-eslint/recommended', |
||||
'plugin:prettier/recommended', |
||||
], |
||||
plugins: ['vue', '@typescript-eslint'], |
||||
/* |
||||
* "off" 或 0 ==> 关闭规则 |
||||
* "warn" 或 1 ==> 打开的规则作为警告(不影响代码执行) |
||||
* "error" 或 2 ==> 规则作为一个错误(代码不能执行,界面报错) |
||||
*/ |
||||
rules: { |
||||
// eslint(https://eslint.bootcss.com/docs/rules/) |
||||
'no-var': 'error', // 要求使用 let 或 const 而不是 var |
||||
'no-multiple-empty-lines': ['warn', { max: 1 }], // 不允许多个空行 |
||||
'no-console': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off', |
||||
'no-unexpected-multiline': 'error', // 禁止空余的多行 |
||||
'no-useless-escape': 'off', // 禁止不必要的转义字符 |
||||
|
||||
// typeScript (https://typescript-eslint.io/rules) |
||||
'@typescript-eslint/no-unused-vars': 'warn', // 禁止定义未使用的变量 |
||||
'@typescript-eslint/prefer-ts-expect-error': 'error', // 禁止使用 @ts-ignore |
||||
'@typescript-eslint/no-explicit-any': 'off', // 禁止使用 any 类型 |
||||
'@typescript-eslint/no-non-null-assertion': 'off', |
||||
'@typescript-eslint/no-namespace': 'off', // 禁止使用自定义 TypeScript 模块和命名空间。 |
||||
'@typescript-eslint/semi': 'off', |
||||
|
||||
// eslint-plugin-vue (https://eslint.vuejs.org/rules/) |
||||
'vue/multi-word-component-names': 'off', // 要求组件名称始终为 “-” 链接的单词 |
||||
'vue/script-setup-uses-vars': 'error', // 防止<script setup>使用的变量<template>被标记为未使用 |
||||
'vue/no-mutating-props': 'off', // 不允许组件 prop的改变 |
||||
'vue/attribute-hyphenation': 'off', // 对模板中的自定义组件强制执行属性命名样式 |
||||
}, |
||||
} |
||||
|
@ -0,0 +1,24 @@ |
||||
# Logs |
||||
logs |
||||
*.log |
||||
npm-debug.log* |
||||
yarn-debug.log* |
||||
yarn-error.log* |
||||
pnpm-debug.log* |
||||
lerna-debug.log* |
||||
|
||||
node_modules |
||||
dist |
||||
dist-ssr |
||||
*.local |
||||
|
||||
# Editor directories and files |
||||
.vscode/* |
||||
!.vscode/extensions.json |
||||
.idea |
||||
.DS_Store |
||||
*.suo |
||||
*.ntvs* |
||||
*.njsproj |
||||
*.sln |
||||
*.sw? |
@ -0,0 +1,7 @@ |
||||
/dist/* |
||||
/html/* |
||||
.local |
||||
/node_modules/** |
||||
**/*.svg |
||||
**/*.sh |
||||
/public/* |
@ -0,0 +1,9 @@ |
||||
{ |
||||
"singleQuote": true, |
||||
"semi": false, |
||||
"bracketSpacing": true, |
||||
"htmlWhitespaceSensitivity": "ignore", |
||||
"endOfLine": "auto", |
||||
"trailingComma": "all", |
||||
"tabWidth": 2 |
||||
} |
@ -0,0 +1,4 @@ |
||||
/node_modules/* |
||||
/dist/* |
||||
/html/* |
||||
/public/* |
@ -0,0 +1,53 @@ |
||||
// @see https://stylelint.bootcss.com/ |
||||
|
||||
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: [ |
||||
{ |
||||
files: ['**/*.(scss|css|vue|html)'], |
||||
customSyntax: 'postcss-scss', |
||||
}, |
||||
{ |
||||
files: ['**/*.(html|vue)'], |
||||
customSyntax: 'postcss-html', |
||||
}, |
||||
], |
||||
ignoreFiles: [ |
||||
'**/*.js', |
||||
'**/*.jsx', |
||||
'**/*.tsx', |
||||
'**/*.ts', |
||||
'**/*.json', |
||||
'**/*.md', |
||||
'**/*.yaml', |
||||
], |
||||
/** |
||||
* null => 关闭该规则 |
||||
* always => 必须 |
||||
*/ |
||||
rules: { |
||||
'value-keyword-case': null, // 在 css 中使用 v-bind,不报错 |
||||
'no-descending-specificity': null, // 禁止在具有较高优先级的选择器后出现被其覆盖的较低优先级的选择器 |
||||
'function-url-quotes': 'always', // 要求或禁止 URL 的引号 "always(必须加上引号)"|"never(没有引号)" |
||||
'no-empty-source': null, // 关闭禁止空源码 |
||||
'selector-class-pattern': null, // 关闭强制选择器类名的格式 |
||||
'property-no-unknown': null, // 禁止未知的属性(true 为不允许) |
||||
'block-opening-brace-space-before': 'always', //大括号之前必须有一个空格或不能有空白符 |
||||
'value-no-vendor-prefix': null, // 关闭 属性值前缀 --webkit-box |
||||
'property-no-vendor-prefix': null, // 关闭 属性前缀 -webkit-mask |
||||
'selector-pseudo-class-no-unknown': [ |
||||
// 不允许未知的选择器 |
||||
true, |
||||
{ |
||||
ignorePseudoClasses: ['global', 'v-deep', 'deep'], // 忽略属性,修改element默认样式的时候能使用到 |
||||
}, |
||||
], |
||||
}, |
||||
} |
@ -0,0 +1,3 @@ |
||||
{ |
||||
"recommendations": ["Vue.volar"] |
||||
} |
@ -0,0 +1,13 @@ |
||||
<!doctype html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
<title>Vite + Vue + TS</title> |
||||
</head> |
||||
<body> |
||||
<div id="app"></div> |
||||
<script type="module" src="/src/main.ts"></script> |
||||
</body> |
||||
</html> |
@ -0,0 +1,61 @@ |
||||
{ |
||||
"name": "teaching-integration-platform-template", |
||||
"private": true, |
||||
"version": "0.0.0", |
||||
"type": "module", |
||||
"scripts": { |
||||
"dev": "vite --open", |
||||
"build:test": "vite build", |
||||
"build:pro": "vue-tsc && vite build --mode production", |
||||
"preview": "vite preview", |
||||
"lint": "eslint src", |
||||
"fix": "eslint src --fix", |
||||
"format": "prettier --write \"./**/*.{html,vue,ts,js,json,md}\"", |
||||
"lint:eslint": "eslint src/**/*.{ts,vue} --cache --fix", |
||||
"lint:style": "stylelint src/**/*.{css,scss,vue} --cache --fix", |
||||
"preinstall": "node ./scripts/preinstall.js" |
||||
}, |
||||
"dependencies": { |
||||
|
||||
"@element-plus/icons-vue": "^2.3.1", |
||||
"axios": "^1.6.8", |
||||
"element-plus": "^2.6.2", |
||||
"pinia": "^2.1.7", |
||||
"postcss-plugin-px2rem": "^0.8.1", |
||||
"px2rem-loader": "^0.1.9", |
||||
"vue": "^3.4.21", |
||||
"vue-router": "^4.3.0" |
||||
}, |
||||
"devDependencies": { |
||||
"@babel/eslint-parser": "^7.24.1", |
||||
"@types/node": "^20.11.30", |
||||
"@typescript-eslint/eslint-plugin": "^7.4.0", |
||||
"@typescript-eslint/parser": "^7.4.0", |
||||
"@vitejs/plugin-vue": "^5.0.4", |
||||
"eslint": "^8.57.0", |
||||
"eslint-config-prettier": "^9.1.0", |
||||
"eslint-plugin-import": "^2.29.1", |
||||
"eslint-plugin-node": "^11.1.0", |
||||
"eslint-plugin-prettier": "^5.1.3", |
||||
"eslint-plugin-vue": "^9.24.0", |
||||
"postcss": "^8.4.38", |
||||
"postcss-html": "^1.6.0", |
||||
"postcss-scss": "^4.0.9", |
||||
"prettier": "^3.2.5", |
||||
"sass": "^1.72.0", |
||||
"sass-loader": "^14.1.1", |
||||
"stylelint": "^16.3.1", |
||||
"stylelint-config-prettier": "^9.0.5", |
||||
"stylelint-config-recess-order": "^5.0.0", |
||||
"stylelint-config-recommended-scss": "^14.0.0", |
||||
"stylelint-config-standard": "^36.0.0", |
||||
"stylelint-config-standard-scss": "^13.0.0", |
||||
"stylelint-config-standard-vue": "^1.0.0", |
||||
"stylelint-order": "^6.0.4", |
||||
"stylelint-scss": "^6.2.1", |
||||
"typescript": "^5.2.2", |
||||
"vite": "^5.2.0", |
||||
"vite-plugin-svg-icons": "^2.0.1", |
||||
"vue-tsc": "^2.0.6" |
||||
} |
||||
} |
After Width: | Height: | Size: 1.5 KiB |
@ -0,0 +1,7 @@ |
||||
if (!/pnpm/.test(process.env.npm_execpath || '')) { |
||||
console.warn( |
||||
`\u001b[33mThis repository must using pnpm as the package manager ` + |
||||
` for scripts to work properly.\u001b[39m\n`, |
||||
) |
||||
process.exit(1) |
||||
} |
@ -0,0 +1,9 @@ |
||||
<template> |
||||
<router-view></router-view> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import {} from 'vue' |
||||
</script> |
||||
|
||||
<style lang="scss" scoped></style> |
@ -0,0 +1,23 @@ |
||||
<template> |
||||
<div class="footer"> |
||||
<h1>FOOTER</h1> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import {} from 'vue' |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.footer { |
||||
// position: fixed; |
||||
// bottom: 0; |
||||
height: 300px; |
||||
width: 100%; |
||||
background-color: #252527; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: center; |
||||
color: #fff; |
||||
} |
||||
</style> |
@ -0,0 +1,134 @@ |
||||
<template> |
||||
<Tabbar /> |
||||
<div class="main-container"> |
||||
<Main /> |
||||
</div> |
||||
<Footer /> |
||||
<div ref="totop" v-if="show" class="gotop" @click="scrollToTop"></div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
// 导入顶部导航栏 |
||||
import Tabbar from './tabbar/index.vue' |
||||
// 导入二级路由容器 |
||||
import Main from './main/index.vue' |
||||
// 导入底部导航栏 |
||||
import Footer from './footer/index.vue' |
||||
import { onMounted, ref } from 'vue' |
||||
const totop = ref() |
||||
const flog = ref(false) |
||||
const show = ref(true) |
||||
const scrollToTop = () => { |
||||
flog.value = true |
||||
const dom = document.querySelector('.gotop') as Element |
||||
console.log(dom) |
||||
totop.value.style.backgroundPosition = '-6px -145px' |
||||
setTimeout(() => { |
||||
totop.value.style.backgroundPosition = '-363px -78px' |
||||
}, 200) |
||||
setTimeout(() => { |
||||
totop.value.style.backgroundPosition = '-316px -78px' |
||||
}, 400) |
||||
setTimeout(() => { |
||||
totop.value.style.backgroundPosition = '-6px -80px' |
||||
totop.value.style.height = '60px' |
||||
|
||||
scrollTop() |
||||
}, 500) |
||||
} |
||||
const scrollTop = () => { |
||||
window.scrollTo({ |
||||
top: 0, |
||||
left: 0, |
||||
behavior: 'smooth', |
||||
}); |
||||
setTimeout(() => { |
||||
show.value = false |
||||
},1500); |
||||
setTimeout(() => { |
||||
show.value = true |
||||
flog.value = false |
||||
num = 800 |
||||
},1600); |
||||
} |
||||
let num = 800 |
||||
onMounted(() => { |
||||
// 页面滚动窗口监听事件 |
||||
window.onscroll = function () { |
||||
let high = document.documentElement.scrollTop || document.body.scrollTop //兼容各浏览器 |
||||
// console.log(high,totop.value.offsetTop) |
||||
|
||||
if (flog.value) { |
||||
num = num - 40 |
||||
totop.value.style.top = num + 'px' |
||||
return |
||||
} |
||||
// 获取浏览器卷去的高度 |
||||
if (high >= 900) { |
||||
totop.value.style.display = 'block' |
||||
} else { |
||||
totop.value.style.display = 'none' |
||||
} |
||||
} |
||||
}) |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.main-container { |
||||
width: 100%; |
||||
min-height: 100vh; |
||||
// padding-top: 80PX; |
||||
} |
||||
|
||||
.gotop { |
||||
display: none; |
||||
width: 45PX; |
||||
height: 45PX; |
||||
z-index: 999; |
||||
position: fixed; |
||||
bottom: 50px; |
||||
right: 50px; |
||||
background-image: url('../assets/images/jinglingtu.png'); |
||||
background-position: -264PX -78PX; |
||||
transition: top 0.2s linear; |
||||
animation: show 0.5s ease-in-out; |
||||
} |
||||
.gotop:hover { |
||||
transition: background-image 0.2s ease-in; |
||||
background-position: -215PX -78PX; |
||||
} |
||||
.bian { |
||||
animation: bian 0.1s ease-in-out; |
||||
} |
||||
.fei { |
||||
position: absolute; |
||||
// animation: fei 3s ease-in-out; |
||||
} |
||||
@keyframes show { |
||||
0% { |
||||
opacity: 0; |
||||
transform: translate3d(0, 100%, 0); |
||||
} |
||||
100% { |
||||
opacity: 1; |
||||
transform: none; |
||||
} |
||||
} |
||||
@keyframes bian { |
||||
0% { |
||||
background-position: -6PX -145PX; |
||||
} |
||||
100% { |
||||
background-position: -316PX -78PX; |
||||
} |
||||
} |
||||
// @keyframes fei { |
||||
// 0% { |
||||
|
||||
// bottom: 50px; |
||||
// } |
||||
// 100% { |
||||
// top: 10%; |
||||
// } |
||||
// } |
||||
</style> |
@ -0,0 +1,19 @@ |
||||
<template> |
||||
<!-- <section class="app-main"> |
||||
<transition name="fade-transform" mode="out-in"> |
||||
<router-view :key="$route.path" /> |
||||
</transition> |
||||
</section> --> |
||||
<router-view></router-view> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import {} from 'vue' |
||||
import {useRoute } from 'vue-router' |
||||
const $route = useRoute() |
||||
console.log( $route); |
||||
|
||||
|
||||
</script> |
||||
|
||||
<style lang="scss" scoped></style> |
@ -0,0 +1,213 @@ |
||||
<template> |
||||
<div :class="!flog ? 'tabbar' : 'tabbar-active'"> |
||||
<div class="container"> |
||||
<div class="left"> |
||||
<div class="logo-box"> |
||||
<div class="lesson">LGOG</div> |
||||
</div> |
||||
|
||||
<div class="menu"> |
||||
<ul> |
||||
<li v-for="(item, index) in constRouter.children" :key="index"> |
||||
{{ item.meta.title }} |
||||
</li> |
||||
</ul> |
||||
</div> |
||||
</div> |
||||
<div class="right"> |
||||
<div class="registered gradient">注册</div> |
||||
<div class="login">登录</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import { constRouter } from '@/router/module/constRouter' |
||||
// import { useRouter, useRoute } from 'vue-router' |
||||
import { onMounted, ref } from 'vue' |
||||
// const $router = useRouter() |
||||
// const $route = useRoute() |
||||
console.log(constRouter, '111') |
||||
|
||||
const flog = ref(false) |
||||
onMounted(() => { |
||||
window.addEventListener('scroll', () => { |
||||
if (window.scrollY >= 50) { |
||||
flog.value = true |
||||
} else if (flog.value && window.scrollY <= 50) { |
||||
flog.value = false |
||||
} |
||||
}) |
||||
}) |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.logo-box { |
||||
display: flex; |
||||
align-items: center; |
||||
column-gap: 20px; |
||||
.logo { |
||||
width: 50px; |
||||
|
||||
img { |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
} |
||||
|
||||
.lesson { |
||||
font-size: 30px; |
||||
font-weight: bolder; |
||||
color: #1d2129; |
||||
} |
||||
} |
||||
|
||||
.tabbar { |
||||
position: fixed; |
||||
top: 0; |
||||
z-index: 1; |
||||
height: 80px; |
||||
width: 100%; |
||||
background-color: transparent; |
||||
animation-duration: 0.3s; |
||||
animation-name: tabber-to; |
||||
} |
||||
|
||||
.tabbar-active { |
||||
position: fixed; |
||||
top: 0; |
||||
height: 80px; |
||||
width: 100%; |
||||
background-color: #fff; |
||||
animation-duration: 0.3s; |
||||
animation-name: tabber; |
||||
z-index: 999; |
||||
box-shadow: 0px 0px 43px rgba(0, 0, 0, 0.2); |
||||
} |
||||
|
||||
@keyframes tabber { |
||||
0% { |
||||
// transform: translateY(-80px); |
||||
background-color: transparent; |
||||
} |
||||
|
||||
100% { |
||||
// transform: translateY(0); |
||||
background-color: #fff; |
||||
} |
||||
} |
||||
|
||||
@keyframes tabber-to { |
||||
0% { |
||||
// transform: translateY(-80px); |
||||
background-color: #fff; |
||||
} |
||||
|
||||
100% { |
||||
// transform: translateY(0); |
||||
background-color: transparent; |
||||
} |
||||
} |
||||
|
||||
.container { |
||||
height: 100%; |
||||
display: flex; |
||||
align-items: center; |
||||
justify-content: space-between; |
||||
margin: 0 auto; |
||||
width: $base-container-width; |
||||
.left { |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
.right { |
||||
display: flex; |
||||
div { |
||||
width: 108px; |
||||
height: 40px; |
||||
text-align: center; |
||||
line-height: 40px; |
||||
border-radius: 5px; |
||||
font-size: 14px; |
||||
cursor: pointer; |
||||
} |
||||
.registered{ |
||||
color: #fff; |
||||
} |
||||
.login{ |
||||
color: #1D2129; |
||||
margin-left: 20px; |
||||
border: 1px solid #E5E6EB; |
||||
} |
||||
} |
||||
.menu { |
||||
position: relative; |
||||
padding: 0 20px; |
||||
height: 100%; |
||||
display: flex; |
||||
align-items: center; |
||||
|
||||
ul { |
||||
display: flex; |
||||
align-items: center; |
||||
|
||||
li { |
||||
padding: 12px 20px; |
||||
color: #1d2129; |
||||
font-size: 14px; |
||||
cursor: pointer; |
||||
transition: all 0.2s; |
||||
position: relative; |
||||
} |
||||
|
||||
li:hover { |
||||
color: #0033f7; |
||||
transform: translateY(-5px); |
||||
} |
||||
|
||||
.active::before { |
||||
content: ' '; |
||||
display: block; |
||||
position: absolute; |
||||
top: 0px; |
||||
left: 50%; |
||||
transform: translateX(-50%); |
||||
width: 5px; |
||||
height: 5px; |
||||
border-radius: 50%; |
||||
background-color: #fff; |
||||
} |
||||
} |
||||
|
||||
.entry { |
||||
position: absolute; |
||||
top: 5px; |
||||
right: 30px; |
||||
display: flex; |
||||
align-content: center; |
||||
|
||||
div { |
||||
// padding: 5px; |
||||
margin: 5px; |
||||
margin-right: 0; |
||||
padding: 0 10px; |
||||
border-right: 1px solid #fff; |
||||
color: #fff; |
||||
font-size: 14px; |
||||
cursor: pointer; |
||||
} |
||||
|
||||
div:last-child { |
||||
border-right: none; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.logo { |
||||
// height: 100%; |
||||
display: flex; |
||||
align-items: center; |
||||
} |
||||
} |
||||
</style> |
After Width: | Height: | Size: 1.8 MiB |
After Width: | Height: | Size: 2.4 MiB |
After Width: | Height: | Size: 555 KiB |
After Width: | Height: | Size: 103 KiB |
After Width: | Height: | Size: 67 KiB |
After Width: | Height: | Size: 52 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 57 KiB |
After Width: | Height: | Size: 36 KiB |
After Width: | Height: | Size: 68 KiB |
After Width: | Height: | Size: 496 B |
@ -0,0 +1,35 @@ |
||||
<template> |
||||
<div> |
||||
<svg :style="{ width: width, height: height }"> |
||||
<use :xlink:href="prefix + name" :fill="color"></use> |
||||
</svg> |
||||
</div> |
||||
</template> |
||||
|
||||
<script setup lang="ts"> |
||||
defineProps({ |
||||
//xlink:href属性值的前缀 |
||||
prefix: { |
||||
type: String, |
||||
default: '#icon-', |
||||
}, |
||||
//svg矢量图的名字 |
||||
name: String, |
||||
//svg图标的颜色 |
||||
color: { |
||||
type: String, |
||||
default: '', |
||||
}, |
||||
//svg宽度 |
||||
width: { |
||||
type: String, |
||||
default: '16px', |
||||
}, |
||||
//svg高度 |
||||
height: { |
||||
type: String, |
||||
default: '16px', |
||||
}, |
||||
}) |
||||
</script> |
||||
<style scoped></style> |
@ -0,0 +1,10 @@ |
||||
import SvgIcon from './SvgIcon/index.vue' |
||||
import type { App, Component } from 'vue' |
||||
const components: { [name: string]: Component } = { SvgIcon } |
||||
export default { |
||||
install(app: App) { |
||||
Object.keys(components).forEach((key: string) => { |
||||
app.component(key, components[key]) |
||||
}) |
||||
}, |
||||
} |
@ -0,0 +1,37 @@ |
||||
import { createApp } from 'vue' |
||||
// import G6 from '@antv/g6'
|
||||
// 导入svg插件
|
||||
import 'virtual:svg-icons-register' |
||||
import App from './App.vue' |
||||
// 引入elementplus组件库
|
||||
import ElementPlus from 'element-plus' |
||||
// 样式;
|
||||
import 'element-plus/dist/index.css' |
||||
//@ts-expect-error忽略当前文件ts类型的检测否则有红色提示(打包会失败)
|
||||
import zhCn from 'element-plus/dist/locale/zh-cn.mjs' |
||||
import gloablComponent from './components/index' |
||||
// 引入全局样式
|
||||
import '@/styles/index.scss' |
||||
// 引入路由
|
||||
import router from '@/router/index' |
||||
// 引入仓库
|
||||
import pinia from '@/store/index' |
||||
import '@/utils/rem.js' |
||||
// 创建vue实例
|
||||
const app = createApp(App) |
||||
// 注册element plus组件库
|
||||
app.use(ElementPlus, { |
||||
locale: zhCn, |
||||
}) |
||||
// 注册全局组件
|
||||
app.use(gloablComponent) |
||||
app.use(router) |
||||
app.use(pinia) |
||||
// app.use(G6)
|
||||
// 挂载点
|
||||
app.mount('#app') |
||||
import * as ElementPlusIconsVue from '@element-plus/icons-vue' |
||||
|
||||
for (const [key, component] of Object.entries(ElementPlusIconsVue)) { |
||||
app.component(key, component) |
||||
} |
@ -0,0 +1,13 @@ |
||||
import { createRouter, createWebHashHistory,createWebHistory } from 'vue-router' |
||||
import { constRouter } from './module/constRouter' |
||||
const router = createRouter({ |
||||
history: createWebHashHistory(), |
||||
routes: [constRouter], |
||||
scrollBehavior() { |
||||
return { |
||||
left: 0, |
||||
top: 0, |
||||
} |
||||
}, |
||||
}) |
||||
export default router |
@ -0,0 +1,55 @@ |
||||
export const constRouter: any =
|
||||
{ |
||||
path: '/', |
||||
component: () => import('@/Layout/index.vue'), |
||||
name: 'Layout', |
||||
redirect: '/home', |
||||
meta: { |
||||
icon: '', |
||||
title: '', |
||||
hidden: false, |
||||
}, |
||||
children: [ |
||||
{ |
||||
path: '/home', |
||||
name: 'Home', |
||||
component: () => import('@/views/home/index.vue'), |
||||
meta: { |
||||
icon: '', |
||||
title: '首页', |
||||
hidden: false, |
||||
}, |
||||
}, |
||||
{ |
||||
path: '/appraise', |
||||
name: 'Appraise', |
||||
component: () => import('@/views/appraise/index.vue'), |
||||
meta: { |
||||
icon: '', |
||||
title: '竞赛评价', |
||||
hidden: false, |
||||
}, |
||||
}, |
||||
{ |
||||
path: '/navigation', |
||||
name: 'Navigation', |
||||
component: () => import('@/views/navigation/index.vue'), |
||||
meta: { |
||||
icon: '', |
||||
title: '竞赛导航', |
||||
hidden: false, |
||||
}, |
||||
}, |
||||
{ |
||||
path: '/achievement', |
||||
name: 'Achievement', |
||||
component: () => import('@/views/achievement/index.vue'), |
||||
meta: { |
||||
icon: '', |
||||
title: '竞赛成果', |
||||
hidden: false, |
||||
}, |
||||
}, |
||||
], |
||||
} |
||||
|
@ -0,0 +1,6 @@ |
||||
// 引入仓库
|
||||
import { createPinia } from 'pinia' |
||||
// 创建仓库
|
||||
const pinia = createPinia() |
||||
// 暴露仓库
|
||||
export default pinia |
@ -0,0 +1,44 @@ |
||||
// 引入清除浏览器默认样式文件 |
||||
@import './reset.scss'; |
||||
|
||||
.container-1420{ |
||||
width: 1420px; |
||||
margin: 0 auto; |
||||
// background-color: #c2acac; |
||||
} |
||||
.gradient{ |
||||
background: linear-gradient(90deg, rgba(66,217,172,1) 0%, rgba(0,208,208,1) 100%); |
||||
} |
||||
/* 设置滚动条的宽度和颜色 */ |
||||
::-webkit-scrollbar { |
||||
width: 10px; |
||||
/* 滚动条宽度 */ |
||||
} |
||||
|
||||
/* 设置滚动条的轨道背景色 */ |
||||
::-webkit-scrollbar-track { |
||||
background-color: #f1f1f1; |
||||
} |
||||
|
||||
/* 设置滚动条上下按钮的样式 */ |
||||
::-webkit-scrollbar-button { |
||||
background-color: #bfbfbf; |
||||
} |
||||
|
||||
/* 设置滚动条的滑块样式 */ |
||||
::-webkit-scrollbar-thumb { |
||||
background-color: #bfbfbf; |
||||
border-radius: 5px; |
||||
/* 滑块圆角 */ |
||||
} |
||||
|
||||
/* 设置滑块在hover状态下的样式 */ |
||||
::-webkit-scrollbar-thumb:hover { |
||||
background-color: #999999; |
||||
} |
||||
|
||||
.scene-tooltip { |
||||
color: #6da0ff !important; |
||||
font-weight: 700; |
||||
opacity: .5; |
||||
} |
@ -0,0 +1,188 @@ |
||||
/** |
||||
* ENGINE |
||||
* v0.2 | 20150615 |
||||
* License: none (public domain) |
||||
*/ |
||||
|
||||
*, |
||||
*:after, |
||||
*:before { |
||||
box-sizing: border-box; |
||||
|
||||
outline: none; |
||||
} |
||||
|
||||
html, |
||||
body, |
||||
div, |
||||
span, |
||||
applet, |
||||
object, |
||||
iframe, |
||||
h1, |
||||
h2, |
||||
h3, |
||||
h4, |
||||
h5, |
||||
h6, |
||||
p, |
||||
blockquote, |
||||
pre, |
||||
a, |
||||
abbr, |
||||
acronym, |
||||
address, |
||||
big, |
||||
cite, |
||||
code, |
||||
del, |
||||
dfn, |
||||
em, |
||||
img, |
||||
ins, |
||||
kbd, |
||||
q, |
||||
s, |
||||
samp, |
||||
small, |
||||
strike, |
||||
strong, |
||||
sub, |
||||
sup, |
||||
tt, |
||||
var, |
||||
b, |
||||
u, |
||||
i, |
||||
center, |
||||
dl, |
||||
dt, |
||||
dd, |
||||
ol, |
||||
ul, |
||||
li, |
||||
fieldset, |
||||
form, |
||||
label, |
||||
legend, |
||||
table, |
||||
caption, |
||||
tbody, |
||||
tfoot, |
||||
thead, |
||||
tr, |
||||
th, |
||||
td, |
||||
article, |
||||
aside, |
||||
canvas, |
||||
details, |
||||
embed, |
||||
figure, |
||||
figcaption, |
||||
footer, |
||||
header, |
||||
hgroup, |
||||
menu, |
||||
nav, |
||||
output, |
||||
ruby, |
||||
section, |
||||
summary, |
||||
time, |
||||
mark, |
||||
audio, |
||||
video { |
||||
font: inherit; |
||||
font-size: 100%; |
||||
|
||||
margin: 0; |
||||
padding: 0; |
||||
|
||||
vertical-align: baseline; |
||||
|
||||
border: 0; |
||||
} |
||||
|
||||
article, |
||||
aside, |
||||
details, |
||||
figcaption, |
||||
figure, |
||||
footer, |
||||
header, |
||||
hgroup, |
||||
menu, |
||||
nav, |
||||
section { |
||||
display: block; |
||||
} |
||||
|
||||
body { |
||||
line-height: 1; |
||||
} |
||||
|
||||
ol, |
||||
ul { |
||||
list-style: none; |
||||
} |
||||
|
||||
blockquote, |
||||
q { |
||||
quotes: none; |
||||
&:before, |
||||
&:after { |
||||
content: ''; |
||||
content: none; |
||||
} |
||||
} |
||||
|
||||
sub, |
||||
sup { |
||||
font-size: 75%; |
||||
line-height: 0; |
||||
|
||||
position: relative; |
||||
|
||||
vertical-align: baseline; |
||||
} |
||||
sup { |
||||
top: -.5em; |
||||
} |
||||
sub { |
||||
bottom: -.25em; |
||||
} |
||||
|
||||
table { |
||||
border-spacing: 0; |
||||
border-collapse: collapse; |
||||
} |
||||
|
||||
input, |
||||
textarea, |
||||
button { |
||||
font-family: inhert; |
||||
font-size: inherit; |
||||
|
||||
color: inherit; |
||||
} |
||||
|
||||
select { |
||||
text-indent: .01px; |
||||
text-overflow: ''; |
||||
|
||||
border: 0; |
||||
border-radius: 0; |
||||
|
||||
-webkit-appearance: none; |
||||
-moz-appearance: none; |
||||
} |
||||
select::-ms-expand { |
||||
display: none; |
||||
} |
||||
|
||||
code, |
||||
pre { |
||||
font-family: monospace, monospace; |
||||
font-size: 1em; |
||||
} |
@ -0,0 +1 @@ |
||||
$base-container-width:1620px; |
@ -0,0 +1,118 @@ |
||||
|
||||
;(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').match(/initial\-scale=([\d\.]+)/); |
||||
if (match) { |
||||
scale = parseFloat(match[1]); |
||||
dpr = parseInt(1 / scale); |
||||
} |
||||
} else if (flexibleEl) { |
||||
var content = flexibleEl.getAttribute('content'); |
||||
if (content) { |
||||
var initialDpr = content.match(/initial\-dpr=([\d\.]+)/); |
||||
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 > 1920) { |
||||
width = 1920 * dpr; |
||||
} |
||||
var rem = width / 10; |
||||
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(e) { |
||||
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'] = {})); |
@ -0,0 +1,20 @@ |
||||
// 引入第三方请求库axios
|
||||
import axios from 'axios' |
||||
// 创建axios实例
|
||||
const server = axios.create({ |
||||
baseURL: import.meta.env.VITE_APP_BASE_API, |
||||
timeout:30000, |
||||
}) |
||||
// 创建请求拦截器
|
||||
server.interceptors.request.use((config) => { |
||||
return config |
||||
|
||||
}) |
||||
// 创建相应拦截器
|
||||
server.interceptors.response.use((response) => { |
||||
return response.data |
||||
}) |
||||
|
||||
// 暴露axios实例
|
||||
|
||||
export default server |
@ -0,0 +1,12 @@ |
||||
<template> |
||||
<h1>404</h1> |
||||
</template> |
||||
|
||||
<script lang='ts' setup> |
||||
import { } from 'vue' |
||||
|
||||
</script> |
||||
|
||||
<style lang='scss' scoped> |
||||
|
||||
</style> |
@ -0,0 +1,14 @@ |
||||
<template> |
||||
<div> |
||||
成果 |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang='ts' setup> |
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue' |
||||
|
||||
</script> |
||||
|
||||
<style lang='scss' scoped> |
||||
|
||||
</style> |
@ -0,0 +1,14 @@ |
||||
<template> |
||||
<div> |
||||
评价 |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang='ts' setup> |
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue' |
||||
|
||||
</script> |
||||
|
||||
<style lang='scss' scoped> |
||||
|
||||
</style> |
@ -0,0 +1,188 @@ |
||||
<template> |
||||
<div class="container-1420"> |
||||
<div class="banner"> |
||||
<div class="title">2024年度全国电子科技大赛火热报名中</div> |
||||
<div class="description"> |
||||
我是一段比赛简介我是一段比赛简介我是一段比赛简介我是一段比赛简介我是一段比赛简介我是一段比赛简介我是一段比赛简介我是一段比赛简介我是一段比赛简介 |
||||
</div> |
||||
<div class="application gradient">立即报名</div> |
||||
<div class="nav-title"> |
||||
<div class="top">竞赛导航</div> |
||||
<div class="bottom">30+项目登陆后报名</div> |
||||
</div> |
||||
</div> |
||||
<!-- 比赛列表 --> |
||||
<div class="race-list"> |
||||
<div class="item" v-for="i in 8" :key="i"> |
||||
<div class="image"> |
||||
<img src="../../assets/images/item.png" alt="" /> |
||||
</div> |
||||
<div class="reac-info"> |
||||
<div class="reac-title">全国计算机等级大赛</div> |
||||
<div class="reac-project">全国计算机等级大赛项目</div> |
||||
<div class="time">报名时间:2022-01-01 18:00-2022-01-01:18:00</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
<!-- 新闻列表 --> |
||||
<div class="news-list"> |
||||
<div class="news-title"> |
||||
<div class="top">竞赛导航</div> |
||||
<div class="bottom">30+项目登陆后报名</div> |
||||
</div> |
||||
<div class="newa-panel"> |
||||
<div class="tab"> |
||||
<div :class="active === i ? 'item active gradient' : 'item'" v-for="i in 5" :key="i" @click="active = i">全部</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang="ts" setup> |
||||
import { ref } from 'vue' |
||||
const active = ref(1) |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.banner { |
||||
position: relative; |
||||
width: 100%; |
||||
height: 692px; |
||||
background: radial-gradient( |
||||
circle, |
||||
rgba(131, 255, 197, 1) 0%, |
||||
rgba(255, 255, 255, 1) 50% |
||||
); |
||||
display: flex; |
||||
flex-direction: column; |
||||
justify-content: center; |
||||
align-items: center; |
||||
.title { |
||||
font-size: 50px; |
||||
font-weight: 600; |
||||
color: #333333; |
||||
} |
||||
.description { |
||||
width: 1074px; |
||||
text-align: center; |
||||
font-size: 20px; |
||||
color: #666; |
||||
margin-top: 37px; |
||||
} |
||||
.application { |
||||
width: 272px; |
||||
height: 64px; |
||||
text-align: center; |
||||
line-height: 64px; |
||||
border-radius: 10px; |
||||
font-size: 24px; |
||||
color: #fff; |
||||
cursor: pointer; |
||||
margin-top: 50px; |
||||
} |
||||
.nav-title { |
||||
position: absolute; |
||||
bottom: 0; |
||||
color: #1e2033; |
||||
.top { |
||||
font-size: 40px; |
||||
font-weight: 600; |
||||
text-align: center; |
||||
} |
||||
.bottom { |
||||
font-size: 16px; |
||||
text-align: center; |
||||
margin-top: 10px; |
||||
} |
||||
} |
||||
} |
||||
.race-list { |
||||
width: 100%; |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
justify-content: space-between; |
||||
margin-top: 40px; |
||||
.item { |
||||
width: 340px; |
||||
height: 360px; |
||||
// background-color: pink; |
||||
.image { |
||||
width: 100%; |
||||
height: 194px; |
||||
img { |
||||
width: 100%; |
||||
height: 100%; |
||||
} |
||||
} |
||||
.reac-info { |
||||
.reac-title { |
||||
margin-top: 19px; |
||||
color: #c9c9c9; |
||||
font-size: 12px; |
||||
} |
||||
.reac-project { |
||||
font-size: 16px; |
||||
font-weight: 600; |
||||
color: #333333; |
||||
margin-top: 10px; |
||||
} |
||||
.time { |
||||
font-size: 14px; |
||||
color: #8c8b8b; |
||||
margin-top: 40px; |
||||
} |
||||
} |
||||
} |
||||
.item:nth-child(n) { |
||||
margin-top: 20px; |
||||
} |
||||
} |
||||
.news-list { |
||||
margin-top: 170px; |
||||
.news-title { |
||||
.top { |
||||
font-size: 40px; |
||||
font-weight: 600; |
||||
text-align: center; |
||||
} |
||||
.bottom { |
||||
font-size: 16px; |
||||
text-align: center; |
||||
margin-top: 10px; |
||||
} |
||||
} |
||||
.newa-panel { |
||||
width: 100%; |
||||
height: 630px; |
||||
background: rgba(255, 255, 255, 0.1); |
||||
backdrop-filter: blur(10px); |
||||
box-shadow: 2px 6px 14px rgba(0, 0, 0, 0.25); |
||||
margin-top: 25px; |
||||
padding: 46px 180px 70px 180px; |
||||
.tab { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
.item { |
||||
width: 152px; |
||||
height: 70px; |
||||
border-radius: 10px; |
||||
text-align: center; |
||||
line-height: 70px; |
||||
color: #1e2033; |
||||
font-size: 18px; |
||||
box-shadow: 7px 7px 22px -10px rgba(0, 0, 0, 0.22); |
||||
cursor: pointer; |
||||
transition: all 0.2s; |
||||
} |
||||
.item:hover{ |
||||
transform: scale(1.1); |
||||
} |
||||
.active { |
||||
color: #fff; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,14 @@ |
||||
<template> |
||||
<div> |
||||
导航 |
||||
</div> |
||||
</template> |
||||
|
||||
<script lang='ts' setup> |
||||
import { onMounted, reactive, ref, toRefs, watch } from 'vue' |
||||
|
||||
</script> |
||||
|
||||
<style lang='scss' scoped> |
||||
|
||||
</style> |
@ -0,0 +1,5 @@ |
||||
declare module '*.vue' { |
||||
import { DefineComponent } from "vue" |
||||
const component: ReturnType<typeof DefineComponent> |
||||
export default component |
||||
} |
@ -0,0 +1 @@ |
||||
/// <reference types="vite/client" />
|
@ -0,0 +1,31 @@ |
||||
{ |
||||
"compilerOptions": { |
||||
"target": "ES2020", |
||||
"useDefineForClassFields": true, |
||||
"module": "ESNext", |
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"], |
||||
"skipLibCheck": true, |
||||
|
||||
/* Bundler mode */ |
||||
"moduleResolution": "bundler", |
||||
"allowImportingTsExtensions": true, |
||||
"resolveJsonModule": true, |
||||
"isolatedModules": true, |
||||
"noEmit": true, |
||||
"jsx": "preserve", |
||||
|
||||
/* Linting */ |
||||
"strict": true, |
||||
"noUnusedLocals": true, |
||||
"noUnusedParameters": true, |
||||
"noFallthroughCasesInSwitch": true, |
||||
"baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录 |
||||
"paths": { |
||||
//路径映射,相对于baseUrl |
||||
"@/*": ["src/*"] |
||||
}, |
||||
"types": ["vite/client"] |
||||
}, |
||||
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "src/utils/rem.js"], |
||||
"references": [{ "path": "./tsconfig.node.json" }] |
||||
} |
@ -0,0 +1,11 @@ |
||||
{ |
||||
"compilerOptions": { |
||||
"composite": true, |
||||
"skipLibCheck": true, |
||||
"module": "ESNext", |
||||
"moduleResolution": "bundler", |
||||
"allowSyntheticDefaultImports": true, |
||||
"strict": true |
||||
}, |
||||
"include": ["vite.config.ts"] |
||||
} |
@ -0,0 +1,58 @@ |
||||
import { defineConfig } from 'vite' |
||||
import vue from '@vitejs/plugin-vue' |
||||
import path from 'path' |
||||
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons' |
||||
//@ts-ignore
|
||||
import postcssPluginPx2rem from "postcss-plugin-px2rem"; //引入插件
|
||||
|
||||
|
||||
//配置参数
|
||||
const px2remOptions = { |
||||
rootValue: 192, //换算基数, 默认100 ,也就是1440px ,这样的话把根标签的字体规定为1rem为50px,这样就可以从设计稿上量出多少个px直接在代码中写多少px了
|
||||
unitPrecision: 5, //允许REM单位增长到的十进制数字,其实就是精度控制
|
||||
// propWhiteList: [], // 默认值是一个空数组,这意味着禁用白名单并启用所有属性。
|
||||
// propBlackList: [], // 黑名单
|
||||
// exclude:false, //默认false,可以(reg)利用正则表达式排除某些文件夹的方法,例如/(node_module)/ 。如果想把前端UI框架内的px也转换成rem,请把此属性设为默认值
|
||||
// selectorBlackList: [], //要忽略并保留为px的选择器
|
||||
// ignoreIdentifier: false, //(boolean/string)忽略单个属性的方法,启用ignoreidentifier后,replace将自动设置为true。
|
||||
// replace: true, // (布尔值)替换包含REM的规则,而不是添加回退。
|
||||
mediaQuery: false, //(布尔值)允许在媒体查询中转换px
|
||||
minPixelValue: 0 , //设置要替换的最小像素值(3px会被转rem)。 默认 0
|
||||
} |
||||
export default defineConfig({ |
||||
plugins: [ |
||||
vue(), |
||||
// 配置svg插件
|
||||
createSvgIconsPlugin({ |
||||
// Specify the icon folder to be cached
|
||||
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], |
||||
// Specify symbolId format
|
||||
symbolId: 'icon-[dir]-[name]', |
||||
}), |
||||
], |
||||
server:{ |
||||
host: '0.0.0.0', |
||||
port: 8866, |
||||
}, |
||||
resolve: { |
||||
alias: { |
||||
'@': path.resolve('./src'), // 相对路径别名配置,使用 @ 代替 src
|
||||
// 'vue': 'vue/dist/vue.esm-bundler.js',
|
||||
}, |
||||
}, |
||||
css: { |
||||
preprocessorOptions: { |
||||
scss: { |
||||
javascriptEnabled: true, |
||||
additionalData: '@import "./src/styles/variable.scss";', |
||||
}, |
||||
}, |
||||
postcss: { |
||||
plugins: [ |
||||
// 配置响应式插件
|
||||
postcssPluginPx2rem(px2remOptions) |
||||
|
||||
], |
||||
}, |
||||
}, |
||||
}) |