一 Vite创建Vue3项目
1.1.创建Vue3项目
1.1.1.运行创建项目命令
# 使用 npm
npm create vite@latest
1.1.2、填写项目名称
1.1.3、选择前端框架
1.1.4、选择语法类型
1.1.5、按提示运行代码
1.1.6浏览器问 localhost:5173 预览
1.2项目结构
1.2.1vite.config.ts
1.2.2 package.json
二 src 路径别名配置
相对路径别名配置,使用 @ 代替 src
Vite 配置
import { defineConfig } from "vite"; // Vite 配置方法
import vue from "@vitejs/plugin-vue"; // Vite 官方的 Vue 插件
import { fileURLToPath, URL } from "node:url";
// https://vite.dev/config/
export default defineConfig({
plugins: [
// Vue.js 插件
vue(),
],
// 模块解析配置
resolve: {
alias: {
// 将 '@' 别名映射到 'src' 目录,简化导入路径
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
});
npm install -D @types/node
三unplugin 自动导入
Element Plus 官方文档中推荐
按需自动导入
的方式,而此需要使用额外的插件unplugin-auto-import
和unplugin-vue-components
来导入要使用的组件。所以在整合Element Plus
之前先了解下自动导入
的概念和作用
概念
为了避免在多个页面重复引入 API
或 组件
,由此而产生的自动导入插件来节省重复代码和提高开发效率。
3.1安装插件依赖
npm install -D unplugin-auto-import unplugin-vue-components
3.2vite.config.ts - 自动导入配置
先创建好 /src/types
目录用于存放自动导入函数和组件的TS类型声明文件,再进行自动导入配置
// vite.config.ts
import AutoImport from "unplugin-auto-import/vite";
import Components from "unplugin-vue-components/vite";
import path from "path";
const pathSrc = path.resolve(__dirname, "src");
plugins: [
AutoImport({
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ["vue"],
eslintrc: {
enabled: true, // 是否自动生成 eslint 规则,建议生成之后设置 false
filepath: "./.eslintrc-auto-import.json", // 指定自动导入函数 eslint 规则的文件
},
dts: path.resolve(pathSrc, "types", "auto-imports.d.ts"), // 指定自动导入函数TS类型声明文件路径
}),
Components({
dts: path.resolve(pathSrc, "types", "components.d.ts"), // 指定自动导入组件TS类型声明文件路径
}),
]
项目中:
四整合 Element Plus
参考: element plus 按需自动导入
需要完成上面一节的 自动导入 的安装和配置
4.1安装 Element Plus
npm install element-plus
4.2配置:
import { defineConfig } from "vite"; // Vite 配置方法
import vue from "@vitejs/plugin-vue"; // Vite 官方的 Vue 插件
import { fileURLToPath, URL } from "node:url";
import Components from "unplugin-vue-components/vite"; // 自动导入 Vue 组件
import AutoImport from "unplugin-auto-import/vite"; // 自动导入 Vue 相关 API
import { ElementPlusResolver } from "unplugin-vue-components/resolvers"; // Element Plus 组件解析器
// https://vite.dev/config/
export default defineConfig({
plugins: [
// Vue.js 插件
vue(),
// 自动导入常用的 Vue API,比如 'ref' 和 'vue-router'
AutoImport({
imports: ["vue", "vue-router"], // 自动导入 Vue 和 Vue Router 的 API
resolvers: [ElementPlusResolver()], // 自动导入 Element Plus 的 API
eslintrc: {
enabled: true, // 启用 ESLint 配置生成
filepath: "./.eslintrc-auto-import.json", // 指定一个生成的 ESLint 配置文件路径
},
}),
// 自动导入组件(如 Element Plus 组件)
Components({
resolvers: [ElementPlusResolver()],
}),
],
// 模块解析配置
resolve: {
alias: {
// 将 '@' 别名映射到 'src' 目录,简化导入路径
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
});
4.3测试:
<div>
<el-button type="success">Success</el-button>
<el-button type="info">nfo</el-button>
<el-button type="warning">Warning</el-button>
<el-button type="danger">Danger</el-button>
</div>
五Element Plus主题色定制(通过scss变量替换方案)
一款CSS预处理语言,SCSS 是 Sass 3 引入新的语法,其语法完全兼容 CSS3,并且继承了 Sass 的强大功能。
如果通过scss变量替换方案来定制Element Plus主题色,按照如下步骤:
- 安装sass:使用命令npm install sass -D
- 准备定制样式文件:在项目下面新增文件styles/themeVar.scss
- 对Element Plus样式进行覆盖:通知Element Plus采用scss语言,再导入定制的scss文件覆盖
5.1安装依赖
npm i -D sass
5.2新建文件/src
/styles/themeVar.scss,并定义scss变量
/* 自定义 element-plus 主题 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with (
$colors: (
'white': #ffffff,
'black': #000000,
'primary': (
'base': #69642c,
),
'success': (
'base': #0e4600,
),
'warning': (
'base': #e7c79f,
),
'danger': (
'base': #fd0000,
),
'error': (
'base': #440303,
),
'info': (
'base': #3aa176,
)
),
);
5.3vite.config.js
1自动导入配置
将vite.config.js文件中的Components修改为如下形式:
Components({
resolvers: [
// 配置Element Plus采用saas样式配色系统
ElementPlusResolver({ importStyle: 'sass' }),
],
})
2自动导入定制化样式文件进行样式覆盖
export default defineConfig(({ command, mode }) => {
// ...
return {
//...
css: {
preprocessorOptions: {
scss: {
// 按需导入自定义主题
additionalData: `@use "@/styles/themeVar.scss" as *;`
}
}
},
}
})
5.4 测试
修改配置后,执行npm run dev重启,info按钮的主题色修改为绿色了:
六reset.scss 整合到vue3中
测试:
reset.scss
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
font-weight: normal;
}
html {
box-sizing: border-box;
width: 100%;
height: 100%;
line-height: 1.5;
tab-size: 4;
text-size-adjust: 100%;
}
body {
width: 100%;
height: 100%;
margin: 0;
font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB",
"Microsoft YaHei", "微软雅黑", Arial, sans-serif;
line-height: inherit;
-moz-osx-font-smoothing: grayscale;
-webkit-font-smoothing: antialiased;
text-rendering: optimizelegibility;
}
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
margin: 0;
padding: 0;
border: 0;
font: inherit;
vertical-align: baseline;
box-sizing: border-box; /* Ensure padding and borders are included in element sizes */
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* 使表格兼容safari,不错位 */
.el-table__body {
width: 100%;
table-layout: fixed;
}
七 整合svg
通过 vite-plugin-svg-icons 插件整合
Iconfont
第三方图标库实现本地图标
八整合 Pinia
Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。
参考:Pinia 官方文档
8.1安装依赖
npm install pinia
npm install pinia-plugin-persistedstate // 持久化插件
8.2 数据持久化
import { createPinia } from "pinia"
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate) // 数据持久化
export default pinia
8.3main.ts
引入 pinia
// src/main.ts
import { createPinia } from "pinia";
import App from "./App.vue";
createApp(App).use(createPinia()).mount("#app");
8.3定义 Store
根据 Pinia 官方文档-核心概念 描述 ,Store 定义分为选项式
和组合式
, 先比较下两种写法的区别:
选项式 Option Store | 组合式 Setup Store |
---|---|
至于如何选择,官方给出的建议 :选择你觉得最舒服的那一个就好
。
这里选择组合式,新建文件 src/store/counter.ts
// src/store/counter.ts
import { defineStore } from "pinia"
export const useCounterStore = defineStore(
"counter",
() => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
function decrement() {
count.value--
}
return {
count,
doubleCount,
increment,
decrement
}
},
{
persist: {
// 不需要持久化,配置项 persist: false
enabled: false,
storage: sessionStorage, // 可以是 localStorage, sessionStorage 或 window.localStorage
key: "counter_key" // 状态的键名
}
}
)
父组件
<!-- src/App.vue -->
<script setup lang="ts">
import HelloWorld from "@/components/HelloWorld.vue";
import { useCounterStore } from "@/stores/counter.ts";
const counterStore = useCounterStore();
</script>
<template>
<h1 class="text-3xl">vue3-element-admin-父组件</h1>
<el-button type="primary" @click="counterStore.increment">count++</el-button>
<HelloWorld />
</template>
子组件
<!-- src/components/HelloWorld.vue -->
<script setup lang="ts">
import { useCounterStore } from "@/stores/counter.ts";
const counterStore = useCounterStore();
</script>
<template>
<el-card class="text-left text-white border-white border-1 border-solid mt-10 bg-[#242424]" >
<template #header> 子组件 HelloWorld.vue</template>
<el-form>
<el-form-item label="数字:"> {{ counterStore.count }}</el-form-item>
<el-form-item label="加倍:"> {{ counterStore.double }}</el-form-item>
</el-form>
</el-card>
</template>
效果预览
九环境变量
Vite 环境变量主要是为了区分开发、测试、生产等环境的变量
参考: Vite 环境变量配置官方文档
env配置文件
项目根目录新建 .env.development
、.env.production
-
开发环境变量配置:.env.development
# 变量必须以 VITE_ 为前缀才能暴露给外部读取
VITE_APP_TITLE = 'vue3-element-admin'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/dev-api'
- 生产环境变量配置:.env.production
VITE_APP_TITLE = 'vue3-element-admin'
VITE_APP_PORT = 3000
VITE_APP_BASE_API = '/prod-api'
十反向代理解决跨域
跨域原理
浏览器同源策略: 协议、域名和端口都相同是同源,浏览器会限制非同源请求读取响应结果。
本地开发环境通过 Vite
配置反向代理解决浏览器跨域问题,生产环境则是通过 nginx
配置反向代理 。
vite.config.ts
配置代理
表面肉眼看到的请求地址: http://localhost:3000/dev-api/api/v1/users/me
真实访问的代理目标地址: http://vapi.youlai.tech/api/v1/users/me
十一 vue-router 静态路由
11.1安装 vue-router
npm install vue-router@next
11.2全局注册路由实例
// main.ts
import router from "@/router";
app.use(router).mount('#app')
11.3路由实例
- views中创建DemoView.vue。Home
- 创建路由实例
import { createRouter, createWebHistory } from "vue-router"
import HomeView from "@/views/HomeView.vue"
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: [
{
path: "/",
name: "home",
component: HomeView
},
{
path: "/demo",
name: "demo",
// route level code-splitting
// this generates a separate chunk (About.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import("../views/DemoView.vue")
}
]
})
export default router
11.4测试
src/App.vue
<script setup lang="ts">
onMounted(() => {
console.log("hello world1");
});
</script>
<template>
<el-config-provider :locale="zhCn">
<header>
<div class="wrapper">
<nav>
<RouterLink to="/">Home</RouterLink> <span>|</span>
<RouterLink to="/demo">demo</RouterLink>
</nav>
</div>
</header>
<RouterView />
</el-config-provider>
</template>
<style scoped></style>