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

Vue3与Vue2中使用对比

一、共有的API

1、修饰符:

v-on 修饰符:.stop、.prevent、.self、.once、.passive 等;

v-model 修饰符:.lazy、.number、.trim 等;

用法与行为在 Vue 2 和 Vue 3 中完全一致。

.stop:阻止事件冒泡

作用:调用 event.stopPropagation(),阻止事件从子元素冒泡到父元素。

场景:当父子元素都绑定了事件,点击子元素时不想触发父元素的事件。

<template><div @click="handleParentClick" style="padding: 20px; background: #eee;">父元素<button @click.stop="handleChildClick">子按钮</button></div>
</template><script setup>
const handleParentClick = () => console.log('父元素事件触发');
const handleChildClick = () => console.log('子元素事件触发');
</script>

结果:点击按钮时,只打印「子元素事件触发」(若不加 .stop,会同时打印父子事件)。

.self:仅自身触发事件

作用:事件仅在事件目标是当前元素自身时触发,忽略子元素冒泡上来的事件。

场景:父元素有事件,但只想在点击父元素自身(非子元素)时触发。

<template><div @click.self="handleParentClick" style="padding: 20px; background: #eee;">父元素(点击这里触发)<button>子按钮(点击我不触发父事件)</button></div>
</template><script setup>
const handleParentClick = () => console.log('父元素自身被点击');
</script>

结果:点击父元素的空白区域(非按钮)会触发事件,点击子按钮不会触发(即使按钮在父元素内部)。

.once:事件只触发一次

作用:事件触发一次后自动解绑,后续点击不再生效。

场景:限制事件只能执行一次(如「同意协议」按钮)。

<template><button @click.once="handleClick">点击我(只生效一次)</button>
</template><script setup>
const handleClick = () => console.log('按钮被点击了');
</script>

结果:第一次点击打印日志,第二次及之后点击无反应。

.passive:优化滚动 / 触摸事件性能

作用:告诉浏览器「此事件不会调用 preventDefault()」,浏览器可提前优化渲染(避免滚动卡顿)。

场景:监听 scroll、touchmove 等高频触发的事件(尤其在移动端)。

<template><!-- 滚动列表时优化性能 --><div @scroll.passive="handleScroll" style="height: 200px; overflow: auto; border: 1px solid #ccc;"><p v-for="i in 100" :key="i">列表项 {{ i }}</p></div>
</template><script setup>
const handleScroll = () => console.log('滚动中...');
</script>

注意:

  • 不能和 .prevent 同时使用(会报错,因为 .passive 已声明不阻止默认行为)。
  • 主要用于提升移动端滚动流畅度。

2、动态组件

动态组件用于通过 component 标签和 is 属性动态渲染不同组件,核心用法在 Vue2 和 Vue3 中保持一致。

差异点:Vue3 中 is 属性支持直接绑定组件对象(无需注册),而 Vue2 中若绑定对象需先在 components 中注册。

Vue2

<!-- Vue2 和 Vue3 通用 -->
<component :is="currentComponent"></component><script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'export default {components: { ComponentA, ComponentB },data() {return {currentComponent: 'ComponentA' // 可动态切换为 ComponentB}}
}
</script>

Vue3

在 Vue 3 中,​​基本用法与 Vue 2 类似​​,也是通过 <component :is="...">来实现。

<template><component :is="currentComponent"></component>
</template><script setup>
import { ref } from 'vue'
import CompA from './CompA.vue'
import CompB from './CompB.vue'const currentComponent = ref('CompA') // 如果注册了全局或局部组件
// 或者
const currentComponent = ref(CompA) // 直接使用组件对象
</script>

注意:​​

  • 在 Vue 3 的 Composition API + <script setup>中,如果你使用的是组件对象(如 CompA),直接传入即可。
  • 如果你使用的是字符串形式的组件名(如 'CompA'),则需要确保该组件已经通过 components选项注册(在 Options API 中)或在 <script setup>中通过 defineAsyncComponent或其它方式导入并使用。如果使用 ​​Options API​​ 的写法(Vue 3 同样支持):
<script>
import CompA from './CompA.vue'
import CompB from './CompB.vue'export default {components: {CompA,CompB},data() {return {currentComponent: 'CompA'}}
}
</script>

3、异步组件

异步组件用于按需加载组件(代码分割),Vue3 对其 API 进行了重构,与 Vue2 差异较大。

Vue2

通过直接返回一个 Promise 定义,或使用 () => import() 语法:

// Vue2 异步组件定义
const AsyncComponent = () => import('./AsyncComponent.vue')// 带选项的异步组件(如加载状态、错误状态)
const AsyncComponentWithOptions = () => ({component: import('./AsyncComponent.vue'),loading: LoadingComponent, // 加载中显示的组件error: ErrorComponent,     // 加载失败显示的组件delay: 200,                // 延迟显示加载组件(毫秒)timeout: 3000              // 超时时间(毫秒)
})

Vue 3 

Vue3 引入了 defineAsyncComponent 方法统一处理异步组件,支持与 <Suspense> 配合,且选项结构有调整:

// Vue3 基础用法(需导入 defineAsyncComponent)
import { defineAsyncComponent } from 'vue'const AsyncComponent = defineAsyncComponent(() => import('./AsyncComponent.vue')
)// 带选项的异步组件
const AsyncComponentWithOptions = defineAsyncComponent({loader: () => import('./AsyncComponent.vue'), // 替代 Vue2 的 componentloadingComponent: LoadingComponent,errorComponent: ErrorComponent,delay: 200,timeout: 3000,suspensible: false // 新增:是否允许被 Suspense 控制(默认 true)
})

使用方式与 Vue 2 类似,在模板中:

<component :is="AsyncComp"></component>

​​关键区别:

  • Vue 2 是直接返回一个带有 component, loading, error等字段的对象。
  • Vue 3 则是使用 defineAsyncComponent工厂函数来创建异步组件,更加规范和清晰。
  • Vue 3 中的异步组件定义方式更统一,也更易于维护。

另外,在 Vue 3 中,​​简单的异步组件可以更简洁地写为:​

const AsyncComp = defineAsyncComponent(() => import('./MyComponent.vue'))

也就是没有加载状态、错误状态等配置的简化形式。

4、插槽

Vue 3 和 Vue 2 在 ​​插槽(Slots)​​ 的使用上有一些重要的区别,主要体现在 ​​作用域插槽(Scoped Slots)​​ 的语法、API 设计以及插槽的底层实现上。下面从几个方面详细对比它们的区别:

​​4.1 基础插槽(默认插槽)​​

Vue 2

<!-- 子组件 Child.vue -->
<template><div><slot></slot>  <!-- 默认插槽 --></div>
</template><!-- 父组件使用 -->
<Child><p>这是插入到子组件默认插槽的内容</p>
</Child>

Vue 3

<!-- 子组件 Child.vue -->
<template><div><slot></slot>  <!-- 默认插槽,写法相同 --></div>
</template><!-- 父组件使用 -->
<Child><p>这是插入到子组件默认插槽的内容</p>
</Child>

✅ ​​结论:​​ 基础插槽在 Vue 2 和 Vue 3 中 ​​用法完全一致​​。

4.2 具名插槽(Named Slots)​

Vue2

<!-- 子组件 Child.vue -->
<template><div><header><slot name="header"></slot></header><main><slot></slot>  <!-- 默认插槽 --></main></div>
</template><!-- 父组件使用 -->
<Child><template slot="header"><h1>这是头部</h1></template><p>这是默认插槽内容</p>
</Child>

Vue 3

<!-- 子组件 Child.vue -->
<template><div><header><slot name="header"></slot></header><main><slot></slot>  <!-- 默认插槽 --></main></div>
</template><!-- 父组件使用:推荐新语法 -->
<Child><template #header><h1>这是头部</h1></template><p>这是默认插槽内容</p>
</Child>

🔁 ​​语法糖变化:

  • Vue 2 使用 slot="header"属性方式。
  • Vue 3 ​​推荐使用 #header(即 v-slot:header 的简写)​​,但 slot="header"仍然兼容(不推荐)。

✅ ​​结论:​​

具名插槽功能一样,但 Vue 3 引入了更简洁的 #语法糖(v-slot 的简写),推荐使用。

4.3 作用域插槽(Scoped Slots) / 插槽传参​

这是 Vue 2 和 Vue 3 差异较大的地方。

Vue 2 中的作用域插槽

作用域插槽允许子组件向父组件传递数据,父组件通过 slot-scope来接收。

<!-- 子组件 Child.vue -->
<template><div><slot :user="user"></slot>  <!-- 向插槽传递数据 --></div>
</template><script>
export default {data() {return {user: { name: 'Alice' }};}
};
</script><!-- 父组件使用 Vue 2 写法 -->
<Child><template slot-scope="props"><p>来自子组件的用户:{{ props.user.name }}</p></template>
</Child>

或者对于 ​​具名作用域插槽​​:

<!-- 子组件 -->
<slot name="user" :user="user"></slot><!-- 父组件 -->
<Child><template slot="user" slot-scope="props"><p>{{ props.user.name }}</p></template>
</Child>

🔹 关键点:

  • 使用 slot-scope接收子组件传递的数据。
  • 对于具名插槽,需要同时使用 slot="name"和 slot-scope。

Vue 3 中的作用域插槽

Vue 3 ​​废弃了 slot-scope和 slot属性​​,统一使用 ​​v-slot(或 #缩写)​​ 来接收所有类型的插槽,包括作用域插槽。

<!-- 子组件 Child.vue -->
<template><div><slot :user="user"></slot>  <!-- 作用域插槽,传递数据 --></div>
</template><script setup>
import { ref } from 'vue'
const user = ref({ name: 'Alice' })
</script><!-- 父组件使用 Vue 3 推荐写法 -->
<Child><template #default="slotProps"><p>来自子组件的用户:{{ slotProps.user.name }}</p></template>
</Child>

或者更简洁地,因为是默认插槽,也可以直接:

<Child><template #default="{ user }"><p>来自子组件的用户:{{ user.name }}</p></template>
</Child>

对于具名作用域插槽:

子组件:

<slot name="user" :user="user"></slot>

父组件:

<Child><template #user="{ user }"><p>用户名:{{ user.name }}</p></template>
</Child>

🔹 ​​关键点:​​

  • Vue 3 ​​不再使用 slot和 slot-scope属性​​。
  • 所有插槽(包括作用域插槽)都通过 ​​v-slot指令(或 #缩写)​​ 来处理。
  • v-slot可以解构传递的参数,如 #default="{ user }"。

5、KeepAlive

在 Vue 2 和 Vue 3 中,KeepAlive 都是用于缓存组件实例以避免重复渲染的内置组件,但两者在使用方式、API 设计和功能细节上存在一些异同,具体如下:

5.1、相同点

核心功能一致

无论是 Vue 2 还是 Vue 3,KeepAlive 的核心作用都是缓存包裹的组件,使其在切换时不被销毁,保留组件的状态(如表单输入、滚动位置等),从而提升性能。

基本用法相似

都通过包裹动态组件(component 标签)或路由组件来实现缓存,例如:

<!-- Vue 2 和 Vue 3 通用写法 -->
<keep-alive><component :is="currentComponent"></component>
</keep-alive>

5.2、不同点

维度Vue 2Vue 3
组件名大小写要求组件名必须为 ** PascalCase **(如 MyComponent),否则 include/exclude 可能匹配失败。支持 ** kebab-case **(如 my-component)和 PascalCase,匹配更灵活(推荐与组件注册名一致)。
max 属性不支持 max 属性,缓存数量无限制。新增 max 属性,用于限制最大缓存组件数量(超出时会销毁最久未使用的组件,类似 LRU 缓存)。
生命周期钩子被缓存组件激活 / 失活时,触发 activated 和 deactivated 钩子(仅在 KeepAlive 包裹时生效)。同样支持 activated 和 deactivated 钩子,** 但在组合式 API 中需配合 onActivated 和 onDeactivated 使用 **。
与路由结合需配合 <router-view> 直接包裹:<keep-alive><router-view></router-view></keep-alive>用法相同,但 Vue 3 的路由组件缓存逻辑更清晰,且支持通过路由元信息(meta)控制缓存(需结合 include)。
v-slot 用法不支持,无法直接访问缓存组件的实例。支持 v-slot,可通过 default 插槽获取缓存组件的实例和状态:vue<br><keep-alive v-slot="{ component }"><br> <component :is="component" /><br></keep-alive><br>
组件注册方式全局内置组件,无需额外导入即可使用。同样是全局内置组件,但在 <script setup> 或组合式 API 中无需导入,直接使用。
缓存键(key)默认基于组件 ID 和标签名生成缓存键。缓存键生成逻辑优化,更稳定,且支持通过组件的 key 属性手动指定缓存标识(避免同类型组件缓存冲突)。

5.3 典型场景差异示例

限制缓存数量(Vue 3 新增)

<!-- Vue 3 中限制最多缓存 3 个组件 -->
<keep-alive :max="3"><component :is="currentComponent"></component>
</keep-alive>

组合式 API 中使用生命周期(Vue 3)

<script setup>
import { onActivated, onDeactivated } from 'vue'onActivated(() => {// 组件被激活时触发console.log('组件激活')
})onDeactivated(() => {// 组件被缓存时触发console.log('组件缓存')
})
</script>

v-slot 访问缓存组件(Vue 3)

<keep-alive v-slot="{ component }"><component :is="component" @custom-event="handleEvent" />
</keep-alive>

二、Vue2独有

1、$set(target, key, value):

在响应式对象 / 数组中添加属性并触发更新(Vue 2 中解决 Object.defineProperty 监听限制;Vue 3 中因 Proxy 可直接赋值,但仍保留该方法兼容)。

2、$delete(target, key):

删除响应式对象 / 数组的属性并触发更新(同理,Vue 3 中可直接删除,但保留方法)。

3、混入 (mixin) 

在 Vue 2 中,​​混入(Mixin)​​ 是一种分发 Vue 组件中可复用功能的灵活方式。一个 ​​mixin​​ 对象可以包含任意组件选项(如 data、methods、computed、生命周期钩子等)。当组件使用 mixin 时,所有 mixin 对象的选项将被“混合”进入该组件本身的选项中。

3.1、Mixin 的作用

Mixin 的主要作用是:

  • ​​代码复用​​:将多个组件共用的逻辑(如方法、数据、计算属性、生命周期等)抽离出来,避免重复代码。
  • ​​模块化​​:将功能模块化,提高代码的可维护性和组织性。
  • ​​组合逻辑​​:通过混入不同的 mixin,组合出具有不同能力的组件。

3.2、Mixin 的基本使用

定义一个 Mixin

Mixin 是一个​​普通的 JavaScript 对象​​,它包含 Vue 组件选项中的任何内容,例如:

// myMixin.js
export const myMixin = {data() {return {mixinMessage: '这是来自 mixin 的数据'}},methods: {mixinMethod() {console.log('这是来自 mixin 的方法');}},created() {console.log('mixin 的 created 钩子被调用');}
}

在组件中使用 Mixin

在 Vue 组件中,通过 mixins选项引入 mixin:

<template><div><p>{{ mixinMessage }}</p><button @click="mixinMethod">调用 mixin 方法</button></div>
</template><script>
import { myMixin } from './myMixin.js'export default {mixins: [myMixin], // 使用 mixindata() {return {componentMessage: '这是组件自身的数据'}},created() {console.log('组件的 created 钩子被调用');}
}
</script>

3.3、Mixin 的合并策略

当组件和 mixin 具有相同的选项时,Vue 会按一定的规则进行合并:

选项类型

合并策略

data

组件的 data会覆盖 mixin 的 data(深度合并对象)

methodscomponentsdirectives

后者(组件自身)会覆盖前者(mixin)的同名属性

生命周期钩子

同名的钩子函数会​​合并为一个数组​​,​​mixin 的钩子先执行,组件的后执行​

computedpropswatch

同名时,组件的定义会覆盖 mixin 的定义

示例:生命周期钩子的执行顺序​

// mixin
const mixin = {created() {console.log('mixin created')}
}// 组件
export default {mixins: [mixin],created() {console.log('component created')}
}

输出顺序为:​

mixin created
component created

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

相关文章:

  • 做电子的外单网站有哪些的优质的成都网站建设推
  • 手机网站建设的现状河南省住房和建设厅网站
  • 企业官方网站建设费用网站免费源码
  • dz做电影网站动画制作过程
  • 哪里有网站建设加工微网站怎么注册账号
  • 《隐变量》
  • 网站建设 厦门金牛区网站建设
  • 做的好的招投标网站深圳建设工程交易服务网官网龙岗
  • 网站建设完工后在什么科目核算画册设计排版的技巧和规则
  • 《第05章 项目整体管理》备考知识点整理
  • QGIS字段计算器常用公式汇总(含实操示例)
  • 国外网站seo用哪个网站做相册视频文件
  • 迅速上排名网站优化微信公众平台号申请注册入口
  • 网站开发语言p我要注册
  • 免费传奇网站模板网站建设是管理费用的哪项费用
  • 学校网站建设所使用的技术如何知道一个网站是谁做的
  • 网站建设分金手指专业五wordpress怎么使用插件下载失败
  • 15.搜索二叉树(一)
  • 营销网站的类型西安市城乡建设厅网站
  • NET开发网站开发工程师招聘cms+wordpress模板
  • FreeHub:一个免费产品的收录平台
  • 网站建设 美词响应式相册网站
  • 网站开发规范有哪些购物网站的商品展示模块
  • 旅游订票网站开发专门做二维码的网站
  • 【速写】优化的深度与广度(Adam Moun)
  • 什么网站有加工外发做的重庆最大的网络公司
  • 网站建设公司团队简介wordpress 主题 模板
  • 建设一个网站用什么搭建电商网站开发建设
  • iis 网站制作网站设计项目书
  • 【C语言初阶】分支和循环语句_for循环