vite4 + vue3 + pinia + axios + vue-router + elementPlus
很全面很长的搭建过程,一定要看完!!!
本机环境问题
npm create vite@latest
创建项目后
npm i
npm run dev
报错: ‘vite’ 不是内部或外部命令,也不是可运行的程序
或批处理文件。
node_modules 有但是就是找不到
使用pnpm i 重新加载依赖就可以了
关键是其他电脑上没有这个问题…(可能是我本机配置有问题)
最最厉害的就是同一台电脑,在另一个文件夹下用npm就可以
正式开始
项目创建完就有vite和vue了
"vite": "^4.2.0"
"vue": "^3.2.47"
需要安装的插件表格(希望需要安装的插件越来越少!!!)
插件名称 | 备注 |
---|---|
pinia | 等同与 vuex |
axios | api请求库 |
vue-router | 路由 |
elementPlus | UI框架 |
unplugin-auto-import | 为 Vite、Webpack、Rollup 和 esbuild 按需自动导入 API。支持 TypeScript。 |
unplugin-vue-components | Vue 的按需组件自动导入。 |
vite-plugin-compression | 压缩大文件 |
rollup-plugin-visualizer | 这是一个依赖分析插件,它提供了多种模式的依赖分析,包括直观的视图分析,sunburst(循环层次图,像光谱)、treemap(矩形层次图,看起来比较直观,也是默认参数)、network(网格图,查看包含关系)、raw-data(原数据模式,json格式), list(列表模式) |
eslint | eslint针对的是javascript,他是一个检测工具,包含js语法以及少部分格式问题,在eslint看来,语法对了就能;保证代码正常允许,格式问题属于其次; |
prettier | prettier属于格式化工具,它看不惯格式不统一,所以它就把eslint没干好的事接着干,另外,prettier支持,包含js在内的多种语言 |
@vitejs/plugin-legacy | 为打包后的文件提供传统浏览器兼容性支持。 |
vite-plugin-vue-setup-extend | 在script标签中添加name属性具体看:https://blog.csdn.net/m0_50074446/article/details/125300541 |
unplugin-icons | 自动按需加载在图标,包括element plus 但是不仅仅时 element plus;使用教程请点击,具体包含图标内容查看iconify官网请点击,unplugin-icons github请点击 |
安装 pinia
pnpm install --save pinia
"dependencies": {"pinia": "^2.0.34","vue": "^3.2.47"},
创建文件夹:src\\stores\\index.js
主要是创建一个实例
// https://pinia.vuejs.org/
import { createPinia } from 'pinia';// 创建
const pinia = createPinia();// 导出
export default pinia;
挂载vue
import { createApp } from 'vue';
import pinia from './stores/index';
const app = createApp(App);
app.use(pinia).mount('#app');
使用时:
创建:src\\stores\\user\\index.js
import { defineStore } from "pinia";export const user = defineStore('user', {state: () => ({user: {total: 0,page: 1,limit: 10,}}),actions: {getList() {//...},}
})
在组件中使用
<script setup>
import {user} from '/@/stores/user/index';
const store = user();
// ...
store.getList({...}); // 直接调用是不是很方便
// ...
store.user.page; // 直接获取
</script>
更多详细使用请点击此处
安装axios
pnpm i axios
// 或者
npm i axios
创建文件: src\\utils\\request.js
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
//"vue-router": "^4.1.6"
创建文件:src\\router\\index.js
import { createRouter, createWebHashHistory } from 'vue-router';
const staticRoutes = [{path: '/login',name: 'login',component: () => import('/@/views/login/index.vue'),meta: {title: '登录',},},
];
/* 创建一个可以被 Vue 应用程序使用的路由实例* @method createRouter(options: RouterOptions): Router* @link 参考:https://next.router.vuejs.org/zh/api/#createrouter*/
export const router = createRouter({history: createWebHashHistory(),routes: staticRoutes,
});
// 路由加载前
router.beforeEach(async (to, from, next) => {next();
});
// 路由加载后
router.afterEach(() => {});// 导出路由
export default router;
动态添加路由
import { router } from '/@/router/index';
setTimeout((route) => { // 模拟接口请求router.addRoute(route);
},5000)
挂载到vue
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import pinia from './stores/index'const app = createApp(App)
app.use(pinia).use(router).mount('#app')
安装 按需加载 element plus
pnpm install element-plus
安装相关按需加载的插件
npm install -D unplugin-vue-components unplugin-auto-import unplugin-icons
vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { resolve } from 'path'
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'const pathResolve = (dir) => {return resolve(__dirname, '.', dir);
};const alias = {'/@': pathResolve('./src/'),
};// https://vitejs.dev/config/
export default defineConfig({plugins: [vue(),AutoImport({imports: ['vue', 'vue-router'], // 自动引入相关apiresolvers: [ElementPlusResolver(),IconsResolver({prefix: 'icon',// enabledCollections: ['ep'],// 标识自定义图标集customCollections: ['ci']})],}),Components({resolvers: [ElementPlusResolver(),IconsResolver({prefix: 'icon',// enabledCollections: ['ep'],// 标识自定义图标集customCollections: ['ci']})],}),Icons({compiler: 'vue3',autoInstall: true,// 自定义配置customCollections: { ci: FileSystemIconLoader('./src/assets/svg', svg => svg.replace(/^<svg /, '<svg fill="currentColor" '))}}),],resolve: { alias },
})
使用方式,直接用不需要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 进行缩小。
pnpm 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-vue-setup-extend 在script标签中添加name属
安装
pnpm i vite-plugin-vue-setup-extend -D
import VueSetupExtend from 'vite-plugin-vue-setup-extend'export default defineConfig({plugins: [VueSetupExtend()]
})
vite-plugin-compression 压缩大文件
安装
pnpm 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 { resolve } from 'path'
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 legacy from '@vitejs/plugin-legacy'
import vueSetupExtend from 'vite-plugin-vue-setup-extend'
import viteCompression from 'vite-plugin-compression'const pathResolve = (dir) => {return resolve(__dirname, '.', dir)
}const alias = {'/@': pathResolve('./src/'),
}// https://vitejs.dev/config/
export default defineConfig((mode) => {// mode 拿的是 process.argv的参数。例如:package.json script 中 "vite build --mode prd" 的 --mode 后面的值// 想在vite.config.ts中使用环境变量,要用vite提供的loadEnv(mode, process.cwd())const env = loadEnv(mode.mode, process.cwd())return {plugins: [legacy({targets: ['defaults', 'not IE 11'],}),vue(),viteCompression({verbose: true,disable: false,deleteOriginFile: false,// 文件大于 100Kb 开启压缩threshold: 100000,algorithm: 'gzip',ext: 'gz',}),vueSetupExtend(),AutoImport({imports: ['vue', 'vue-router'], // 自动引入相关apiresolvers: [ElementPlusResolver(),IconsResolver({prefix: 'Deep',// enabledCollections: ['ep'],// 标识自定义图标集customCollections: ['ci'],}),],}),Components({resolvers: [ElementPlusResolver(),IconsResolver({prefix: 'Deep',// enabledCollections: ['ep'],// 标识自定义图标集customCollections: ['ci'],}),],}),Icons({compiler: 'vue3',autoInstall: true,customCollections: {ci: FileSystemIconLoader('./src/assets/svg', (svg) =>svg.replace(/^<svg /, '<svg fill="currentColor" '),),},}),],resolve: { alias },root: process.cwd(),// 当前启动的命令 commandbase: mode.command === 'serve' ? './' : env.VITE_PUBLIC_PATH,server: {host: '0.0.0.0',port: env.VITE_PORT,open: false,proxy: {'/api': {target: 'https://gitee.com',ws: true,changeOrigin: true,rewrite: (path) => 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) {// 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 === 'production',drop_debugger: mode.mode === 'production',},},sourcemap: mode.mode !== 'production',},css: {devSourcemap: true,preprocessorOptions: { css: { charset: false } },},}
})
安装eslint && prettier
根据个人需求,我参考的这几个链接:
http://52code.net/a/bAwoc9jJ7M
https://segmentfault.com/a/1190000041954694?utm_source=sf-similar-article
https://zhuanlan.zhihu.com/p/619030608
https://juejin.cn/post/7077346415424307214
https://blog.csdn.net/lijiahui_/article/details/128134797
https://blog.csdn.net/weixin_43459866/article/details/124249172