vite + vue + typscript + pinia + axios + vue-router + elementPlus

打印 上一主题 下一主题

主题 857|帖子 857|积分 2571

  1. npm create vite@latest
复制代码
创建项目后
  1. npm i
  2. npm run dev
复制代码
  1. "dependencies": {
  2.     "vue": "^3.4.21"
  3.   },
  4. "devDependencies": {
  5.   "@vitejs/plugin-vue": "^5.0.4",
  6.   "typescript": "^5.2.2",
  7.   "vite": "^5.2.0",
  8.   "vue-tsc": "^2.0.6"
  9. }
复制代码
需要安装的插件表格(希望需要安装的插件越来越少!!!)

插件名称备注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,不然会警告找不到对应的类型声明
  1. npm install @types/node --save-dev
复制代码
vite.config.ts
  1. import { defineConfig } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import { fileURLToPath, URL } from 'node:url'
  4. // https://vitejs.dev/config/
  5. export default defineConfig({
  6.   plugins: [vue()],
  7.   resolve: {
  8.     alias: {
  9.       '@': fileURLToPath(new URL('./src', import.meta.url))
  10.     }
  11.   },
  12. })
复制代码
引入TS 文件会报错找不到相应类型声明,由于在设置好 vite.config.ts 文件后
tsconfig.json 文件 或者 jsconfig.json 文件也要举行文件系统路径别名设置。需要设置baseUrl和paths字段
tsconfig.json
  1. {
  2.   "compilerOptions": {
  3.     "target": "ESNext",
  4.     "useDefineForClassFields": true,
  5.     "module": "ESNext",
  6.     "moduleResolution": "Node",
  7.     "strict": true,
  8.     "jsx": "preserve",
  9.     "resolveJsonModule": true,
  10.     "isolatedModules": true,
  11.     "esModuleInterop": true,
  12.     "lib": ["ESNext", "DOM"],
  13.     "skipLibCheck": true,
  14.     "noEmit": true,
  15.     "types": ["element-plus/global"],
  16.     "baseUrl": "./",  // 解析非相对模块的基础地址,默认是当前目录
  17.     "paths": {
  18.       "@/*": ["./src/*"]  // 路径映射,相对于baseUrl
  19.     }
  20.   },
  21.   "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
  22.   "references": [{ "path": "./tsconfig.node.json" }]
  23. }
复制代码
安装 pinia

  1. pnpm install --save pinia
  2. npm i pinia-plugin-persistedstate
复制代码
  1. "dependencies": {
  2.     "pinia": "^2.1.7",
  3.     "pinia-plugin-persistedstate": "^3.2.1",
  4.     "vue": "^3.4.21"
  5.   },
复制代码
创建文件夹:src\store\index.ts

重要是创建一个实例
  1. import type { App } from 'vue'
  2. import { createPinia } from 'pinia'
  3. import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' //数据持久化
  4. const store = createPinia()
  5. store.use(piniaPluginPersistedstate)
  6. export const setupStore = (app: App<Element>) => {
  7.   app.use(store)
  8. }
  9. export { store }
复制代码
挂载vue

  1. import { createApp } from 'vue'
  2. import './style.css'
  3. import App from './App.vue'
  4. import { setupStore } from '@/store'
  5. const app = createApp(App)
  6. setupStore(app)
  7. app.mount('#app')
复制代码
使用时:

创建:src/store/modules/user.ts
  1. import { defineStore } from 'pinia'
  2. interface UserState {
  3.   userInfo?: string
  4.   tokenKey: string
  5.   token: string
  6.   roleRouters?: string[]
  7.   rememberMe: boolean
  8.   loginInfo?: string
  9. }
  10. export const useUserStore = defineStore('user', {
  11.   state: (): UserState => {
  12.     return {
  13.       userInfo: undefined,
  14.       tokenKey: '',
  15.       token: '',
  16.       roleRouters: undefined,
  17.       rememberMe: true,
  18.       loginInfo: undefined
  19.     }
  20.   },
  21.   getters: {
  22.     getTokenKey(): string {
  23.       return this.tokenKey
  24.     },
  25.     getToken(): string {
  26.       return this.token
  27.     },
  28.   },
  29.   actions: {
  30.     setTokenKey(tokenKey: string) {
  31.       this.tokenKey = tokenKey
  32.     },
  33.     setToken(token: string) {
  34.       this.token = token
  35.     },
  36.   },
  37.   // persist: true // 一键开启数据持久化,使用默认配置
  38.   // 开启数据持久化,自定义配置
  39.   persist: {
  40.         // Key 用于引用 storage 中的数据
  41.           // 这个 Store 将被持久化存储在 localStorage 中的 my-custom-key key 中。
  42.     key: 'my-custom-key',
  43.     // 将数据持久化到 storage 中,必须具有 getItem: (key: string) => string | null 和 setItem: (key: string, value: string) => void 两个方法。
  44.         // 这个 store 将被持久化存储在 sessionStorage中。
  45.     storage: sessionStorage,
  46.     // 用于指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state。
  47.     // 该 store 中, 只有userInfo 和 rememberMe 被持久化,而其他不会被持久化。
  48.     paths: ['userInfo', 'rememberMe'],
  49.     // 该 hook 将在从 storage 中恢复数据之前触发,并且它可以访问整个 PiniaPluginContext,这可用于在恢复数据之前强制地执行特定的操作。
  50.     beforeRestore: (ctx) => {
  51.       console.log(`即将恢复 '${ctx.store.$id}'`)
  52.     },
  53.     // 该 hook 将在从 storage 中恢复数据之后触发,并且它可以访问整个 PiniaPluginContext,这可用于在恢复数据之后强制地执行特定的操作。
  54.     afterRestore: (ctx) => {
  55.       console.log(`刚刚恢复完 '${ctx.store.$id}'`)
  56.     },
  57.     // 当设置为 true 时,持久化/恢复 Store 时可能发生的任何错误都将使用 console.error 输出。
  58.     debug: true
  59.   },
  60. })
复制代码
在组件中使用

  1. <script setup>
  2. import {useUserStore} from '@/store/modules/user';
  3. const store = useUserStore();
  4. // ...
  5. store.setTokenKey({...}); // 直接调用是不是很方便
  6. // ...
  7. store.user.page; // 直接获取
  8. </script>
复制代码
更多具体使用请点击此处

安装axios

  1. pnpm i axios
  2. // 或者
  3. npm i axios
复制代码
创建文件: src\utils\request.ts
  1. import axios from 'axios';
  2. // 配置新建一个 axios 实例
  3. const service = axios.create({
  4.         baseURL: import.meta.env.VITE_API_URL, // 环境变量
  5.         timeout: 50000,
  6.         headers: { 'Content-Type': 'application/json' },
  7. });
  8. // 添加请求拦截器
  9. service.interceptors.request.use(
  10.         (config) => {
  11.                 // 在发送请求之前做些什么
  12.                 return config;
  13.         },
  14.         (error) => {
  15.                 // 对请求错误做些什么
  16.                 return Promise.reject(error);
  17.         }
  18. );
  19. // 添加响应拦截器
  20. service.interceptors.response.use(
  21.         (response) => {
  22.                 // 对响应数据做点什么
  23.                 const res = response.data;
  24.                 const {status, data, message} = response || {};
  25.                 if (status !== 200) {
  26.                         const {message: messageErr} = service.interceptors.response.data || {};
  27.                         return Promise.reject(messageErr);
  28.                 } else {
  29.                         return {status, data};
  30.                 }
  31.         },
  32.         (error) => {
  33.                 const {data, status} = error.response || {};
  34.                 // 对响应错误做点什么 ...
  35.                 return Promise.reject(messageErr);
  36.         }
  37. );
  38. // 导出 axios 实例
  39. export default service;
复制代码
使用时:
创建
  1. import request from "../../utils/request";
  2. export function userlist(params) {
  3.   return request({
  4.     url: `/userlist`,
  5.     method: "GET",
  6.     params,
  7.   });
  8. }
  9. export function addUser(params) {
  10.   return request({
  11.     url: `/addUser`,
  12.     method: "POST",
  13.     data: {
  14.       ...params
  15.     }
  16.   });
  17. }
复制代码
在组件中使用
  1. <script setup>
  2. import {deleteRoleApi} from '/@/api/...';
  3. deleteRoleApi(id).then(res => {})
  4. </script>
复制代码
安装vue-router

  1. pnpm install vue-router --save
复制代码
创建文件:src\router\index.ts
  1. import { createRouter, createWebHashHistory } from 'vue-router'
  2. import type { RouteRecordRaw } from 'vue-router'
  3. import type { App } from 'vue'
  4. import { NO_RESET_WHITE_LIST } from '@/assets/constants'
  5. const Layout = () => import('@/layout/Layout.vue')
  6. export const constantRouterMap: AppRouteRecordRaw[] = [
  7.   {
  8.     path: '/',
  9.     component: Layout,
  10.     redirect: '/dashboard/analysis',
  11.     name: 'Root',
  12.     meta: {
  13.       hidden: true
  14.     }
  15.   },
  16.   {
  17.     path: '/login',
  18.     component: () => import('@/views/Login/Login.vue'),
  19.     name: 'Login',
  20.     meta: {
  21.       hidden: true,
  22.       noTagsView: true
  23.     }
  24.   },
  25.   {
  26.     path: '/personal',
  27.     component: Layout,
  28.     redirect: '/personal/personal-center',
  29.     name: 'Personal',
  30.     meta: {
  31.       hidden: true,
  32.       canTo: true
  33.     },
  34.     children: [
  35.       {
  36.         path: 'personal-center',
  37.         component: () => import('@/views/Personal/PersonalCenter/PersonalCenter.vue'),
  38.         name: 'PersonalCenter',
  39.         meta: {
  40.           hidden: true,
  41.           canTo: true
  42.         }
  43.       }
  44.     ]
  45.   },
  46.   {
  47.     path: '/404',
  48.     component: () => import('@/views/Error/404.vue'),
  49.     name: 'NoFind',
  50.     meta: {
  51.       hidden: true,
  52.       title: '404',
  53.       noTagsView: true
  54.     }
  55.   }
  56. ]
  57. export const asyncRouterMap: AppRouteRecordRaw[] = [
  58.   
  59.   {
  60.     path: '/error',
  61.     component: Layout,
  62.     redirect: '/error/404',
  63.     name: 'Error',
  64.     meta: {
  65.       icon: 'ci:error',
  66.       alwaysShow: true
  67.     },
  68.     children: [
  69.       {
  70.         path: '404-demo',
  71.         component: () => import('@/views/Error/404.vue'),
  72.         name: '404Demo',
  73.         meta: {
  74.           title: '404'
  75.         }
  76.       },
  77.       {
  78.         path: '403-demo',
  79.         component: () => import('@/views/Error/403.vue'),
  80.         name: '403Demo',
  81.         meta: {
  82.           title: '403'
  83.         }
  84.       },
  85.       {
  86.         path: '500-demo',
  87.         component: () => import('@/views/Error/500.vue'),
  88.         name: '500Demo',
  89.         meta: {
  90.           title: '500'
  91.         }
  92.       }
  93.     ]
  94.   },
  95.   
  96. ]
  97. const router = createRouter({
  98.   history: createWebHashHistory(),
  99.   strict: true,
  100.   routes: constantRouterMap as RouteRecordRaw[],
  101.   scrollBehavior: () => ({ left: 0, top: 0 })
  102. })
  103. export const resetRouter = (): void => {
  104.   router.getRoutes().forEach((route) => {
  105.     const { name } = route
  106.     if (name && !NO_RESET_WHITE_LIST.includes(name as string)) {
  107.       router.hasRoute(name) && router.removeRoute(name)
  108.     }
  109.   })
  110. }
  111. export const setupRouter = (app: App<Element>) => {
  112.   app.use(router)
  113. }
  114. export default router
复制代码
挂载到vue
  1. import { createApp } from 'vue'
  2. import '@/style.css'
  3. import App from '@/App.vue'
  4. import { setupStore } from '@/store'
  5. import { setupRouter } from '@/router'
  6. const app = createApp(App)
  7. setupStore(app)
  8. setupRouter(app)
  9. app.mount('#app')
复制代码
安装scss

直接安装不需要node-sass 和 sass-loader
  1. npm install -D sass
复制代码
安装 按需加载 element plus

  1. npm install element-plus
复制代码
安装相关按需加载的插件

  1. npm install -D unplugin-vue-components unplugin-auto-import unplugin-icons vite-plugin-style-import consola
复制代码
vite.config.ts
  1. import { defineConfig } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import { fileURLToPath, URL } from 'node:url'
  4. import AutoImport from 'unplugin-auto-import/vite'
  5. import Components from 'unplugin-vue-components/vite'
  6. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  7. import { FileSystemIconLoader } from 'unplugin-icons/loaders'
  8. import Icons from 'unplugin-icons/vite'
  9. import IconsResolver from 'unplugin-icons/resolver'
  10. import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
  11. // https://vitejs.dev/config/
  12. export default defineConfig({
  13.   plugins: [
  14.     vue(),
  15.     AutoImport({
  16.       imports: ['vue', 'vue-router'], // 自动引入相关api
  17.       resolvers: [
  18.         ElementPlusResolver(),
  19.         IconsResolver({
  20.           // 设置自动导入的图标组件前缀
  21.           prefix: 'icon',
  22.           // 标识自定义图标集
  23.           customCollections: ['ci']
  24.         })
  25.       ],
  26.     }),
  27.     Components({
  28.       resolvers: [
  29.         ElementPlusResolver(),
  30.         IconsResolver({
  31.           // 设置自动导入的图标组件前缀
  32.           prefix: 'icon',
  33.           // 标识自定义图标集
  34.           customCollections: ['ci']
  35.         })
  36.       ],
  37.     }),
  38.     Icons({
  39.       compiler: 'vue3',
  40.       autoInstall: true,
  41.       // 自定义配置
  42.       customCollections: {
  43.         ci: FileSystemIconLoader('./src/assets/svg', svg => svg.replace(/^<svg /, '<svg fill="currentColor" '))
  44.       }
  45.     }),
  46.     createStyleImportPlugin({
  47.       resolves: [ElementPlusResolve()],
  48.       libs: [
  49.         {
  50.           libraryName: 'element-plus',
  51.           esModule: true,
  52.           resolveStyle: (name) => {
  53.             if (name === 'click-outside') {
  54.               return ''
  55.             }
  56.             return `element-plus/es/components/${name.replace(/^el-/, '')}/style/css`
  57.           }
  58.         }
  59.       ]
  60.     }),
  61.   ],
  62.   resolve: {
  63.     alias: {
  64.       '@': fileURLToPath(new URL('./src', import.meta.url))
  65.     }
  66.   },
  67. })
复制代码
使用方式,直接用不需要import
  1. <script setup>
  2. import IconBaseline5g from '~icons/ep/edit'
  3. </script>
  4. <template>
  5.   
  6. <!-- 使用component 需要先引用 -->
  7.   <el-icon :size="20">
  8.     <component :is="IconBaseline5g" />
  9.   </el-icon>
  10.   <!--  直接使用,不需要引用 -->
  11.   <!-- icon是头部(上面vite.config.js 配置的prefix: 'icon')-->
  12.   <!-- ep是element plus图标库的简称 edit是图标的名字 -->
  13.   <el-icon :size="20">
  14.     <iconEpEdit />
  15.   </el-icon>
  16.   <!--  使用本地自定义的svg -->
  17.   <!-- icon是头部(上面vite.config.js 配置的prefix: 'icon')-->
  18.   <!-- Ci是自定义图标的集合(上面vite.config.js 配置的customCollections: {
  19.       ci: FileSystemIconLoader...) vue是自定义目录下的svg文件的名称 -->
  20.   <el-icon :size="20">
  21.     <iconCiVue />
  22.   </el-icon>
  23. </template>
复制代码
静态资源动态引用:图片

vite官方推荐
使用require的可以用上面的方法更换
@vitejs/plugin-legacy

安装
必须安装 Terser,由于插件遗留版使用 Terser 举行缩小。
  1. npm i -D @vitejs/plugin-legacy terser
复制代码
  1. // vite.config.js
  2. import legacy from '@vitejs/plugin-legacy'
  3. export default {
  4.   plugins: [
  5.     legacy({
  6.       targets: ['defaults', 'not IE 11'],
  7.     }),
  8.   ],
  9. }
复制代码
vite-plugin-compression 压缩大文件

安装
  1. npm i -D vite-plugin-compression
复制代码
  1. import viteCompression from "vite-plugin-compression";
  2. plugins: [
  3.                         viteCompression({
  4.                                 verbose: true,
  5.                                 disable: false,
  6.                                 deleteOriginFile: false,
  7.                                 // 文件大于 100Kb 开启压缩
  8.                                 threshold: 100000,
  9.                                 algorithm: "gzip",
  10.                                 ext: "gz",
  11.                         }),
  12.                 ],
复制代码
压缩文件需要搭配nginx 设置,详情请点击
rollup-plugin-visualizer 这是一个依赖分析插件

参考链接:https://blog.csdn.net/g18204746769/article/details/127431733
安装
  1. pnpm install vite-plugin-cdn-import --save-dev
复制代码
  1. import { visualizer } from 'rollup-plugin-visualizer';
  2. plugins: [
  3.         visualizer()
  4. ]
复制代码
vite.config.js全部的设置

想了解设置想请点击
  1. import { defineConfig, loadEnv } from 'vite'
  2. import vue from '@vitejs/plugin-vue'
  3. import { fileURLToPath, URL } from 'node:url'
  4. import AutoImport from 'unplugin-auto-import/vite'
  5. import Components from 'unplugin-vue-components/vite'
  6. import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
  7. import { FileSystemIconLoader } from 'unplugin-icons/loaders'
  8. import Icons from 'unplugin-icons/vite'
  9. import IconsResolver from 'unplugin-icons/resolver'
  10. import { createStyleImportPlugin, ElementPlusResolve } from 'vite-plugin-style-import'
  11. import legacy from '@vitejs/plugin-legacy'
  12. import viteCompression from "vite-plugin-compression";
  13. // https://vitejs.dev/config/
  14. export default defineConfig((mode): any => {
  15.   const env = loadEnv(mode.mode, process.cwd())
  16.   return {
  17.     plugins: [
  18.       vue(),
  19.       AutoImport({
  20.         imports: ['vue', 'vue-router'], // 自动引入相关api
  21.         resolvers: [
  22.           ElementPlusResolver(),
  23.           IconsResolver({
  24.             // 设置自动导入的图标组件前缀
  25.             prefix: 'icon',
  26.             // 标识自定义图标集
  27.             customCollections: ['ci']
  28.           })
  29.         ],
  30.       }),
  31.       Components({
  32.         resolvers: [
  33.           ElementPlusResolver(),
  34.           IconsResolver({
  35.             // 设置自动导入的图标组件前缀
  36.             prefix: 'icon',
  37.             // 标识自定义图标集
  38.             customCollections: ['ci']
  39.           })
  40.         ],
  41.       }),
  42.       Icons({
  43.         compiler: 'vue3',
  44.         autoInstall: true,
  45.         // 自定义配置
  46.         customCollections: {
  47.           ci: FileSystemIconLoader('./src/assets/svg', svg => svg.replace(/^<svg /, '<svg fill="currentColor" '))
  48.         }
  49.       }),
  50.       createStyleImportPlugin({
  51.         resolves: [ElementPlusResolve()],
  52.         libs: [
  53.           {
  54.             libraryName: 'element-plus',
  55.             esModule: true,
  56.             resolveStyle: (name) => {
  57.               if (name === 'click-outside') {
  58.                 return ''
  59.               }
  60.               return `element-plus/es/components/${name.replace(/^el-/, '')}/style/css`
  61.             }
  62.           }
  63.         ]
  64.       }),
  65.       legacy({
  66.         targets: ['defaults', 'not IE 11'],
  67.       }),
  68.       viteCompression({
  69.         verbose: true,
  70.         disable: false,
  71.         deleteOriginFile: false,
  72.         // 文件大于 100Kb 开启压缩
  73.         threshold: 100000,
  74.         algorithm: "gzip",
  75.         ext: "gz",
  76.       }),
  77.     ],
  78.     resolve: {
  79.       alias: {
  80.         '@': fileURLToPath(new URL('./src', import.meta.url))
  81.       }
  82.     },
  83.     server: {
  84.       host: '0.0.0.0',
  85.       port: env.VITE_PORT,
  86.       open: false,
  87.       proxy: {
  88.         '/api': {
  89.           target: 'https://gitee.com',
  90.           ws: true,
  91.           changeOrigin: true,
  92.           rewrite: (path:string) => path.replace(/^\/gitee/, ''),
  93.         },
  94.       },
  95.     },
  96.     build: {
  97.       outDir: 'dist',
  98.       chunkSizeWarningLimit: 1500,
  99.       rollupOptions: {
  100.         output: {
  101.           entryFileNames: `assets/[name].${new Date().getTime()}.js`,
  102.           chunkFileNames: `assets/[name].${new Date().getTime()}.js`,
  103.           assetFileNames: `assets/[name].${new Date().getTime()}.[ext]`,
  104.           compact: true,
  105.           // manualChunks: {
  106.           //         vue: ['vue', 'vue-router', 'pinia'],
  107.           //         echarts: ['echarts'],
  108.           // antvG6: ['@antv/g6'],
  109.           // elementPlus: ['element-plus'],
  110.           // },
  111.           manualChunks(id:string[]) {
  112.             // if (id.includes("style.css")) {
  113.             //         // 需要单独分割那些资源 就写判断逻辑就行
  114.             //         return 'src/style.css';
  115.             // }
  116.             // if (id.includes("HelloWorld.vue")) {
  117.             //         // 单独分割hello world.vue文件
  118.             //         return 'src/components/HelloWorld.vue';
  119.             // }
  120.             // // 最小化拆分包
  121.             if (id.includes('node_modules')) {
  122.               return id
  123.                 .toString()
  124.                 .split('node_modules/')[1]
  125.                 .split('/')[0]
  126.                 .toString()
  127.             }
  128.           },
  129.         },
  130.       },
  131.       minify: 'terser',
  132.       terserOptions: {
  133.         compress: {
  134.           drop_console: mode.mode === 'prd',
  135.           drop_debugger: mode.mode === 'prd',
  136.         },
  137.       },
  138.       sourcemap: mode.mode !== 'prd',
  139.     },
  140.     css: {
  141.       devSourcemap: true,
  142.       preprocessorOptions: { css: { charset: false } },
  143.     },
  144.   }
  145. })
复制代码
找不到模块“@/xxx/xxx.vue”或其相应的类型声明。ts(2307)

设置tsconfig.json:确保你的tsconfig.json文件中包罗了对.vue文件的支持。
  1. {
  2.   "compilerOptions": {
  3.     "types": ["vue/vue3"] // 如果你使用的是Vue 3
  4.     // 或者 "types": ["vue/vue2"] 如果你使用的是Vue 2
  5.   }
  6. }
复制代码
创建类型声明文件(如果主动处理不起作用):如果主动处理不起作用,你可以手动创建一个声明文件,例如shims-vue.d.ts,并在此中添加以下内容
  1. declare module '*.vue' {
  2.   import type { DefineComponent } from 'vue'
  3.   const component: DefineComponent<{}, {}, any>
  4.   export default component
  5. }
复制代码
安装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企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

勿忘初心做自己

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表