首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Vue3、Vue2

Vue3、Vue2

原创
作者头像
用户11850140
发布2025-12-31 10:43:59
发布2025-12-31 10:43:59
1630
举报
文章被收录于专栏:前端前端

1.API 风格:选项式 vs 组合式

总结 选项方和组合式的区别

对比维度

Vue2 选项式 API

Vue3 组合式 API(setup 函数 / setup 语法糖)

代码组织方式

按选项类型组织:data、methods、computed、watch 等分散在不同选项中

按逻辑功能组织:相关变量、函数、计算属性和监听器集中在一起

访问响应式数据

通过 this 访问 data、methods 等成员

使用 ref 和 reactive 创建响应式数据,通过 .value 访问 ref 值(在 JS 中)

模板中使用变量

直接使用 data 中定义的属性,无需 .value

模板中使用 ref 时自动解包,无需 .value

入口函数

组件选项对象本身(如 export default { ... })

setup() 函数作为组件的入口,或使用 setup 语法糖自动执行

语法糖支持

不支持 setup

支持 setup语法糖,省去 setup() 函数和 return,更简洁

this 指向

在 methods、computed 中可使用 this 指向组件实例

例 setup() 中没有 this,完全基于函数式编程思想

代码拆分灵活性

难以将同一功能的逻辑拆分到多个文件

可轻松将逻辑提取为独立的组合函数(composables)并跨组件复用

Vue2:选项式 API

  • 逻辑按类型组织:data、methods、computed、watch分散在不同区域
代码语言:vue
复制
<template>
  <div>
    <h2>计数器: {{ count }}</h2>
    <p>双倍值: {{ doubleCount }}</p>
    <button @click="increment">+1</button>

    <input v-model="search" placeholder="搜索用户" />
    <ul>
      <li v-for="user in filteredUsers" :key="user.id">
        {{ user.name }}
      </li>
    </ul>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        count: 0,
        search: '',
        users: [
          { id: 1, name: 'Alice' },
          { id: 2, name: 'Bob' },
          { id: 3, name: 'Charlie' }
        ]
      }
    },
    methods: {
      increment() {
        this.count++
      }
    },
    computed: {
      doubleCount() {
        return this.count * 2
      },
      filteredUsers() {
        return this.users.filter(u =>
            u.name.toLowerCase().includes(this.search.toLowerCase())
        )
      }
    },
    watch: {
      count(newVal) {
        console.log('count changed:', newVal)
      }
    }
  }
</script> 

Vue3:组合式 API

  • 逻辑按功能组织,复用性更强,适合大型项目
写法一:使用 setup() 函数
代码语言:vue
复制
<!-- Vue 3 - 标准 setup -->
<template>
  <div>
    <h2>计数器: {{ count }}</h2>
    <p>双倍值: {{ doubleCount }}</p>
    <button @click="increment">+1</button>

    <input v-model="search" placeholder="搜索用户" />
    <ul>
      <li v-for="user in filteredUsers" :key="user.id">
        {{ user.name }}
      </li>
    </ul>
  </div>
</template>

<script>
import { ref, computed, watch } from 'vue'

export default {
  setup() {
    // 计数逻辑
    const count = ref(0)
    const doubleCount = computed(() => count.value * 2)
    const increment = () => {
      count.value++
    }

    // 搜索逻辑
    const search = ref('')
    const users = ref([
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' },
      { id: 3, name: 'Charlie' }
    ])
    const filteredUsers = computed(() => {
      return users.value.filter(u =>
        u.name.toLowerCase().includes(search.value.toLowerCase())
      )
    })

    // 监听
    watch(count, (newVal) => {
      console.log('count changed:', newVal)
    })

    // 返回给模板使用的变量和方法
    return {
      count,
      doubleCount,
      increment,
      search,
      filteredUsers
    }
  }
}
</script>
写法二:使用 setup(语法糖)
代码语言:vue
复制
<!-- Vue 3 - 使用 <script setup>(顶级语法糖) -->
<script setup>
import { ref, computed, watch } from 'vue'

// 计数逻辑
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
const increment = () => count.value++

// 搜索逻辑
const search = ref('')
const users = ref([
  { id: 1, name: 'Alice' },
  { id: 2, name: 'Bob' },
  { id: 3, name: 'Charlie' }
])
const filteredUsers = computed(() => {
  return users.value.filter(u =>
    u.name.toLowerCase().includes(search.value.toLowerCase())
  )
})

// 监听
watch(count, (newVal) => {
  console.log('count changed:', newVal)
})
</script>

<template>
  <div>
    <h2>计数器: {{ count }}</h2>
    <p>双倍值: {{ doubleCount }}</p>
    <button @click="increment">+1</button>

    <input v-model="search" placeholder="搜索用户" />
    <ul>
      <li v-for="user in filteredUsers" :key="user.id">
        {{ user.name }}
      </li>
    </ul>
  </div>
</template>

2.应用初始化方式不同

Vue2全局构造函数

代码语言:vue
复制
import Vue from 'vue'
import App from './App.vue'

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

Vue3全局构造函数

代码语言:vue
复制
import { createApp } from 'vue'
import App from './App.vue'

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

3.初始化生命周期

Vue 2 生命周期钩子

钩子

执行时机

是否常用

beforeCreate

实例初始化后,数据观测和事件配置之前

少用

created

实例创建完成,数据已响应式,但 DOM 未挂载

常用于请求数据

beforeMount

模板编译完成,即将挂载到 DOM

较少使用

mounted

组件已挂载到 DOM,可操作真实 DOM

最常用之一

beforeUpdate

数据更新时,虚拟 DOM 重新渲染前

可用于调试

updated

虚拟 DOM 重新渲染并应用到 DOM 后

注意避免无限循环

beforeDestroy

组件销毁前,仍可访问实例

清理定时器、事件监听等

destroyed

组件已销毁,所有绑定解除,子实例也被销毁

常用

Vue 2 完整生命周期演示

代码语言:vue
复制
<!-- Vue 2 -->
<template>
  <div id="app">
    <h2 v-if="show">当前计数:{{ count }}</h2>
    <button @click="count++">+1</button>
    <button @click="show = false">销毁组件</button>
  </div>
</template>

<script>
export default {
  name: 'App',

  data() {
    return {
      count: 0,
      show: true,
      timer: null
    }
  },

  beforeCreate() {
    console.log(' beforeCreate: 实例还未初始化')
    // 此时 this.$el 不存在,data 未代理
  },

  created() {
    console.log('created: 实例创建完成', this.count)
    // 可以发起网络请求
    this.timer = setInterval(() => {
      console.log('定时器运行中...')
    }, 1000)
  },

  beforeMount() {
    console.log(' beforeMount: 模板编译完成,DOM 未挂载')
  },

  mounted() {
    console.log(' mounted: 组件已挂载到页面', this.$el)
    // 可操作 DOM
  },

  beforeUpdate() {
    console.log(' beforeUpdate: 数据变化,视图更新前')
  },

  updated() {
    console.log(' updated: 视图已更新')
  },

  beforeDestroy() {
    console.log(' beforeDestroy: 组件即将销毁')
    // 必须手动清除副作用
    if (this.timer) {
      clearInterval(this.timer)
      this.timer = null
    }
  },

  destroyed() {
    console.log('destroyed: 组件已完全销毁')
  }
}
</script> 

Vue3 生命周期钩子

钩子

执行时机

是否常用

setup

组件创建前,替代 beforeCreate 和 created,是 Composition API 的入口

必用,用于初始化数据和逻辑

onBeforeMount

模板编译完成,即将挂载到 DOM

较少使用,但可用于调试

onMounted

组件已挂载到 DOM,可安全操作真实 DOM

最常用之一,常用于请求数据、绑定事件、初始化第三方库

onBeforeUpdate

数据更新时,虚拟 DOM 重新渲染前

可用于调试或获取更新前的 DOM 状态

onUpdated

虚拟 DOM 重新渲染并应用到 DOM 后

注意避免在其中修改数据导致无限循环

onBeforeUnmount

组件销毁前,实例仍可用,可清理副作用(如定时器、事件监听

常用于资源清理,防止内存泄漏

onUnmounted

组件已完全卸载,所有绑定解除,子实例也被销毁

常用于确认销毁逻辑或日志记录

Vue3 生命周期示例代码

代码语言:vue
复制
<!-- Vue 3 - 使用 <script setup> -->
<script setup>
import {
  ref,
  onBeforeMount,
  onMounted,
  onBeforeUpdate,
  onUpdated,
  onBeforeUnmount,
  onUnmounted
} from 'vue'

const count = ref(0)
const show = ref(true)
let timer = null

// 模拟副作用:定时器
timer = setInterval(() => {
  console.log('[Timer] 运行中...')
}, 1000)

// === 生命周期钩子 ===

console.log(' setup: 组件开始初始化')

onBeforeMount(() => {
  console.log(' onBeforeMount: 即将挂载')
})

onMounted(() => {
  console.log('onMounted: 组件已挂载', document.getElementById('app'))
})

onBeforeUpdate(() => {
  console.log(' onBeforeUpdate: 视图更新前')
})

onUpdated(() => {
  console.log(' onUpdated: 视图已更新')
})

onBeforeUnmount(() => {
  console.log(' onBeforeUnmount: 组件即将卸载')
  // 清理副作用
  if (timer) {
    clearInterval(timer)
    timer = null
    console.log(' 定时器已清除')
  }
})

onUnmounted(() => {
  console.log(' onUnmounted: 组件已完全卸载')
})
</script>

<template>
  <div id="app">
    <h2 v-if="show">当前计数:{{ count }}</h2>
    <button @click="count++">+1</button>
    <button @click="show = false">销毁组件</button>
  </div>
</template>

vue2 和 vue3 的初始化总结

功能

Vue 2

Vue 3

区别说明

初始化前

beforeCreate

setup() 开始处

setup() 替代了 beforeCreate 和 created

初始化后

created

setup() 结束前

Vue 3 推荐在 setup() 中统一处理初始化逻辑

挂载前

beforeMount

onBeforeMount()

名称一致,但 Vue 3 需导入使用

挂载后

mounted

onMounted()

用法相同,功能不变

更新前

beforeUpdate

onBeforeUpdate()

无本质变化

更新后

updated

onUpdated()

注意避免在其中修改响应式数据

销毁前

beforeDestroy

onBeforeUnmount()

命名变更,语义更准确(“卸载”而非“销毁”)

销毁后

destroyed

onUnmounted()

同上,名称更规范

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.API 风格:选项式 vs 组合式
    • 总结 选项方和组合式的区别
    • Vue2:选项式 API
    • Vue3:组合式 API
      • 写法一:使用 setup() 函数
      • 写法二:使用 setup(语法糖)
  • 2.应用初始化方式不同
    • Vue2全局构造函数
    • Vue3全局构造函数
  • 3.初始化生命周期
    • Vue 2 生命周期钩子
    • Vue 2 完整生命周期演示
    • Vue3 生命周期钩子
    • Vue3 生命周期示例代码
    • vue2 和 vue3 的初始化总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档