赞
踩
记录一下使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件。
(1)在桌面新建一个 temp 文件夹,然后在 VS Code 中打开此文件夹,打开一个终端;
(1)具体操作如下:
- npm create vite@latest
-
- (1) 输入项目名,如: vite-vue3-ts-less-element_plus ,然后回车
- ? Project name: » vite-vue3-ts-less-element_plus
-
- (2) 选择 Vue 框架,回车
- ? Select a framework: » - Use arrow-keys. Return to submit.
- Vanilla
- > Vue
- React
- Preact
- Lit
- Svelte
- Others
-
- (3) 选择数据类型,回车
- ? Select a variant: » - Use arrow-keys. Return to submit.
- > TypeScript
- JavaScript
- Customize with create-vue ↗
- Nuxt ↗
-
- (4) 创建完成,运行项目
- Done. Now run:
-
- cd vite-vue3-ts-less-element_plus
- npm install
- npm run dev
-
- PS C:\Users\Administrator\Desktop\temp>
(1)修改【vite.config.ts】文件
修改前:
- import { defineConfig } from 'vite'
- import vue from '@vitejs/plugin-vue'
-
- // https://vitejs.dev/config/
- export default defineConfig({
- plugins: [vue()],
- })
修改后:
- import { defineConfig } from 'vite'
- import vue from '@vitejs/plugin-vue'
- import { resolve } from 'path'
-
- /**
- * 详情见 vitejs 文档:https://vitejs.dev/config/
- */
- export default defineConfig({
- plugins: [vue()],
- base: '/xxx/', // 配置相对地址或绝对地址,此处应为绝对地址,若将 Web 部署到 Nginx 所在的目录为 nginx-1.17.8/html/xxx ,则这个 base 的值就为 /xxx/
- resolve: {
- alias: {
- '@': resolve(__dirname, './src'),
- assets: resolve(__dirname, './src/assets'),
- }
- },
- server: {
- host: '', // 主机
- port: 5173, // 端口
- proxy: {
- // 项目 v1 的服务端接口地址
- '/v1/api': {
- target: 'http://127.0.0.1:8091/',
- changeOrigin: true,
- secure: false,
- ws: true
- },
-
- // 项目 v2 的服务端接口地址
- '/v2/api': {
- target: 'http://127.0.0.1:8092/',
- changeOrigin: true,
- secure: false,
- ws: true
- },
-
- // 项目 v3 的服务端接口地址
- '/v3/api': {
- target: 'http://127.0.0.1:8093/',
- changeOrigin: true,
- secure: false,
- ws: true
- },
-
- // // 默认服务端接口地址
- // '/': {
- // target: 'http://127.0.0.1:8090/',
- // changeOrigin: true,
- // secure: false,
- // ws: false
- // }
- }
- }
- })
(2)修改【tsconfig.json】文件
修改前:
- {
- "compilerOptions": {
- "target": "ES2020",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "skipLibCheck": true,
-
- /* Bundler mode */
- "moduleResolution": "bundler",
- "allowImportingTsExtensions": true,
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "preserve",
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
- "references": [{ "path": "./tsconfig.node.json" }]
- }
修改后:
- {
- "compilerOptions": {
- "allowJs": true, // xxx.vue is a JavaScript file. Did you mean to enable the 'allowJs' option?
- "target": "ES2020",
- "useDefineForClassFields": true,
- "module": "ESNext",
- "lib": ["ES2020", "DOM", "DOM.Iterable"],
- "skipLibCheck": true,
-
- /* Bundler mode */
- "moduleResolution": "Node",
- "allowImportingTsExtensions": true,
- "resolveJsonModule": true,
- "isolatedModules": true,
- "noEmit": true,
- "jsx": "preserve",
-
- /* Linting */
- "strict": true,
- "noUnusedLocals": true,
- "noUnusedParameters": true,
- "noFallthroughCasesInSwitch": true
- },
- "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
- "references": [{ "path": "./tsconfig.node.json" }]
- }
(3)修改【tsconfig.node.json】文件
修改前:
- {
- "compilerOptions": {
- "composite": true,
- "skipLibCheck": true,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "allowSyntheticDefaultImports": true
- },
- "include": ["vite.config.ts"]
- }
修改后:
- {
- "compilerOptions": {
- "composite": true,
- "skipLibCheck": true,
- "module": "ESNext",
- "moduleResolution": "bundler",
- "allowSyntheticDefaultImports": true
- },
- "include": ["vite.config.ts"]
- }
(1)找不到名称“__dirname”。
原因:path 模块是 node.js 的内置模块,而 node.js 默认不支持 ts 文件的
解决:安装 【@type/node】 依赖包【npm install @types/node --save-dev】
(2)未设置 "baseUrl" 时,不允许使用非相对路径。是否忘记了前导 "./"?。
解决:在【tsconfig.json】文件添加【baseUrl】配置
- {
- "compilerOptions": {
- ...
- "baseUrl": ".", // 未设置 "baseUrl" 时,不允许使用非相对路径。
- "paths": {
- "@": ["src"],
- "@/*": ["src/*"]
- }
- },
- ...
- }
(3)找不到模块“./App.vue”或其相应的类型声明。
解决:在【src】目录新建【shims-vue.d.ts】文件,文件内容为以下代码
- /* eslint-disable */
- declare module '*.vue' {
- import type { DefineComponent } from 'vue'
- const component: DefineComponent<{}, {}, any>
- export default component
- }
(4)Vite 项目如何配置相对地址或绝对地址?
解决:在【vite.config.ts】文件中加上【base】属性,值可以为相对地址【'./'】,也可以为绝对地址【'/xxx/'】
- export default defineConfig({
- plugins: [vue()],
- base: '/xxx/', // 配置相对地址或绝对地址,此处应为绝对地址,若将 Web 部署到 Nginx 所在的目录为 nginx-1.17.8/html/xxx ,则这个 base 的值就为 /xxx/
- resolve: {
- alias: {
- '@': resolve(__dirname, './src'),
- assets: resolve(__dirname, './src/assets'),
- }
- },
- })
(5)当【npm run build】打包时,报错,提示信息为【Did you mean to enable the 'allowJs' option?】
解决:在【tsconfig.json】文件增加 allowJs 配置
- {
- "compilerOptions": {
- "allowJs": true, // xxx.vue is a JavaScript file. Did you mean to enable the 'allowJs' option?
- // ...
- }
- }
(6)因项目未指定 ESlint 解析器,导致一些语法解析错误
解决:项目根目录新建【.eslintrc.js】文件,注意文件名开头有个点,然后就完美解决
- module.exports = {
- env: {
- browser: true,
- es2020: true,
- node: true,
- },
- extends: ["plugin:vue/vue3-recommended", "plugin:prettier/recommended"],
- parserOptions: {
- ecmaVersion: "latest",
- parser: "@typescript-eslint/parser", // 指定ESlint的解析器
- sourceType: "module",
- },
- plugins: ["vue", "@typescript-eslint", "prettier"],
- rules: {
- "prettier/prettier": "error",
- },
- }
(1)具体操作如下:
- 第一步:导入依赖包
- npm i element-plus -D
-
- 第二步:在项目的 src 目录新建 plugins 文件夹,里面再新建 element-plus.ts 文件,写入以下代码
- import ElementPlus from 'element-plus'
- import 'element-plus/theme-chalk/index.css'
- import zhCn from 'element-plus/es/locale/lang/zh-cn' // 汉化 element-plus 组件
-
- export default (app: any) => {
- app.use(ElementPlus, {
- locale: zhCn,
- })
- }
-
- 第三步:在项目的 main.ts 文件夹引入和使用该插件和注册图标,即整合完成,main.ts 文件如下所示
- import { createApp } from 'vue'
- import App from './App.vue'
- import router from './router'
- import store from './store'
-
- const app = createApp(App)
-
- // 引入 ElementPlus 插件(npm i element-plus)
- import ElementPlusPlugin from '@/plugins/element-plus'
-
- // 全局注册 ElementPlus 图标组件(npm install @element-plus/icons-vue)
- import * as ElementPlusIcons from '@element-plus/icons-vue'
- for(const [key, component] of Object.entries(ElementPlusIcons)) {
- app.component(key, component)
- }
-
- app
- .use(store)
- .use(router)
- .use(ElementPlusPlugin)
- .mount('#app')
-
-
- 第四步:验证整合成功,在项目的 App.vue 文件夹,例如写个按钮标签,保存即可看到效果,App.vue 文件如下所示
- <template>
- <div style="display: flex; padding: 100px; align-item: center;">
- <el-button size="small" type="primary" icon="UploadFilled" @click="void (0)">
- 点击事件
- </el-button>
-
- <el-button size="small" type="primary" plain @click="void (0)">
- <el-icon :size="18">
- <UploadFilled />
- </el-icon>
- <span>点击事件</span>
- </el-button>
-
- <el-button size="small" type="primary" circle>
- <el-icon :size="18">
- <UploadFilled />
- </el-icon>
- </el-button>
-
- <el-icon :size="20" style="color: #409eff; cursor: pointer" @click="void (0)">
- <UploadFilled />
- </el-icon>
- </div>
- </template>
-
- <style lang="less">
- * {
- margin: 0;
- padding: 0;
- }
-
- html, body {
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- border: none;
- }
-
- #app {
- width: 100%;
- height: 100%;
- }
- </style>
(1)导入相关依赖,封装 axios 工具并且使用;
- 第一步:导入 axios 和 nprogress 依赖包
- npm i axios
- npm i nprogress
- npm i --save-dev @types/nprogress
-
- 第二步:在 src 目录新建 utils 文件夹,再新建 requestUtil.ts 文件,写上以下代码
- import axios from 'axios'
- import Nprogress from 'nprogress'
- import 'nprogress/nprogress.css'
- import { ElMessage } from 'element-plus'
-
- const http = axios.create({
- baseURL: '',
- timeout: 300 * 1000, // 请求超时时间设置为300秒
- })
-
- const NETWORK_ERROR = '网络错误,请联系开发人员'
-
- /**
- * 请求拦截器
- */
- http.interceptors.request.use((req) => {
- console.log('请求拦截器 =>', req)
- Nprogress.start()
- return req;
- }, (error) => {
- Nprogress.done()
- return Promise.reject(error);
- });
-
- /**
- * 响应拦截器
- */
- http.interceptors.response.use(function (res) {
- console.log('响应拦截器 =>', res)
- Nprogress.done()
- if (res.status == 200) {
- return res.data
- } else {
- ElMessage.error((NETWORK_ERROR))
- return Promise.reject(NETWORK_ERROR)
- }
- });
-
- export default http
-
- 第三步:在 src 目录新建 api 文件夹,里面再新建 UserManage 文件夹,里面再新建 index.ts 文件,写上以下代码
- import http from '@/utils/requestUtil'
-
- export default {
- /**
- * 根据用户ID查询用户信息
- * 请服务端先准备好此接口:http://localhost:8080/v1/api/getUserById?userId=10001
- */
- getUserById(userId: any) {
- return http.get(`/v1/api/getUserById?userId=${userId}`)
- },
-
- /**
- * 保存用户信息
- */
- saveUser(data: any) {
- return http.post(
- '/v1/api/saveUser',
- data,
- {
- headers: {
- 'Content-Type': 'application/json'
- },
- }
- )
- },
- }
-
- 第四步:在 main.ts 文件引入HTTP请求工具并配置为全局方法
- // 引入HTTP请求工具并配置为全局方法
- import axios from 'axios'
- import UserManage_Api from '@/api/UserManage/index'
- app.config.globalProperties.$http = {
- ...UserManage_Api,
- }
- app.config.globalProperties.$axios = axios
(2)接口请求示例,在 App.vue 文件加上接口请求代码,如下所示;
- <template>
- <div style="display: flex; padding: 100px; align-item: center;">
- <el-button size="small" type="primary" icon="UploadFilled" @click="void (0)">
- 点击事件
- </el-button>
-
- <el-button size="small" type="primary" plain @click="void (0)">
- <el-icon :size="18">
- <UploadFilled />
- </el-icon>
- <span>点击事件</span>
- </el-button>
-
- <el-button size="small" type="primary" circle>
- <el-icon :size="18">
- <UploadFilled />
- </el-icon>
- </el-button>
-
- <el-icon :size="20" style="color: #409eff; cursor: pointer" @click="void (0)">
- <UploadFilled />
- </el-icon>
- </div>
- </template>
-
- <script>
- export default {
- data: () => ({
- content: ''
- }),
- created() {
- this.getUserById(10001)
- },
- methods: {
- /**
- * 根据用户ID查询用户信息
- */
- async getUserById(userId) {
- // http://127.0.0.1:8080/v1/api/getUserById?userId=10001
- const res = await this.$http.getUserById(userId)
- console.log(res)
- },
- }
- }
- </script>
-
- <style>
- * {
- margin: 0;
- padding: 0;
- }
-
- html, body {
- width: 100%;
- height: 100%;
- margin: 0;
- padding: 0;
- border: none;
- }
-
- #app {
- width: 100%;
- height: 100%;
- }
- </style>
(1)使用方式和以前一样
- npm view vue-router versions --json
- npm i vue-router@4.2.0
(1)听说 Vuex 拥抱 ts 没有 Pinia 好,详情使用方式见官网(Pinia 中文文档)
npm i pinia
(2)在 src 目录新建 store 文件夹,再新建 index.ts 文件, 文件内容如下
- import { createPinia } from 'pinia'
- const store = createPinia()
- export default store
(3)再新建 ILoveYouStore 文件,文件内容如下
- import { defineStore } from 'pinia'
-
- /**
- * 爱老虎油状态管理仓库
- */
- export const ILoveYouStore = defineStore({
- id: 'ILoveYouStore', // ID必填且唯一
- state: () => {
- return {
- xxx: 'Hello,World!',
- yyy: 520,
- }
- },
- getters: {
-
- },
- actions: {
- setXxx(xxx: string) {
- this.xxx = xxx
- },
- }
- })
(4) 如下为在某个 vue 页面,简单使用 pinia 状态管理仓库
- <script>
- // 引入爱老虎油状态管理仓库
- import { ILoveYouStore } from '@/store/ILoveYouStore'
- const useILoveYouStore = ILoveYouStore()
- </script>
-
- 然后随便用Vue2、Vue3、Vue3+语法糖来定义数据
- <!-- ^ Vue2 -->
- <template>
- <div v-if="useILoveYouStore.$state.xxx != null">{{ useILoveYouStore.$state.xxx }}</div>
- <div v-else>{{ useILoveYouStore.$state }}</div>
- </template>
-
- <script>
- export default {
- data: () => ({
- useILoveYouStore: useILoveYouStore,
- }),
- }
- </script>
- <!-- / Vue2 -->
-
- <!-- ^ Vue3 -->
- <script>
- import { ref } from 'vue';
- export default {
- setup() {
- const useILoveYouStore = useILoveYouStore
-
- return { useILoveYouStore }
- },
- }
- </script>
- <!-- / Vue3 -->
-
- <!-- ^ Vue3+语法糖 -->
- <script setup>
- const useILoveYouStore = useILoveYouStore
- </script>
- <!-- / Vue3+语法糖 -->
(1)导入依赖后,就可以在页面任意使用了
npm i less -D
到此,使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios 等组件或插件的工作已全部完成,传送门如下。
vite-vue3-ts-less-element_plus: 这是一个基于 Vite 构建的 Vue3 + TS 项目,以及整合了 Less、ElementPlus 等组件或插件。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。