创建项目
npm create vite
npx eslint –init
安装eslint插件在插件市场
可以在eslint.config.ts中进行相关的配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 import js from "@eslint/js"; import globals from "globals"; import tseslint from "typescript-eslint"; import pluginVue from "eslint-plugin-vue"; import { defineConfig } from "eslint/config"; export default defineConfig([ { files: ["**/*.{js,mjs,cjs,ts,mts,cts,vue}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: { ...globals.browser, ...globals.node } } }, ...tseslint.configs.recommended, // 确保使用展开语法 ...pluginVue.configs["flat/essential"], // 确保使用展开语法 { files: ["**/*.vue"], languageOptions: { parserOptions: { parser: tseslint.parser } } }, { ignores: ['**/*.css', '**/*.d.ts'] // 修正为 glob 模式 }, { //自定义规则 rules: { //日志打印视为警告 "no-console": "warn", //强制使用分号可以去掉 //"semi": ['error'] } } ]);
还可以在package.json中的配置lint执行和修复的脚本在控制台可以看到相关的日志
1 2 3 4 5 6 7 "scripts": { "lint": "eslint", "lint:fix": "eslint --fix --quiet", "dev": "vite", "build": "vue-tsc -b && vite build", "preview": "vite preview" },
安装prettier插件格式化代码 防止一些设置和eslint配置冲突使用eslint-config-pretter 合并冲突以pretter 为主
1 npm install prettier eslint-plugin-prettier eslint-config-prettier -D
然后配置prettier.config文件进行配置;配置好后要在eslint.config.js中配置 import prettierRecommanded from “eslint-plugin-prettier/recommended”; 然后再export default defineConfig加上prettierRecommanded
1 2 3 4 5 6 7 8 9 export default{ singleQuote: false,//使用单引号 semi:false,//不使用分号 tabWidth:2,//缩进2个空格 trailingComma: "none", // 不使用尾逗号 useTabs: false, // 不使用tab缩进,使用空格缩进 endOfLine: "auto" // 使用换行符lf }
然后再安装prettier -code for.. 插件 并添加到工作区建议 并设置:保存时自动格式化 点击设置搜索Editor: Default Formatter设置为prettier,并勾选Editor: Format On Save设置
安装EditorConfig for vs…p并配置: 编译器换行,缩进统一
1 2 3 4 5 6 root =true [*] charset = utf-8 indent_style = space indent_size = 2 end_of_line = lf // windows 下使用crlf
11.要在git提交的时候检测校验代码是否规范,添加一个git钩子 npm install husky,每次提交执行一些脚本去检测,如果校验的时候只想校验一部分的内容可以使用一个插件 lint-staged.即安装 npm install husky lint-staged -D。然后在package.json中补充
1 2 3 4 5 6 7 8 9 10 "lint-staged":{ "src/**/*.{js,cjs,ts,vue}":[ "npx eslint --fix" 等同于//" npm run lint:fix" ], //这里的意思是不需要检测了上面的才是检测这里只对代码格式化重写让代码符合规范 "src/**/*.{html,json,css,scss}":[ "npx prettier --write" ] }
随后执行 npx husky init 先初始化,在生成的pre-commit文件中写入npx lint-staged这样在每次提交前都会检查一遍代码。然后再git commit 的时候会先修复语法,再检查格式(lint-staged )里面配置的内容
git提交工具 安装npm install @commitlint/cli @commitlint/config-conventional -D 然后新建一个commitlint.config.cjs文件配置:规范代码提交形式
1 2 3 module.exports = { extends: ["@commitlint/config-conventional"] }
配置路径映射: a.打开vite.config.ts配置resolve
1 2 3 4 5 6 7 8 9 // https://vite.dev/config/ export default defineConfig({ resolve: { alias: { "@": "/src" } }, plugins: [vue()] })
b. 然后的话该路径还需要配置tsconfig.app.json 让ts也识别这个路径在compilerOptions配置:
1 2 3 4 "baseUrl": ".",//当前项目下查找 "paths":{ "@/*": ["src/*"] // @.== src/ }
然后安装组件库 npm intall element-plus a. 在main.ts中注册import ElementPlus from “element-plus”和import “element-plus/dist/index.css”
b.app.use(ElementPlus)
c.配置ts让el的类型可以被ts识别,在tsconfig.app.json中的compilerOptions内配置”types”: [“element-plus/global”]即可。
15.配置sass和unocss a. npm install unocss @unocss/preset-uno @unocss/preset-attributify -D b. 在vite.config.js中配置
1 2 3 4 5 6 7 8 9 // vite.config.js import UnoCSS from 'unocss/vite' import { defineConfig } from 'vite' export default defineConfig({ UnoCSS({ configFile: './uno.config.ts' }), })
c.创建一个uno.config.ts文件
1 2 3 4 5 6 7 8 import { defineConfig } from "unocss" import presetAttributify from "@unocss/preset-attributify" import presetUno from "@unocss/preset-uno" export default defineConfig({ presets: [presetUno(), presetAttributify()] })
d.然后再main.ts中引入import ‘uno.css’;
安装UnoCSS 的指令转换器,用于 @apply、@screen 和 theme() 指令:@unocss/transformer-directives。
1 npm install -D @unocss/transformer-directives
安装好后需要再uno.config.ts中配置:
1 2 3 4 5 6 7 import transformerDirectives from '@unocss/transformer-directives' export default defineConfig({ // ... transformers: [ transformerDirectives(), ], })
17.可以使用npm install normalize.css 清除浏览器默认样式白边间距什么的,然后再main.ts中引入import “normalize.css/normalize.css”
18.element-plus按需导入 npm install -D unplugin-vue-components unplugin-auto-import 然后再vite.config.js中配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { defineConfig } from 'vite' import AutoImport from 'unplugin-auto-import/vite' import Components from 'unplugin-vue-components/vite' import { ElementPlusResolver } from 'unplugin-vue-components/resolvers' export default defineConfig({ // ... plugins: [ // ... AutoImport({ resolvers: [ElementPlusResolver()], }), Components({ resolvers: [ElementPlusResolver()], }), ], })
19.也可以实现自定义的组件或者引入的api的动态加载需要再vite.config.js中的export default defineConfig({下面的Components配置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 export default defineConfig({ plugins: [ UnoCSS(), vue(), AutoImport({ //api的自动导入在这里配置 imports: ["vue", "vue-router", "pinia"], resolvers: [ElementPlusResolver()] }), Components({ resolvers: [ElementPlusResolver()], //所有的组件可以自动加载 要配置这里。 dirs: ["src/components", "src/layout/components"] }) ], resolve: { alias: { "@": "/src" } } })
但是同时eslint也会检测所以要配置eslintrc:{enable:true} //只需要一次所以要在vite.config.ts中的export default defineConfig({的AutoImport下配置:
1 2 3 eslintrc: { enabled: true }
设置了这个后ctrl+s 保存看下目录是否生成了.eslintrc-auto-import.json文件,如果没有的话npm run dev (serve)一下. 生成后了然后需要再eslint.config.ts中配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import { createRequire } from "module" const require = createRequire(import.meta.url) const autoImport = require("./.eslintrc-auto-import.json") export default defineConfig([ { files: ["**/*.{js,mjs,cjs,ts,mts,cts,vue}"], plugins: { js }, extends: ["js/recommended"], languageOptions: { globals: { ...globals.browser, ...globals.node, ...autoImport.globals//要加上这个 } } },
光eslint识别还不够,需要ts也要识别需要再tsconfig.app.json(前端)中配置:
1 "types": ["element-plus/global","./auto-imports.d.ts", "./components.d.ts"] //需要加上这两个的ts文件
然后的话需要安装npm install unplugin-element-plus 这个专门会导入页面组件用到的样式(按需导入),不会导致打包体积过大。???(直接使用 npm install -D unplugin-vue-components unplugin-auto-import这个即可听得我晕乎乎的)
采用unocss配置图表,同时使用iconify作为图标数据源
1 2 npm install -D @unocss/preset-icons @iconify-json/[你想要的集合] npm install -D @unocss/preset-icons @iconify-json/ant-design
然后再icoes中添加 npm add -D @iconify-json/ant-design //unocss图标预设加载我们安装的图标库 ant-design. 然后在页面中引入
记住要加(i-) 在引入的图标名字的前面。这样使用就可以实现按需加载:只打包实际使用的图标。随着而来的问题是
1 2 3 4 5 6 7 <div i-ant-design:alipay-circle-filled inline-block w-10em h-10em align-middle ></div> //这样会显示样式设可读性差
所以可以给这些复杂的类名取个别名:在uno.config.ts下的
1 2 3 4 5 6 export default defineConfig({ presets: [presetUno(), presetAttributify(), presetIcons()], //apply transformers: [transformerDirectives()], shortcuts:[{"icon",inclne-block w-1em h-1em align-miaddle text-current}] //表明使用icon这个别名默认使用后面标明的样式效果 })
为了让引入的图标比如放大没有锯齿,显示的时候为svg,然后可以自然的切换多个库的图标组件库。此时要下载一个第三方库会根据图标名字自动的寻找对应图标所在的库并加载svg图片。
1 npm install @iconify/vue
这个组件库会动态加载并缓存
然后定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 第一步:项目结构准备 1. 创建组件目录 src/ ├── components/ │ └── SvgIcon/ │ └── index.vue // 我们要创建的图标组件 ├── utils/ │ └── validate.ts // 工具函数 └── views/ └── Home/ └── index.vue // 使用图标的页面 2. 安装依赖 npm install @iconify/vue //已安装 第二步:创建工具函数 创建文件:src/utils/validate.ts // 这个函数用来判断是否是外部URL export const isExternal = (path: string): boolean => { return /^https?:\/\//.test(path) } 作用:区分是外部链接还是图标名称 第三步:创建图标组件 创建文件:src/components/SvgIcon/index.vue <template> <!-- 情况1: Iconify图标库的图标 (格式: prefix:icon-name) --> <IconifyIcon :class="svgClass" :icon="iconName" v-if="isIconifyIcon" v-bind="$attrs" /> <!-- 情况2: 外部URL的SVG文件 --> <div v-else-if="isExternal(iconName)" :style="maskStyle" :class="svgClass" v-bind="$attrs" /> <!-- 情况3: 本地SVG文件 --> <div v-else :class="svgClass" v-html="localSvgContent" v-bind="$attrs" /> </template> <script setup lang="ts"> import { ref, computed, watchEffect } from 'vue' import { Icon as IconifyIcon } from '@iconify/vue' import { isExternal } from '@/utils/validate' // 1.定义组件接收的属性 const { iconName, customClass, size } = defineProps<{ iconName: string // 图标名称或URL customClass?: string // 自定义CSS类 size?: string | number // 图标尺寸 }>() //2.这种写法也可以 const { iconName, customClass } = defineProps({ iconName: { type: String, default: "" }, customClass: { type: String, default: "" } }) // 判断是否是Iconify格式的图标名 (包含冒号,如 "mdi:home") const isIconifyIcon = computed(() => { return iconName.includes(':') && !isExternal(iconName) }) // 组合CSS类名 const svgClass = computed(() => { let classes = customClass || 'icon' // 添加尺寸类 if (size) { const sizeValue = typeof size === 'number' ? `${size}px` : size classes += ` w-[${sizeValue}] h-[${sizeValue}]` } return classes }) // CSS mask样式 (用于外部URL的SVG) const maskStyle = computed(() => ({ mask: `url(${iconName}) no-repeat 50% 50%`, '-webkit-mask': `url(${iconName}) no-repeat 50% 50%`, 'mask-size': 'cover', backgroundColor: 'currentColor' })) // 本地SVG内容 const localSvgContent = ref('') // 加载本地SVG文件 const loadLocalSvg = async (path: string) => { try { const response = await fetch(path) if (response.ok) { localSvgContent.value = await response.text() } } catch (error) { console.error('加载SVG失败:', error) } } // 监听iconName变化,加载本地SVG watchEffect(() => { if (!isIconifyIcon.value && !isExternal(iconName)) { loadLocalSvg(iconName) } }) </script> <style scoped> .icon { display: inline-block; width: 1em; height: 1em; } </style> 组件功能解释: 1. 自动识别图标类型:根据名称格式判断使用哪种加载方式 2. 三种加载模式:Iconify图标库、外部URL、本地文件 3. 属性透传:通过 v-bind="$attrs" 让父组件的事件和属性能正常传递 4. 尺寸控制:支持设置图标大小 5. 样式定制:支持自定义CSS类 第四步:配置自动导入 修改文件:vite.config.ts import { defineConfig } from 'vite' import vue from '@vitejs/plugin-vue' import Components from 'unplugin-vue-components/vite' export default defineConfig({ plugins: [ vue(), Components({ // 自动导入组件的目录 dirs: ['src/components'],//按照教程走应该已经配置了 // 生成类型声明文件 dts: true }) ], resolve: { alias: { '@': '/src' } } }) 作用:让 SvgIcon 组件在所有页面中无需手动导入就能使用 第五步:在页面中使用 创建文件:src/views/Home/index.vue <template> <div class="home-page"> <h1>图标展示页面</h1> <!-- 使用Iconify图标库的图标 --> <svg-icon icon-name="mdi:home" custom-class="text-blue-500" size="24" @click="handleClick" /> <!-- 使用外部URL的SVG --> <svg-icon icon-name="https://raw.githubusercontent.com/Lazi66/image/master/ikun.svg" custom-class="text-red-500" size="32" @click="handleClick" /> <!-- 使用本地SVG文件 --> <svg-icon icon-name="/src/assets/logo.svg" custom-class="text-green-500" size="40" /> </div> </template> <script setup lang="ts"> const handleClick = () => { console.log('图标被点击了!') } </script> 第六步:类型声明文件 自动生成的文件:components.d.ts // 这个文件会自动生成,提供TypeScript类型支持 declare module 'vue' { export interface GlobalComponents { SvgIcon: typeof import('./src/components/SvgIcon/index.vue')['default'] } }