创建项目后
- "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等同与 vuexpinia-plugin-persistedstatepinia持久化插件axiosapi请求库vue-router路由elementPlusUI框架unplugin-auto-import为 Vite、Webpack、Rollup 和 esbuild 按需主动导入 API。支持 TypeScript。unplugin-vue-componentsVue 的按需组件主动导入。vite-plugin-compression压缩大文件vite-plugin-style-import它会根据需要主动导入组件的样式文件rollup-plugin-visualizer这是一个依赖分析插件,它提供了多种模式的依赖分析,包括直观的视图分析,sunburst(循环层次图,像光谱)、treemap(矩形层次图,看起来比较直观,也是默认参数)、network(网格图,查看包罗关系)、raw-data(原数据模式,json格式), list(列表模式)eslinteslint针对的是javascript,他是一个检测工具,包罗js语法以及少部分格式题目,在eslint看来,语法对了就能;包管代码正常允许,格式题目属于其次;prettierprettier属于格式化工具,它看不惯格式差别一,所以它就把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?: string
- tokenKey: string
- token: string
- roleRouters?: string[]
- rememberMe: boolean
- loginInfo?: 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 } = route
- if (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
安装 按需加载 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'], // 自动引入相关api
- resolvers: [
- 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'], // 自动引入相关api
- resolvers: [
- 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 } },
- },
- }
- })
复制代码 找不到模块“@/xxx/xxx.vue”或其相应的类型声明。ts(2307)
设置tsconfig.json:确保你的tsconfig.json文件中包罗了对.vue文件的支持。
- {
- "compilerOptions": {
- "types": ["vue/vue3"] // 如果你使用的是Vue 3
- // 或者 "types": ["vue/vue2"] 如果你使用的是Vue 2
- }
- }
复制代码 创建类型声明文件(如果主动处理不起作用):如果主动处理不起作用,你可以手动创建一个声明文件,例如shims-vue.d.ts,并在此中添加以下内容
- declare module '*.vue' {
- import type { DefineComponent } from 'vue'
- const component: DefineComponent<{}, {}, any>
- export default component
- }
复制代码 安装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
源码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |