【Vue】Vue3 介绍

Vue3 相对于 Vue2 值得关注的新特性

  1. Composition API 组合式 API
  2. 重新实现了数据响应式原理(利用 ES6 的 proxy 代替了 ES5的 Object.defineProperty)
  3. 源码使用 typescript 进行了重写,拥有更好的类型推导
  4. Virtual DOM Rewrite 重写虚拟DOM(渲染机制和优化)
  5. Fragment 片段
  6. Teleport 瞬移术
  7. emits 触发组件选项

Composition API 组合式 API

通过代码来理解 Composition API 的作用和好处,以下是一个实例,实现了一个能实时显示鼠标坐标位置的例子。

<template>
  <h1>Hello World</h1>
  <div>
    x: {{ position.x }}
  </div>
  <div>
    y: {{ position.y }}
  </div>
</template>
import { onMounted, onUnmounted, reactive } from 'vue'
export default {
  name: 'App',
  setup() {
    const position = reactive({
      x: 0,
      y: 0
    })

    const update = e => {
      position.x = e.pageX
      position.y = e.pageY
    }


    onMounted(()=>{
      window.addEventListener('mousemove', update)
    })

    onUnmounted(()=>{
      window.removeEventListener('mousemove', update)
    })

    return {
      position
    }

  }
}

重构逻辑部分代码

import { onMounted, onUnmounted, reactive } from 'vue'


function useMousePosition () {
  const position = reactive({
    x: 0,
    y: 0
  })

  // 定义事件处理函数
  const update = e => {
    position.x = e.pageX
    position.y = e.pageY
  }

  // 注册事件
  onMounted(()=>{
    window.addEventListener('mousemove', update)
  })

  // 注销事件
  onUnmounted(()=>{
    window.removeEventListener('mousemove', update)
  })

  return position
}

export default {
  name: 'App',
  setup() {
    const position = useMousePosition()

    return {
      position
    }
  }
}

从上述的代码中可以看出,与 position 相关的变量、函数、生命周期、逻辑操作都被集中抽离到一个 useMousePosition 这个函数中,逻辑更加耦合,整套流程代码查询的时候也比较好定位,整个处理逻辑比较清晰,易于修改。

setup 组件选项

为了开始使用组合式 API,我们首先需要一个可以实际使用它的地方。在 Vue 组件中,我们将此位置称为 setup,setup 选项应该是一个接受 props 和 context 的函数。

props 是 setup 函数接收的第一个参数,即组件的 props 属性。context(上下文) 是 setup 函数接收的第二个参数,context 可以被解构为 { attrs, slots, emit } 这三个参数。

新的 setup 组件选项在创建组件之前执行,一旦 props 被解析,并充当合成 API 的入口点。

WARNING:setup的执行时机在:beforeCreate 之后 created之前。由于在执行 setup 时尚未创建组件实例,因此在 setup 选项中没有 this。这意味着,除了 props 之外,你将无法访问组件中声明的任何属性——本地状态、计算属性或方法。

reactive 和 ref

reactive 函数将传递的 json 对象或者数组包装成了 proxy 对象,使其具备响应式
ref 函数可以处理基本数据类型的变量,包装原始的基本值为一个对象,使其变成响应式数据,通过 primaryValue.value 来访问或更高该响应式变量的值。

computed 和 watched 函数

computed 和 watched 可以单独作为一个函数来使用

import { computed, ref } from '@vue/composition-api'
export default {
  setup() {
    const refCount = ref(1)
    // 只读
    let computedCount = computed(() => refCount.value + 1)
    console.log(computedCount)
    return {
      refCount,
      computedCount
    }
  }
};
import { watch, ref } from '@vue/composition-api'
export default {
  setup() {
    const refCount = ref(100)
    // 定义 watch,只要 count 值变化,就会触发 watch 回调
    // 组件在第一次创建的时候执行一次 watch
    watch(() => console.log(refCount.value), { lazy: false})
    setInterval(() => {
      refCount.value += 2
    }, 5000)
    return {
      refCount
    }
  }
};

生命周期钩子注册内部 setup

为了使组合式 API 的特性与选项式 API 相比更加完整,我们还需要一种在 setup 中注册生命周期钩子的方法。这要归功于从 Vue 导出的几个新函数。组合式 API 上的生命周期钩子与选项式 API 的名称相同,但前缀为 on:即 mounted 看起来像 onMounted。

这些函数接受在组件调用钩子时将执行的回调。

例如代码中的 onMounted() 和 onUnmouted() 钩子函数,将在组件 mounted(加载) 和 unmouted(卸载) 的时候执行事件回调。

Virtual DOM Rewrite 重写虚拟DOM(渲染机制和优化)

利用 patch flag 优化静态树

https://www.pianshen.com/article/16291732261/

Fragment 片段

在 Vue 3 中,组件现在正式支持多根节点组件,即片段!
在 2.x 中,不支持多根组件,当用户意外创建多根组件时会发出警告,因此,为了修复此错误,许多组件被包装在一个 <div> 中。
在 3.x 中,组件现在可以有多个根节点!但是,这确实要求开发者明确定义属性应该分布在哪里。

与单个根节点组件不同,具有多个根节点的组件不具有自动 attribute 回退行为。如果未显式绑定 $attrs,将发出运行时警告。

<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
// 警告
app.component('custom-layout', {
  template: `
    <div class="one">one</div>
    <div class="two">two</div>
    <div class="three">three</div>
  `
})

// 没有警告,$attrs被传递到two元素
app.component('custom-layout', {
  template: `
    <div class="one">one</div>
    <div class="two" v-bind="$attrs">two</div>
    <div class="three">three</div>
  `
})

Teleport 瞬移术

Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下呈现 HTML,而不必求助于全局状态或将其拆分为两个组件。
以模态框举例,可以在一个深度嵌套的 UI 组件中定义一个模态框,通过 Teleport To 把该模态框 append 到 body 的标签下。

Vue3 相对于 Vue2 的一些小改变

生命周期函数重命名

destroyed 生命周期选项被重命名为 unmounted
beforeDestroy 生命周期选项被重命名为 beforeUnmount

data 选项

在 3.x,data 选项已标准化为只接受返回 object 的 function。而不能像 2.x 中的那样 data 可以是一个 object

<script>
  import { createApp } from 'vue'

  createApp({
    data() {
      return {
        apiKey: 'a1b2c3'
      }
    }
  }).mount('#app')
</script>

mixins 行为改变

此外,当来自组件的 data() 及其 mixin 或 extends 基类被合并时,现在将浅层次执行合并。而不是深度合并。

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

在 Vue 2.x中,生成的 $data 是:

{
  user: {
    id: 2,
    name: 'Jack'
  }
}

在 3.0 中,其结果将会是:

{
  user: {
    id: 2
  }
}

Vue3 相对于 Vue2 不兼容的变化

过滤器 filters

从 Vue 3.0 开始,过滤器已删除,不再支持。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351

推荐阅读更多精彩内容