Vue3快速入门
一、 简介
Vue是一个用于构建用户界面(UI) 的前端 JavaScript 框架。由中国开发者创建,目标是让开发网页变得简单、高效、灵活。
特点
|
特点 |
解释 |
|
响应式数据绑定 |
数据变了,页面自动更新(不用手动改 DOM)。 |
|
组件化开发 |
页面可以拆分成一个个可复用的小模块(组件)。 |
|
指令系统 |
用简单语法(如 v-if、v-for、v-model)控制显示逻辑。 |
|
生态完善 |
有路由(Vue Router)、状态管理(Pinia/Vuex)、构建工具(Vite)。 |
|
学习曲线平缓 |
对初学者友好,比 React、Angular 更容易上手。 |
二、 项目的创建
首先一定要有node.js的环境,这里安装教程作者之后会写。。。
提供两种下载方法:Vue CLI 与 Vite
Vue CLI
安装脚手架
npm install -g @vue/cli
创建项目
vue create vue_learn
选择自定义选项

选择包含的功能

选择下载的版本呢

项目启动:
npm run serve
Vite(官方推荐)
创建项目
npm create vite@latest vue3_learn
按照以下选择:
创建vue项目

选择js版本


启动项目
npm run dev

Shortcuts快捷方式
press r to restart the server 按 R 重新启动服务器
press u to show server url 按你显示服务器网址
press o to open in browser 按 O 在浏览器中打开
press c to clear console 按 C 清除控制台
press q to quit 按 Q 退出
三、 理解vue3(以vite为例)
项目组成
my-vue-app/
├─ index.html # 入口 HTML 文件
├─ package.json # 项目依赖和命令配置
├─ vite.config.js # Vite 配置(开发服务器、代理等)
├─ node_modules/ # npm 安装的依赖包
└─ src/ # 源代码目录(重点)
├─ main.js # 入口文件,创建 Vue 应用
├─ App.vue # 根组件
├─ assets/ # 静态资源(图片、CSS等)
└─ components/ # 各种子组件
从“启动”到“显示”的流程
index.html
↓
main.js
↓
App.vue
↓
components/ 下的组件
具体职责
index.html(网页的壳) 定义网页骨架,加载 Vue 程序入口。
main.js(Vue 应用的入口) 创建 Vue 应用实例。告诉 Vu把 App.vue 挂载到 #app 这个 div 里。
App.vue(根组件) 定义整个网页的主界面。组织和引用其它组件。使用响应式数据、事件绑定、模板语法。
components/(组件目录) 每个 .vue 文件都是一个可复用模块。封装页面的一部分逻辑。
assets/(静态资源) 放图片、CSS、字体等。
package.json(项目信息与依赖) 定义项目依赖(Vue、Vite)
vite.config.js(开发配置) 开发配置,例如代理后端接口、端口号等。
核心概念
概念 简介
|
概念 |
简介 |
|
组件化 |
每个功能/页面都是一个组件,组合成完整网站。 |
|
响应式系统 |
数据变了,界面自动更新(不用手动改DOM)。 |
|
模板语法 |
{{ }}、v-if、v-for 等,让HTML动态化。 |
|
Composition API |
Vue3 新语法,用 setup() 来写逻辑。 |
|
路由(Vue Router) |
页面跳转(如 /home, /video/1)。 |
|
状态管理(Pinia/Vuex) |
管理全局数据(如用户登录状态)。 |
|
构建工具(Vite) |
编译打包代码、启动开发服务器。 |
Vue组件包括三个部分
<template> 视图层(HTML 结构)
定义页面上要显示的结构和数据绑定方式。
{{ title }} → 动态显示数据(数据绑定)
v-if、v-for → 控制逻辑
@click → 绑定事件
<script> 逻辑层(Model + ViewModel)(数据、方法)
定义数据(data)和行为(methods)。
它控制视图的内容和变化。
原理(MVVM 模型):
• Model(数据) → 存在 ref() 或 reactive() 中
• View(视图) → <template> 中展示
• ViewModel(响应系统) → Vue 自动把两者连接起来,数据改了视图自动更新
部分 全称 作用 Vue 对应部分
M Model 数据模型(状态) <script> 中的变量
V View 视图(界面) <template>
VM ViewModel 连接两者的桥梁 Vue 的响应式系统
<style> 样式层(Style)
定义页面的外观,比如颜色、大小、布局等。
scoped 表示样式只在当前组件生效,不会影响其他页面。
四、 双向绑定
当数据变化时,页面会自动更新;当用户修改页面输入时,数据也会自动变化。
利用v-model绑定定义的变量,即可实现双向绑定:
这里做一个演示:
<div>
姓名:<input v-model="userName"/>{{userName}}<br/>
薪水:<input type="number" v-model="salary"/>{{salary}}<br/>
<button v-on:click="addSalary">加薪水1000</button>
</div>
export default {
data(){
return{
userName:'哈哈嗨',
salary:150000,
}
},
methods:{
addSalary(){
this.salary += 1000;
}
}
}
可以看到效果:

当然我们也可以设置绑定一个对象:userInfo
可以利用v-for遍历数组:
v-for="item in userInfo.skills" :key="item"
<template>
<div>
姓名:<input v-model="userName"/>{{userName}}<br/>
薪水:<input type="number" v-model="salary"/>{{salary}}<br/>
<button v-on:click="addSalary">加薪水1000</button>
</div>
<hr/>
<button @click="showInfo">查看信息</button>
<div v-if="isShow">
<h2>个人信息</h2>
<p>年龄:<input type="number" v-model="userInfo.age"/></p>
<p>性别:<input type="radio" v-model="userInfo.sex" value="男"/>男
<input type="radio" v-model="userInfo.sex" value="女"/>女
</p>
<p>岗位:<select type="text" v-model="userInfo.department">
<option value="前端">前端</option>
<option value="后端">后端</option>
<option value="测试">测试</option>
</select></p>
<p>技术:<span v-for="item in userInfo.skills" :key="item">{{item}};</span></p>
学习新技术:<input type="text" v-model="newSkill"/><button @click="addNewSkill">添加</button>
<p>个人信息汇总:{{userInfo}}</p>
</div>
</template>
<script>
export default {
data(){
return{
userName:'哈哈嗨',
salary:150000,
userInfo:{
age:18,
sex:'男',
department:'',
skills:['JAVA','PYTHON','JS']
},
newSkill:'',
isShow:false,
}
},
methods:{
addSalary(){
this.salary += 1000;
},
addNewSkill(){
this.userInfo.skills.push(this.newSkill);
this.newSkill = '';
},
showInfo(){
this.isShow = !this.isShow;
}
}
}
</script>
可见效果:

五、 OptionsAPI和CompositionAPI
Options API(选项式 API)
通过在组件中定义“选项对象”(options)来组织代码,比如 data、methods、computed、watch 等。
Composition API(组合式 API)
通过 setup() 函数(或 <script setup> 语法糖)来写逻辑。
Composition API(组合式 API)
在 script 标签添加setup
<script setup>
import {ref} from "vue";
let userName = ref('哈哈嗨');
let salary = ref(150000);
function addSalary(){
salary.value += 1000;
}
<script/>
可以链接外部js文件
创建aaa.js
import {ref} from "vue";
export default function (){
const userName = ref('哈哈嗨');
const salary = ref(150000);
function addSalary(){
salary.value += 1000;
}
return {
userName,
salary,
addSalary
}
};
链接aaa.js
<script setup>
import aaa from "../src/aaa"
let {userName,salary,addSalary} = aaa();
</script>
六、 ref与reactive
ref包裹单个变量,它的value能够实现双向绑定效果:
例如:
<template>
<div>
<p>点击次数:{{ count }}</p>
<button @click="count++">点我 +1</button>
</div>
</template>
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
Reactive包裹对象、数组,
例如:
<template>
<div>
<p>{{ user.name }},{{ user.age }} 岁</p>
<button @click="user.age++">年龄 +1</button>
</div>
</template>
<script setup>
import { reactive } from 'vue'
const user = reactive({
name: '李四',
age: 20
})
</script>要解构 reactive 对象 用 toRefs()
<script setup>
//ref 只有value是响应式数据
// reactive 所有数据都是响应式数据
// import {ref} from "vue";
// let userName = ref('哈哈嗨');
// let salary = ref(150000);
// function addSalary(){
// salary.value += 1000;
// }
import {reactive, ref, toRef, toRefs} from "vue";
let info = reactive( {userName:'哈哈嗨',salary:150000})
function addSalary(){
info.salary += 1000;
}
//toref 响应式数据 将reactive数据转换成ref数据
let userName = toRef(info,'userName');
let salary = toRef(info,'salary');
</script>
如果嫌麻烦,可以用torefs实现结构:
//torefs 将reactive数据转换成多个ref数据
let {userName,salary} = toRefs(info);
let age = ref()
在标签内使用ref,可以动态获得标签的信息,
如:
<template>
<!-- 使用reactive + toref双向数据绑定-->
<hr/>
<div>
姓名:<input v-model="userName"/>{{userName}}<br/>
薪水:<input type="number" v-model="salary"/>{{salary}}<br/>
<button @click="addSalary">加薪水1000</button>
年龄:<input type="number" ref="age"/>
<button @click="showAge">查看年龄</button>
</div>
</template>
//也可以在标签内 使用 ref
function showAge(){
console.log(age.value)
console.log(age.value.value)
}
如图,可以实现:

七、 自由组件传参
创建组件MySalarInfo.vue ,并暴露数据
<template>
<div>
姓名:<input v-model="userName"/>{{userName}}<br/>
薪水:<input type="number" v-model="salary"/>{{salary}}<br/>
<button v-on:click="addSalary">加薪水1000</button>
</div>
</template>
<script setup>
import {ref} from "vue";
let userName = ref('哈哈嗨');
let salary = ref(150000);
function addSalary(){
salary.value += 1000;
}
// 暴露数据
defineExpose({userName,salary,addSalary})
</script>
引用组件,通过ref获取信息:
<template>
<div>
<MySalarInfo ref="salarInfo"/>
<button @click="showSalary()">查看信息</button>
</div>
</template>
<script setup>
import MySalarInfo from "./components/MySalarInfo.vue";
import {ref} from "vue";
let salarInfo = ref();
function showSalary(){
console.log(salarInfo.value)
console.log(salarInfo.value.salary)
console.log(salarInfo.value.userName)
}
</script>
如图效果:

以上实现了子级组件给父级组件传递数据的方式。
那么父级组件如何向子集传输?创建MySalarInfoB.vue组件
<template>
<div>
姓名:<input v-model="salaryInfo.userName"/>{{salaryInfo.userName}}<br/>
薪水:<input type="number" v-model="salaryInfo.salary"/>{{salaryInfo.salary}}<br/>
</div>
</template>
<script setup>
// // 暴露数据
// defineExpose({userName,salary,addSalary})
// 获取 数据
defineProps(["salaryInfo"])
</script>
子父组件中返回
<template>
<div>
<!-- 返回值给子组件-->
<MySalarInfoB :salary-info="salarInfo"/>
<button @click="showSalary()">增加薪水1000</button>
</div>
</template>
<script setup>
import MySalarInfoB from "./components/MySalarInfoB.vue";
import {reactive, ref} from "vue";
let salarInfo = reactive({userName:'哈哈嗨',salary:150000});
function showSalary(){
salarInfo.salary += 1000;
}
</script>
八、 Vue的生命周期
指的是一个 Vue 组件从创建到销毁的整个过程,Vue 在不同阶段自动调用特定的“钩子函数(生命周期函数)。
过程:
创建阶段(组件诞生)
挂载阶段(DOM 渲染到页面)
更新阶段(数据变化、页面重新渲染)
销毁阶段(组件被移除)例子
<template>
<div>
<p>计数:{{ count }}</p>
<button @click="count++">+1</button>
</div>
</template>
<script setup>
import {ref, onMounted, onUpdated, onUnmounted, onBeforeMount, onBeforeUnmount} from 'vue'
const count = ref(0)
onBeforeMount(() => {
console.log('挂载之前')
})
onMounted(() => {
console.log('组件已挂载!DOM 可以访问')
})
onBeforeMount(() => {
console.log('更新之前')
})
onUpdated(() => {
console.log('组件更新了!')
})
onUnmounted(() => {
console.log('组件已销毁!清理工作完成')
})
onBeforeUnmount(() => {
console.log('销毁之前')
})
</script>
如图效果

九、 路由
概念
在 Vue 中,路由(Router) 就是控制页面显示哪个组件的“导航系统”。
它让单页应用(SPA)看起来像在切换页面,实际上只是在不同组件间切换。
实战
下载路由依赖:
npm install vue-router@4
在入口(main.js)引入
import router from './router'
createApp(App).use(router).mount('#app')
创建路由设置:
router/index.js
// src/router/index.js
import { createRouter, createWebHistory } from 'vue-router'
// 引入页面组件
import Home from '../views/Home.vue'
import About from '../views/About.vue'
import Contact from '../views/Contact.vue'
// 定义路由规则
const routes = [
{ path: '/home', component: Home },
{ path: '/about', component: About },
{ path: '/contact', component: Contact }
]
// 创建路由实例
const router = createRouter({
history: createWebHistory(),
routes
})
export default router
创建视图:
Views/
<template>
<div>
<h1>关于我们</h1>
<p>这是一个学习 Vue 路由的简单示例。</p>
</div>
</template>
<template>
<div>
<h1>联系我们</h1>
<p>邮箱:example@mail.com</p>
</div>
</template>
<template>
<div>
<h1>首页</h1>
<p>欢迎来到我的网站!</p>
</div>
</template>
在app中设计导航:
!--路由-->
<template>
<div>
<nav>
<router-link to="/">首页</router-link> |
<router-link to="/about">关于</router-link> |
<router-link to="/contact">联系</router-link>
</nav>
<hr />
<!-- 路由组件在这里显示 -->
<router-view></router-view>
</div>
</template>
<style>
nav {
margin: 20px;
}
a {
text-decoration: none;
color: #42b983;
font-weight: bold;
}
a.router-link-exact-active {
color: red;
}
</style>
可以看到效果:

十、 路由模式
Vue Router 有两种常见的“工作模式”,也叫“路由模式”:
模式名 说明 URL 示例 特点
hash 模式(默认) 使用 #(哈希)符号控制路由 http://localhost:5173/#/about 兼容性好,无需服务器配置
history 模式 使用 HTML5 的 History API http://localhost:5173/about URL 更干净,但需要后端支持
hash 模式(默认)
实际上页面路径永远是同一个 HTML 文件(通常是 index.html);
# 号后的部分不会被浏览器发送到服务器;
所以刷新页面不会 404。
配置方法:
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [...]
})
生成的 URL:http://localhost:5173/#/about
适合场景:
• 前端静态网站;
• 不方便配置服务器;
• 想要最简单、最兼容的方式。
________________________________________
history 模式(推荐)
使用浏览器的 history.pushState() 和 popstate 事件;
URL 看起来就像真正的多页面网站(没有 #);
但是!如果你直接刷新 /about,服务器会报 404 ——
因为服务器默认找不到这个路径。
配置方法:
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [...]
})
生成的 URL:http://localhost:5173/about
当使用histroy模式时,
访问/时,出现报错:

原因是我们没有配置 / 路径,
这时我们可以使用redirect: '/home'
重定向到/home
push与 push
这两个方法都是用于跳转路由的:
方法 说明 浏览器行为
router.push() 跳转到新页面 会在历史记录中新增一条记录(可以后退)
router.replace() 替换当前页面 不会新增历史记录(无法后退)例子:
import { useRouter } from 'vue-router'
const router = useRouter()
function goToAbout() {
router.push('/about') // 跳转并记录历史
}
function goToContact() {
router.replace('/contact') // 跳转但不留历史记录
}
或者:
<router-link to="/">首页</router-link> |
<router-link to="/about">关于</router-link> |
<router-link replace to="/contact">联系</router-link>
十一、 Pinia集中状态管理
Vue 3 官方推荐的 状态管理库,用来在多个组件之间共享数据。可以认为是vue2 vuex的升级版。(注意两个不能同时用)
核心思想
Pinia 相当于一个“全局的数据仓库”:
每个组件都能访问和修改里面的数据;
数据是响应式的,修改后会自动更新 UI;
类似 Vuex,但更简单、语法更现代(Composition API 风格)。
实战
下载依赖:
npm install pinia
在入口引入、注册
import { createPinia } from 'pinia'
createApp(App).use(router).use(createPinia()).mount('#app')
创建一个仓库:
stores/counter.js
import { defineStore } from 'pinia'
// 创建一个仓库
// defineStore(仓库id, 配置)
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0,
name: '游鱼'
}),
// 计算属性
getters: {
double: (state) => state.count * 2
},
// 方法
actions: {
increment() {
this.count++
}
}
})
我们分别在/about /Contact.vue 添加
<!--<template>-->
<!-- <div>-->
<!-- <h1>联系我们</h1>-->
<!-- <p>邮箱:example@mail.com</p>-->
<!-- </div>-->
<!--</template>-->
<template>
<div>
<h2>当前计数:{{ counter.count }}</h2>
<h3>双倍:{{ counter.double }}</h3>
<button @click="counter.increment">+1</button>
</div>
</template>
<script setup>
import { useCounterStore } from '../stores/counter'
const counter = useCounterStore()
</script>
可以看到改变数据后,两个页面保持一致:


十二、 嵌套路由和路由传参
嵌套路由
嵌套路由指的是:
一个页面(父路由)中再包含子页面(子路由)。
例子
在路由设置中:
{ path: '/user', component: User,
children: [
{
path: 'profile', // 注意这里没有斜杠!
component: UserProfile
},
{
path: 'posts',
component: UserPosts
}
]
}
创建User页面
<template>
<div>
<h2>用户中心</h2>
<nav>
<router-link to="/user/profile">个人资料</router-link> |
<router-link to="/user/posts">我的帖子</router-link>
</nav>
<!-- 子路由在这里渲染 -->
<router-view></router-view>
</div>
</template>
创建UserPosts UserProfile 文件
<script setup>
</script>
<template>
个人信息
</template>
<style scoped>
</style>
<script setup>
</script>
<template>
<div>
我的帖子
</div>
</template>
<style scoped>
</style>
路由传参
路由传参有两种主要方式:
类型 形式 使用场景
动态路由参数 /user/:id 访问用户详情、文章详情等唯一标识的页面
查询参数 /user?id=123 可选参数、筛选项等
动态路由参数
Main.js 中:
{ path: '/user/:id', component: UserDetail }
创建页面:
UserDetail.vue
<template>
<div>
<h2>用户详情</h2>
<p>用户 ID:{{ route.params.id }}</p>
</div>
</template>
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute() // 获取当前路由信息
</script>
访问 http://localhost:5174/user/1

查询参数
Main.js
{ path: '/search', component: Search }
创建search页面,
<script setup>
import { useRoute } from 'vue-router'
const route = useRoute()
console.log(route.query.keyword) // "斗罗大陆"
console.log(route.query.page) // "2"
</script>
在浏览器查询
/search?keyword=斗罗大陆&page=2
可以看到打印:

2740

被折叠的 条评论
为什么被折叠?



