news 2026/6/15 6:28:54

Vue 3 入门教程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vue 3 入门教程

目录

  • 1. Vue 是什么
  • 2. 第一个 Vue 项目
    • 2.1 创建项目
    • 2.2 启动项目
    • 2.3 认识项目结构
  • 3. 从官方"创建一个应用"理解 Vue 启动流程
  • 4. 单文件组件.vue
  • 5. 模板语法
    • 5.1 文本插值
    • 5.2 属性绑定v-bind/:
    • 5.3 事件绑定v-on/@
  • 6. 响应式基础:refreactive
    • 6.1ref示例
    • 6.2reactive示例
  • 7. 常用功能一:条件渲染
    • 7.1v-if/v-else-if/v-else
    • 7.2v-show
  • 8. 常用功能二:列表渲染
    • 8.1 遍历数组
    • 8.2 获取索引
  • 9. 常用功能三:事件处理
    • 9.1 基本事件
    • 9.2 传参数
    • 9.3 事件修饰符
  • 10. 常用功能四:表单绑定v-model
  • 11. 常用功能五:计算属性computed
  • 12. 常用功能六:侦听器watch
  • 13. 常用功能七:生命周期
  • 14. 常用功能八:组件
    • 14.1 创建组件
    • 14.2 Props:父传子
    • 14.3 Emits:子传父
    • 14.4 插槽 slot
  • 15. 常用功能九:模板引用ref
  • 16. 常用功能十:样式绑定
    • 16.1 class 绑定
    • 16.2 style 绑定
  • 17. 路由 Vue Router
    • 17.1 基本概念
    • 17.2 路由配置示例
    • 17.3 动态路由
    • 17.4 编程式导航
  • 18. 状态管理 Pinia
    • 18.1 注册 Pinia
    • 18.2 创建 Store
  • 19. 请求接口
    • 19.1 fetch 示例
    • 19.2 axios 示例
  • 20. 常用项目功能怎么组合
    • 20.1 登录功能
    • 20.2 列表页
    • 20.3 表单页
    • 20.4 详情页
  • 21. 新手常见问题
    • 21.1 为什么 JS 里要写.value
    • 21.2refreactive怎么选
    • 21.3 computed 和 watch 区别
  • 22. 最小记忆清单

1. Vue 是什么

Vue 是一个用于构建用户界面的 JavaScript 框架。它最常见的用途是开发前端页面、后台管理系统、单页应用、组件化页面和交互式业务系统。

Vue 的核心特点:

  • 数据驱动界面:数据变了,页面自动更新。
  • 组件化开发:把页面拆成一个个可复用组件。
  • 模板语法简单:接近 HTML,容易上手。
  • 官方生态完整:Vue Router 做路由,Pinia 做状态管理,Vite 做开发构建。
  • 渐进式:可以从一个小页面开始,也可以做完整大型应用。

2. 第一个 Vue 项目

2.1 创建项目

在你想放项目的目录执行:

npmcreate vue@latest

创建时会问你一些选项。新手建议:

Add TypeScript? No Add JSX Support? No Add Vue Router? Yes Add Pinia? Yes Add Vitest? No Add End-to-End Testing? No Add ESLint? Yes Add Prettier? Yes Add Vue DevTools? Yes

如果你只是想先学 Vue 基础,也可以 Router 和 Pinia 都选 No,后面再加。

2.2 启动项目

cdyour-project-namenpminstallnpmrun dev

浏览器打开终端提示的地址,通常是:

http://localhost:5173

2.3 认识项目结构

常见结构:

src/ main.js App.vue components/ views/ router/ stores/

重点理解:

  • main.js:应用入口,创建 Vue 应用并挂载到页面。
  • App.vue:根组件,整个应用的最外层组件。
  • components/:通用组件。
  • views/:页面级组件,通常配合路由使用。
  • router/:路由配置。
  • stores/:Pinia 状态管理。

3. 从官方“创建一个应用”理解 Vue 启动流程

Vue 应用通过createApp()创建应用实例,然后通过.mount()挂载到 HTML 容器。

典型入口:

import{createApp}from'vue'importAppfrom'./App.vue'constapp=createApp(App)app.mount('#app')

对应index.html里通常有:

<divid="app"></div>

理解这三个点:

  • createApp(App):用根组件创建 Vue 应用。
  • App.vue:根组件,其他组件都挂在它下面。
  • mount('#app'):把 Vue 应用渲染到页面里的#app容器。

注意:全局配置、插件注册、全局组件注册,一般要在mount()之前完成。

4. 单文件组件.vue

.vue文件是 Vue 的单文件组件,把模板、脚本、样式写在一个文件里,用<template><script><style>三个标签组织。

<script setup> import { ref } from 'vue' const message = ref('Hello Vue') </script> <template> <h1>{{ message }}</h1> </template> <style scoped> h1 { color: #42b883; } </style>

含义:

  • <script setup>:写组件逻辑,变量和方法可直接在模板中使用。
  • <template>:写页面结构,支持 Vue 模板语法。
  • <style scoped>:写当前组件样式,scoped表示样式只影响当前组件,不影响其他组件。

新手重点:

  • 一个.vue文件就是一个组件。
  • 组件名建议用大驼峰,比如TodoList.vue
  • 页面复杂后,要主动拆组件,每个组件只负责一个功能。

5. 模板语法

Vue 模板基于 HTML,支持插值表达式{{ }}和指令(如v-bindv-if)来绑定数据和逻辑。

5.1 文本插值

<script setup> const name = '小明' const count = 10 const isLogin = true </script> <template> <p>你好,{{ name }}</p> <p>{{ count + 1 }}</p> <p>{{ isLogin ? '已登录' : '未登录' }}</p> </template>

{{ }}里可以写简单表达式,但不要在模板里写太复杂的逻辑,复杂逻辑放到计算属性或函数里。

5.2 属性绑定v-bind/:

<script setup> const imageUrl = '/logo.png' const title = 'Vue Logo' const disabled = true </script> <template> <img :src="imageUrl" :alt="title" /> <button :disabled="disabled">提交</button> </template>

:v-bind:的简写,用于动态绑定 HTML 属性。

5.3 事件绑定v-on/@

<script setup> function handleClick() { alert('点击了按钮') } </script> <template> <button @click="handleClick">点击我</button> </template>

@clickv-on:click的简写,用于绑定事件监听。

6. 响应式基础:refreactive

ref用于基本类型和对象,取值需.valuereactive只用于对象,直接访问属性。两者都是响应式的,数据变化时视图自动更新。

6.1ref示例

<script setup> import { ref } from 'vue' const count = ref(0) const name = ref('小明') function add() { count.value++ } </script> <template> <p>{{ name }} 点击了 {{ count }} 次</p> <button @click="add">+1</button> </template>

注意:

  • 在 JS 里访问和修改 ref,要用.value
  • 在模板里使用 ref,不需要写.value,Vue 会自动解包。

6.2reactive示例

<script setup> import { reactive } from 'vue' const user = reactive({ name: '小明', age: 18 }) function birthday() { user.age++ } </script> <template> <p>{{ user.name }}:{{ user.age }} 岁</p> <button @click="birthday">过生日</button> </template>

新手建议:

  • 简单值用ref
  • 表单对象、复杂对象用reactive
  • 如果纠结,就优先用ref,因为它更统一,且ref也可以放对象。

7. 常用功能一:条件渲染

v-if按条件渲染/销毁元素,v-show仅切换display属性。频繁切换用v-show,运行时条件少变用v-if

7.1v-if/v-else-if/v-else

<script setup> import { ref } from 'vue' const score = ref(85) </script> <template> <p v-if="score >= 90">优秀</p> <p v-else-if="score >= 60">及格</p> <p v-else>不及格</p> </template>

v-if是"真正的"条件渲染,条件为假时元素不会出现在 DOM 中。

7.2v-show

<script setup> import { ref } from 'vue' const visible = ref(true) </script> <template> <button @click="visible = !visible">切换显示</button> <p v-show="visible">这段内容可以显示或隐藏</p> </template>

v-show只是切换 CSS 的display属性,元素始终在 DOM 中。

选择建议:

  • 切换不频繁(如登录状态判断):用v-if
  • 切换很频繁(如选项卡切换):用v-show

8. 常用功能二:列表渲染

v-for遍历数组或对象,需绑定:key提升性能。格式:v-for="item in items" :key="item.id"

8.1 遍历数组

<script setup> import { ref } from 'vue' const todos = ref([ { id: 1, text: '学习模板语法', done: true }, { id: 2, text: '学习列表渲染', done: false }, { id: 3, text: '写一个 Todo 项目', done: false } ]) </script> <template> <ul> <li v-for="todo in todos" :key="todo.id"> <span :style="{ textDecoration: todo.done ? 'line-through' : 'none' }"> {{ todo.text }} </span> </li> </ul> </template>

8.2 获取索引

<template> <ul> <li v-for="(item, index) in items" :key="index"> {{ index + 1 }}. {{ item }} </li> </ul> </template>

重点:

  • v-for用来循环数组或对象。
  • 必须写:key,通常用后端 ID。
  • 不建议用数组下标当 key,除非列表永远不排序、不删除、不插入。

9. 常用功能三:事件处理

9.1 基本事件

<button @click="submit">提交</button>
functionsubmit(){console.log('提交')}

9.2 传参数

<button @click="removeTodo(todo.id)">删除</button>
functionremoveTodo(id){console.log(id)}

9.3 事件修饰符

<form @submit.prevent="submitForm"> <button type="submit">提交</button> </form>

常见修饰符:

  • .prevent:阻止默认行为。
  • .stop:阻止冒泡。
  • .once:只触发一次。
  • .enter:监听回车键。

示例:

<input @keyup.enter="search" />

11. 常用功能四:表单绑定v-model

v-model用来做双向绑定:输入框变,数据变;数据变,输入框也变。

<script setup> import { ref } from 'vue' const username = ref('') </script> <template> <input v-model="username" placeholder="请输入用户名" /> <p>你输入的是:{{ username }}</p> </template>

常见表单:

<input v-model="text" /> <textarea v-model="content"></textarea> <input type="checkbox" v-model="checked" /> <select v-model="selected"> <option value="frontend">前端</option> <option value="backend">后端</option> </select>

常用修饰符:

<input v-model.trim="name" /> <input v-model.number="age" /> <input v-model.lazy="message" />

含义:

  • .trim:去掉首尾空格。
  • .number:转成数字。
  • .lazy:失焦或 change 时再更新。

12. 常用功能五:计算属性computed

计算属性用于根据已有数据派生新数据。

<script setup> import { ref, computed } from 'vue' const price = ref(100) const count = ref(2) const total = computed(() => price.value * count.value) </script> <template> <p>总价:{{ total }}</p> </template>

什么时候用 computed:

  • 根据一个或多个响应式数据计算出一个结果。
  • 希望结果有缓存。
  • 模板里的表达式变复杂了。

不要在 computed 里做:

  • 发请求。
  • 修改其他状态。
  • 操作 DOM。

这些副作用应该放到watch、事件函数或生命周期里。

13. 常用功能六:侦听器watch

watch用于监听数据变化,然后执行副作用。

<script setup> import { ref, watch } from 'vue' const keyword = ref('') watch(keyword, (newValue, oldValue) => { console.log('搜索词变化了', oldValue, '->', newValue) }) </script> <template> <input v-model="keyword" placeholder="搜索" /> </template>

常见用途:

  • 搜索框输入变化后请求接口。
  • 监听路由参数变化。
  • 数据变化后写入 localStorage。
  • 根据某个开关加载额外数据。

立即执行:

watch(keyword,()=>{// 初始化时执行一次,之后 keyword 变化也执行},{immediate:true})

深度监听:

watch(()=>form,()=>{console.log('表单变化')},{deep:true})

注意:深度监听复杂对象会有性能开销,不要滥用。

14. 常用功能七:生命周期

生命周期是组件从创建到销毁过程中可以插入逻辑的时机。

组合式 API 常用:

<script setup> import { onMounted, onUnmounted } from 'vue' onMounted(() => { console.log('组件已经挂载,可以请求接口或操作 DOM') }) onUnmounted(() => { console.log('组件卸载,清理定时器或事件监听') }) </script>

常用钩子:

  • onMounted:组件挂载后,常用于请求初始数据。
  • onUpdated:组件更新后。
  • onUnmounted:组件卸载后,常用于清理资源。

新手重点掌握onMountedonUnmounted即可。

15. 常用功能八:组件

组件是 Vue 项目的核心。

15.1 创建组件

src/components/UserCard.vue

<script setup> defineProps({ name: String, age: Number }) </script> <template> <div class="user-card"> <p>姓名:{{ name }}</p> <p>年龄:{{ age }}</p> </div> </template>

在父组件使用:

<script setup> import UserCard from './components/UserCard.vue' </script> <template> <UserCard name="小明" :age="18" /> </template>

15.2 Props:父传子

父组件:

<TodoItem :todo="todo" />

子组件:

<script setup> defineProps({ todo: Object }) </script>

15.3 Emits:子传父

子组件:

<script setup> const emit = defineEmits(['remove']) function handleClick() { emit('remove') } </script> <template> <button @click="handleClick">删除</button> </template>

父组件:

<TodoItem @remove="removeTodo(todo.id)" />

15.4 插槽 slot

插槽用于让父组件传入一段模板内容。

子组件:

<template> <div class="card"> <slot></slot> </div> </template>

父组件:

<BaseCard> <h2>标题</h2> <p>内容</p> </BaseCard>

常用组件拆分思路:

  • 页面级组件放views/
  • 可复用业务组件放components/
  • 基础组件命名可以用BaseButton.vueBaseModal.vue

16. 常用功能九:模板引用ref

有时候需要拿到 DOM 元素。

<script setup> import { ref, onMounted } from 'vue' const inputRef = ref(null) onMounted(() => { inputRef.value.focus() }) </script> <template> <input ref="inputRef" /> </template>

常见用途:

  • 自动聚焦输入框。
  • 获取元素尺寸。
  • 调用第三方库时传入 DOM。

不要过度使用 DOM 操作。Vue 推荐数据驱动界面。

17. 常用功能十:样式绑定

17.1 class 绑定

<div :class="{ active: isActive, error: hasError }"></div>

数组写法:

<div :class="[baseClass, isActive ? 'active' : '']"></div>

17.2 style 绑定

<div :style="{ color: textColor, fontSize: size + 'px' }"></div>

实际项目建议:

  • 大部分样式写 class。
  • 少量动态数值用 style 绑定。

18. 路由 Vue Router

当项目有多个页面时,需要 Vue Router。

18.1 基本概念

  • 路由:URL 和页面组件的对应关系。
  • router-link:页面跳转链接。
  • router-view:当前路由页面显示的位置。

18.2 路由配置示例

src/router/index.js

import{createRouter,createWebHistory}from'vue-router'importHomeViewfrom'../views/HomeView.vue'importAboutViewfrom'../views/AboutView.vue'constrouter=createRouter({history:createWebHistory(),routes:[{path:'/',name:'home',component:HomeView},{path:'/about',name:'about',component:AboutView}]})exportdefaultrouter

src/main.js

import{createApp}from'vue'importAppfrom'./App.vue'importrouterfrom'./router'createApp(App).use(router).mount('#app')

App.vue

<template> <nav> <RouterLink to="/">首页</RouterLink> <RouterLink to="/about">关于</RouterLink> </nav> <RouterView /> </template>

18.3 动态路由

{path:'/users/:id',name:'user-detail',component:UserDetailView}

组件里读取参数:

<script setup> import { useRoute } from 'vue-router' const route = useRoute() console.log(route.params.id) </script>

18.4 编程式导航

<script setup> import { useRouter } from 'vue-router' const router = useRouter() function goHome() { router.push('/') } </script>

常用场景:

  • 登录成功后跳转首页。
  • 保存表单后跳转详情页。
  • 删除数据后返回列表页。

19. 状态管理 Pinia

当多个组件都要共享同一份数据时,可以使用 Pinia。

19.1 注册 Pinia

src/main.js

import{createApp}from'vue'import{createPinia}from'pinia'importAppfrom'./App.vue'constapp=createApp(App)app.use(createPinia())app.mount('#app')

19.2 创建 Store

src/stores/user.js

import{defineStore}from'pinia'import{ref,computed}from'vue'exportconstuseUserStore=defineStore('user',()=>{consttoken=ref('')constname=ref('')constisLogin=computed(()=>Boolean(token.value))functionlogin(payload){token.value=payload.token name.value=payload.name}functionlogout(){token.value=''name.value=''}return{token,name,isLogin,login,logout}})

组件中使用:

<script setup> import { useUserStore } from '@/stores/user' const userStore = useUserStore() </script> <template> <p v-if="userStore.isLogin">你好,{{ userStore.name }}</p> <button @click="userStore.logout">退出登录</button> </template>

什么时候用 Pinia:

  • 登录用户信息。
  • token。
  • 购物车。
  • 全局主题。
  • 多页面共享筛选条件。
  • 复杂页面的共享状态。

什么时候不用:

  • 只在一个组件内部使用的数据。
  • 父子组件之间简单传值,优先 props/emit。

20. 请求接口

Vue 本身不规定请求库。新手可以先用fetch,项目里常用axios

20.1 fetch 示例

<script setup> import { ref, onMounted } from 'vue' const list = ref([]) const loading = ref(false) const error = ref('') async function loadData() { loading.value = true error.value = '' try { const res = await fetch('/api/todos') list.value = await res.json() } catch (err) { error.value = '加载失败' } finally { loading.value = false } } onMounted(loadData) </script> <template> <p v-if="loading">加载中...</p> <p v-else-if="error">{{ error }}</p> <ul v-else> <li v-for="item in list" :key="item.id">{{ item.title }}</li> </ul> </template>

20.2 axios 示例

安装:

npminstallaxios

使用:

importaxiosfrom'axios'constres=awaitaxios.get('/api/todos')list.value=res.data

建议封装src/api/

src/api/ request.js user.js todo.js

这样组件里不要散落很多 URL。

21. 常用项目功能怎么组合

21.1 登录功能

涉及:

  • 表单v-model
  • 点击事件@click
  • 请求接口
  • Pinia 存 token/user
  • Vue Router 跳转

流程:

输入账号密码 -> 点击登录 -> 请求接口 -> 保存 token -> 跳转首页

21.2 列表页

涉及:

  • onMounted请求数据
  • v-for渲染列表
  • v-if显示 loading/empty/error
  • 搜索框v-model
  • 分页组件

流程:

进入页面 -> 请求列表 -> 展示数据 -> 搜索/分页 -> 重新请求

21.3 表单页

涉及:

  • reactive表单对象
  • v-model双向绑定
  • 表单校验
  • 提交请求
  • 成功后跳转

流程:

编辑表单 -> 校验 -> 提交接口 -> 成功提示 -> 返回列表

21.4 详情页

涉及:

  • 动态路由参数
  • useRoute
  • onMounted
  • 请求详情接口

流程:

/users/1001 -> 读取 id -> 请求用户详情 -> 渲染页面

22. 新手常见问题

22.1 为什么 JS 里要写.value

因为ref返回的是一个包装对象,真正的值在.value上。

constcount=ref(0)count.value++

模板里 Vue 会自动解包:

<p>{{ count }}</p>

22.2refreactive怎么选

简单规则:

  • 数字、字符串、布尔值:ref
  • 对象、表单:reactiveref
  • 不确定:先用ref

22.3 computed 和 watch 区别

computed用来算值:

商品单价 + 数量 -> 总价

watch用来做事情:

搜索词变化 -> 请求接口

23. 最小记忆清单

必须记住:

  • createApp(App).mount('#app'):创建并挂载应用。
  • .vue文件就是组件。
  • ref创建响应式数据,JS 里用.value
  • {{ }}显示数据。
  • :属性绑定属性。
  • @事件绑定事件。
  • v-if控制是否渲染。
  • v-for渲染列表,必须写:key
  • v-model表单双向绑定。
  • computed算派生值。
  • watch监听变化做副作用。
  • props 父传子,emit 子传父。
  • Router 管页面,Pinia 管全局状态。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/15 6:27:56

LabVIEW新手必看:MAX里找不到你的CompactRIO?这5个排查步骤帮你搞定

LabVIEW新手实战&#xff1a;MAX中找不到CompactRIO的终极排查指南当你满怀期待地打开LabVIEW准备大展身手时&#xff0c;却发现MAX里根本找不到你的CompactRIO设备——这种挫败感我太熟悉了。作为过来人&#xff0c;我整理了这份实战派排查手册&#xff0c;帮你系统性地定位问…

作者头像 李华
网站建设 2026/6/15 6:23:04

避开这些坑:S32K344 FlexCAN初始化与邮箱配置的实战避坑指南

S32K344 FlexCAN实战避坑指南&#xff1a;从初始化陷阱到邮箱配置的深度解析在嵌入式系统开发中&#xff0c;CAN总线通信一直是工业控制、汽车电子等领域的核心通信协议。NXP S32K344芯片集成的FlexCAN模块作为支持CAN FD的高性能控制器&#xff0c;其灵活性和强大功能背后也隐…

作者头像 李华
网站建设 2026/6/15 6:19:51

主动学习在极端不平衡行星宜居性分类中的应用与优化

1. 项目概述&#xff1a;主动学习在极端不平衡行星宜居性分类中的应用在系外行星研究领域&#xff0c;我们面临着一个极具挑战性的数据科学问题&#xff1a;如何从数千颗已知系外行星中识别出极少数可能适合生命存在的行星。根据最新统计&#xff0c;在NASA系外行星档案记录的5…

作者头像 李华