关于javascript:vue3中一些不兼容的小改变

34次阅读

共计 4345 个字符,预计需要花费 11 分钟才能阅读完成。

vue3 中一些不兼容的小扭转

生命周期选项名称的变动

destroyed 被重命名为 unmounted
beforeDestroy 被重命名为 beforeUnmount

在 prop 的默认函数中拜访 this

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

// vue3
// 把组件接管到的原始 prop 作为参数传递给默认函数
// inject API 能够在默认函数中应用
import {inject} from 'vue'
export default {
  props: {
    theme: {default(props) {
        // props 是传递给组件的原始值
        // 在任何类型 / 默认强制转换之前
        // 也能够应用 inject 来拜访注入的 property
        return inject('theme', 'default-theme')
      }
    }
  }
}

自定义指令 API 已更改为与组件生命周期统一

指令的钩子函数被重命名

在 2.x 中,自定义指令是通过应用鞋面列出的狗子来创立的,这些钩子是可选的

  • bind – 指令绑定到元素后产生,只产生一次
  • inserted – 元素插入父 DOM 后产生
  • update – 单元数更新,但子元素尚未更新时,将调用此钩子
  • componentUpdated – 一旦组件和子级被更新,就会调用此钩子
  • unbind – 指令被移除时调用,只调用一次
<p v-highlignt="'yellow'"> 高亮文本,黄色 </p>
Vue.directive('highlight', {bind(el, binding, vnode) {el.style.background = binding.value}
})
// 在这个元素的初始设置中,指令通过传递一个值来绑定款式,该值能够通过应用程序更新为不同的值

在 3.x 中,自定义指令有了新的 API,当初将组件生命周期和自定义指令的生命周期对立了起来

  • created – 新的!在元素的 attribute 或事件侦听器利用之前调用。
  • bind → beforeMount
  • inserted → mounted
  • beforeUpdate:新的!这是在元素自身更新之前调用的,很像组件生命周期钩子。
  • update → 移除!有太多的相似之处要更新,所以这是多余的,请改用 updated
  • componentUpdated → updated
  • beforeUnmount:新的!与组件生命周期钩子相似,它将在卸载元素之前调用。
  • unbind -> unmounted
// 最终 API
const MyDirective = {beforeMount(el, binding, vnode, prevVnode) {},
  mounted() {},
  beforeUpdate() {},
  updated() {},
  beforeUnmount() {},
  unmounted() {}
}
// 应用办法
const app = Vue.createApp({})
app.directive('highlight', {beforeMount(el, binding, vnode) {el.style.background = binding.value}
})

拜访组件实例的变动

// vue2  通过 vnode 拜访组件实例
bind(el, binding, vnode) {const vm = vnode.context}
// vue3  通过 binding 拜访
mounted(el, binding, vnode) {const vm = binding.instance}
// 借助片段反对,组件可能具备多个根节点。当利用于多根组件时,指令将被疏忽,并且将记录正告。

Data 选项始终都是 function,mixin 合并 data 的变动

data 选项只反对 function

// 2.x
data: {apiKey: 'value'}
// 或
data() {
  return {apiKey: 'value'}
}
// 3.x 当初只反对函数模式的 data
data() {
  return {apiKey: 'value'}
}

Mixin 合并行为变更
当来自组件的 data()及其 mixin 或 extends 基类被合并时,当初将会 浅层次 合并

const Mixin = {data() {
    return {
      user: {
        name: 'Jack',
        id: 1
      }
    }
  }
}
const CompA = {mixins: [Mixin]
  data() {
    return {
      user: {id: 2}
    }
  }
}

以上代码在不同版本 vue 中后果不同

// 2.x
{
  user: {
    id: 2,
    name: 'Jack'
  }
}
// 3.x
{
  user: {id: 2}
}

过渡的 class 名更改

过渡类名 v-enter 批改为 v-enter-from
过渡类名 v-leave 批改为 v-leave-form

v2.1.8 版本中, 引入 v-enter-to 来定义 enter 或 leave 变换之间的过渡动画插帧, 为了向下兼容, 并没有变动 v-enter 类名

这样做会带来很多困惑, 相似 enter 和 leave 含意过于宽泛并且没有遵循类名钩子的命名约定。在 vue3 中为了更加明确易读,当初将这些初始状态重命名
/* 2.x */
.v-enter,
.v-leave-to{opcity: 0;}
.v-leave,
.v-enter-to {opcity: 1;}
/* 3.x */
.v-enter-from,
.v-leave-to{opcity: 0;}
.v-leave-from,
.v-enter-to{opcity: 0;}

<transition>组件相干属性名也产生了变动:

  • leave-class 重命名为 leave-from-class(JSX 中:leaveFromClass)
  • enter-class 重命名为 enter-from-class(JSX 中:enterFromClass)

<transition-group>组件变动

<transition-group>不再默认渲染恩元素,但仍能够用 tag 属性创立根元素

<!-- 2.x 中 如果不指定 tag 属性,则会默认创立一个 span 元素包裹 -->
<transition-group tag="ul">
<li v-for="item in items" :key="item">
  {{item}}
</li>
</transition-group>
<!-- 3.x 中 组件不再须要一个根节点,所以 transition-group 不再渲染根节点 -->
<transition-group tag="span">
  <!-- -->
</transition-group>
<!-- 等同以上代码 -->

watch 监听数组的变动

只有数组被替换的时候才会触发 watch 的回调,如果要在数组扭转时触发,须要指定 deep 选项

watch: {
  bookList: {handler(val, oldVal) {console.log('changed!')
    },
    deep: true
  }
}

没有非凡指令标记的<template>

没有非凡指令的标记 (v-if/else-if/else、v-for 或 v-slot), 将会生成原生<template> 元素,而不是渲染外部内容

vue3 中,容器自身不再是模板的一部分

在 Vue 2.x 中,利用根容器的 outerHTML 将替换为根组件模板 (如果根组件没有模板 / 渲染选项,则最终编译为模板)。Vue 3.x 当初应用利用容器的 innerHTML,这意味着容器自身不再被视为模板的一部分。


attribute 的强制行为

这是一个低级的外部 API 更改,不会影响大多数开发人员。

  • 删除枚举 attribute 的外部概念,并将这些 attribute 视为一般的非布尔 attribute
  • 重大扭转:如果值为布尔值,则不再删除 attribute false。相同,它被设置为 attr=“false”。移除 attribute,应用 null 或者 undefined。

在 2.x,咱们有以下策略来强制 v-bind 的值:

  • 对于某些 attribute/ 元素对,Vue 始终应用相应的 IDL attribute(property):比方 value 的 <input><select><progress>,等等
  • 对于“枚举 attribute”(目前 contenteditable,draggable 和 spellcheck),Vue 会尝试强制将它们串起来 (目前对 contenteditable 做了非凡解决,修复 vuejs/vue#9397)
  • 对于其余 attribute,咱们移除了 falsy 值 (undefined,null,or false) 并按原样设置其余值 (见这里)。
绑定表达式 foo 失常 draggable 枚举
:attr=”null” / draggable=”false”
:attr=”undefined” / /
:attr=”true” foo=”true” draggable=”true”
:attr=”false” / draggable=”false”
:attr=”0″ foo=”0″ draggable=”true”
attr=”” foo=”” draggable=”true”
attr=”foo” foo=”foo” draggable=”true”
attr foo=”” draggable=”true”

从上表能够看出,以后实现 true 强制为 ‘true’ 但如果 attribute 为 false,则移除该 attribute。这也导致了不一致性,并要求用户在十分常见的用例中手动强制布尔值为字符串,例如 aria-* attribute 像 aria-selected,aria-hidden,等等。

在 vue3 中,放弃“枚举 attribute”的外部概念,并将它们视为一般的非布尔 HTML attribute。

  • 这解决了一般非布尔 attribute 和“枚举 attribute”之间的不一致性
  • 它还能够应用 ‘true’ 和 ‘false’ 以外的值,甚至能够应用 contenteditable 等 attribute 的关键字 `
  • 对于非布尔 attribute,如果 attribute 为 false,Vue 将进行删除它们,相同强制它们为 ‘false’。
  • 这解决了 true 和 false 之间的不一致性,并使输入 aria-* attributes 更容易
绑定表达式 foo 失常 draggable 枚举
:attr=”null” / / †
:attr=”undefined” / /
:attr=”true” foo=”true” draggable=”true”
:attr=”false” foo=”false” † draggable=”false”
:attr=”0″ foo=”0″ draggable=”0″ †
attr=”” foo=”” draggable=”” †
attr=”foo” foo=”foo” draggable=”foo” †
attr foo=”” draggable=””

†:变更
布尔 attributes 的强制放弃不变。

正文完
 0