使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件
前言
记录一下使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件。
一、使用 Vite 创建 Vue3+TS 项目
1.新建一个 temp 文件夹
(1)在桌面新建一个 temp 文件夹,然后在 VS Code 中打开此文件夹,打开一个终端;
2.创建一个 Vue3 项目工程
(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
> VueReactPreactLitSvelteOthers(3) 选择数据类型,回车
? Select a variant: » - Use arrow-keys. Return to submit.
> TypeScriptJavaScriptCustomize with create-vue ↗Nuxt ↗(4) 创建完成,运行项目
Done. Now run: cd vite-vue3-ts-less-element_plusnpm installnpm run devPS C:\Users\Administrator\Desktop\temp>
二、解决一下配置问题
1.修改配置文件
(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"]
}
2.解决报错问题
(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",},
}
三、整合 ElementPlus 组件库
(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>
四、封装并使用 Axios 插件
(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=10001const 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>
五、整合 vue-router、pinia、less 等插件
1.安装较新版本的 vue-router 路由插件
(1)使用方式和以前一样
npm view vue-router versions --json
npm i vue-router@4.2.0
2.安装 pinia 插件
(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 = useILoveYouStorereturn {useILoveYouStore }},
}
</script>
<!-- / Vue3 --><!-- ^ Vue3+语法糖 -->
<script setup>const useILoveYouStore = useILoveYouStore
</script>
<!-- / Vue3+语法糖 -->
3.安装 less 插件
(1)导入依赖后,就可以在页面任意使用了
npm i less -D
以上部分内容借鉴其他文章。
相关文章:
使用 Vite 创建 Vue3+TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件
前言 记录一下使用 Vite 创建 Vue3TS 项目并整合 ElementPlus、Axios、Pinia、Less、Vue-router 等组件或插件。 一、使用 Vite 创建 Vue3TS 项目 1.新建一个 temp 文件夹 (1)在桌面新建一个 temp 文件夹,然后在 VS Code 中打开此文件夹&…...
Flink随笔 20241203 Flink重点内容
Flink 是一个强大的流处理框架,它的设计理念是高吞吐量、低延迟的流式计算。你提到的这些重点是 Flink 的核心组成部分,下面我将详细解析每一个方面。 1. 窗口(Window) 窗口是 Flink 流处理中一个非常重要的概念,主要…...

shell脚本实战
学习视频来自B站UP主泷羽sec,如涉及侵权马上删除文章。 笔记只是方便学习,以下内容只涉及学习内容,切莫逾越法律红线。 安全见闻,包含了各种网络安全,网络技术,旨在明白自己的渺小,知识的广博&a…...
【机器学习】分类任务: 二分类与多分类
二分类与多分类:概念与区别 二分类和多分类是分类任务的两种类型,区分的核心在于目标变量(label)的类别数: 二分类:目标变量 y 只有两个类别,通常记为 y∈{0,1} 或 y∈{−1,1}。 示例ÿ…...
FreeSWITCH mod_conference 的按键会控
又是一篇命题作文 mod_conference 官方文档: https://developer.signalwire.com/freeswitch/FreeSWITCH-Explained/Modules/mod_conference_3965534/ 英文不好的可以看中文: http://www.freeswitch.org.cn/books/references/1.7-mod_conference.html…...

串口工作方式
串口工作方式 方式0方式0输出方式0输入 方式1方式1输出方式1输入 方式2或方式3输出输入 串口使用方法如何计算波特率串口初始化步骤串口回传实验模拟printf实验串口接收数据不丢失实验 方式0 方式 0 时,串行口为同步移位寄存器的输入输出方式。主要用于扩展并行输 入…...
统计Nginx的客户端IP,可以通过分析Nginx的访问日志文件来实现
要统计Nginx的客户端IP,可以通过分析Nginx的访问日志文件来实现。以下是一些常见的方法和步骤: 一、通过命令行工具统计 查看Nginx访问日志: Nginx的访问日志通常默认存储在/var/log/nginx/access.log,但具体位置可能因安装和配置…...

Apache Airflow 快速入门教程
Apache Airflow已经成为Python生态系统中管道编排的事实上的库。与类似的解决方案相反,由于它的简单性和可扩展性,它已经获得了普及。在本文中,我将尝试概述它的主要概念,并让您清楚地了解何时以及如何使用它。 Airflow应用场景 …...

42 基于单片机的智能浇花系统
目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机,采样DHT11温湿度传感器检测温湿度,通过LCD1602显示 4*4按键矩阵可以设置温度湿度阈值,温度大于阈值则开启水泵,湿度大于阈值则开启风扇…...
乐橙云小程序插件接入HbuilderX
乐橙插件使用: 1.配置app.json文件,uniapp中在mainfest.json中配置 https://uniapp.dcloud.net.cn/collocation/manifest.html#mp-weixin ** 2、集成插件页面.json文件 ** uniapp在 pages.json 对应页面的 style -> usingComponents 引入组件&…...
VoCo-LLaMA: Towards Vision Compression with Large Language Models
视觉语言模型在各种多模态任务上取得了显著的成功,但经常受到有限上下文窗口和处理高分辨率图像输入和视频的高计算成本的瓶颈。视觉压缩可以通过减少视觉令牌数量避免该问题。先前方法使用额外模块压缩视觉令牌并强制LLM理解压缩的令牌。然而,LLM对视觉…...

Vue+vite 组件开发的环境准备
一.nodejs安装 进入Node.js 官网(Node.js — Run JavaScript Everywhere),点击下载。 双击打开,进行安装 双击打开后,点击 next(下一步),后面也是一直点击 next 无其他设置,直到 …...

基于社区发现的GraphRAG思路
GraphRAG出自2024年4月的论文《From Local to Global: A Graph RAG Approach to Query-Focused Summarization》,其代码也在2024年年中开源 。它在用图结构来完成RAG时,使用社区这个概念并基于社区摘要来回答一些概括性的问题。 Graph RAG流程如论文图1所…...
react学习记录
一、目录结构react优秀代码之react目录结构简洁之道React 作为一个库,不会决定你如何组织项目的结构。这是件好事,因为这样 - 掘金【React】项目的目录结构全面指南_react项目结构-CSDN博客 1、创建项目:开发文档 Getting Started | Create…...

Day2——需求分析与设计
教师端签到应用软件的需求分析; 产品经理如何写好产品需求文档(附模板) 需求分析是软件开发过程中的关键步骤,它确保了开发的软件能够满足用户的需求。以下是进行需求分析的具体步骤: 1. 确定分析目标 明确教师端签到…...

VScode离线下载扩展安装
在使用VScode下在扩展插件时,返现VScode搜索不到插件,网上搜了好多方法,都不是常规操作,解决起来十分麻烦,可以利用离线下载安装的方式安装插件!亲测有效!!! 1.找到VScod…...

【机器学习】机器学习的基本分类-监督学习-决策树(Decision Tree)
决策树是一种树形结构的机器学习模型,适用于分类和回归任务。它通过一系列基于特征的条件判断来将数据分割为多个子区域,从而预测目标变量的值。 1. 决策树的结构 根节点(Root Node) 决策树的起点,包含所有样本。根据某…...

【第 1 章 初识 C 语言】1.8 使用 C 语言的 7 个步骤
目录 1.8 使用 C 语言的 7 个步骤 1.8.1 第 1 步:定义程序的目标 1.8.2 第 2 步:设计程序 1.8.3 第 3 步:编写代码 1.8.4 第 4 步:编译 1.8.5 第 5 步:运行程序 1.8.6 第 6 步:测试和调试程序 1.8.…...
Docker 使用 Dockerfile 文件打包部署前端项目
编写 Dockerfile 文件: FROM nginx:latest ADD dist /etc/nginx/html/dist COPY nginx.conf /etc/nginx/nginx.conf ENV PATH /usr/sbin:$PATH EXPOSE 80 ENTRYPOINT ["nginx"] CMD ["-g","daemon off;"]编写 nginx.conf 文件&#…...
HTML-全
. CSS css后缀名的文件被html引用 在HTML中,CSS(层叠样式表,Cascading Style Sheets)是一种用于设置网页上的文本内容、图片布局和版面设计等外观样式的样式表语言。简单来说,CSS定义了HTML元素如何显示在浏览器中。…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...

USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

力扣热题100 k个一组反转链表题解
题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测
uniapp 中配置 配置manifest 文档:manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号:4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...