VUE3入门

Vue3 理解为:用组件化方式,把页面、数据、交互和工程结构组织起来的一套前端开发框架


一、先建立整体框架:Vue3 到底解决什么问题?

传统前端写法通常是:

html 复制代码
<button id="btn">+1</button>
<span id="count">0</span>

<script>
  let count = 0
  document.querySelector('#btn').onclick = function () {
    count++
    document.querySelector('#count').innerText = count
  }
</script>

这种写法的问题是:

你要自己找 DOM、改 DOM、维护数据和页面同步。页面小还好,页面一复杂,代码就乱。

Vue3 的核心思想是:

开发者主要维护"数据状态",Vue 自动根据数据变化更新页面。

也就是:

vue 复制代码
<script setup>
import { ref } from 'vue'

const count = ref(0)
</script>

<template>
  <button @click="count++">+1</button>
  <span>{{ count }}</span>
</template>

你不再手动操作 DOM,而是让 Vue 帮你完成"数据 → 页面"的更新。


二、Vue3 必学核心概念总览

Vue3 的核心基础概念可以按层次理解:

text 复制代码
Vue3 应用
│
├── 1. createApp:创建应用入口
│
├── 2. 单文件组件 .vue:页面开发的基本单位
│   ├── template:页面结构
│   ├── script setup:逻辑代码
│   └── style:样式
│
├── 3. 响应式数据
│   ├── ref
│   ├── reactive
│   ├── computed
│   └── watch / watchEffect
│
├── 4. 模板语法
│   ├── 插值表达式 {{ }}
│   ├── v-bind
│   ├── v-on
│   ├── v-if
│   ├── v-for
│   └── v-model
│
├── 5. 组件化开发
│   ├── props:父传子
│   ├── emit:子传父
│   ├── slot:插槽
│   └── provide / inject:跨层传递
│
├── 6. 生命周期
│   ├── onMounted
│   ├── onUpdated
│   └── onUnmounted
│
├── 7. 组合式 API
│   ├── setup
│   ├── composable
│   └── 逻辑复用
│
├── 8. 路由 Vue Router
│   ├── 页面切换
│   ├── 动态路由
│   └── 编程式跳转
│
├── 9. 状态管理 Pinia
│   ├── state
│   ├── getters
│   └── actions
│
└── 10. 工程化
    ├── Vite
    ├── npm
    ├── 目录结构
    └── 构建部署

Vue 官方文档把组件描述为可以把 UI 拆成独立、可复用的小块;Composition API 则通过 ref()reactive() 等函数直接创建响应式状态、计算状态和监听器;Pinia 是 Vue 生态中用于共享跨组件状态的状态管理库。(vuejs.org)


三、核心概念逐个讲解

1. createApp:Vue 应用入口

专业解释

createApp() 是 Vue3 创建应用实例的入口函数。它负责创建 Vue 应用,并通过 .mount() 挂载到真实 DOM 容器中。

小白解释

你可以把它理解为:

Vue 项目的"启动按钮"。

HTML 页面里有一个空盒子:

html 复制代码
<div id="app"></div>

Vue 会把你的应用安装到这个盒子里。

简单案例

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'

createApp(App).mount('#app')

用途

它决定:

这个 Vue 应用从哪个组件开始运行;

挂载到页面中的哪个 DOM 节点;

后续是否安装路由、Pinia、插件等。


2. 单文件组件 SFC:.vue 文件

专业解释

Vue 的单文件组件,也叫 SFC,通常由三部分组成:

vue 复制代码
<template>
  页面结构
</template>

<script setup>
  逻辑代码
</script>

<style scoped>
  样式代码
</style>

小白解释

一个 .vue 文件就像一个"页面积木块":

template 写页面长什么样;

script 写页面怎么动;

style 写页面好不好看。

简单案例

vue 复制代码
<template>
  <h1>{{ title }}</h1>
</template>

<script setup>
const title = '欢迎学习 Vue3'
</script>

<style scoped>
h1 {
  color: blue;
}
</style>

用途

单文件组件让一个功能模块的结构、逻辑、样式集中在一起,便于维护。

例如:

text 复制代码
StudentCard.vue    学生卡片组件
CourseList.vue     课程列表组件
LoginForm.vue      登录表单组件

3. 响应式数据:ref 和 reactive

这是 Vue3 最核心的概念。

专业解释

Vue3 的响应式系统可以追踪数据变化,并在数据变化后自动触发页面更新。ref() 常用于基本类型,也可以包裹对象;reactive() 常用于对象。Vue 官方文档说明,ref 会让其值具备深层响应式能力,对嵌套对象或数组的修改也能被检测到。(vuejs.org)

小白解释

你可以把响应式数据理解为:

数据和页面之间绑了一根自动同步的线。

数据一变,页面自动变。

ref 案例

vue 复制代码
<script setup>
import { ref } from 'vue'

const count = ref(0)

function add() {
  count.value++
}
</script>

<template>
  <button @click="add">点击</button>
  <p>当前数量:{{ count }}</p>
</template>

注意:

在 JS 里访问 ref 要写:

js 复制代码
count.value

在模板里可以直接写:

html 复制代码
{{ count }}

reactive 案例

vue 复制代码
<script setup>
import { reactive } from 'vue'

const student = reactive({
  name: '张三',
  age: 20
})

function grow() {
  student.age++
}
</script>

<template>
  <p>{{ student.name }} - {{ student.age }}岁</p>
  <button @click="grow">年龄+1</button>
</template>

用途

refreactive 用来保存页面状态,比如:

输入框内容;

按钮点击次数;

用户信息;

列表数据;

接口返回结果。


4. 模板语法:让数据和页面绑定起来

Vue 的模板语法是连接"数据"和"页面"的桥梁。


4.1 插值表达式 {``{ }}

专业解释

插值表达式用于在模板中渲染响应式数据。

小白解释

就是把 JS 里的变量显示到页面上。

案例

vue 复制代码
<script setup>
const name = '李雷'
</script>

<template>
  <p>你好,{{ name }}</p>
</template>

4.2 v-bind:绑定属性

专业解释

v-bind 用于动态绑定 HTML 属性。

简写形式是 :

小白解释

如果图片地址、按钮状态、链接地址是变量,就用 v-bind

案例

vue 复制代码
<script setup>
const imgUrl = 'https://example.com/logo.png'
</script>

<template>
  <img :src="imgUrl" />
</template>

等价于:

html 复制代码
<img v-bind:src="imgUrl" />

4.3 v-on:绑定事件

专业解释

v-on 用于监听 DOM 事件。

简写形式是 @

小白解释

点击按钮、输入内容、鼠标移动,这些用户动作都可以用它处理。

案例

vue 复制代码
<script setup>
function sayHello() {
  alert('你好')
}
</script>

<template>
  <button @click="sayHello">点击</button>
</template>

4.4 v-if:条件渲染

专业解释

v-if 用于根据条件决定元素是否渲染到 DOM 中。

小白解释

满足条件才显示,不满足就不显示。

案例

vue 复制代码
<script setup>
import { ref } from 'vue'

const isLogin = ref(false)
</script>

<template>
  <p v-if="isLogin">欢迎回来</p>
  <p v-else>请先登录</p>
</template>

4.5 v-for:列表渲染

专业解释

v-for 用于根据数组或对象循环渲染多个节点。

小白解释

有多少条数据,就自动生成多少个页面元素。

案例

vue 复制代码
<script setup>
const students = ['张三', '李四', '王五']
</script>

<template>
  <ul>
    <li v-for="name in students" :key="name">
      {{ name }}
    </li>
  </ul>
</template>

重点

v-for 一般要配合 :key 使用,帮助 Vue 更高效地更新列表。


4.6 v-model:双向绑定

专业解释

v-model 用于表单输入和响应式数据之间建立双向绑定。

小白解释

输入框里打字,变量自动变;变量变,输入框也自动变。

案例

vue 复制代码
<script setup>
import { ref } from 'vue'

const username = ref('')
</script>

<template>
  <input v-model="username" placeholder="请输入用户名" />
  <p>你输入的是:{{ username }}</p>
</template>

四、computed:计算属性

专业解释

computed 用于基于已有响应式数据派生出新的数据,并且具有缓存能力。只有依赖的数据发生变化时,计算属性才会重新计算。

小白解释

它像 Excel 里的公式。

比如:

text 复制代码
总价 = 单价 × 数量

只要单价或数量变了,总价自动变。

案例

vue 复制代码
<script setup>
import { ref, computed } from 'vue'

const price = ref(10)
const count = ref(2)

const total = computed(() => price.value * count.value)
</script>

<template>
  <p>单价:{{ price }}</p>
  <p>数量:{{ count }}</p>
  <p>总价:{{ total }}</p>
</template>

用途

适合处理:

总价;

筛选后的列表;

格式化后的用户名;

是否可以提交表单;

根据状态派生出来的新状态。


五、watch:监听数据变化

专业解释

watch 用于监听响应式数据的变化,并在变化时执行副作用逻辑,比如请求接口、保存本地缓存、打印日志等。

小白解释

watch 就像一个"观察员"。

它盯着某个数据,一旦数据变了,就立刻做某件事。

案例

vue 复制代码
<script setup>
import { ref, watch } from 'vue'

const keyword = ref('')

watch(keyword, (newValue, oldValue) => {
  console.log('搜索关键词变化了:', newValue)
})
</script>

<template>
  <input v-model="keyword" placeholder="请输入搜索关键词" />
</template>

computed 和 watch 的区别

概念 作用 是否返回新值 典型用途
computed 根据已有数据算出新数据 总价、过滤列表、格式化显示
watch 监听数据变化后执行动作 发请求、存缓存、打印日志

一句话理解:

computed 用来"算结果",watch 用来"做事情"。


六、组件化开发:Vue 的核心开发方式

专业解释

组件是 Vue 应用的基本组织单位。Vue 官方文档指出,组件可以把 UI 拆成独立、可复用的部分,并且可以单独思考每个部分。(vuejs.org)

小白解释

组件就像乐高积木。

一个页面不是一整坨代码,而是由很多小组件拼起来的。

例如一个后台管理页面:

text 复制代码
App.vue
├── Header.vue
├── Sidebar.vue
├── UserTable.vue
├── SearchForm.vue
└── Pagination.vue

简单案例

父组件 App.vue

vue 复制代码
<script setup>
import StudentCard from './components/StudentCard.vue'
</script>

<template>
  <StudentCard />
</template>

子组件 StudentCard.vue

vue 复制代码
<template>
  <div>
    <h3>学生姓名:张三</h3>
    <p>专业:计算机科学</p>
  </div>
</template>

用途

组件化可以带来:

代码复用;

结构清晰;

多人协作方便;

维护成本低;

页面复杂时不容易混乱。


七、props:父组件给子组件传数据

专业解释

props 是父组件向子组件传递数据的机制。

小白解释

父组件就像家长,子组件像孩子。

家长把数据交给孩子展示。

案例

父组件

vue 复制代码
<script setup>
import StudentCard from './StudentCard.vue'
</script>

<template>
  <StudentCard name="张三" major="软件工程" />
</template>

子组件

vue 复制代码
<script setup>
defineProps({
  name: String,
  major: String
})
</script>

<template>
  <div>
    <h3>{{ name }}</h3>
    <p>{{ major }}</p>
  </div>
</template>

用途

适合:

父组件把用户信息传给用户卡片;

父组件把商品信息传给商品组件;

父组件把配置项传给按钮、弹窗、表格组件。


八、emit:子组件通知父组件

专业解释

emit 是子组件向父组件发送事件的机制。

小白解释

孩子不能直接改家长的数据,但可以告诉家长:

"我被点击了,你来处理吧。"

案例

子组件 DeleteButton.vue

vue 复制代码
<script setup>
const emit = defineEmits(['delete'])

function handleClick() {
  emit('delete')
}
</script>

<template>
  <button @click="handleClick">删除</button>
</template>

父组件

vue 复制代码
<script setup>
import DeleteButton from './DeleteButton.vue'

function removeItem() {
  console.log('父组件执行删除')
}
</script>

<template>
  <DeleteButton @delete="removeItem" />
</template>

用途

适合:

子组件按钮点击后通知父组件;

弹窗组件通知父组件关闭;

表单组件通知父组件提交;

列表项通知父组件删除某条数据。


九、slot:插槽

专业解释

slot 用于让父组件向子组件传入一段模板内容。

小白解释

插槽就像一个"预留空位"。

子组件先留一个位置,父组件想放什么就放什么。

案例

Card.vue

vue 复制代码
<template>
  <div class="card">
    <slot></slot>
  </div>
</template>

父组件

vue 复制代码
<Card>
  <h3>标题</h3>
  <p>这是卡片内容</p>
</Card>

用途

适合封装通用组件:

卡片;

弹窗;

布局容器;

按钮;

表格列内容。


十、生命周期:组件从出生到销毁

专业解释

生命周期是组件在创建、挂载、更新、卸载等阶段提供的钩子函数。Vue3 Composition API 中常用的生命周期函数包括 onMountedonUpdatedonUnmounted 等。官方文档说明,onMounted 通常用于执行需要访问已渲染 DOM 的副作用逻辑。(vuejs.org)

小白解释

一个组件也有"生命过程":

text 复制代码
创建 → 显示到页面 → 数据变化重新渲染 → 从页面移除

你可以在不同阶段做不同事情。

案例

vue 复制代码
<script setup>
import { onMounted } from 'vue'

onMounted(() => {
  console.log('组件已经显示到页面上了')
})
</script>

<template>
  <p>生命周期示例</p>
</template>

用途

常用于:

页面加载后请求接口;

组件显示后获取 DOM;

页面离开前清理定时器;

图表组件初始化;

地图组件初始化。


十一、Composition API:组合式 API

专业解释

Composition API 是 Vue3 推荐的重要写法。它允许开发者使用导入函数来组织组件逻辑,而不是把代码分散在 datamethodscomputed 等选项中。官方文档说明,Composition API 包含响应式 API,例如 ref()reactive(),可以直接创建响应式状态、计算状态和监听器。(vuejs.org)

小白解释

传统写法像这样:

text 复制代码
数据放一个地方
方法放一个地方
计算属性放一个地方
监听器放一个地方

功能一复杂,同一个业务逻辑会被拆得很散。

Composition API 的好处是:

和"用户搜索"相关的代码放一起,和"购物车"相关的代码放一起,和"登录"相关的代码放一起。

案例

vue 复制代码
<script setup>
import { ref, computed } from 'vue'

const keyword = ref('')
const list = ref(['Vue', 'React', 'Angular'])

const filteredList = computed(() => {
  return list.value.filter(item => item.includes(keyword.value))
})
</script>

<template>
  <input v-model="keyword" />
  <ul>
    <li v-for="item in filteredList" :key="item">
      {{ item }}
    </li>
  </ul>
</template>

用途

Composition API 特别适合:

复杂页面;

逻辑复用;

大型项目;

TypeScript 项目;

把业务逻辑抽离成 composable。


十二、Composable:可复用逻辑函数

专业解释

Composable 是基于 Composition API 抽离出来的可复用逻辑函数,通常命名为 useXxx

小白解释

如果多个页面都要用同一套逻辑,就不要复制粘贴,而是把它封装成一个函数。

案例:封装计数逻辑

useCounter.js

js 复制代码
import { ref } from 'vue'

export function useCounter() {
  const count = ref(0)

  function add() {
    count.value++
  }

  function minus() {
    count.value--
  }

  return {
    count,
    add,
    minus
  }
}

组件中使用

vue 复制代码
<script setup>
import { useCounter } from './useCounter'

const { count, add, minus } = useCounter()
</script>

<template>
  <button @click="minus">-</button>
  <span>{{ count }}</span>
  <button @click="add">+</button>
</template>

用途

适合复用:

搜索逻辑;

分页逻辑;

表单校验逻辑;

接口请求逻辑;

倒计时逻辑;

弹窗开关逻辑。


十三、Vue Router:前端路由

专业解释

Vue Router 是 Vue 的官方路由工具,用于管理单页应用中的页面切换。Vue Router 4 可用于 Vue3,并支持 Composition API 和 Options API;官方文档也说明,Vue3 应使用 Vue Router 4,而 Vue Router 3 是面向 Vue2 的旧版本。(router.vuejs.org)

小白解释

传统网站跳页面是:

text 复制代码
浏览器重新请求一个新 HTML 页面

Vue 单页应用中,页面切换通常是:

text 复制代码
不刷新整个页面,只切换中间显示的组件

案例

路由配置

js 复制代码
import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'

const router = createRouter({
  history: createWebHistory(),
  routes: [
    { path: '/', component: Home },
    { path: '/about', component: About }
  ]
})

export default router

main.js

js 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

createApp(App).use(router).mount('#app')

App.vue

vue 复制代码
<template>
  <router-link to="/">首页</router-link>
  <router-link to="/about">关于</router-link>

  <router-view />
</template>

用途

Vue Router 用来实现:

首页;

详情页;

登录页;

后台管理页面;

菜单导航;

动态路由;

权限路由。


十四、Pinia:状态管理

专业解释

Pinia 是 Vue 官方生态推荐的状态管理库,用于管理跨组件、跨页面共享的数据。Pinia 官方文档说明,Store 是保存状态和业务逻辑的实体,不绑定到组件树;它包含 state、getters、actions,这三者可以类比为组件中的 data、computed、methods。(pinia.vuejs.org)

Vue 官方文档也提到,Pinia 由 Vue 核心团队维护,Vuex 目前处于维护模式,新项目推荐使用 Pinia。(vuejs.org)

小白解释

如果只是父子组件传数据,用 props 和 emit 就够了。

但如果很多页面都要用同一份数据,比如:

当前登录用户;

购物车;

系统主题;

权限菜单;

全局消息;

这时候就需要 Pinia。

它像一个"全局仓库"。

案例

stores/user.js

js 复制代码
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  state: () => ({
    name: '张三',
    isLogin: false
  }),

  getters: {
    welcomeText: state => `欢迎,${state.name}`
  },

  actions: {
    login(name) {
      this.name = name
      this.isLogin = true
    }
  }
})

组件中使用

vue 复制代码
<script setup>
import { useUserStore } from './stores/user'

const userStore = useUserStore()

function handleLogin() {
  userStore.login('李四')
}
</script>

<template>
  <p>{{ userStore.welcomeText }}</p>
  <button @click="handleLogin">登录</button>
</template>

用途

Pinia 适合管理:

用户信息;

购物车数据;

后台权限;

跨页面共享状态;

主题设置;

多组件共享的业务状态。


十五、接口请求:前端和后端交互

专业解释

Vue 本身不限定请求库,项目中常用 fetchaxios 与后端 API 通信。接口返回的数据通常保存到 refreactive 中,再由模板渲染。

小白解释

Vue 页面不是所有数据都写死在前端。

很多数据来自服务器,比如:

学生列表;

商品列表;

新闻列表;

登录结果;

课程信息。

案例

vue 复制代码
<script setup>
import { ref, onMounted } from 'vue'

const students = ref([])

onMounted(async () => {
  const res = await fetch('/api/students')
  students.value = await res.json()
})
</script>

<template>
  <ul>
    <li v-for="stu in students" :key="stu.id">
      {{ stu.name }}
    </li>
  </ul>
</template>

用途

真实项目中,Vue 主要负责:

展示后端数据;

收集用户输入;

调用接口提交数据;

根据接口结果更新页面。


十六、工程化:Vite、npm、目录结构

专业解释

Vue3 项目通常使用 Vite 作为构建工具,通过 npm 管理依赖,并采用模块化目录结构组织代码。

小白解释

写几个 HTML 文件可以不用工程化。

但做真正项目时,需要:

自动启动开发服务器;

自动热更新;

打包压缩代码;

安装第三方库;

管理多个组件和页面。

这就是工程化。

常见目录结构

text 复制代码
src
├── assets        静态资源
├── components    公共组件
├── views         页面组件
├── router        路由配置
├── stores        Pinia 状态管理
├── utils         工具函数
├── api           接口请求
├── App.vue       根组件
└── main.js       应用入口

十七、把所有概念串起来:一个 Todo 小案例

下面这个案例可以把 Vue3 的核心概念串起来。

功能

输入任务;

点击添加;

显示任务列表;

点击删除;

显示任务总数。

vue 复制代码
<script setup>
import { ref, computed } from 'vue'

const newTodo = ref('')

const todos = ref([
  { id: 1, text: '学习 Vue3 基础' },
  { id: 2, text: '练习组件化开发' }
])

const total = computed(() => todos.value.length)

function addTodo() {
  if (!newTodo.value.trim()) return

  todos.value.push({
    id: Date.now(),
    text: newTodo.value
  })

  newTodo.value = ''
}

function removeTodo(id) {
  todos.value = todos.value.filter(todo => todo.id !== id)
}
</script>

<template>
  <div>
    <h2>任务清单</h2>

    <input v-model="newTodo" placeholder="请输入任务" />
    <button @click="addTodo">添加</button>

    <p>当前任务数量:{{ total }}</p>

    <ul>
      <li v-for="todo in todos" :key="todo.id">
        {{ todo.text }}
        <button @click="removeTodo(todo.id)">删除</button>
      </li>
    </ul>
  </div>
</template>

这个例子中:

代码 用到的 Vue 概念
ref('') 响应式数据
computed() 计算属性
v-model 表单双向绑定
@click 事件绑定
v-for 列表渲染
:key 列表更新优化
{``{ total }} 插值表达式
addTodo() 方法逻辑
removeTodo() 数据驱动页面更新

十八、Vue3 核心概念之间的逻辑关系

你可以这样理解 Vue3 的整体运行逻辑:

text 复制代码
用户操作页面
    ↓
触发事件 @click / @input
    ↓
修改响应式数据 ref / reactive
    ↓
computed 自动重新计算
    ↓
template 自动重新渲染
    ↓
页面更新

再往项目层面扩展:

text 复制代码
main.js
创建 Vue 应用
    ↓
App.vue
根组件
    ↓
Vue Router
决定当前显示哪个页面组件
    ↓
页面组件 views
组织业务页面
    ↓
公共组件 components
拆分可复用 UI
    ↓
props / emit / slot
完成组件通信
    ↓
Pinia
管理跨页面共享状态
    ↓
API 请求
和后端交换数据

十九、学习 Vue3 的推荐顺序

建议你按这个顺序学:

text 复制代码
第一阶段:基础语法
1. Vue 项目创建
2. .vue 单文件组件
3. 插值表达式
4. v-bind
5. v-on
6. v-if
7. v-for
8. v-model

第二阶段:响应式核心
9. ref
10. reactive
11. computed
12. watch
13. 生命周期

第三阶段:组件化
14. 组件拆分
15. props
16. emit
17. slot
18. provide / inject

第四阶段:项目开发
19. Vue Router
20. Pinia
21. axios / fetch
22. 表单
23. 权限
24. 项目目录结构

第五阶段:进阶
25. composable
26. TypeScript
27. 性能优化
28. 组件库
29. 打包部署
30. SSR / Nuxt

二十、一句话总结 Vue3

Vue3 的核心不是"多背几个指令",而是理解这条主线:

用组件组织页面,用响应式数据驱动页面,用模板声明页面结构,用事件修改状态,用路由组织页面切换,用 Pinia 管理全局数据,用工程化工具组织大型项目。

掌握这条主线后,你再看任何 Vue3 项目,基本都能知道:

哪个文件是入口;

哪个组件负责页面;

数据在哪里;

事件在哪里;

接口在哪里;

路由在哪里;

全局状态在哪里。

相关推荐
yqcoder1 小时前
JavaScript 浅拷贝:只复制“第一层”的艺术
开发语言·javascript·ecmascript
yqcoder1 小时前
JavaScript 闭包:函数背后的“背包”
开发语言·javascript·ecmascript
threelab2 小时前
挑战AI辅助从零构建3D模型编辑器:01基于Vue3 + Three.js的现代化架构设计
javascript·人工智能·3d·前端框架·着色器
张元清2 小时前
React 浏览器标签页 UX:用标题、Favicon 和通知把用户拉回来
前端·javascript·面试
葛兰岱尔2 小时前
葛兰岱尔rapid3D Loader for Three.js使用方式及7个基础API说明
开发语言·javascript·3d
Lkstar2 小时前
读完红宝书和YDKJS,我终于搞懂了原型链、闭包和this
javascript·面试
用户11489669441052 小时前
JavaScript原型链解析
javascript
Mr数据杨2 小时前
【Codex】用APP绑定教程模块规范移动端接入指引
java·前端·javascript·django·codex·项目开发
博客zhu虎康2 小时前
小程序按钮实现先表单校验再走手机号获取功能
android·javascript·小程序