Vue3 创建项目
npm create vite@latest
安装依赖,并启动应用:
npm install
npm run dev
项目结构
一个 Vue 3 项目通常包含以下文件和文件夹:
javascript
my-vue-app/
├── node_modules/ # 项目依赖的第三方库
├── public/ # 静态资源文件夹
│ └── ... # 其他静态资源(如图片、字体等)
├── src/ # 项目源代码
│ ├── assets/ # 静态资源(如图片、字体等)
│ ├── components/ # 可复用的 Vue 组件
│ ├── views/ # 页面级组件
│ ├── App.vue # 根组件
│ ├── main.js # 项目入口文件
│ ├── router/index.js # 路由配置
│ ├── store/index.js # Vuex 状态管理配置
│ └── ... # 其他配置和资源
├── index.html # 应用的 HTML 模板
├── package.json # 项目配置和依赖管理
├── package-lock.json # 依赖的精确版本锁定文件
└── README.md # 项目说明文档
index.html
Vue 应用的 HTML 模板文件。
Vue 会将应用挂载到 <div id="app"></div> 中。
html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
src\main.js
Vue 应用的入口文件。
src/main.js 负责创建 Vue 应用实例,并将根组件(通常是 App.vue)挂载到 index.html 中的 div#app 中。
javascript
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)//定义一个常量app
app.mount('#app')
src\components
包含可复用的 Vue 组件

src\views
包含页面级组件,通常与路由配置一起使用

src\router\index.js
Vue Router 的配置文件,用于定义路由。
javascript
import { createRouter,createWebHistory } from "vue-router"
const routes = [
{
path: "/", // http://localhost:5174
// alias:"/home", //定义别名 http://localhost:5174/home
alias:["/home","/index"],
// component: () => import("../views/index.vue")
component: () => import("@/views/index.vue")
},
]
const router = createRouter({
//使用url的#符号之后的部分模拟url路径的变化,因为不会触发页面刷新,所以不需要服务端支持
//history: createWebHashHistory(),
history: createWebHistory(),
routes
})
export default router
src\store\index.js
Vuex 状态管理的配置文件(如果使用 Vuex)
javascript
import { createStore } from 'vuex';
export default createStore({
state: {
message: 'Hello, Vuex!',
},
mutations: {
setMessage(state, newMessage) {
state.message = newMessage;
},
},
actions: {
updateMessage({ commit }, newMessage) {
commit('setMessage', newMessage);
},
},
});
(如果使用 pinia)
javascript
import { reactive, ref } from 'vue'
import { defineStore } from 'pinia'
/*
定义一个基于 Pinia 的 Store
第1个参数 web 是 useWebStore 在应用中的唯一标识符(ID)
第2个参数是 Setup函数 或 Option对象
*/
export const useWebStore = defineStore('web', () => {
//定义一个响应式对象,存储网站信息
const web = reactive({
title: "bilibili",
url: "bilibili.com"
})
//定义一个响应式引用,存储用户数
const users = ref(1000)
//定义方法
const userAdd = () => {
users.value++
}
return {
web,
users,
userAdd
}
},
{
//持久化存储到 lonpmcalStorage 中
persist: true
}
)
package.json
项目的配置文件,包含项目的元数据、依赖和脚本。
javascript
{
"name": "demo1",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"element-plus": "^2.9.11",
"pinia": "^3.0.2",
"pinia-plugin-persistedstate": "^4.3.0",
"vue": "^3.5.13",
"vue-router": "^4.5.1"
},
"devDependencies": {
"@iconify-json/ep": "^1.2.2",
"@vitejs/plugin-vue": "^5.2.3",
"unplugin-auto-import": "^19.3.0",
"unplugin-icons": "^22.1.0",
"unplugin-vue-components": "^28.7.0",
"vite": "^6.3.5"
}
}
Vue 组件的基本结构
Vue 3 Snippets
这个插件包含了所有的 Vue.js 2 和 Vue.js 3 的 api 对应的代码片段。

生成vue基本模板代码

快速生成Vue.js相关代码

Vue VSCode Snippets(常用


自定义模板:
C:\Users\用户名\.vscode\extensions\sdras.vue-vscode-snippets-3.2.0\snippets\vue.json

Vite 教程
创建 Vite 项目
Vite 提供了多种方式来创建新项目,最简单的方式是使用命令行工具。
打开终端或命令行工具,运行以下命令来创建一个新的 Vite 项目:
javascript
npm create vite@latest

按照提示输入项目名称并选择模板。

Vite 提供了多种模板,包括:
-
vanilla: 纯 JavaScript 项目
-
vue: Vue.js 项目
-
react: React 项目
-
preact: Preact 项目
-
lit: Lit 项目
-
svelte: Svelte 项目
-
**solid:**Solid 项目
-
**qwik :**Qwik 组件与 React 组件非常相似
-
**angular:**angular项目
-
**marko:**Marko项目

选择一个变体:

启用 rolldown-vite(实验性):No

Install with npm and start now? Yes




Vite 常用功能
Vite 提供了丰富的功能,可以帮助你更高效地开发前端应用。
1. 使用 CSS 预处理器
Vite 支持使用 Sass、Less、Stylus 等 CSS 预处理器。
要使用这些预处理器,你需要先安装相应的依赖:
Sass:
javascript
npm install -D sass
Less:
javascript
npm install -D less
Stylus:
javascript
npm install -D stylus
2.使用静态资源
Vite 支持使用图片、字体等静态资源。
可以将这些资源放在public目录下,或者使用 import 语句导入资源。
1.引入 public 中的资源永远应该使用根绝对路径,例如:public/icon.png 应该在源码中被引用为 /icon.png。
2.public 中的资源不应该被 JavaScript 文件引用。
3.使用 import 语句
javascript
<script setup>
//导入子组件
import Header from "@/components/header.vue"
import Footer from "@/components/footer.vue"
</script>
<template>
<!-- 共享的Header组件 -->
<Header/>
<!-- 根据不同的子路由加载不同子页面 -->
<router-view />
<!-- 共享的Footer组件 -->
<Footer/>
</template>
<style scoped>
</style>
4.使用环境变量
Vite 支持使用环境变量来配置不同的环境。

javascript
# 页面标题
VITE_APP_TITLE =
# 开发环境配置
VITE_APP_ENV =
# 开发环境
VITE_APP_BASE_API =
# 应用访问路径 例如使用前缀 /admin/
VITE_APP_CONTEXT_PATH = '/'
5.使用插件
安装插件:
在 vite.config.js 文件中配置插件:
配置说明:
javascript
// 导入 defineConfig 函数,用于定义 Vite 配置
import { defineConfig } from 'vite';
// 导入 Vue 插件,用于支持 Vue 项目
import vue from '@vitejs/plugin-vue';
// 导入 path 模块,用于处理路径
import path from 'path';
// 使用 defineConfig 定义 Vite 配置
export default defineConfig({
// 项目根目录,默认为当前工作目录
root: path.resolve(__dirname, './src'),
// 基础路径,用于部署在子路径时使用
base: '/my-app/',
// 开发服务器配置
server: {
// 指定开发服务器端口
port: 3000,
// 是否自动打开浏览器
open: true,
// 配置代理服务器,用于解决跨域问题
proxy: {
'/api': {
target: 'http://localhost:8080', // 目标服务器地址
changeOrigin: true, // 是否改变请求源
rewrite: (path) => path.replace(/^\/api/, ''), // 重写请求路径
},
},
},
// 构建配置
build: {
// 指定输出目录
outDir: path.resolve(__dirname, '../dist'),
// 指定静态资源目录
assetsDir: 'static',
// 是否生成 sourcemap 文件
sourcemap: true,
// 是否压缩代码
minify: 'terser', // 使用 terser 进行代码压缩
// 配置 Rollup 选项
rollupOptions: {
// 配置外部依赖
external: ['lodash'],
// 配置输出格式
output: {
manualChunks: {
// 将 lodash 单独打包
lodash: ['lodash'],
},
},
},
},
// 插件配置
plugins: [
// 使用 Vue 插件
vue(),
],
// 模块解析配置
resolve: {
// 配置路径别名
alias: {
'@': path.resolve(__dirname, './src'), // 将 @ 映射到 src 目录
},
},
// CSS 配置
css: {
// 配置 CSS 预处理器选项
preprocessorOptions: {
scss: {
// 全局注入 SCSS 变量
additionalData: `@import "@/styles/variables.scss";`,
},
},
},
// 环境变量配置
envPrefix: 'VITE_', // 环境变量前缀,默认为 VITE_
});
例子:
javascript
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path' //导入 node.js path
//unplugin
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { ElementPlusResolver } from 'unplugin-vue-components/resolvers'
import Icons from 'unplugin-icons/vite' //图标
import IconsResolver from 'unplugin-icons/resolver'
// https://vite.dev/config/
export default defineConfig({
plugins: [vue(),
AutoImport({
// 自动导入 Vue 相关函数,如:ref, reactive, toRef 等
imports: ['vue'],
resolvers: [
ElementPlusResolver(),
// 自动导入图标组件
IconsResolver(),
],
}),
Components({
resolvers: [
ElementPlusResolver(),
// 自动注册图标组件
IconsResolver({
enabledCollections: ['ep'],
}),
],
}),
Icons({
autoInstall: true,
}),
],
resolve: {
alias: { //配置路径别名
'@': path.resolve(__dirname, 'src')
}
}
})
Vue3 目录结构
Vue3 起步
Vue3 基础语法
Vue3 声明式渲染
Vue3 指令
Vue3 模板语法
Vue3 条件语句
| 特性 | v-if | v-show |
|---|---|---|
| 实现方式 | 条件性地渲染元素 | 通过 CSS display 属性控制显示/隐藏 |
| DOM 存在 | 不满足条件时不存在于 DOM 中 | 始终存在于 DOM 中 |
| 初始渲染开销 | 较小(条件为假时不渲染) | 较大(总是渲染) |
| 切换开销 | 较大(涉及添加/删除 DOM) | 较小(仅改变 CSS 属性) |
| 生命周期 | 完整的生命周期钩子 | 不会触发生命周期钩子 |
| 编译时 | 编译为条件分支 | 编译为指令 |
Vue.js 循环语句
Vue3 组件
Vue3 计算属性
Vue3 监听属性
Vue 3 还提供了 watchEffect API,它比 watch 更加简洁,可以自动地跟踪响应式数据的变化,而不需要指定具体的数据源。
| 特性 | watch | watchEffect |
|---|---|---|
| 依赖追踪 | 显式指定监听源 | 自动收集依赖 |
| 执行时机 | 默认惰性,依赖变化后执行 | 立即执行,依赖变化后重新执行 |
| 旧值访问 | 提供新旧值 | 不提供新旧值 |
| 使用方式 | 需要明确指定监听的数据 | 直接在回调中使用响应式数据 |
| 适用场景 | 需要获取旧值或特定数据变化 | 副作用函数,自动依赖收集 |
Vue3 样式绑定
Class 绑定要点
- 对象语法 :
{ class: condition }- 适用于条件类名 - 数组语法 :
[class1, class2]- 适用于多个类名组合 - 计算属性:适用于复杂类名逻辑
- 组件绑定:类名会自动应用到组件根元素
Style 绑定要点
- 对象语法 :
{ property: value }- 适用于动态样式 - 数组语法 :
[styleObject1, styleObject2]- 适用于多个样式对象 - 自动前缀:Vue 自动处理浏览器前缀
- 多值处理 :提供兼容性数组
[value1, value2]
Vue3 事件处理
Vue.js 通过由点 . 表示的指令后缀来调用修饰符。
.stop- 阻止冒泡.prevent- 阻止默认事件.capture- 阻止捕获.self- 只监听触发该元素的事件.once- 只触发一次.left- 左键事件.right- 右键事件.middle- 中间滚轮事件
全部的按键别名:
.enter.tab.delete(捕获 "删除" 和 "退格" 键).esc.space.up.down.left.right
系统修饰键:
.ctrl.alt.shift.meta
鼠标按钮修饰符:
.left.right.middle
Vue3 表单
Vue3 自定义指令
Vue3 路由(Vue Router)
Vue 路由允许我们通过不同的 URL 访问不同的内容。
npm 安装
npm install vue-router@4
基本应用
1、创建路由表
javascript
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{ path: '/', component: Home },
]
export default createRouter({
history: createWebHistory(),
routes
})
2、在应用中挂载
javascript
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
createApp(App).use(router).mount('#app')
3、页面出口
src\App.vue
html
<router-view/>
4、跳转
html
<router-link to="/user/profile">
个人中心
</router-link>
router-link
使用一个自定义组件 router-link 来创建链接
属性详解
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| to | string | Location | - | 目标路由的路径或路由对象 |
| replace | boolean | false | 设置后,导航时不会向history添加新记录 |
| append | boolean | false | 设置后,当前路径被附加到目标路径 |
| tag | string | a | 指定渲染的HTML标签 |
| active-class | string | router-link-active | 指定链接激活时的CSS类名 |
| exact-active-class | string | router-link-exact-active | 指定链接精确匹配时的CSS类名 |
| exact | boolean | false | 设置后,只有在完全匹配时才激活 |
| event | string | Array | click | 指定触发导航的事件 |
| aria-current-value | string | page | 指定aria-current属性的值 |
Vue3 混入
注意事项
在Vue3中,混入仍然支持,但官方推荐使用组合式API(Composition API)来实现代码复用,因为组合式API提供了更清晰、更灵活的代码组织方式。
混入与组合式API的比较
| 特性 | 混入 (Mixins) | 组合式API |
|---|---|---|
| 代码组织 | 按选项类型组织 | 按逻辑功能组织 |
| 命名冲突 | 可能发生,组件优先 | 避免了命名冲突 |
| 类型推导 | 较差 | 更好的TypeScript支持 |
| 数据来源 | 难以追踪 | 清晰的来源追踪 |
| 依赖关系 | 隐式依赖 | 显式依赖 |
| 复用方式 | 选项合并 | 函数调用 |
| 性能 | 全部混入,即使部分不用 | 按需使用 |
Vue3 Ajax(axios)
安装Axios
使用npm安装
npm install axios

src\utils\request.js or src\utils\axios.js
文件整体结构
javascript
// 1. 导入依赖
import axios from "axios";
import { getToken } from '@/composables/auth'; // 获取 token
import { toast } from '@/composables/util'; // 提示工具
import store from './store'; // Vuex 状态管理
// 2. 创建 Axios 实例
const service = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_API, // 基础路径(从环境变量读取)
});
// 3. 请求拦截器
service.interceptors.request.use(...);
// 4. 响应拦截器
service.interceptors.response.use(...);
// 5. 导出实例
export default service;
使用

注册为全局属性
main.js
javascript
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import axiosInstance from './utils/axios'
const app = createApp(App)
// 将axios实例添加为全局属性
app.config.globalProperties.$axios = axiosInstance
app.use(router)
app.mount('#app')
提供API服务

Vue3 组合式 API
Vue3引入的组合式API(Composition API)是一套低侵入性的、函数式的API,使得我们能够更灵活地组织组件逻辑。
setup函数
setup函数是组合式API的入口点。它在组件创建之前执行,是所有组合式API函数的调用场所。
响应式基础
组合式API提供了两个主要的API来创建响应式状态:ref和reactive。
ref
ref接受一个内部值并返回一个响应式且可变的ref对象。ref对象只有一个指向内部值的属性.value。
reactive
reactive返回一个对象的响应式代理。它将对象的所有嵌套属性都转换为响应式。
ref与reactive的区别
| 特性 | ref | reactive |
|---|---|---|
| 适用类型 | 基本类型(字符串、数字等)和对象 | 对象和数组 |
| 访问方式 | 通过.value属性访问 | 直接访问属性 |
| 模板中访问 | 自动解包,不需要.value | 直接访问属性 |
| 替换整个值 | 可以直接替换整个值 | 不能直接替换整个值 |
| 解构 | 解构会失去响应性,需要使用toRefs | 解构会失去响应性,需要使用toRefs |
toRefs与toRef
toRefs可以将reactive对象转换为普通对象,其中结果对象的每个属性都是指向原始对象相应属性的ref。
计算属性
计算属性是基于响应式依赖进行缓存的值,只有当相关依赖发生改变时才会重新计算。在组合式API中,使用computed函数创建计算属性。
计算属性的缓存
计算属性基于它们的响应式依赖进行缓存。只有在相关响应式依赖改变时它们才会重新计算。
侦听器
侦听器用于观察和响应Vue实例上的数据变动。在组合式API中,使用watch和watchEffect函数创建侦听器。
watch
watch用于侦听特定的数据源,并在数据源变化时执行回调。
watchEffect
watchEffect会立即执行一个函数,同时响应式地追踪其依赖,并在依赖更改时重新运行该函数。
watch vs watchEffect
| 特性 | watch | watchEffect |
|---|---|---|
| 执行时机 | 默认不立即执行,需要配置 | 立即执行一次 |
| 依赖追踪 | 显式指定要侦听的数据源 | 自动追踪回调函数内的响应式依赖 |
| 获取旧值 | 可以获取变化前后的值 | 无法获取旧值 |
| 使用场景 | 需要在数据变化时执行特定逻辑 | 需要根据响应式状态自动更新某些值 |
watch的配置选项
javascript
// 立即执行一次
watch(count, (newValue, oldValue) => {
console.log(`计数从 ${oldValue} 变为 ${newValue}`)
}, { immediate: true })
// 深度侦听
watch(
() => deepObject.nested.value,
(newValue, oldValue) => {
console.log(`嵌套值从 ${oldValue} 变为 ${newValue}`)
},
{ deep: true }
)
停止侦听器
watch和watchEffect都返回一个停止函数,调用它可以停止侦听器。
javascript
const stopWatch = watch(ref(0), () => {
console.log('侦听器被调用')
})
// 在某些条件下停止侦听
stopWatch()
生命周期钩子
在组合式API中,可以使用onX系列函数来注册生命周期钩子。这些函数在setup()中调用。
生命周期钩子列表
| 选项式API | 组合式API | 说明 |
|---|---|---|
| beforeCreate | setup() | 实例初始化后,数据观测和事件配置前 |
| created | setup() | 实例创建完成 |
| beforeMount | onBeforeMount | 挂载开始前 |
| mounted | onMounted | 挂载完成后 |
| beforeUpdate | onBeforeUpdate | 数据更新前 |
| updated | onUpdated | 数据更新后 |
| beforeUnmount | onBeforeUnmount | 卸载前 |
| unmounted | onUnmounted | 卸载后 |
| errorCaptured | onErrorCaptured | 捕获后代组件错误 |
API 手册
API对应关系
| 选项式API | 组合式API |
|---|---|
| data | ref() / reactive() |
| computed | computed() |
| methods | 函数声明 |
| watch | watch() / watchEffect() |
| beforeCreate / created | setup() |
| beforeMount / mounted | onBeforeMount() / onMounted() |
| beforeUpdate / updated | onBeforeUpdate() / onUpdated() |
| beforeUnmount / unmounted | onBeforeUnmount() / onUnmounted() |
| emits | context.emit |
| props | setup第一个参数 |
| attrs / slots | context.attrs / context.slots |