欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

精讀《Vue3.0 Function API》

 更新時(shí)間:2020年05月20日 11:54:06   作者:黃子毅  
這篇文章主要介紹了精讀《Vue3.0 Function API》,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧

1. 引言

Vue 3.0 的發(fā)布引起了軒然大波,讓我們解讀下它的 function api RFC 詳細(xì)了解一下 Vue 團(tuán)隊(duì)是怎么想的吧!

首先官方回答了幾個(gè)最受關(guān)注的問(wèn)題:

Vue 3.0 是否有 break change,就像 Python 3 / Angular 2 一樣?

不,100% 兼容 Vue 2.0,且暫未打算廢棄任何 API(未來(lái)也不)。之前有草案試圖這么做,但由于用戶反饋太猛,被撤回了。

Vue 3.0 的設(shè)計(jì)蓋棺定論了嗎?

沒(méi)有呀,這次精讀的稿子就是 RFC(Request For Comments),翻譯成中文就是 “意見(jiàn)征求稿”,還在征求大家意見(jiàn)中哦。

這 RFC 咋這么復(fù)雜?

RFC 是寫(xiě)給貢獻(xiàn)者/維護(hù)者的,要考慮許多邊界情況與細(xì)節(jié),所以當(dāng)然會(huì)復(fù)雜很多嘍!當(dāng)然 Vue 本身使用起來(lái)還是很簡(jiǎn)單的。

Vue 本身 Mutable + Template 就注定了是個(gè)用起來(lái)簡(jiǎn)單(約定 + 自然),實(shí)現(xiàn)起來(lái)復(fù)雜(解析 + 雙綁)的框架。

這次改動(dòng)很像在模仿 React,為啥不直接用 React?

首先 Template 機(jī)制還是沒(méi)變,其次模仿的是 Hooks 而不是 React 全部,如果你不喜歡這個(gè)改動(dòng),那你更不會(huì)喜歡用 React。
PS: 問(wèn)這個(gè)問(wèn)題的人,一定沒(méi)有同時(shí)理解 React 與 Vue,其實(shí)這兩個(gè)框架到現(xiàn)在差別蠻大的,后面精讀會(huì)詳細(xì)說(shuō)明。
下面正式進(jìn)入 Vue 3.0 Function API 的介紹。

2. 概述

Vue 函數(shù)式基本 Demo:

<template>
 <div>
  <span>count is {{ count }}</span>
  <span>plusOne is {{ plusOne }}</span>
  <button @click="increment">count++</button>
 </div>
</template>

<script>
import { value, computed, watch, onMounted } from 'vue'

export default {
 setup() {
  // reactive state
  const count = value(0)
  // computed state
  const plusOne = computed(() => count.value + 1)
  // method
  const increment = () => { count.value++ }
  // watch
  watch(() => count.value * 2, val => {
   console.log(`count * 2 is ${val}`)
  })
  // lifecycle
  onMounted(() => {
   console.log(`mounted`)
  })
  // expose bindings on render context
  return {
   count,
   plusOne,
   increment
  }
 }
}
</script>

函數(shù)式風(fēng)格的入口是 setup 函數(shù),采用了函數(shù)式風(fēng)格后可以享受如下好處:類型自動(dòng)推導(dǎo)、減少打包體積。

setup 函數(shù)返回值就是注入到頁(yè)面模版的變量。我們也可以返回一個(gè)函數(shù),通過(guò)使用 value 這個(gè) API 產(chǎn)生屬性并修改:

import { value } from 'vue'

const MyComponent = {
 setup(props) {
  const msg = value('hello')
  const appendName = () => {
   msg.value = `hello ${props.name}`
  }
  return {
   msg,
   appendName
  }
 },
 template: `<div @click="appendName">{{ msg }}</div>`
}

要注意的是,value() 返回的是一個(gè)對(duì)象,通過(guò) .value 才能訪問(wèn)到其真實(shí)值。

為何 value() 返回的是 Wrappers 而非具體值呢?原因是 Vue 采用雙向綁定,只有對(duì)象形式訪問(wèn)值才能保證訪問(wèn)到的是最終值,這一點(diǎn)類似 React 的 useRef() API 的 .current 規(guī)則。

那既然所有 value() 返回的值都是 Wrapper,那直接給模版使用時(shí)要不要調(diào)用 .value 呢?答案是否定的,直接使用即可,模版會(huì)自動(dòng) Unwrapping:

const MyComponent = {
 setup() {
  return {
   count: value(0)
  }
 },
 template: `<button @click="count++">{{ count }}</button>`
}

接下來(lái)是 Hooks,下面是一個(gè)使用 Hooks 實(shí)現(xiàn)獲得鼠標(biāo)實(shí)時(shí)位置的例子:

function useMouse() {
 const x = value(0)
 const y = value(0)
 const update = e => {
  x.value = e.pageX
  y.value = e.pageY
 }
 onMounted(() => {
  window.addEventListener('mousemove', update)
 })
 onUnmounted(() => {
  window.removeEventListener('mousemove', update)
 })
 return { x, y }
}

// in consuming component
const Component = {
 setup() {
  const { x, y } = useMouse()
  const { z } = useOtherLogic()
  return { x, y, z }
 },
 template: `<div>{{ x }} {{ y }} {{ z }}</div>`
}

可以看到,useMouse 將所有與 “處理鼠標(biāo)位置” 相關(guān)的邏輯都封裝了進(jìn)去,乍一看與 React Hooks 很像,但是有兩個(gè)區(qū)別:

  1. useMouse 函數(shù)內(nèi)改變 x、y 后,不會(huì)重新觸發(fā) setup 執(zhí)行。
  2. x y 拿到的都是 Wrapper 而不是原始值,且這個(gè)值會(huì)動(dòng)態(tài)變化。

另一個(gè)重要 API 就是 watch,它的作用類似 React Hooks 的 useEffect,但實(shí)現(xiàn)原理和調(diào)用時(shí)機(jī)其實(shí)完全不一樣。

watch 的目的是監(jiān)聽(tīng)某些變量變化后執(zhí)行邏輯,比如當(dāng) id 變化后重新取數(shù):

const MyComponent = {
 props: {
  id: Number
 },
 setup(props) {
  const data = value(null)
  watch(() => props.id, async (id) => {
   data.value = await fetchData(id)
  })
 }
}

之所以要 watch,因?yàn)樵?Vue 中,setup 函數(shù)僅執(zhí)行一次,所以不像 React Function Component,每次組件 props 變化都會(huì)重新執(zhí)行,因此無(wú)論是在變量、props 變化時(shí)如果想做一些事情,都需要包裹在 watch 中。

后面還有 unwatching、生命周期函數(shù)、依賴注入,都是一些語(yǔ)法定義,感興趣可以繼續(xù)閱讀原文,筆者就不贅述了。

3. 精讀

對(duì)于 Vue 3.0 的 Function API + Hooks 與 React Function Component + Hooks,筆者做一些對(duì)比。

Vue 與 React 邏輯結(jié)構(gòu)

React Function Component 與 Hooks,雖然在實(shí)現(xiàn)原理上,與 Vue3.0 存在 Immutable 與 Mutable、JSX 與 Template 的區(qū)別,但邏輯理解上有著相通之處。

const MyComponent = {
 setup(props) {
  const x = value(0)

  const setXRandom = () => {
   x.value = Math.random()
  }

  return { x, setXRandom }
 },
 template: `
  <button @onClick="setXRandom"/>{{x}}</button>
 `
}

雖然在 Vue 中,setup 函數(shù)僅執(zhí)行一次,看上去與 React 函數(shù)完全不一樣(React 函數(shù)每次都執(zhí)行),但其實(shí) Vue 將渲染層(Template)與數(shù)據(jù)層(setup)分開(kāi)了,而 React 合在了一起。

我們可以利用 React Hooks 將數(shù)據(jù)層與渲染層完全隔離:

// 類似 vue 的 setup 函數(shù)
function useMyComponentSetup(props) {
 const [x, setX] = useState(0)

 const setXRandom = useCallback(() => {
  setX(Math.random())
 }, [setX])

 return { x, setXRandom }
}

// 類似 vue 的 template 函數(shù)
function MyComponent(props: { name: String }) {
 const { x, setXRandom } = useMyComponentSetup(props)

 return (
  <button onClick={setXRandom}>{x}</button>
 )
}

這源于 JSX 與 Template 的根本區(qū)別。JSX 使模版與 JS 可以寫(xiě)在一起,因此數(shù)據(jù)層與渲染層可以耦合在一起寫(xiě)(也可以拆分),但 Vue 采取的 Template 思路使數(shù)據(jù)層強(qiáng)制分離了,這也使代碼分層更清晰了。
而實(shí)際上 Vue3.0 的 setup 函數(shù)也是可選的,再配合其支持的 TSX 功能,與 React 真的只有 Mutable 的區(qū)別了:

// 這是個(gè) Vue 組件
const MyComponent = createComponent((props: { msg: string }) => {
 return () => h('div', props.msg)
})

我們很難評(píng)價(jià) Template 與 JSX 的好壞,但為了更透徹的理解 Vue 與 React,需要拋開(kāi) JSX&Template,Mutable&Immutable 去看,其實(shí)去掉這兩個(gè)框架無(wú)關(guān)的技術(shù)選型,React@16 與 Vue@3 已經(jīng)非常像了。

Vue3.0 的精髓是學(xué)習(xí)了 React Hooks 概念,因此正好可以用 Hooks 在 React 中模擬 Vue 的 setup 函數(shù)。

關(guān)于這兩套技術(shù)選型,已經(jīng)是相對(duì)完美的組合,不建議在 JSX 中再實(shí)現(xiàn)類似 Mutable + JSX 的花樣來(lái)(因?yàn)橄矚g Mutable 可以用 Vue 呀):

  • Vue:Mutable + Template
  • React:Immutable + JSX

真正影響編碼習(xí)慣的就是 Mutable 與 Immutable,使用 Vue 就堅(jiān)定使用 Mutable,使用 React 就堅(jiān)定使用 Immutable,這樣能最大程度發(fā)揮兩套框架的價(jià)值。

Vue Hooks 與 React Hooks 的差異

先看 React Hooks 的簡(jiǎn)單語(yǔ)法:

const [ count, setCount ] = useState(0)
const setToOne = () => setCount(1)

Vue Hooks 的簡(jiǎn)單語(yǔ)法:

const count = value(0)
const setToOne = () => count.value = 1

之所以 React 返回的 count 是一個(gè)數(shù)字,是因?yàn)?Immutable 規(guī)則,而 Vue 返回的 count 是個(gè)對(duì)象,擁有 count.value 屬性,也是因?yàn)?Vue Mutable 規(guī)則導(dǎo)致,這使得 Vue 定義的所有變量都類似 React 中 useRef 定義變量,因此不存 React capture value 的特性。

關(guān)于 capture value 更多信息,可以閱讀精讀《Function VS Class 組件》 Capute Value 介紹

另外,對(duì)于 Hooks 的值變更機(jī)制也不同,我們看 Vue 的代碼:

const Component = {
 setup() {
  const { x, y } = useMouse()
  const { z } = useOtherLogic()
  return { x, y, z }
 },
 template: `<div>{{ x }} {{ y }} {{ z }}</div>`
}

由于 setup 函數(shù)僅執(zhí)行一次,怎么做到當(dāng) useMouse 導(dǎo)致 x、y 值變化時(shí),可以在 setup 中拿到最新的值?

在 React 中,useMouse 如果修改了 x 的值,那么使用 useMouse 的函數(shù)就會(huì)被重新執(zhí)行,以此拿到最新的 x,而在 Vue 中,將 Hooks 與 Immutable 深度結(jié)合,通過(guò)包裝 x.value,使得當(dāng) x 變更時(shí),引用保持不變,僅值發(fā)生了變化。所以 Vue 利用 Proxy 監(jiān)聽(tīng)機(jī)制,可以做到 setup 函數(shù)不重新執(zhí)行,但 Template 重新渲染的效果。

這就是 Mmutable 的好處,Vue Hooks 中,不需要 useMemo useCallback useRef 等機(jī)制,僅需一個(gè) value 函數(shù),直觀的 Mutable 修改,就可以實(shí)現(xiàn) React 中一套 Immutable 性能優(yōu)化后的效果,這個(gè)是 Mutable 的魅力所在。

Vue Hooks 的優(yōu)勢(shì)

筆者對(duì) RFC 中對(duì) Vue、React Hooks 的對(duì)比做一個(gè)延展解釋:
首先最大的不同:setup 僅執(zhí)行一遍,而 React Function Component 每次渲染都會(huì)執(zhí)行。

Vue 的代碼使用更符合 JS 直覺(jué)。

這句話直截了當(dāng)戳中了 JS 軟肋,JS 并非是針對(duì) Immutable 設(shè)計(jì)的語(yǔ)言,所以 Mutable 寫(xiě)法非常自然,而 Immutable 的寫(xiě)法就比較別扭。

當(dāng) Hooks 要更新值時(shí),Vue 只要用等于號(hào)賦值即可,而 React Hooks 需要調(diào)用賦值函數(shù),當(dāng)對(duì)象類型復(fù)雜時(shí),還需借助第三方庫(kù)才能保證進(jìn)行了正確的 Immutable 更新。

對(duì) Hooks 使用順序無(wú)要求,而且可以放在條件語(yǔ)句里。

對(duì) React Hooks 而言,調(diào)用必須放在最前面,而且不能被包含在條件語(yǔ)句里,這是因?yàn)?React Hooks 采用下標(biāo)方式尋找狀態(tài),一旦位置不對(duì)或者 Hooks 放在了條件中,就無(wú)法正確找到對(duì)應(yīng)位置的值。
而 Vue Function API 中的 Hooks 可以放在任意位置、任意命名、被條件語(yǔ)句任意包裹的,因?yàn)槠洳⒉粫?huì)觸發(fā) setup 的更新,只在需要的時(shí)候更新自己的引用值即可,而 Template 的重渲染則完全繼承 Vue 2.0 的依賴收集機(jī)制,它不管值來(lái)自哪里,只要用到的值變了,就可以重新渲染了。

不會(huì)再每次渲染重復(fù)調(diào)用,減少 GC 壓力。

這確實(shí)是 React Hooks 的一個(gè)問(wèn)題,所有 Hooks 都在渲染閉包中執(zhí)行,每次重渲染都有一定性能壓力,而且頻繁的渲染會(huì)帶來(lái)許多閉包,雖然可以依賴 GC 機(jī)制回收,但會(huì)給 GC 帶來(lái)不小的壓力。

而 Vue Hooks 只有一個(gè)引用,所以存儲(chǔ)的內(nèi)容就非常精簡(jiǎn),也就是占用內(nèi)存小,而且當(dāng)值變化時(shí),也不會(huì)重新觸發(fā) setup 的執(zhí)行,所以確實(shí)不會(huì)造成 GC 壓力。

必須要總包裹 useCallback 函數(shù)確保不讓子元素頻繁重渲染。

React Hooks 有一個(gè)問(wèn)題,就是完全依賴 Immutable 屬性。而在 Function Component 內(nèi)部創(chuàng)建函數(shù)時(shí),每次都會(huì)創(chuàng)建一個(gè)全新的對(duì)象,這個(gè)對(duì)象如果傳給子組件,必然導(dǎo)致子組件無(wú)法做性能優(yōu)化。 因此 React 采取了 useCallback 作為優(yōu)化方案:

const fn = useCallback(() => /* .. */, [])

只有當(dāng)?shù)诙€(gè)依賴參數(shù)變化時(shí)才返回新引用。但第二個(gè)依賴參數(shù)需要 lint 工具確保依賴總是正確的(關(guān)于為何要對(duì)依賴誠(chéng)實(shí),感興趣可以移步 精讀《Function Component 入門(mén)》 - 永遠(yuǎn)對(duì)依賴誠(chéng)實(shí))。

回到 Vue 3.0,由于 setup 僅執(zhí)行一次,因此函數(shù)本身只會(huì)創(chuàng)建一次,不存在多實(shí)例問(wèn)題,不需要 useCallback 的概念,更不需要使用lint 插件 保證依賴書(shū)寫(xiě)正確,這對(duì)開(kāi)發(fā)者是實(shí)實(shí)在在的友好。

不需要使用 useEffect useMemo 等進(jìn)行性能優(yōu)化,所有性能優(yōu)化都是自動(dòng)的。

這也是實(shí)在話,畢竟 Mutable + 依賴自動(dòng)收集就可以做到最小粒度的精確更新,根本不會(huì)觸發(fā)不必要的 Rerender,因此 useMemo 這個(gè)概念也不需要了。

而 useEffect 也需要傳遞第二個(gè)參數(shù) “依賴項(xiàng)”,在 Vue 中根本不需要傳遞 “依賴項(xiàng)”,所以也不會(huì)存在用戶不小心傳錯(cuò)的問(wèn)題,更不需要像 React 寫(xiě)一個(gè) lint 插件保證依賴的正確性。(這也是筆者想對(duì) React Hooks 吐槽的點(diǎn),React 團(tuán)隊(duì)如何保障每個(gè)人都安裝了 lint?就算裝了 lint,如果 IDE 有 BUG,導(dǎo)致沒(méi)有生效,隨時(shí)可能寫(xiě)出依賴不正確的 “危險(xiǎn)代碼”,造成比如死循環(huán)等嚴(yán)重后果)

4. 總結(jié)

通過(guò)對(duì)比 Vue Hooks 與 React Hooks 可以發(fā)現(xiàn),Vue 3.0 將 Mutable 特性完美與 Hooks 結(jié)合,規(guī)避了一些 React Hooks 的硬傷。所以我們可以說(shuō) Vue 借鑒了 React Hooks 的思想,但創(chuàng)造出來(lái)的確實(shí)一個(gè)更精美的藝術(shù)品。
但 React Hooks 遵循的 Immutable 也有好的一面,就是每次渲染中狀態(tài)被穩(wěn)定的固化下來(lái)了,不用擔(dān)心狀態(tài)突然變更帶來(lái)的影響(其實(shí)反而要注意狀態(tài)用不變更帶來(lái)的影響),對(duì)于數(shù)據(jù)記錄、程序運(yùn)行的穩(wěn)定性都有較高的可預(yù)期性。
最后,對(duì)于喜歡 Mutable 的開(kāi)發(fā)者,Vue 3.0 是你的最佳選擇,基于 React + Mutable 搞的一些小輪子做到頂級(jí)可能還不如 Vue 3.0。對(duì)于 React 開(kāi)發(fā)者來(lái)說(shuō),堅(jiān)持你們的 Immutable 信仰吧,Vue 3.0 已經(jīng)將 Mutable 發(fā)揮到極致,只有將 React Immutable 特性發(fā)揮到極致才能發(fā)揮 React 的最大價(jià)值。

討論地址是:精讀《Vue3.0 Function API》 · Issue #173 · dt-fe/weekly

到此這篇關(guān)于精讀《Vue3.0 Function API》的文章就介紹到這了,更多相關(guān)Vue3.0 Function API內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • vue打包項(xiàng)目版本號(hào)自加的操作步驟

    vue打包項(xiàng)目版本號(hào)自加的操作步驟

    項(xiàng)目每次打包后都需要改動(dòng)項(xiàng)目版本號(hào),這個(gè)改動(dòng)每次都需要在package.json中修改version,比較麻煩,到底有沒(méi)有一種打包后版本號(hào)自加的辦法,這篇文章主要介紹了vue打包項(xiàng)目版本號(hào)自加的步驟,需要的朋友可以參考下
    2022-09-09
  • vue2中如何自定義組件的v-model

    vue2中如何自定義組件的v-model

    這篇文章主要介紹了vue2中如何自定義組件的v-model,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • vue-router實(shí)現(xiàn)組件間的跳轉(zhuǎn)(參數(shù)傳遞)

    vue-router實(shí)現(xiàn)組件間的跳轉(zhuǎn)(參數(shù)傳遞)

    這篇文章主要為大家詳細(xì)介紹了vue-router實(shí)現(xiàn)組件間的跳轉(zhuǎn),參數(shù)傳遞方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • vue--點(diǎn)擊當(dāng)前增加class,其他刪除class的方法

    vue--點(diǎn)擊當(dāng)前增加class,其他刪除class的方法

    今天小編就為大家分享一篇vue--點(diǎn)擊當(dāng)前增加class,其他刪除class的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-09-09
  • Vue從TodoList中學(xué)父子組件通信

    Vue從TodoList中學(xué)父子組件通信

    這篇文章主要介紹了Vue從TodoList中學(xué)父子組件通信,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-02-02
  • 在Vue中實(shí)現(xiàn)地圖熱點(diǎn)展示與交互的方法詳解(如熱力圖)

    在Vue中實(shí)現(xiàn)地圖熱點(diǎn)展示與交互的方法詳解(如熱力圖)

    隨著大數(shù)據(jù)和可視化技術(shù)的發(fā)展,地圖熱點(diǎn)展示越來(lái)越受到人們的關(guān)注,在Vue應(yīng)用中,我們通常需要實(shí)現(xiàn)地圖熱點(diǎn)的展示和交互,以便更好地呈現(xiàn)數(shù)據(jù)和分析結(jié)果,本文將介紹在Vue中如何進(jìn)行地圖熱點(diǎn)展示與交互,包括熱力圖、點(diǎn)聚合等
    2023-07-07
  • 封裝 axios+promise通用請(qǐng)求函數(shù)操作

    封裝 axios+promise通用請(qǐng)求函數(shù)操作

    這篇文章主要介紹了封裝 axios+promise通用請(qǐng)求函數(shù)操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-08-08
  • 如何解決d3.event在v7版本無(wú)效影響zoom拖拽縮放問(wèn)題

    如何解決d3.event在v7版本無(wú)效影響zoom拖拽縮放問(wèn)題

    這篇文章主要介紹了如何解決d3.event在v7版本無(wú)效影響zoom拖拽縮放問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-03-03
  • vue的滾動(dòng)條插件實(shí)現(xiàn)代碼

    vue的滾動(dòng)條插件實(shí)現(xiàn)代碼

    這篇文章主要介紹了vue的滾動(dòng)條插件實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Vue如何給組件添加點(diǎn)擊事件?@click.native

    Vue如何給組件添加點(diǎn)擊事件?@click.native

    這篇文章主要介紹了Vue如何給組件添加點(diǎn)擊事件?@click.native,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10

最新評(píng)論