本文主要是介绍vite + vue + typscript + pinia + axios + vue-router + elementPlus,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
npm create vite@latest
创建项目后
npm i
npm run dev
"dependencies": {"vue": "^3.4.21"},
"devDependencies": {"@vitejs/plugin-vue": "^5.0.4","typescript": "^5.2.2","vite": "^5.2.0","vue-tsc": "^2.0.6"
}
需要安装的插件表格(希望需要安装的插件越来越少!!!)
插件名称 | 备注 |
---|---|
pinia | 等同与 vuex |
pinia-plugin-persistedstate | pinia持久化插件 |
axios | api请求库 |
vue-router | 路由 |
elementPlus | UI框架 |
unplugin-auto-import | 为 Vite、Webpack、Rollup 和 esbuild 按需自动导入 API。支持 TypeScript。 |
unplugin-vue-components | Vue 的按需组件自动导入。 |
vite-plugin-compression | 压缩大文件 |
vite-plugin-style-import | 它会根据需要自动导入组件的样式文件 |
rollup-plugin-visualizer | 这是一个依赖分析插件,它提供了多种模式的依赖分析,包括直观的视图分析,sunburst(循环层次图,像光谱)、treemap(矩形层次图,看起来比较直观,也是默认参数)、network(网格图,查看包含关系)、raw-data(原数据模式,json格式), list(列表模式) |
eslint | eslint针对的是javascript,他是一个检测工具,包含js语法以及少部分格式问题,在eslint看来,语法对了就能;保证代码正常允许,格式问题属于其次; |
prettier | prettier属于格式化工具,它看不惯格式不统一,所以它就把eslint没干好的事接着干,另外,prettier支持,包含js在内的多种语言 |
@vitejs/plugin-legacy | 为打包后的文件提供传统浏览器兼容性支持。 |
unplugin-icons | 自动按需加载在图标,包括element plus 但是不仅仅时 element plus;使用教程请点击,具体包含图标内容查看iconify官网请点击,unplugin-icons github请点击 |
添加基础路径
TS版本需要安装@types/node,不然会警告找不到对应的类型声明
npm install @types/node --save-dev
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue()],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}},
})
引入TS 文件会报错找不到相应类型声明,因为在配置好 vite.config.ts 文件后
tsconfig.json 文件 或者 jsconfig.json 文件也要进行文件系统路径别名设置。需要配置baseUrl和paths字段
tsconfig.json
{"compilerOptions": {"target": "ESNext","useDefineForClassFields": true,"module": "ESNext","moduleResolution": "Node","strict": true,"jsx": "preserve","resolveJsonModule": true,"isolatedModules": true,"esModuleInterop": true,"lib": ["ESNext", "DOM"],"skipLibCheck": true,"noEmit": true,"types": ["element-plus/global"],"baseUrl": "./", // 解析非相对模块的基础地址,默认是当前目录"paths": {"@/*": ["./src/*"] // 路径映射,相对于baseUrl}},"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],"references": [{ "path": "./tsconfig.node.json" }]
}
安装 pinia
pnpm install --save pinia
npm i pinia-plugin-persistedstate
"dependencies": {"pinia": "^2.1.7","pinia-plugin-persistedstate": "^3.2.1","vue": "^3.4.21"},
创建文件夹:src\store\index.ts
主要是创建一个实例
import type { App } from 'vue'
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' //数据持久化const store = createPinia()store.use(piniaPluginPersistedstate)export const setupStore = (app: App<Element>) => {app.use(store)
}
export { store }
挂载vue
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { setupStore } from '@/store'const app = createApp(App)
setupStore(app)app.mount('#app')
使用时:
创建:src/store/modules/user.ts
import { defineStore } from 'pinia'interface UserState {userInfo?: stringtokenKey: stringtoken: stringroleRouters?: string[]rememberMe: booleanloginInfo?: string
}export const useUserStore = defineStore('user', {state: (): UserState => {return {userInfo: undefined,tokenKey: '',token: '',roleRouters: undefined,rememberMe: true,loginInfo: undefined}},getters: {getTokenKey(): string {return this.tokenKey},getToken(): string {return this.token},},actions: {setTokenKey(tokenKey: string) {this.tokenKey = tokenKey},setToken(token: string) {this.token = token},},// persist: true // 一键开启数据持久化,使用默认配置// 开启数据持久化,自定义配置persist: {// Key 用于引用 storage 中的数据// 这个 Store 将被持久化存储在 localStorage 中的 my-custom-key key 中。key: 'my-custom-key', // 将数据持久化到 storage 中,必须具有 getItem: (key: string) => string | null 和 setItem: (key: string, value: string) => void 两个方法。// 这个 store 将被持久化存储在 sessionStorage中。storage: sessionStorage, // 用于指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state。// 该 store 中, 只有userInfo 和 rememberMe 被持久化,而其他不会被持久化。paths: ['userInfo', 'rememberMe'], // 该 hook 将在从 storage 中恢复数据之前触发,并且它可以访问整个 PiniaPluginContext,这可用于在恢复数据之前强制地执行特定的操作。beforeRestore: (ctx) => {console.log(`即将恢复 '${ctx.store.$id}'`)},// 该 hook 将在从 storage 中恢复数据之后触发,并且它可以访问整个 PiniaPluginContext,这可用于在恢复数据之后强制地执行特定的操作。afterRestore: (ctx) => {console.log(`刚刚恢复完 '${ctx.store.$id}'`)},// 当设置为 true 时,持久化/恢复 Store 时可能发生的任何错误都将使用 console.error 输出。debug: true},
})
在组件中使用
<script setup>
import {useUserStore} from '@/store/modules/user';
const store = useUserStore();
// ...
store.setTokenKey({...}); // 直接调用是不是很方便
// ...
store.user.page; // 直接获取
</script>
更多详细使用请点击此处
安装axios
pnpm i axios
// 或者
npm i axios
创建文件: src\utils\request.ts
import axios from 'axios';
// 配置新建一个 axios 实例
const service = axios.create({baseURL: import.meta.env.VITE_API_URL, // 环境变量timeout: 50000,headers: { 'Content-Type': 'application/json' },
});
// 添加请求拦截器
service.interceptors.request.use((config) => {// 在发送请求之前做些什么return config;},(error) => {// 对请求错误做些什么return Promise.reject(error);}
);// 添加响应拦截器
service.interceptors.response.use((response) => {// 对响应数据做点什么const res = response.data;const {status, data, message} = response || {};if (status !== 200) {const {message: messageErr} = service.interceptors.response.data || {};return Promise.reject(messageErr);} else {return {status, data};}},(error) => {const {data, status} = error.response || {};// 对响应错误做点什么 ...return Promise.reject(messageErr);}
);
// 导出 axios 实例
export default service;
使用时:
创建
import request from "../../utils/request";export function userlist(params) {return request({url: `/userlist`,method: "GET",params,});
}export function addUser(params) {return request({url: `/addUser`,method: "POST",data: {...params}});
}
在组件中使用
<script setup>
import {deleteRoleApi} from '/@/api/...';
deleteRoleApi(id).then(res => {})
</script>
安装vue-router
pnpm install vue-router --save
创建文件:src\router\index.ts
import { createRouter, createWebHashHistory } from 'vue-router'
import type { RouteRecordRaw } from 'vue-router'
import type { App } from 'vue'
import { NO_RESET_WHITE_LIST } from '@/assets/constants'const Layout = () => import('@/layout/Layout.vue')export const constantRouterMap: AppRouteRecordRaw[] = [{path: '/',component: Layout,redirect: '/dashboard/analysis',name: 'Root',meta: {hidden: true}},{path: '/login',component: () => import('@/views/Login/Login.vue'),name: 'Login',meta: {hidden: true,noTagsView: true}},{path: '/personal',component: Layout,redirect: '/personal/personal-center',name: 'Personal',meta: {hidden: true,canTo: true},children: [{path: 'personal-center',component: () => import('@/views/Personal/PersonalCenter/PersonalCenter.vue'),name: 'PersonalCenter',meta: {hidden: true,canTo: true}}]},{path: '/404',component: () => import('@/views/Error/404.vue'),name: 'NoFind',meta: {hidden: true,title: '404',noTagsView: true}}
]export const asyncRouterMap: AppRouteRecordRaw[] = [{path: '/error',component: Layout,redirect: '/error/404',name: 'Error',meta: {icon: 'ci:error',alwaysShow: true},children: [{path: '404-demo',component: () => import('@/views/Error/404.vue'),name: '404Demo',meta: {title: '404'}},{path: '403-demo',component: () => import('@/views/Error/403.vue'),name: '403Demo',meta: {title: '403'}},{path: '500-demo',component: () => import('@/views/Error/500.vue'),name: '500Demo',meta: {title: '500'}}]},]const router = createRouter({history: createWebHashHistory(),strict: true,routes: constantRouterMap as RouteRecordRaw[],scrollBehavior: () => ({ left: 0, top: 0 })
})export const resetRouter = (): void => {router.getRoutes().forEach((route) => {const { name } = routeif (name && !NO_RESET_WHITE_LIST.includes(name as string)) {router.hasRoute(name) && router.removeRoute(name)}})
}export const setupRouter = (app: App<Element>) => {app.use(router)
}export default router
挂载到vue
import { createApp } from 'vue'
import '@/style.css'
import App from '@/App.vue'
import { setupStore } from '@/store'
import { setupRouter } from '@/router'const app = createApp(App)
setupStore(app)
setupRouter(app)
app.mount('#app')
安装scss
直接安装不需要node-sass 和 sass-loader
npm install -D sass
安装 按需加载 element plus
npm install element-plus
安装相关按需加载的插件
npm install -D unplugin-vue-components unplugin-auto-import unplugin-icons vite-plugin-style-import consola
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),AutoImport({imports: ['vue', 'vue-router'], // 自动引入相关apiresolvers: [ElementPlusResolver(),IconsResolver({// 设置自动导入的图标组件前缀prefix: 'icon',// 标识自定义图标集customCollections: ['ci']})],}),Components({resolvers: [ElementPlusResolver(),IconsResolver({// 设置自动导入的图标组件前缀prefix: 'icon',// 标识自定义图标集customCollections: ['ci']})],}),Icons({compiler: 'vue3',autoInstall: true,// 自定义配置customCollections: { ci: FileSystemIconLoader('./src/assets/svg', svg => svg.replace(/^<svg /, '<svg fill="currentColor" '))}}),createStyleImportPlugin({resolves: [ElementPlusResolve()],libs: [{libraryName: 'element-plus',esModule: true,resolveStyle: (name) => {if (name === 'click-outside') {return ''}return `element-plus/es/components/${name.replace(/^el-/, '')}/style/css`}}]}),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}},
})
使用方式,直接用不需要import
<script setup>import IconBaseline5g from '~icons/ep/edit'</script><template><!-- 使用component 需要先引用 --><el-icon :size="20"><component :is="IconBaseline5g" /></el-icon><!-- 直接使用,不需要引用 --><!-- icon是头部(上面vite.config.js 配置的prefix: 'icon')--><!-- ep是element plus图标库的简称 edit是图标的名字 --><el-icon :size="20"><iconEpEdit /></el-icon><!-- 使用本地自定义的svg --><!-- icon是头部(上面vite.config.js 配置的prefix: 'icon')--><!-- Ci是自定义图标的集合(上面vite.config.js 配置的customCollections: { ci: FileSystemIconLoader...) vue是自定义目录下的svg文件的名称 --><el-icon :size="20"><iconCiVue /></el-icon>
</template>
静态资源动态引用:图片
vite官方推荐
使用require的可以用上面的方法替换
@vitejs/plugin-legacy
安装
必须安装 Terser,因为插件遗留版使用 Terser 进行缩小。
npm i -D @vitejs/plugin-legacy terser
// vite.config.js
import legacy from '@vitejs/plugin-legacy'export default {plugins: [legacy({targets: ['defaults', 'not IE 11'],}),],
}
vite-plugin-compression 压缩大文件
安装
npm i -D vite-plugin-compression
import viteCompression from "vite-plugin-compression";
plugins: [viteCompression({verbose: true,disable: false,deleteOriginFile: false,// 文件大于 100Kb 开启压缩 threshold: 100000,algorithm: "gzip",ext: "gz",}),],
压缩文件需要搭配nginx 配置,详情请点击
rollup-plugin-visualizer 这是一个依赖分析插件
参考链接:https://blog.csdn.net/g18204746769/article/details/127431733
安装
pnpm install vite-plugin-cdn-import --save-dev
import { visualizer } from 'rollup-plugin-visualizer';
plugins: [visualizer()
]
vite.config.js全部的配置
想了解配置想请点击
import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue'
import { fileURLToPath, URL } from 'node:url'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import { FileSystemIconLoader } from 'unplugin-icons/loaders'
import Icons from 'unplugin-icons/vite'
import IconsResolver from 'unplugin-icons/resolver'
import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
import legacy from '@vitejs/plugin-legacy'
import viteCompression from "vite-plugin-compression";// https://vitejs.dev/config/
export default defineConfig((mode): any => {const env = loadEnv(mode.mode, process.cwd())return {plugins: [vue(),AutoImport({imports: ['vue', 'vue-router'], // 自动引入相关apiresolvers: [ElementPlusResolver(),IconsResolver({// 设置自动导入的图标组件前缀prefix: 'icon',// 标识自定义图标集customCollections: ['ci']})],}),Components({resolvers: [ElementPlusResolver(),IconsResolver({// 设置自动导入的图标组件前缀prefix: 'icon',// 标识自定义图标集customCollections: ['ci']})],}),Icons({compiler: 'vue3',autoInstall: true,// 自定义配置customCollections: { ci: FileSystemIconLoader('./src/assets/svg', svg => svg.replace(/^<svg /, '<svg fill="currentColor" '))}}),createStyleImportPlugin({resolves: [ElementPlusResolve()],libs: [{libraryName: 'element-plus',esModule: true,resolveStyle: (name) => {if (name === 'click-outside') {return ''}return `element-plus/es/components/${name.replace(/^el-/, '')}/style/css`}}]}),legacy({targets: ['defaults', 'not IE 11'],}),viteCompression({verbose: true,disable: false,deleteOriginFile: false,// 文件大于 100Kb 开启压缩 threshold: 100000,algorithm: "gzip",ext: "gz",}),],resolve: {alias: {'@': fileURLToPath(new URL('./src', import.meta.url))}},server: {host: '0.0.0.0',port: env.VITE_PORT,open: false,proxy: {'/api': {target: 'https://gitee.com',ws: true,changeOrigin: true,rewrite: (path:string) => path.replace(/^\/gitee/, ''),},},},build: {outDir: 'dist',chunkSizeWarningLimit: 1500,rollupOptions: {output: {entryFileNames: `assets/[name].${new Date().getTime()}.js`,chunkFileNames: `assets/[name].${new Date().getTime()}.js`,assetFileNames: `assets/[name].${new Date().getTime()}.[ext]`,compact: true,// manualChunks: {// vue: ['vue', 'vue-router', 'pinia'],// echarts: ['echarts'],// antvG6: ['@antv/g6'],// elementPlus: ['element-plus'],// },manualChunks(id:string[]) {// if (id.includes("style.css")) {// // 需要单独分割那些资源 就写判断逻辑就行// return 'src/style.css';// }// if (id.includes("HelloWorld.vue")) {// // 单独分割hello world.vue文件// return 'src/components/HelloWorld.vue';// }// // 最小化拆分包if (id.includes('node_modules')) {return id.toString().split('node_modules/')[1].split('/')[0].toString()}},},},minify: 'terser',terserOptions: {compress: {drop_console: mode.mode === 'prd',drop_debugger: mode.mode === 'prd',},},sourcemap: mode.mode !== 'prd',},css: {devSourcemap: true,preprocessorOptions: { css: { charset: false } },},}
})
安装eslint && prettier
根据个人需求,我参考的这几个链接:
https://blog.csdn.net/m0_53022813/article/details/137379423
https://juejin.cn/post/7118294114734440455#heading-1
https://blog.csdn.net/weixin_43459866/article/details/124249172
https://blog.csdn.net/weixin_43993776/article/details/132564724
无法找到模块 vite-plugin-eslint 插件中的 TS 声明文件,隐式含有 “any” 类型。
vscode使用eslint
源码
这篇关于vite + vue + typscript + pinia + axios + vue-router + elementPlus的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!