Vue3-03 从Vue2迁移

本文详细介绍了Vue3相较于Vue2的主要变化,包括新增的Teleport组件,Ref数组的变化,异步组件的定义,组件属性与事件处理的调整,过滤器的移除,以及对自定义指令、全局API、数据处理、渲染函数和过渡效果等方面的更新。Vue3提供了更多的灵活性和优化,同时也需要注意兼容性和适配问题。
摘要由CSDN通过智能技术生成

Teleport

一个新增的内置组件,用来提供一种干净的方法,允许我们控制在DOM哪个父节点下渲染HTML,不必求助于全局状态或者将其拆分为两个组件

<teleport to="body">
  <div v-if="modalOpen" class="model-wrapper">
    <div class="modal">
      <i class="el-icon-close" @click="modalOpen = false"></i>
      <p>Hello</p>
    </div>
  </div>
</teleport>

Vue会将<teleport>标签内的内容渲染为<body>标签的子级

它接受两个参数,第一个参数to是有效的查询选择器,指定要挂载的目标元素,第二个参数disabled用来禁用<teleport>的功能,元素会在原组件位置渲染

注意,disabled状态变化后,将移动实际的DOM节点,而不是被销毁和重新创建,并且它还将保持任何组件实例的活动状态(例如播放的视频等)

在同一个目标上使用多个<teleport>组件,会将内容挂载到同一个目标元素,顺序就是简单的追加,稍后挂载的将位于目标元素中较早的挂载之后

v-for中的Ref数组

从单个绑定获取多个Ref时,需要将ref绑定到一个更灵活的函数上,在函数中,将函数的参数el推书预置的数组中:

<div v-for="item in list" :ref="setItemRef"></div>

选项式API:

export default {
  data() {
    return {
      itemRefs: []
    }
  },
  methods: {
    setItemRef(el) {
      if (el) {
        this.itemRefs.push(el)
      }
    }
  },
  beforeUpdate() {
    this.itemRefs = []
  },
  updated() {
    console.log(this.itemRefs)
  }
}

组合式API:

import { onBeforeUpdate, onUpdated } from 'vue'

export default {
  setup() {
    let itemRefs = []
    const setItemRef = el => {
      if (el) {
        itemRefs.push(el)
      }
    }
    onBeforeUpdate(() => {
      itemRefs = []
    })
    onUpdated(() => {
      console.log(itemRefs)
    })
    return {
      setItemRef
    }
  }
}

注意:

  • itemRefs不必是数组,可以是一个对象
  • 如果需要,itemRef也可以是响应式的,可以被监听
  • 需要在onBeforeUpdate中对itemRefs重置,否则会出问题

异步组件(新增)

Vue3中函数式组件被定义为纯函数,异步组件的定义需要通过defineAsyncComponent方法显示定义:

import { defineAsyncComponent } from 'vue'
import ErrorComponent from './components/ErrorComponent.vue'
import LoadingComponent from './components/LoadingComponent.vue'

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

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

相比于Vue2,component选项被重命名为loaderloader函数不接受resolvereject参数,必须始终返回Promise

const { createApp, defineAsyncComponent } = Vue

const app = createApp({})

const AsyncComp = defineAsyncComponent(
  () =>
    new Promise((resolve, reject) => {
      resolve({
        template: '<div>I am async!</div>'
      })
    })
)

app.component('async-example', AsyncComp)

如果利用Webpack和ES2015的能力,可以使用import直接导入:

import { defineAsyncComponent } from 'vue'

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

app.component('async-component', AsyncComp)

defineAsyncComponent的完整用法:

import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent({
  // 工厂函数
  loader: () => import('./Foo.vue')
  // 加载异步组件时要使用的组件
  loadingComponent: LoadingComponent,
  // 加载失败时要使用的组件
  errorComponent: ErrorComponent,
  // 在显示 loadingComponent 之前的延迟 | 默认值:200(单位 ms)
  delay: 200,
  // 如果提供了 timeout ,并且加载组件的时间超过了设定值,将显示错误组件
  // 默认值:Infinity(即永不超时,单位 ms)
  timeout: 3000,
  // 定义组件是否可挂起 | 默认值:true
  suspensible: false,
  /**
   *
   * @param {*} error 错误信息对象
   * @param {*} retry 一个函数,用于指示当 promise 加载器 reject 时,加载器是否应该重试
   * @param {*} fail  一个函数,指示加载程序结束退出
   * @param {*} attempts 允许的最大重试次数
   */
  onError(error, retry, fail, attempts) {
    if (error.message.match(/fetch/) && attempts <= 3) {
      // 请求发生错误时重试,最多可尝试 3 次
      retry()
    } else {
      // 注意,retry/fail 就像 promise 的 resolve/reject 一样:
      // 必须调用其中一个才能继续错误处理。
      fail()
    }
  }
})

$attrs包含classstyle

Vue2中v-bind="$attrs"会把除了classstyle的属性应用到元素上,而Vue3中的$attrs则会包含classstyle

组件的inheritAttrs默认为true,这样加载组件的不被认作Props的Attribute会应用到子组件的根元素上,通过设置inheritAttrsfalse,这个默认行为会被取消,通过配合v-bind="$attrs"会把这些Attribute显性的绑定到非根元素上

$children

Vue2中可以通过$children访问当前组件实例的子组件,这个API在Vue3中取消了,需要使用ref来访问子组件

自定义指令

Vue3中自定义指令的钩子有了很大变化:

  • created(new):在元素的Attribute或事件侦听器创建前调用
  • bindbeforeMount
  • inserted → <
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值