深入了解vue2向vue3变迁过渡的知识点

简介: 深入了解vue2向vue3变迁过渡的知识点

TypeScript 类型支持

vue2.x使用的是Flow来进行开发,但是flow对于一些复杂的场景flow支持的不是很好。

vue3.x中vue全面转向typescript,typescript提供了更好的类型检查,也支持复杂的类型推导。

vue3移除vue2的实例方法或修饰符

- $children已经被移除。如果要访问子组件,可以使用 $refs
- $on、 $off、 $once 实例方法被移除
- vue3对`filter`过滤器过滤器移除,建议议用方法调用或计算属性来替换它们
- vue3 移除了 $listeners,封装进了 $attrs中
- 移除了v-on.native 修饰符,触发可用emits对象暴露

watch监听数组

vue3当中,如果想要监听数组内容的变化那么必须要写deep。

v-if和v-for优先级已更改

vue2在同一元素v-for优先级高于v-if,vue3则相反,仍不建议在同一标签同时使用

性能优化

  • 数据劫持优化 proxy
  • 编译优化:diff 算法优化
  • 编译优化:PatchFlag(静态标记)、hoistStatic(静态提升)与渲染复用
  • cacheHandler 事件监听缓存
  • 编译优化:Fragment
  • SSR 服务端渲染
  • StaticNode(静态节点)
  • slot 编译优化

生命周期的对比

beforeCreate -> setup()

created -> setup()

beforeDestroy -> beforeUnmount

destroyed -> unmounted

创建VUE实例的对比

vue2创建

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

vue3创建

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
createApp(App,{ userName: "sara" })
.use(store)
.use(router)
.mount('#app')  
// createApp 方法返回应用实例本身,因此可以在其后链式调用其它方法

指令的变化

vue2.x

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})

vue3.x

const { createApp } from "vue"
const app = createApp({})
app.directive('focus', {
    mounted(el) {
        el.focus()
    }
})

Hooks

vue2使用的mixin,

vue3提供了一种新的东西 ,叫做vue-hooks

响应式数据

在vue2中,实现数据监听使用的是Object.defineProperty。我们使用$set。

vue3使用的是Proxy

v-model 升级

  • 变更:在自定义组件上使用v-model时, 属性以及事件的默认名称变了
  • 变更:v-bind.sync修饰符在 Vue 3 中又被去掉了, 合并到了v-model
  • 新增:同一组件可以同时设置多个 v-model
  • 新增:开发者可以自定义 v-model修饰符

在 prop 的默认函数中访问this

生成 prop 默认值的工厂函数不再能访问 this。

取而代之的是:

  • 组件接收到的原始 prop 将作为参数传递给默认函数;
  • inject API 可以在默认函数中使用。
import { inject } from 'vue'
export default {
  props: {
    theme: {
      default (props) {
        // `props` 是传递给组件的、
        // 在任何类型/默认强制转换之前的原始值,
        // 也可以使用 `inject` 来访问注入的 property
        return inject('theme', 'default-theme')
      }
    }
  }
}

插槽统一

此更改统一了 3.x 中的普通插槽和作用域插槽。

以下是变化的变更总结:

  • this.$slots 现在将插槽作为函数公开
  • 非兼容:移除 this.$scopedSlots

vue2.x

<!-- 当使用渲染函数,即 h 时,2.x 曾经在内容节点上定义 slot 数据 property。 -->
// 2.x 语法
h(LayoutComponent, [
  h('div', { slot: 'header' }, this.header),
  h('div', { slot: 'content' }, this.content)
])
<!-- 此外,可以使用以下语法引用作用域插槽: -->
// 2.x 语法
this.$scopedSlots.header

vue3.x

<!-- 在 3.x 中,插槽以对象的形式定义为当前节点的子节点: -->
// 3.x Syntax
h(LayoutComponent, {}, {
  header: () => h('div', this.header),
  content: () => h('div', this.content)
})
<!-- 当你需要以编程方式引用作用域插槽时,它们现在被统一到 $slots 选项中了。 -->
// 2.x 语法
this.$scopedSlots.header
// 3.x 语法
this.$slots.header()

过渡的class名更改

过渡类名 v-enter 修改为 v-enter-from、过渡类名 v-leave 修改为 v-leave-from。

vue2.x

<!-- 在 v2.1.8 版本之前,每个过渡方向都有两个过渡类:初始状态与激活状态。 -->
<!-- 在 v2.1.8 版本中,引入了 v-enter-to 来定义 enter 或 leave 变换之间的过渡动画插帧。然而,为了向下兼容,并没有变动 v-enter 类名: -->
.v-enter,
.v-leave-to {
  opacity: 0;
}
.v-leave,
.v-enter-to {
  opacity: 1;
}
<!-- 这样做会带来很多困惑,类似 enter 和 leave 含义过于宽泛,并且没有遵循类名钩子的命名约定。 -->

vue3.x

<!-- 为了更加明确易读,我们现在将这些初始状态重命名为: -->
.v-enter-from,
.v-leave-to {
  opacity: 0;
}
.v-leave-from,
.v-enter-to {
  opacity: 1;
}
<!-- 现在,这些状态之间的区别就清晰多了。 -->

Transition 作为根节点

当使用 <transition> 作为根结点的组件从外部被切换时将不再触发过渡效果

vue2.x

<!-- 在 Vue 2 中,通过使用 <transition> 作为一个组件的根节点,过渡效果存在从组件外部触发的可能性: -->
<!-- 模态组件 -->
<template>
  <transition>
    <div class="modal"><slot/></div>
  </transition>
</template>
<!-- 用法 -->
<modal v-if="showModal">hello</modal>
<!-- 切换 showModal 的值将会在模态组件内部触发一个过渡效果。
这是无意为之的,并不是设计效果。一个 <transition> 原本是希望被其子元素触发的,而不是 <transition> 自身。
这个怪异的现象现在被移除了。 -->

vue3.x

<!-- 换做向组件传递一个 prop 就可以达到类似的效果: -->
<template>
  <transition>
    <div v-if="show" class="modal"><slot/></div>
  </transition>
</template>
<script>
export default {
  props: ['show']
}
</script>
<!-- 用法 -->
<modal :show="showModal">hello</modal>

Transition Group 根元素

<transition-group> 不再默认渲染根元素,但仍然可以用 tag attribute 创建根元素

vue2.x

<!-- 默认情况下,传递给带有 v-on 的组件的事件监听器只能通过 this.$emit 触发。要将原生 DOM 监听器添加到子组件的根元素中,可以使用 .native 修饰符: -->
<my-component
  v-on:close="handleComponentEvent"
  v-on:click.native="handleNativeClickEvent"
/>

vue3.x

<!-- v-on 的 .native 修饰符已被移除。同时,新增的 emits 选项允许子组件定义真正会被触发的事件。 -->
<!-- 因此,对于子组件中未被定义为组件触发的所有事件监听器,Vue 现在将把它们作为原生事件监听器添加到子组件的根元素中 (除非在子组件的选项中设置了 inheritAttrs: false)。 -->
<my-component
  v-on:close="handleComponentEvent"
  v-on:click="handleNativeClickEvent"
/>
// MyComponent.vue
<script>
  export default {
    emits: ['close']
  }
</script>
相关文章
|
5天前
|
缓存 JavaScript 前端开发
Vue 3的响应式系统
【5月更文挑战第31天】Vue 3的响应式系统
9 1
|
6天前
|
JavaScript 前端开发 API
vue2 /vue3【nextTick】的使用方法及实现原理,一文全搞懂!
vue2 /vue3【nextTick】的使用方法及实现原理,一文全搞懂!
|
6天前
|
JavaScript 开发者
[vue2/vue3] -- 深入剖析v-model的原理、父子组件双向绑定的多种写法
[vue2/vue3] -- 深入剖析v-model的原理、父子组件双向绑定的多种写法
[vue2/vue3] -- 深入剖析v-model的原理、父子组件双向绑定的多种写法
|
6天前
|
JavaScript API
vue3父子组件相互调用方法详解
vue3父子组件相互调用方法详解
|
7天前
|
JavaScript
Vue常用知识点总结
Vue常用知识点总结
14 0
|
13天前
|
JavaScript API
Vue3 基础语法
该内容介绍了Vue项目的创建和Vue3的语法、响应式API、生命周期、组件通信及跨组件通信方法。包括使用`npm init vue@latest`创建项目,`npm install`初始化,Vue3的`setup`语法,`reactive`、`ref`、`computed`和`watch`的用法,生命周期图解,以及父子组件间的数据传递。此外,还提到了Vue3中使用`provide`和`inject`进行跨层数据传递,以及通过Pinia库进行状态管理。
40 0
Vue3 基础语法
|
16天前
|
JavaScript 定位技术 API
在 vue3 中使用高德地图
在 vue3 中使用高德地图
23 0
|
16天前
vue3 键盘事件 回车发送消息,ctrl+回车 内容换行
const textarea = textInput.value.textarea; //获取输入框元素
30 3
|
6天前
|
JavaScript 前端开发 安全
Vue响应式设计
【5月更文挑战第30天】Vue响应式设计
26 1
|
3天前
|
JavaScript API
vue组合式和选项式
vue组合式和选项式
4 2