Vue 3.0 入门

v3.0.0 One Piece

新功能

Composition API #

提供了一种SFC(单文件组件)写法之外的实现方式

增加了 setup 语法和相关语法糖[实验性]

teleport(传送)

将组件中的 DOM 挂载到 body 或指定 DOM

position: fixedz-index 等问题

Fragments(片段)

在Vue 3中,组件现已正式支持多根节点组件

Emits Component Option

新的组件选项:emits,和 props 一样,通过对象的写法,可以对方法进行验证

目前没有语法提示

验证失败会在控制台抛出 [Vue warn]

scoped-styles

深度选择器>>>/deep/支持已弃用,他们仅被Vue的SFC编译器用作编译时提示以重写选择器,并在最终CSS中被删除。

::v-deep 不推荐用作选择器

原来的选择器有各种兼容问题,CSS伪元素实际上在语义上不是选择器。与惯用CSS相比,伪元素可以接受参数更一致

  • 深度选择器
  • 插槽选择器:在 Vue3 中默认使子组件的样式不影响插槽的内容,为了明确地指定插槽内容,可以使用该选择器
  • 全局选择器:在 scoped style 中声明全局样式。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style scoped>
/* deep selectors */
::v-deep(.foo) {}
/* shorthand */
:deep(.foo) {}

/* targeting slot content */
::v-slotted(.foo) {}
/* shorthand */
:slotted(.foo) {}

/* one-off global rule */
::v-global(.foo) {}
/* shorthand */
:global(.foo) {}
</style>

style-variables 【实验性】

允许在 css 中使用可响应变量

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<template>
<div class="text">hello</div>
</template>

<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>

<style vars="{ color }">
.text {
color: var(--color);
}
</style>

编译后:

1
<div style="--color:red" class="text">hello</div>

如果同时使用了 scoped 和 vars,则所有变量都是本地变量,可以使用 global: 前缀来使用全局变量:

1
2
3
4
5
6
<style scoped vars="{ color }">
h1 {
color: var(--color);
font-size: var(--global:fontSize);
}
</style>

新提案:SFC style CSS variable injection (new edition)

破坏性改动

移除全局 Vue

为了避免全局污染,提供新的API createApp 来返回应用实例

此改动会导致:

  1. 无法通过原型链(prototype)挂载,新增 config.globalProperties 替代挂载原型链操作
  2. 插件无法自安装

可以自定义工厂函数来为所有应用共享配置

Global API Treeshaking #

tree shaking 是一个术语,通常用于描述移除 JavaScript 上下文中的未引用代码(dead-code)。它依赖于 ES2015 模块系统中的静态结构特性,例如 import 和 export。这个术语和概念实际上是兴起于 ES2015 模块打包工具 rollup。

受影响的API:

  • Vue.nextTick (<Promise>)
  • Vue.observable(替换为Vue.reactive)
  • Vue.version
  • Vue.compile (仅完整版本)
  • Vue.set (仅在兼容版本中)
  • Vue.delete (仅在兼容版本中)

除此之外,许多内部组件/帮助器现在也以命名导出的形式导出,当你使用时才导出功能代码,例如:

1
2
3
<transition>
<div v-show="ok">hello</div>
</transition>

被编译成类似于以下内容:

1
2
3
4
5
import { h, Transition, withDirectives, vShow } from 'vue'

export function render() {
return h(Transition, [withDirectives(h('div', 'hello'), [[vShow, this.ok]])])
}

移除 filters

使用 计算属性 computed 或调用函数处理

v-model

  1. 移除 v-bind.sync 修饰符
  2. 移除组件的 model 选项
  3. 一个组件可以绑定多个 v-model
  4. 自定义组件上使用时,v-model 的 props 和 event 默认名称已改为:
    • props: value -> modelValue
    • event: input -> update:modelValue

杂项

  1. key:<template v-for> key 应放置在<template>标签上

  2. 修饰符:

    • v-on不再支持使用数字(即keyCodes)作为修饰符
    • v-on.native 已删除,现在组件所有事件都会在根元素添加监听
  3. props:props default 不能访问 this

  4. 事件:$on$off$once被删除,不再支持事件巴士写法

  5. 过渡:v-enter 过渡类名改为 v-enter-fromv-leave 过渡类改为 v-leave-from

  6. 移除了 Functional Component,两者差别在vue3可以忽略不计

  7. 指令优先级:

    1. v-for 高于 v-if -> v-if 优先级始终高于 v-for
    2. 单个属性始终覆盖 v-bind="object" -> 根据绑定的声明顺序决定
  8. watch 数组时,只有数组在被替换时才会触发 handler,如果想要监听数组内部改动,需要使用 deep: true

  9. 生命周期选项 destroyed 已更名为 unmountedbeforeDestroy 更名为 beforeUnmount

底层原理

响应式

defineProperty -> proxy

Proxy: 代理是一个包含另一个对象或功能并允许您对其进行拦截的对象

只能兼容到 IE 11

参考

Vue3 官方文档

Vue2 进阶指南

Vue rfcs(意见征求稿)

作者

朷北

发布于

2020-12-10

更新于

2023-03-07

许可协议

评论