当前位置: 首页 > news >正文

从vue2到vue3

一、脚手架

        vue2: vue-cli 基于webpack

        vue3:基于vite

二、TypeScript支持

  • Vue 3对TypeScript的支持进行了大量改进,包括更好的类型推断和更清晰的API设计,使得在TypeScript环境中使用Vue更加顺畅

三、状态存储

        vue2: vuex

        vue3:pinia 更简单

四、template限制

        vue2: 要求有唯一根元素

        vue3:没有唯一限制,可多个,解决了多个div嵌套的问题

五、script

        vue2: <script>

        vue3:<script setup>

在 Vue 3 单文件组件 (SFC) 中,<script setup> 和传统的 <script>(选项式 API 写法)是两种不同的脚本编写方式,核心区别体现在语法风格、功能特性和使用场景上。以下是具体对比:

特性传统 <script>(选项式 API)<script setup>(组合式 API 语法糖)
语法风格选项对象(datamethods 等)顶层声明,自动暴露给模板
组件注册需在 components 中显式注册导入后自动注册
响应式依赖 data 和 this依赖 refreactive 等 API
异步操作需在生命周期中处理支持顶层 await
灵活性结构固定,逻辑拆分较难逻辑可自由组合、拆分(配合组合函数)

1. 语法结构

传统 <script>(选项式 API)
  • 需要通过 export default 导出一个选项对象(如 datamethodscomputed 等)。

  • 数据和方法需要定义在特定选项中,模板通过选项名访问。

    <template><button @click="increment">{{ count }}</button>
    </template><script>
    export default {data() {return { count: 0 } // 数据必须放在 data 中},methods: {increment() { this.count++ } // 方法必须放在 methods 中}
    }
    </script>
    
<script setup>(组合式 API 语法糖)
  • 无需 export default,顶层声明的变量、函数会自动暴露给模板

  • 直接使用 Vue 的组合式 API(如 refreactive)定义响应式数据,逻辑更灵活。

    <template><button @click="increment">{{ count }}</button>
    </template><script setup>
    import { ref } from 'vue'
    const count = ref(0) // 直接声明响应式数据
    const increment = () => { count.value++ } // 直接定义函数
    </script>

2. 组件注册

传统 <script>
  • 导入的组件必须在 components 选项中注册后才能使用。

    vue

    <script>
    import Child from './Child.vue'
    export default {components: { Child } // 必须显式注册
    }
    </script>
    
<script setup>
  • 导入的组件自动注册,可直接在模板中使用,无需额外配置。

    vue

    <script setup>
    import Child from './Child.vue' // 导入后直接可用
    </script><template><Child />
    </template>
    

3. 响应式处理

传统 <script>
  • 依赖选项式 API 的固定结构(data 返回响应式对象,methods 定义方法)。
  • 通过 this 访问组件实例的数据和方法(this.countthis.increment())。
<script setup>
  • 依赖组合式 API(refreactive 等)手动创建响应式数据。
  • 无需 this,直接通过变量名访问(如 count.value),避免了 this 指向问题。

4. 异步操作

传统 <script>
  • 初始化异步操作需放在 created 或 mounted 生命周期中,写法较繁琐。

    vue

    <script>
    export default {data() { return { data: null } },async mounted() {this.data = await fetch('/api').then(res => res.json())}
    }
    </script>
    

<script setup>
  • 支持顶层 await,可直接在脚本顶层编写异步逻辑,更简洁。

    vue

    <script setup>
    const data = await fetch('/api').then(res => res.json()) // 直接使用 await
    </script>

六、API

        vue2: 选项式api

        vue3:组合式api (兼容选项式api)

七、双向数据绑定的方式

        vue2: 采用ES5的object.definePropert()对数据进行劫持,结合发布订阅和观察者模式进行的;

        vue3:采用ES6的Proxy的数据代理来对数据进行代理,修复了vue2中对象和数组的属性添加修改的问题;

//vue3使用 ref() 函数来声明响应式状态,Ref 可以持有任何类型的值,包括深层嵌套的对象、数组或者 JavaScript 内置的数据结构
import { ref } from 'vue'const count = ref(0)
// reactive() 将使对象本身具有响应性,只能用于对象类型 (对象、数组和如 Map、Set 这样的集合类型)。
import { reactive } from 'vue'const state = reactive({ count: 0 })

八、生命周期钩子

vue3新增钩子:

  • onRenderTracked: 调试工具中用于追踪组件渲染过程中的依赖关系。
  • onRenderTriggered: 当响应式依赖发生变更时触发,可用于调试性能问题。
  • setup:Vue 3 引入了 setup 函数,它会在组件实例创建之前执行,因此 beforeCreate 和 created 钩子不再必要。所有原本放在这两个钩子里的逻辑可以直接写在 setup 函数内。

九、父组件访问子组件数据 ref

        vue2: this.$refs.childComponent.message;

  • 在父组件中,通过 ref="childComponent" 获取子组件实例。
  • 使用 this.$refs.childComponent.message 获取子组件的数据。

        vue3:defineExpose 

defineExpose 是 Vue 3 提供的一个仅能在 <script setup> 中使用的函数,用来显式暴露组件内部的属性或方法,使得父组件可以通过 ref 访问子组件的暴露内容。

//vue2
<!-- Parent.vue -->
<template><div><child ref="childComponent" /><button @click="getMessage">Get Message from Child</button><p>{{ childMessage }}</p></div>
</template><script>
import Child from './Child.vue';export default {components: {Child},data() {return {childMessage: ''};},methods: {getMessage() {this.childMessage = this.$refs.childComponent.message;}}
};
</script><!-- Child.vue -->
<template><div><p>{{ message }}</p></div>
</template><script>
export default {data() {return {message: 'Hello from Child'};}
};
</script>
//vue3
//子组件
<script setup>
import { ref } from 'vue';// 子组件内部的状态和方法
const count = ref(0);function increment() {count.value++;
}// 通过 defineExpose 暴露给父组件
defineExpose({count,increment
});
</script><template><div><p>计数器子组件:{{ count }}</p></div>
</template>//父组件
<script setup>
import { ref } from 'vue';
import Counter from './Counter.vue';// 通过 ref 获取子组件实例
const counterRef = ref(null);function callChildMethod() {counterRef.value.increment(); // 调用子组件的方法console.log('子组件计数值:', counterRef.value.count); // 访问子组件的暴露属性
}
</script><template><Counter ref="counterRef" /><button @click="callChildMethod">调用子组件方法</button>
</template>

http://www.dtcms.com/a/342229.html

相关文章:

  • VASPKIT模版INCAR笔记
  • K8s快速上手-微服务篇篇
  • 【ZeroNews】OpenWrt路由器小存储开启内网穿透
  • 2025年8月新算法—云漂移优化算法(Cloud Drift Optimization Algorithm, CDO)
  • C++ this 指针
  • 2025-08-21 Python进阶2——数据结构
  • Rancher部署的K8S集群服务节点上执行 kubectl 命令
  • JavaCV + Spring 实现高效 RTSP 视频流帧缓存与管理
  • MybatisPlusAutoConfiguration源码阅读
  • 稀土元素带来农业科技革命
  • Qt5 数据库编程详解
  • “Data + AI Agent”技术架构解析:衡石科技如何重塑数据智能演进路径?
  • YggJS RToast(科技风全局消息通知库) 使用教程 v0.1.0(详细教学)
  • RoPE, 2D RoPE, 3D RoPE和复数
  • 安卓app、微信小程序等访问多个api时等待提示调用与关闭问题
  • 为什么会“偶发 539/500 与建连失败”
  • 如何通过传感器选型优化,为设备寿命 “续航”?
  • 微服务介绍及Nacos中间件
  • java⽇志体系
  • 桌面挂件不能承受之重——GIF
  • Windows 系统中,添加打印机主要有以下几种方式
  • 聚铭安全管家平台2.0实战解码 | 安服篇(四):重构威胁追溯体系
  • 新手向:Python开发简易网络服务器
  • 解决springai 项目中引入多个chatModel存在冲突问题
  • 服务器间大文件迁移
  • SparkSQL、FlinkSQL与普通sql比较
  • Git项目报错git@gitlab.com: Permission denied (publickey).【已解决】
  • Jenkins+GitLab在CentOS7上的自动化部署方案
  • iOS混淆工具实战 金融支付类 App 的安全防护与合规落地
  • 飞牛系统总是死机,安装个工具查看一下日志