从vue2迁移到vue3,细节处有啥变化?

一、说明

其实vue3大部分的知识点和vue2都是一样的,这篇文章是介绍vue2中部分属性在vue3中的变化,以及vue3新增加的一些比较重要的东西。

二、子传父时使用的emit

  • 在 Vue 2 中,你可以定义一个组件可接收的 prop,但是你无法声明它可以触发哪些事件
<template>
  <div>
    <p>{
   {
    text }}</p>
    <button v-on:click="$emit('accepted')">OK</button>
  </div>
</template>
<script>
  export default {
   
    props: ['text']
  }
</script>
  • 在vue3中,和 prop 类似,现在可以通过 emits 选项来定义组件可触发的事件
<template>
  <div>
    <p>{
   {
    text }}</p>
    <button v-on:click="$emit('accepted')">OK</button>
  </div>
</template>
<script>
  export default {
   
    props: ['text'],
    emits: ['accepted']
  }
</script>

该选项也可以接收一个对象,该对象允许开发者定义传入事件参数的验证器,和 props 定义里的验证器类似

举个例子
我们封装一个CounterOperation.vue的组件

内部其实是监听两个按钮的点击,点击之后通过 this.$emit的方式发出去事件
在这里插入图片描述
在这里插入图片描述

  • 自定义事件的时候,我们也可以传递一些参数给父组件
    在这里插入图片描述
  • 在vue3当中,我们可以对传递的参数进行验证
    在这里插入图片描述

三、$children

在 2.x 中,开发者可以使用 this.$children 访问当前实例的直接子组件:

<template>
  <div>
    <img alt="Vue logo" src="./assets/logo.png">
    <my-button>Change logo</my-button>
  </div>
</template>

<script>
import MyButton from './MyButton'

export default {
   
  components: {
   
    MyButton
  },
  mounted() {
   
    console.log(this.$children) // [VueComponent]
  }
}
</script>
在Vue3中已经移除了$children的属性,所以不可以使用了。如果你需要访问子组件实例,我们建议使用 $refs

四、异步组件

  • 新的 defineAsyncComponent 助手方法,用于显式地定义异步组件

  • component 选项被重命名为 loader

  • Loader 函数本身不再接收 resolve 和 reject 参数,且必须返回一个 Promise
    在vue2.x中

  • 异步组件是通过将组件定义为返回 Promise 的函数来创建的,例如:

const asyncModal = () => import('./Modal.vue')
  • 或者,对于带有选项的更高阶的组件语法
const asyncModal = {
   
  component: () => import('./Modal.vue'),
  delay: 200,
  timeout: 3000,
  error: ErrorComponent,
  loading: LoadingComponent
}

在 Vue 3 中

  • 由于函数式组件被定义为纯函数,因此异步组件需要通过将其包裹在新的 defineAsyncComponent 助手方法中来显式地定义
import {
    defineAsyncComponent } from 'vue'
import ErrorComponent from './components/ErrorComponent.vue'
import LoadingComponent from './components/LoadingComponent.vue'

// 不带选项的异步组件
const asyncModal = defineAsyncComponent(() => import('./Modal.vue'))

// 带选项的异步组件
const asyncModalWithOptions = defineAsyncComponent({
   
  loader: () => import('./Modal.vue'),
  delay: 200,
  timeout: 3000,
  errorComponent: ErrorComponent,
  loadingComponent: LoadingComponent
})

与 2.x 不同,loader 函数不再接收 resolve 和 reject 参数,且必须始终返回 Promise。

// 2.x 版本
const oldAsyncComponent = (resolve, reject) => {
   
  /* ... */
}

// 3.x 版本
const asyncComponent = defineAsyncComponent(
  () =>
    new Promise((resolve, reject) => {
   
      /* ... */
    })
)

五、$attrs包含class&style

$attrs 现在包含了所有传递给组件的 attribute,包括 class 和 style

2.x 行为

  • Vue 2 的虚拟 DOM 实现对 class 和 style attribute 有一些特殊处理。因此,与其它所有 attribute 不一样,它们没有被包含在 $attrs 中。
  • 上述行为在使用 inheritAttrs: false 时会产生副作用
  • $attrs 中的 attribute 将不再被自动添加到根元素中,而是由开发者决定在哪添加
  • 但是 class 和 style 不属于 $attrs,它们仍然会被应用到组件的根元素中
<template>
  <label>
    <input type="text" v-bind="$attrs" />
  </label>
</template>
<script>
export default {
   
  inheritAttrs: false
}
</script>

像这样使用时:

<my-component id="my-id" class="my-class"></my-component>

将生成以下 HTML:

<label class="my-class">
  <input type="text" id="my-id" />
</label>

3.x 行为
$attrs 包含了所有的 attribute,这使得把它们全部应用到另一个元素上变得更加容易了。现在上面的示例将生成以下 HTML

<label>
  <input type="text" id="my-id" class="my-class" />
</label>

六、自定义指令

2.x 语法

  • 在 Vue 2 中,自定义指令通过使用下列钩子来创建,以对齐元素的生命周期,它们都是可选的
  • bind - 指令绑定到元素后调用。只调用一次
  • inserted - 元素插入父 DOM 后调用。
  • update - 当元素更新,但子元素尚未更新时,将调用此钩子
  • componentUpdated - 一旦组件和子级被更新,就会调用这个钩子
  • unbind - 一旦指令被移除,就会调用这个钩子。也只调用一次
    下面是一个例子:
<p v-highlight
  • 6
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值