主页 > 互联网  > 

admin端


一、创建项目 1.1 技术栈

1.2  vite 项目初始化 npm init vite@latest vue3-element-admin --template vue-ts  1.3 src 路径别名配置

Vite 配置

配置 vite.config.ts 

// https://vitejs.dev/config/ import { UserConfig, ConfigEnv, loadEnv, defineConfig } from 'vite' import path from 'path' import vue from '@vitejs/plugin-vue' const pathSrc = path.resolve(__dirname, 'src') export default defineConfig(({ mode }: ConfigEnv): UserConfig => { return { // 路径别名 resolve: { alias: { '@': pathSrc } }, plugins: [vue()] } })

 安装@types/node

import path from 'path'编译器报错:TS2307: Cannot find module 'path' or its corresponding type declarations.

本地安装 Node 的 TypeScript 类型描述文件即可解决编译器报错

npm install @types/node --save-dev

TypeScript 编译配置

同样还是import path from 'path' 编译报错: TS1259: Module '"path"' can only be default-imported using the 'allowSyntheticDefaultImports' flag

因为 typescript 特殊的 import 方式 , 需要配置允许默认导入的方式,还有路径别名的配置

// tsconfig.json { "compilerOptions": { "baseUrl": "./", // 解析非相对模块的基地址,默认是当前目录 "paths": { //路径映射,相对于baseUrl "@/*": ["src/*"] }, "allowSyntheticDefaultImports": true // 允许默认导入 } } 1.4 unplugin 自动导入

Element Plus 官方文档中推荐 按需自动导入 的方式,而此需要使用额外的插件 unplugin-auto-import 和 unplugin-vue-components 来导入要使用的组件。所以在整合 Element Plus 之前先了解下自动导入的概念和作用

概念

为了避免在多个页面重复引入 API 或 组件,由此而产生的自动导入插件来节省重复代码和提高开发效率。

安装插件依赖

npm install -D unplugin-auto-import unplugin-vue-components

vite.config.ts - 自动导入配置

先创建好 /src/types 目录用于存放自动导入函数和组件的TS类型声明文件,再进行自动导入配置

// vite.config.ts import AutoImport from "unplugin-auto-import/vite"; import Components from "unplugin-vue-components/vite"; import path from "path"; const pathSrc = path.resolve(__dirname, "src"); plugins: [ AutoImport({ // 自动导入 Vue 相关函数,如:ref, reactive, toRef 等 imports: ["vue"], eslintrc: { enabled: true, // 是否自动生成 eslint 规则,建议生成之后设置 false filepath: "./.eslintrc-auto-import.json", // 指定自动导入函数 eslint 规则的文件 }, dts: path.resolve(pathSrc, "types", "auto-imports.d.ts"), // 指定自动导入函数TS类型声明文件路径 }), Components({ dts: path.resolve(pathSrc, "types", "components.d.ts"), // 指定自动导入组件TS类型声明文件路径 }), ]

 .eslintrc.cjs - 自动导入函数 eslint 规则引入

"extends": [ "./.eslintrc-auto-import.json" ],

tsconfig.json - 自动导入TS类型声明文件引入

{ "include": ["src/**/*.d.ts"] }

 自动导入效果

 1.5 整合 Element Plus

安装 Element Plus

npm install element-plus

安装自动导入 Icon 依赖

npm i -D unplugin-icons

vite.config.ts 配置

// vite.config.ts import vue from "@vitejs/plugin-vue"; import { UserConfig, ConfigEnv, loadEnv, defineConfig } from "vite"; import { ElementPlusResolver } from "unplugin-vue-components/resolvers"; import Icons from "unplugin-icons/vite"; import IconsResolver from "unplugin-icons/resolver"; export default ({ mode }: ConfigEnv): UserConfig => { return { plugins: [ // ... AutoImport({ // ... resolvers: [ // 自动导入 Element Plus 相关函数,如:ElMessage, ElMessageBox... (带样式) ElementPlusResolver(), // 自动导入图标组件 IconsResolver({}), ] vueTemplate: true, // 是否在 vue 模板中自动导入 dts: path.resolve(pathSrc, 'types', 'auto-imports.d.ts') // 自动导入组件类型声明文件位置,默认根目录 }), Components({ resolvers: [ // 自动导入 Element Plus 组件 ElementPlusResolver(), // 自动注册图标组件 IconsResolver({ enabledCollections: ["ep"] // element-plus图标库,其他图标库 https://icon-sets.iconify.design/ }), ], dts: path.resolve(pathSrc, "types", "components.d.ts"), // 自动导入组件类型声明文件位置,默认根目录 }), Icons({ // 自动安装图标库 autoInstall: true, }), ], }; };

示例代码

<!-- src/components/HelloWorld.vue --> <div> <el-button type="success"><i-ep-SuccessFilled />Success</el-button> <el-button type="info"><i-ep-InfoFilled />Info</el-button> <el-button type="warning"><i-ep-WarningFilled />Warning</el-button> <el-button type="danger"><i-ep-WarnTriangleFilled />Danger</el-button> </div> 1.6 整合 SVG 图标

安装依赖

npm install -D fast-glob@3.2.11 vite-plugin-svg-icons@2.0.1

创建 src/assets/icons 目录 , 放入从 Iconfont 复制的 svg 图标

main.ts 引入注册脚本

// src/main.ts import 'virtual:svg-icons-register';

 vite.config.ts 配置插件

// vite.config.ts import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'; export default ({command, mode}: ConfigEnv): UserConfig => { return ( { plugins: [ createSvgIconsPlugin({ // 指定需要缓存的图标文件夹 iconDirs: [path.resolve(process.cwd(), 'src/assets/icons')], // 指定symbolId格式 symbolId: 'icon-[dir]-[name]', }) ] } ) }

SVG 组件封装

<!-- src/components/SvgIcon/index.vue --> <script setup lang="ts"> const props = defineProps({ prefix: { type: String, default: "icon", }, iconClass: { type: String, required: false, }, color: { type: String, }, size: { type: String, default: "1em", }, }); const symbolId = computed(() => `#${props.prefix}-${props.iconClass}`); </script> <template> <svg aria-hidden="true" class="svg-icon" :style="'width:' + size + ';height:' + size" > <use :xlink:href="symbolId" :fill="color" /> </svg> </template> <style scoped> .svg-icon { display: inline-block; outline: none; width: 1em; height: 1em; vertical-align: -0.15em; /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */ fill: currentColor; /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */ overflow: hidden; } </style>

组件使用

<!-- src/components/HelloWorld.vue --> <template> <el-button type="info"><svg-icon icon-class="block"/>SVG 本地图标</el-button> </template> 1.7 整合 SCSS

一款CSS预处理语言,SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。

安装依赖

npm i -D sass

创建 variables.scss 变量文件,添加变量 $bg-color 定义,注意规范变量以 $ 开头

// src/styles/variables.scss $bg-color:#242424;

Vite 配置导入 SCSS 全局变量文件

// vite.config.ts // 路径别名 resolve: { alias: { '@': pathSrc } }, css: { // CSS 预处理器 preprocessorOptions: { //define global scss variable scss: { javascriptEnabled: true, additionalData: `@use "@/styles/variables.scss" as *;` } } }

style 标签使用SCSS全局变量

<!-- src/components/HelloWorld.vue --> <template> <div class="box" /> </template> <style lang="scss" scoped> .box { width: 100px; height: 100px; background-color: $bg-color; } </style>

上面导入的 SCSS 全局变量在 TypeScript 不生效的,需要创建一个以 .module.scss 结尾的文件

// src/styles/variables.module.scss // 导出 variables.scss 文件的变量 :export{ bgColor:$bg-color }

TypeScript 使用 SCSS 全局变量

<!-- src/components/HelloWorld.vue --> <script setup lang="ts"> import variables from "@/styles/variables.module.scss"; console.log(variables.bgColor) </script> <template> <div style="width:100px;height:100px" :style="{ 'background-color': variables.bgColor }" /> </template> 1.8 整合 UnoCSS

UnoCSS 是一个具有高性能且极具灵活性的即时原子化 CSS 引擎 。

安装依赖

npm install -D unocss

vite.config.ts 配置 

// vite.config.ts import UnoCSS from 'unocss/vite' export default { plugins: [ UnoCSS({ /* options */ }), ], }

main.ts 引入 uno.css

// src/main.ts import 'uno.css'

VSCode 安装 UnoCSS 插件

 1.9 整合 Pinia

Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

 安装依赖

npm install pinia //持久化 npm i pinia-plugin-persistedstate

创建 stores/index.ts

// 创建大仓库 import { createPinia } from 'pinia' // pinia持久化 import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' // createPinia方法可以用于创建大仓库 const pinia = createPinia() pinia.use(piniaPluginPersistedstate) // 对外暴露,安装仓库 export default pinia

main.ts引入

import { createApp } from 'vue' import './style.css' import App from './App.vue' import 'virtual:svg-icons-register' import 'uno.css' // 引入仓库pinia import pinia from './stores/index.ts' // 创建app const app = createApp(App) // 注册pinia app.use(pinia) // 挂载 app.mount('#app')

创建 stores/modules/counter.ts 

import { defineStore } from 'pinia' // defineStore方法执行会返回一个函数,函数的作用就是让组件可以获取到仓库数据 const counterStore = defineStore('counter', { // 开启数据持久化 persist: { // enabled: true, // true 表示开启持久化保存,默认localStorage key: 'counter', // 默认会以 store 的 id 作为 key storage: localStorage }, // 可以通过为属性指定选项来配置持久化方式persist // persist: { //     paths: ['isCollapse'], //     storage: sessionStorage // }, // 存储数据state state: (): any => { return { count: 5 } }, // 该函数没有上下文数据,所以获取state中的变量需要使用this actions: { increment() { this.count++ console.log(this.count) } }, // 计算属性,和vuex是使用一样,getters里面不是方法,是计算返回的结果值 getters: { double(state) { return state.count * 2 } } }) // 对外暴露方法 export default counterStore

在App.vue引入试用

import useCounterStore from '@/stores/modules/counter.ts' const counterStore = useCounterStore() <el-button type="primary" @click="counterStore.increment">count++</el-button> 2.0 环境变量

Vite 环境变量主要是为了区分开发、测试、生产等环境的变量

 参考: Vite 环境变量配置官方文档

env配置文件

项目根目录新建 .env.development 、.env.production

环境变量智能提示

新建 src/types/env.d.ts文件存放环境变量TS类型声明 

// src/types/env.d.ts interface ImportMetaEnv { /** * 应用标题 */ VITE_APP_TITLE: string; /** * 应用端口 */ VITE_APP_PORT: number; /** * API基础路径(反向代理) */ VITE_APP_BASE_API: string; /** * 接口地址 */ VITE_APP_API_URL: string; } interface ImportMeta { readonly env: ImportMetaEnv; }

使用自定义环境变量就会有智能提示,环境变量的读取和使用请看下一节的跨域处理中的 vite.config.ts的配置。

2.1 反向代理解决跨域

跨域原理

浏览器同源策略: 协议、域名和端口都相同是同源,浏览器会限制非同源请求读取响应结果。

本地开发环境通过 Vite 配置反向代理解决浏览器跨域问题,生产环境则是通过 nginx 配置反向代理 。

vite.config.ts 配置代理

// 路径别名 resolve: { alias: { '@': pathSrc } }, server: { // 允许IP访问 host: "0.0.0.0", // 应用端口 (默认:3000) port: Number(env.VITE_APP_PORT), // 运行是否自动打开浏览器 open: true, proxy: { /** 代理前缀为 /dev-api 的请求 */ [env.VITE_APP_BASE_API]: { changeOrigin: true, // 接口地址 target: env.VITE_APP_API_URL, rewrite: (path) => path.replace(new RegExp("^" + env.VITE_APP_BASE_API), ""), }, }, },

根目录nginx.conf

user nginx; worker_processes auto; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid; events { worker_connections 1024; } http { include /etc/nginx/mime.types; default_type application/octet-stream; log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; #tcp_nopush on; keepalive_timeout 65; #gzip on; include /etc/nginx/conf.d/*.conf; server { listen 3000; server_name localhost; location / { root /usr/share/nginx/html; index index.html index.htm; } # 代理转发请求至网关,prod-api标识解决跨域,vapi.youlai.tech 线上接口地址,注意后面/ location /prod-api/ { proxy_pass https://web-test.digitmold.com:9901/; } # 代理转发请求至网关,prod-api标识解决跨域,vapi.youlai.tech 线上接口地址,注意后面/ location /prod-dme-api/ { proxy_pass https://web-test2.digitmold.com:9901/; } } }

标签:

admin端由讯客互联互联网栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“admin端