【Vue】Vue3 介紹

Vue3 相對于 Vue2 值得關(guān)注的新特性

  1. Composition API 組合式 API
  2. 重新實現(xiàn)了數(shù)據(jù)響應(yīng)式原理(利用 ES6 的 proxy 代替了 ES5的 Object.defineProperty)
  3. 源碼使用 typescript 進行了重寫,擁有更好的類型推導(dǎo)
  4. Virtual DOM Rewrite 重寫虛擬DOM(渲染機制和優(yōu)化)
  5. Fragment 片段
  6. Teleport 瞬移術(shù)
  7. emits 觸發(fā)組件選項

Composition API 組合式 API

通過代碼來理解 Composition API 的作用和好處,以下是一個實例,實現(xiàn)了一個能實時顯示鼠標(biāo)坐標(biāo)位置的例子豌鹤。

<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
    }

  }
}

重構(gòu)邏輯部分代碼

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


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

  // 定義事件處理函數(shù)
  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 相關(guān)的變量根资、函數(shù)胎撇、生命周期狸捕、邏輯操作都被集中抽離到一個 useMousePosition 這個函數(shù)中热幔,邏輯更加耦合乐设,整套流程代碼查詢的時候也比較好定位,整個處理邏輯比較清晰绎巨,易于修改近尚。

setup 組件選項

為了開始使用組合式 API,我們首先需要一個可以實際使用它的地方场勤。在 Vue 組件中戈锻,我們將此位置稱為 setup,setup 選項應(yīng)該是一個接受 props 和 context 的函數(shù)和媳。

props 是 setup 函數(shù)接收的第一個參數(shù)格遭,即組件的 props 屬性。context(上下文) 是 setup 函數(shù)接收的第二個參數(shù)留瞳,context 可以被解構(gòu)為 { attrs, slots, emit } 這三個參數(shù)拒迅。

新的 setup 組件選項在創(chuàng)建組件之前執(zhí)行,一旦 props 被解析她倘,并充當(dāng)合成 API 的入口點璧微。

WARNING:setup的執(zhí)行時機在:beforeCreate 之后 created之前。由于在執(zhí)行 setup 時尚未創(chuàng)建組件實例硬梁,因此在 setup 選項中沒有 this前硫。這意味著,除了 props 之外荧止,你將無法訪問組件中聲明的任何屬性——本地狀態(tài)屹电、計算屬性或方法。

reactive 和 ref

reactive 函數(shù)將傳遞的 json 對象或者數(shù)組包裝成了 proxy 對象罩息,使其具備響應(yīng)式
ref 函數(shù)可以處理基本數(shù)據(jù)類型的變量嗤详,包裝原始的基本值為一個對象个扰,使其變成響應(yīng)式數(shù)據(jù)瓷炮,通過 primaryValue.value 來訪問或更高該響應(yīng)式變量的值。

computed 和 watched 函數(shù)

computed 和 watched 可以單獨作為一個函數(shù)來使用

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 值變化娘香,就會觸發(fā) watch 回調(diào)
    // 組件在第一次創(chuàng)建的時候執(zhí)行一次 watch
    watch(() => console.log(refCount.value), { lazy: false})
    setInterval(() => {
      refCount.value += 2
    }, 5000)
    return {
      refCount
    }
  }
};

生命周期鉤子注冊內(nèi)部 setup

為了使組合式 API 的特性與選項式 API 相比更加完整苍狰,我們還需要一種在 setup 中注冊生命周期鉤子的方法。這要歸功于從 Vue 導(dǎo)出的幾個新函數(shù)烘绽。組合式 API 上的生命周期鉤子與選項式 API 的名稱相同淋昭,但前綴為 on:即 mounted 看起來像 onMounted。

這些函數(shù)接受在組件調(diào)用鉤子時將執(zhí)行的回調(diào)安接。

例如代碼中的 onMounted() 和 onUnmouted() 鉤子函數(shù)翔忽,將在組件 mounted(加載) 和 unmouted(卸載) 的時候執(zhí)行事件回調(diào)。

Virtual DOM Rewrite 重寫虛擬DOM(渲染機制和優(yōu)化)

利用 patch flag 優(yōu)化靜態(tài)樹

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

Fragment 片段

在 Vue 3 中盏檐,組件現(xiàn)在正式支持多根節(jié)點組件歇式,即片段!
在 2.x 中胡野,不支持多根組件材失,當(dāng)用戶意外創(chuàng)建多根組件時會發(fā)出警告,因此硫豆,為了修復(fù)此錯誤龙巨,許多組件被包裝在一個 <div> 中。
在 3.x 中熊响,組件現(xiàn)在可以有多個根節(jié)點旨别!但是,這確實要求開發(fā)者明確定義屬性應(yīng)該分布在哪里汗茄。

與單個根節(jié)點組件不同昼榛,具有多個根節(jié)點的組件不具有自動 attribute 回退行為。如果未顯式綁定 $attrs剔难,將發(fā)出運行時警告胆屿。

<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 瞬移術(shù)

Teleport 提供了一種干凈的方法,允許我們控制在 DOM 中哪個父節(jié)點下呈現(xiàn) HTML偶宫,而不必求助于全局狀態(tài)或?qū)⑵洳鸱譃閮蓚€組件非迹。
以模態(tài)框舉例,可以在一個深度嵌套的 UI 組件中定義一個模態(tài)框纯趋,通過 Teleport To 把該模態(tài)框 append 到 body 的標(biāo)簽下憎兽。

Vue3 相對于 Vue2 的一些小改變

生命周期函數(shù)重命名

destroyed 生命周期選項被重命名為 unmounted
beforeDestroy 生命周期選項被重命名為 beforeUnmount

data 選項

在 3.x,data 選項已標(biāo)準(zhǔn)化為只接受返回 object 的 function吵冒。而不能像 2.x 中的那樣 data 可以是一個 object

<script>
  import { createApp } from 'vue'

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

mixins 行為改變

此外纯命,當(dāng)來自組件的 data() 及其 mixin 或 extends 基類被合并時,現(xiàn)在將淺層次執(zhí)行合并痹栖。而不是深度合并亿汞。

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 中揪阿,其結(jié)果將會是:

{
  user: {
    id: 2
  }
}

Vue3 相對于 Vue2 不兼容的變化

過濾器 filters

從 Vue 3.0 開始疗我,過濾器已刪除咆畏,不再支持。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末吴裤,一起剝皮案震驚了整個濱河市旧找,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌麦牺,老刑警劉巖钮蛛,帶你破解...
    沈念sama閱讀 218,682評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異剖膳,居然都是意外死亡愿卒,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評論 3 395
  • 文/潘曉璐 我一進店門潮秘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來琼开,“玉大人,你說我怎么就攤上這事枕荞」窈颍” “怎么了?”我有些...
    開封第一講書人閱讀 165,083評論 0 355
  • 文/不壞的土叔 我叫張陵躏精,是天一觀的道長渣刷。 經(jīng)常有香客問我,道長矗烛,這世上最難降的妖魔是什么辅柴? 我笑而不...
    開封第一講書人閱讀 58,763評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮瞭吃,結(jié)果婚禮上碌嘀,老公的妹妹穿的比我還像新娘。我一直安慰自己歪架,他們只是感情好股冗,可當(dāng)我...
    茶點故事閱讀 67,785評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著和蚪,像睡著了一般止状。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上攒霹,一...
    開封第一講書人閱讀 51,624評論 1 305
  • 那天怯疤,我揣著相機與錄音,去河邊找鬼催束。 笑死集峦,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播少梁,決...
    沈念sama閱讀 40,358評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼矫付!你這毒婦竟也來了凯沪?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,261評論 0 276
  • 序言:老撾萬榮一對情侶失蹤买优,失蹤者是張志新(化名)和其女友劉穎妨马,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體杀赢,經(jīng)...
    沈念sama閱讀 45,722評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡烘跺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了脂崔。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滤淳。...
    茶點故事閱讀 40,030評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖砌左,靈堂內(nèi)的尸體忽然破棺而出脖咐,到底是詐尸還是另有隱情,我是刑警寧澤汇歹,帶...
    沈念sama閱讀 35,737評論 5 346
  • 正文 年R本政府宣布屁擅,位于F島的核電站,受9級特大地震影響产弹,放射性物質(zhì)發(fā)生泄漏派歌。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,360評論 3 330
  • 文/蒙蒙 一痰哨、第九天 我趴在偏房一處隱蔽的房頂上張望胶果。 院中可真熱鬧,春花似錦斤斧、人聲如沸稽物。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,941評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽贝或。三九已至,卻和暖如春锐秦,著一層夾襖步出監(jiān)牢的瞬間咪奖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,057評論 1 270
  • 我被黑心中介騙來泰國打工酱床, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留羊赵,地道東北人。 一個月前我還...
    沈念sama閱讀 48,237評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像昧捷,于是被迫代替她去往敵國和親闲昭。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,976評論 2 355

推薦閱讀更多精彩內(nèi)容