feat: vite-plugin-svg-icons引入
1. vite-plugin-svg-icons引入 2. vite.config.ts读取环境变量 3. vite配置跨域
10
README.md
@@ -479,4 +479,14 @@ export default defineComponent({
|
||||
```
|
||||
|
||||
|
||||
## SVG图标
|
||||
|
||||
vite-plugin-svg-icons 使用说明:https://github.com/anncwb/vite-plugin-svg-icons/blob/main/README.zh_CN.md
|
||||
|
||||
安装:
|
||||
|
||||
```
|
||||
npm i vite-plugin-svg-icons -D
|
||||
```
|
||||
|
||||
## 跨域处理
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
"dependencies": {
|
||||
"axios": "^0.24.0",
|
||||
"element-plus": "^1.2.0-beta.3",
|
||||
"fs": "0.0.1-security",
|
||||
"path-to-regexp": "^6.2.0",
|
||||
"screenfull": "^6.0.0",
|
||||
"vue": "^3.2.16",
|
||||
@@ -21,9 +20,9 @@
|
||||
"@types/nprogress": "^0.2.0",
|
||||
"@vitejs/plugin-vue": "^1.9.3",
|
||||
"sass": "^1.43.4",
|
||||
"svg-sprite-loader": "^6.0.11",
|
||||
"typescript": "^4.4.3",
|
||||
"vite": "^2.6.4",
|
||||
"vite-plugin-svg-icons": "^1.0.5",
|
||||
"vue-tsc": "^0.3.0"
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 954 B After Width: | Height: | Size: 954 B |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 179 B After Width: | Height: | Size: 179 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 971 B After Width: | Height: | Size: 971 B |
|
Before Width: | Height: | Size: 732 B After Width: | Height: | Size: 732 B |
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB After Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 418 B After Width: | Height: | Size: 418 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 356 B After Width: | Height: | Size: 356 B |
|
Before Width: | Height: | Size: 724 B After Width: | Height: | Size: 724 B |
|
Before Width: | Height: | Size: 818 B After Width: | Height: | Size: 818 B |
|
Before Width: | Height: | Size: 627 B After Width: | Height: | Size: 627 B |
|
Before Width: | Height: | Size: 347 B After Width: | Height: | Size: 347 B |
|
Before Width: | Height: | Size: 497 B After Width: | Height: | Size: 497 B |
|
Before Width: | Height: | Size: 459 B After Width: | Height: | Size: 459 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 944 B After Width: | Height: | Size: 944 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 421 B After Width: | Height: | Size: 421 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 320 B After Width: | Height: | Size: 320 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 744 B After Width: | Height: | Size: 744 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 983 B After Width: | Height: | Size: 983 B |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 285 B After Width: | Height: | Size: 285 B |
|
Before Width: | Height: | Size: 1017 B After Width: | Height: | Size: 1017 B |
|
Before Width: | Height: | Size: 444 B After Width: | Height: | Size: 444 B |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 669 B After Width: | Height: | Size: 669 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 883 B After Width: | Height: | Size: 883 B |
|
Before Width: | Height: | Size: 821 B After Width: | Height: | Size: 821 B |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 664 B After Width: | Height: | Size: 664 B |
|
Before Width: | Height: | Size: 873 B After Width: | Height: | Size: 873 B |
|
Before Width: | Height: | Size: 600 B After Width: | Height: | Size: 600 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 757 B After Width: | Height: | Size: 757 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 211 B After Width: | Height: | Size: 211 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 564 B After Width: | Height: | Size: 564 B |
|
Before Width: | Height: | Size: 563 B After Width: | Height: | Size: 563 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 679 B After Width: | Height: | Size: 679 B |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 655 B After Width: | Height: | Size: 655 B |
|
Before Width: | Height: | Size: 597 B After Width: | Height: | Size: 597 B |
|
Before Width: | Height: | Size: 787 B After Width: | Height: | Size: 787 B |
|
Before Width: | Height: | Size: 689 B After Width: | Height: | Size: 689 B |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 805 B After Width: | Height: | Size: 805 B |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 906 B After Width: | Height: | Size: 906 B |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 440 B After Width: | Height: | Size: 440 B |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
40
src/components/SvgIcon/index.vue
Normal file
@@ -0,0 +1,40 @@
|
||||
<template>
|
||||
<svg aria-hidden="true" class="svg-icon">
|
||||
<use :xlink:href="symbolId" :fill="color" />
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { defineComponent, computed } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'SvgIcon',
|
||||
props: {
|
||||
prefix: {
|
||||
type: String,
|
||||
default: 'icon',
|
||||
},
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: '#FFF',
|
||||
},
|
||||
},
|
||||
setup(props) {
|
||||
const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`);
|
||||
return { symbolId };
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
overflow: hidden;
|
||||
}
|
||||
</style>
|
||||
@@ -1,50 +0,0 @@
|
||||
import { readFileSync, readdirSync } from 'fs'
|
||||
|
||||
let idPrefix = ''
|
||||
const svgTitle = /<svg([^>+].*?)>/
|
||||
const clearHeightWidth = /(width|height)="([^>+].*?)"/g
|
||||
const hasViewBox = /(viewBox="[^>+].*?")/g
|
||||
const clearReturn = /(\r)|(\n)/g
|
||||
|
||||
// 查找svg文件
|
||||
function svgFind(e) {
|
||||
const arr = []
|
||||
const dirents = readdirSync(e, { withFileTypes: true })
|
||||
for (const dirent of dirents) {
|
||||
if (dirent.isDirectory()) arr.push(...svgFind(e + dirent.name + '/'))
|
||||
else {
|
||||
const svg = readFileSync(e + dirent.name)
|
||||
.toString()
|
||||
.replace(clearReturn, '')
|
||||
.replace(svgTitle, ($1, $2) => {
|
||||
let width = 0,
|
||||
height = 0,
|
||||
content = $2.replace(clearHeightWidth, (s1 : string, s2:string, s3:number) => {
|
||||
if (s2 === 'width') width = s3
|
||||
else if (s2 === 'height') height = s3
|
||||
return ''
|
||||
})
|
||||
if (!hasViewBox.test($2)) content += `viewBox="0 0 ${width} ${height}"`
|
||||
return `<symbol id="${idPrefix}-${dirent.name.replace('.svg', '')}" ${content}>`
|
||||
}).replace('</svg>', '</symbol>')
|
||||
arr.push(svg)
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
// 生成svg
|
||||
export const createSvg = (path: any, prefix = 'icon') => {
|
||||
if (path === '') return
|
||||
idPrefix = prefix
|
||||
const res = svgFind(path)
|
||||
return {
|
||||
name: 'svg-transform',
|
||||
transformIndexHtml(dom: String) {
|
||||
return dom.replace(
|
||||
'<body>',
|
||||
`<body><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="position: absolute; width: 0; height: 0">${res.join('')}</svg>`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
<template>
|
||||
<svg :class="svgClass" v-bind="$attrs" :style="{ color: color }">
|
||||
<use :xlink:href="iconName"></use>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {computed, defineProps} from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
iconClass: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
className: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
})
|
||||
|
||||
const iconName = computed(() => `#icon-${props.iconClass}`)
|
||||
const svgClass = computed(() => {
|
||||
if (props.className) return `svg-icon icon-${props.className}`
|
||||
return 'svg-icon'
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.svg-icon {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
vertical-align: -0.15em;
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
</style>
|
||||
@@ -8,11 +8,10 @@ import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
|
||||
|
||||
import SvgIcon from './icons/index.vue'
|
||||
import 'virtual:svg-icons-register';
|
||||
|
||||
const app=createApp(App)
|
||||
app
|
||||
.component('svg-icon', SvgIcon)
|
||||
.use(router)
|
||||
.use(store,key)
|
||||
.use(ElementPlus)
|
||||
|
||||
@@ -52,9 +52,13 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SvgIcon from '@/components/SvgIcon/index.vue';
|
||||
|
||||
export default {
|
||||
name: 'Login',
|
||||
components:{
|
||||
SvgIcon
|
||||
},
|
||||
data() {
|
||||
const validatePassword = (rule, value, callback) => {
|
||||
if (value.length < 6) {
|
||||
|
||||
128
vite.config.ts
@@ -1,59 +1,85 @@
|
||||
import {defineConfig} from 'vite'
|
||||
import {defineConfig, ConfigEnv, loadEnv} from 'vite'
|
||||
import vue from '@vitejs/plugin-vue'
|
||||
import { createSvg } from './src/icons/index'
|
||||
import viteSvgIcons from 'vite-plugin-svg-icons';
|
||||
// 在 ts 模块中加载 node 核心模块需要安装 node 的类型补充模块: npm i -D @types/node
|
||||
import path from 'path'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
createSvg('./src/icons/svg/')
|
||||
export default ({mode}: ConfigEnv) => {
|
||||
|
||||
const env = loadEnv(mode, process.cwd())
|
||||
|
||||
return defineConfig({
|
||||
plugins: [
|
||||
vue(),
|
||||
viteSvgIcons({
|
||||
// 指定需要缓存的图标文件夹
|
||||
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')],
|
||||
// 指定symbolId格式
|
||||
symbolId: 'icon-[dir]-[name]',
|
||||
})
|
||||
|
||||
],
|
||||
// 本地反向代理解决跨域
|
||||
server: {
|
||||
host: '0.0.0.0',
|
||||
port: Number(env.VITE_APP_PORT),
|
||||
open: true, // 运行自动打开浏览器
|
||||
proxy: {
|
||||
[env.VITE_APP_BASE_API]: {
|
||||
target: 'http://localhost:9999',
|
||||
changeOrigin: true,
|
||||
rewrite: path => path.replace(/^\/api/, '') //TODO
|
||||
}
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
// Vite2设置别名路径方式一
|
||||
// alias:{
|
||||
// "/@":path.resolve("./src"), // 相对路径别名配置,@表示src
|
||||
// },
|
||||
// Vite2设置别名路径方式二
|
||||
alias: [
|
||||
{
|
||||
find: "@",
|
||||
replacement: path.resolve("./src")
|
||||
},
|
||||
{
|
||||
find: "@image",
|
||||
replacement: path.resolve("./src/assets/images")
|
||||
},
|
||||
{
|
||||
find: "@router",
|
||||
replacement: path.resolve("./src/router")
|
||||
},
|
||||
{
|
||||
find: "@store",
|
||||
replacement: path.resolve("./src/store")
|
||||
},
|
||||
{
|
||||
find: "@api",
|
||||
replacement: path.resolve("./src/api")
|
||||
},
|
||||
{
|
||||
find: "@utils",
|
||||
replacement: path.resolve("./src/utils")
|
||||
},
|
||||
{
|
||||
find: "@views",
|
||||
replacement: path.resolve("./src/views")
|
||||
},
|
||||
{
|
||||
find: "@styles",
|
||||
replacement: path.resolve("./src/styles")
|
||||
},
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
],
|
||||
resolve: {
|
||||
// Vite2设置别名路径方式一
|
||||
/**
|
||||
alias:{
|
||||
|
||||
"/@":path.resolve("./src"),
|
||||
},
|
||||
**/
|
||||
|
||||
// Vite2设置别名路径方式二
|
||||
alias: [
|
||||
{
|
||||
find: "@",
|
||||
replacement: path.resolve("./src")
|
||||
},
|
||||
{
|
||||
find: "@image",
|
||||
replacement: path.resolve("./src/assets/images")
|
||||
},
|
||||
{
|
||||
find: "@router",
|
||||
replacement: path.resolve("./src/router")
|
||||
},
|
||||
{
|
||||
find: "@store",
|
||||
replacement: path.resolve("./src/store")
|
||||
},
|
||||
{
|
||||
find: "@api",
|
||||
replacement: path.resolve("./src/api")
|
||||
},
|
||||
{
|
||||
find:"@utils",
|
||||
replacement: path.resolve("./src/utils")
|
||||
},
|
||||
{
|
||||
find:"@views",
|
||||
replacement: path.resolve("./src/views")
|
||||
},
|
||||
{
|
||||
find:"@styles",
|
||||
replacement: path.resolve("./src/styles")
|
||||
},
|
||||
]
|
||||
}
|
||||
})
|
||||
|
||||