前端八股Vue---Vue2和Vue3的区别,set up的用法

目录

一、核心区别速览

二、详细对比

[1. 响应式原理不同(最重要)](#1. 响应式原理不同(最重要))

[2. 写法不同(最明显)](#2. 写法不同(最明显))

[3. 生命周期变化](#3. 生命周期变化)

[4. 性能提升](#4. 性能提升)

[5. 其他重要区别](#5. 其他重要区别)

[5.1 多根节点(Fragment)](#5.1 多根节点(Fragment))

[5.2 Teleport(传送门)](#5.2 Teleport(传送门))

[5.3 Suspense(异步组件)](#5.3 Suspense(异步组件))

[5.4 根实例创建方式](#5.4 根实例创建方式)

[5.5 移除的 API](#5.5 移除的 API)

[三、setup 提供的核心优势](#三、setup 提供的核心优势)

[四、setup 怎么用?](#四、setup 怎么用?)

[4.1 传统写法(setup 函数)](#4.1 传统写法(setup 函数))

[4.2 现代写法script setup语法糖](#4.2 现代写法script setup语法糖)

[4.3 script setup的优势](#4.3 script setup的优势)

五、面试高频问题

[Q1:Vue2 和 Vue3 的区别有哪些?](#Q1:Vue2 和 Vue3 的区别有哪些?)

[Q2:setup 提供了什么?](#Q2:setup 提供了什么?)

[Q3:script setup和普通 script有什么区别?](#Q3:script setup和普通 script有什么区别?)


一、核心区别速览

对比维度 Vue2 Vue3
响应式原理 Object.defineProperty Proxy
API 风格 Options API(选项式) Composition API(组合式)
生命周期 beforeCreate、created... setup 代替前两个,其他加 on
性能 一般 更快、更小
TypeScript 支持较弱 原生支持
根实例创建 new Vue() createApp()
多根节点 ❌ 不支持 ✅ 支持(Fragment)
Teleport ❌ 无 ✅ 有
Suspense ❌ 无 ✅ 有

二、详细对比

1. 响应式原理不同(最重要)

Vue2:Object.defineProperty

javascript 复制代码
// Vue2 响应式原理(简化)
Object.defineProperty(obj, 'name', {
  get() { /* 收集依赖 */ },
  set() { /* 触发更新 */ }
})

// 问题1:新增属性监听不到
this.user.newProp = 'hello'  // ❌ 不响应,需要 $set
this.$set(this.user, 'newProp', 'hello')  // ✅ 需要额外 API

// 问题2:删除属性监听不到
delete this.user.name  // ❌ 不响应,需要 $delete

// 问题3:数组下标修改监听不到
this.list[0] = newValue  // ❌ 不响应

Vue3:Proxy

javascript 复制代码
// Vue3 响应式原理(简化)
const proxy = new Proxy(obj, {
  get(target, key) { /* 收集依赖 */ },
  set(target, key, value) { /* 触发更新 */ },
  deleteProperty(target, key) { /* 触发更新 */ }
})

// ✅ 新增属性自动响应
state.user.newProp = 'hello'  // ✅ 自动响应

// ✅ 删除属性自动响应
delete state.user.name  // ✅ 自动响应

// ✅ 数组下标自动响应
state.list[0] = newValue  // ✅ 自动响应

// 不需要 $set、$delete

2. 写法不同(最明显)

Vue2:Options API

javascript 复制代码
<script>
export default {
  data() {
    return {
      count: 0,
      user: null
    }
  },
  computed: {
    double() {
      return this.count * 2
    }
  },
  methods: {
    increment() {
      this.count++
    }
  },
  mounted() {
    this.fetchUser()
  }
}
</script>

Vue3:Composition API

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

// 计数器逻辑(聚在一起)
const count = ref(0)
const double = computed(() => count.value * 2)
const increment = () => count.value++

// 用户逻辑(聚在一起)
const user = ref(null)
const fetchUser = async () => {
  user.value = await api.getUser()
}
onMounted(() => {
  fetchUser()
})
</script>

3. 生命周期变化

Vue2 Vue3 (Options API) Vue3 (Composition API)
beforeCreate beforeCreate ❌ 不需要(setup 替代)
created created ❌ 不需要(setup 替代)
beforeMount beforeMount onBeforeMount
mounted mounted onMounted
beforeUpdate beforeUpdate onBeforeUpdate
updated updated onUpdated
beforeDestroy beforeUnmount onBeforeUnmount
destroyed unmounted onUnmounted

4. 性能提升

优化点 说明
Tree shaking 未使用的代码不打包,体积更小
Diff 算法优化 增加静态标记,只对比动态内容
静态节点提升 静态节点只创建一次,复用
事件缓存 事件处理函数缓存,减少内存开销

5. 其他重要区别

5.1 多根节点(Fragment)
javascript 复制代码
<!-- Vue2:必须只有一个根节点 -->
<template>
  <div>  <!-- 必须有一个包裹元素 -->
    <h1>标题</h1>
    <p>内容</p>
  </div>
</template>

<!-- Vue3:支持多个根节点 -->
<template>
  <h1>标题</h1>
  <p>内容</p>
</template>
5.2 Teleport(传送门)
javascript 复制代码
<!-- 弹窗挂载到 body,避免被父组件样式影响 -->
<template>
  <teleport to="body">
    <div class="modal">
      <h3>弹窗标题</h3>
      <p>弹窗内容</p>
    </div>
  </teleport>
</template>
5.3 Suspense(异步组件)
javascript 复制代码
<template>
  <Suspense>
    <template #default>
      <AsyncComponent />  <!-- 异步组件 -->
    </template>
    <template #fallback>
      <div>加载中...</div>  <!-- 加载时显示 -->
    </template>
  </Suspense>
</template>
5.4 根实例创建方式
javascript 复制代码
// Vue2
import Vue from 'vue'
import App from './App.vue'

const vm = new Vue({
  render: h => h(App)
}).$mount('#app')

// Vue3
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)
app.mount('#app')
5.5 移除的 API
移除项 替代方案
$on$off mitt、事件总线
$set$delete 不需要了(Proxy 自动响应)
过滤器 计算属性或方法
$children 使用 $refs

三、setup 提供的核心优势

优势 说明
按功能组织代码 相关逻辑放在一起,而不是分散在 data、methods、mounted
逻辑复用 可以封装成自定义 Hooks,在多个组件间复用
TypeScript 友好 类型推导完美,不需要额外类型声明
更好的性能 编译时优化,减少运行时开销
没有 this 困扰 普通函数中用变量,不用担心 this 指向
Tree-shaking 支持 未使用的 API 不会打包

四、setup 怎么用?

4.1 传统写法(setup 函数)

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

export default {
  setup() {
    const count = ref(0)
    const increment = () => count.value++
    
    // 必须 return,才能在模板中使用
    return { count, increment }
  }
}
</script>

4.2 现代写法script setup语法糖

<script setup> 语法糖)

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

// 直接写,不需要 return
const count = ref(0)
const increment = () => count.value++
</script>

<template>
  <button @click="increment">{{ count }}</button>
</template>

4.3 script setup的优势

优势 说明
代码更少 不需要 export defaultreturn
自动暴露 定义的变量、函数自动在模板可用
更好的性能 编译时优化
更好的 TS 支持 类型推导更准确

五、面试高频问题

Q1:Vue2 和 Vue3 的区别有哪些?

答:

  1. 响应式原理 :Vue2 用 Object.defineProperty,Vue3 用 Proxy(能监听新增、删除、数组)

  2. API 风格 :Vue2 是 Options API,Vue3 是 Composition API(<script setup>

  3. 生命周期 :Vue3 用 setup 代替 beforeCreate/created,其他加 on 前缀

  4. 性能:Vue3 打包更小、渲染更快

  5. 新特性:Vue3 支持多根节点、Teleport、Suspense

  6. TypeScript:Vue3 原生支持更好

  7. 根实例 :Vue2 用 new Vue(),Vue3 用 createApp()

Q2:setup 提供了什么?

答:setup 是 Vue3 组合式 API 的入口,提供了以下核心能力:

  1. 响应式 APIrefreactive

  2. 计算属性computed

  3. 侦听器watchwatchEffect

  4. 生命周期onMountedonUpdatedonUnmounted

  5. 组件通信definePropsdefineEmitsdefineExpose

  6. 依赖注入provideinject

  7. 模板引用ref

核心优势:代码按功能组织、逻辑复用方便、TypeScript 友好、没有 this 困扰、性能更好。

Q3: script setup和普通 script有什么区别?

答:

  • <script setup> 是语法糖,代码更简洁,不需要 return

  • 定义的变量、函数自动在模板中可用

  • 更好的性能(编译时优化)和 TypeScript 支持

  • 是 Vue 3 推荐写法

相关推荐
mldong2 小时前
你的 Vue3 项目也能有钉钉同款审批流设计器:npm 装包,10 分钟画出第一条审批流
前端·vue.js
2分钟速写快排3 小时前
什么是 RAG?如何用 RAG 实现一个用户记忆?
前端·后端·ai编程
passerby60613 小时前
如何自己造一个时间处理库
前端·javascript·github
走到天涯海角4 小时前
react里面的长列表渲染优化
前端·react.js·前端框架
小羊没烦恼!4 小时前
Hello Web API系列教程——Web API与国际化
java·服务器·前端·javascript·php
北岛贰5 小时前
迷茫焦虑期,我做了一个带支付带官网的 AI 聊天虚拟恋人 App
前端·人工智能·后端
mayaairi6 小时前
Vue2 组件通讯(三):全局事件总线、PubSub、插槽与组件实例属性
前端·javascript·vue.js
kyriewen7 小时前
面试官问我:AI 都能写代码了,前端凭什么还值 25K
前端·javascript·人工智能
风骏时光牛马8 小时前
AI源码分析:拆解模型底层实现逻辑
前端
BillKu8 小时前
全局样式变量:CSS 自定义属性(--border-color)和SCSS 变量($border-color)的说明
javascript·css·scss