亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

精讀《Vue3.0 Function API》

voyagelab / 2691人閱讀

摘要:拿到的都是而不是原始值,且這個(gè)值會(huì)動(dòng)態(tài)變化。精讀對(duì)于的與,筆者做一些對(duì)比。因此采取了作為優(yōu)化方案只有當(dāng)?shù)诙€(gè)依賴參數(shù)變化時(shí)才返回新引用。不需要使用等進(jìn)行性能優(yōu)化,所有性能優(yōu)化都是自動(dòng)的。前端精讀幫你篩選靠譜的內(nèi)容。

1. 引言

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

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

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

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

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

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

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

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

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

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

首先 Template 機(jī)制還是沒變,其次模仿的是 Hooks 而不是 React 全部,如果你不喜歡這個(gè)改動(dòng),那你更不會(huì)喜歡用 React。

PS: 問這個(gè)問題的人,一定沒有同時(shí)理解 React 與 Vue,其實(shí)這兩個(gè)框架到現(xiàn)在差別蠻大的,后面精讀會(huì)詳細(xì)說明。

下面正式進(jìn)入 Vue 3.0 Function API 的介紹。

2. 概述

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



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

setup 函數(shù)返回值就是注入到頁面模版的變量。我們也可以返回一個(gè)函數(shù),通過使用 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: `
{{ msg }}
` }

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

為何 value() 返回的是 Wrappers 而非具體值呢?原因是 Vue 采用雙向綁定,只有對(duì)象形式訪問值才能保證訪問到的是最終值,這一點(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: ``
}

接下來是 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: `
{{ x }} {{ y }} {{ z }}
` }

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

useMouse 函數(shù)內(nèi)改變 x、y 后,不會(huì)重新觸發(fā) setup 執(zhí)行。

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)聽某些變量變化后執(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í)行,因此無論是在變量、props 變化時(shí)如果想做一些事情,都需要包裹在 watch 中。

后面還有 unwatching、生命周期函數(shù)、依賴注入,都是一些語法定義,感興趣可以繼續(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: `
    
  `
}

雖然在 Vue 中,setup 函數(shù)僅執(zhí)行一次,看上去與 React 函數(shù)完全不一樣(React 函數(shù)每次都執(zhí)行),但其實(shí) Vue 將渲染層(Template)與數(shù)據(jù)層(setup)分開了,而 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 (
    
  )
}

這源于 JSX 與 Template 的根本區(qū)別。JSX 使模版與 JS 可以寫在一起,因此數(shù)據(jù)層與渲染層可以耦合在一起寫(也可以拆分),但 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,需要拋開 JSX&Template,Mutable&Immutable 去看,其實(shí)去掉這兩個(gè)框架無關(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 的花樣來(因?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)單語法:

const [ count, setCount ] = useState(0)

const setToOne = () => setCount(1)

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

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: `
{{ x }} {{ y }} {{ z }}
` }

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

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

這就是 Immutable 的好處,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 直覺。

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

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

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

對(duì) React Hooks 而言,調(diào)用必須放在最前面,而且不能被包含在條件語句里,這是因?yàn)?React Hooks 采用下標(biāo)方式尋找狀態(tài),一旦位置不對(duì)或者 Hooks 放在了條件中,就無法正確找到對(duì)應(yīng)位置的值。

而 Vue Function API 中的 Hooks 可以放在任意位置、任意命名、被條件語句任意包裹的,因?yàn)槠洳⒉粫?huì)觸發(fā) setup 的更新,只在需要的時(shí)候更新自己的引用值即可,而 Template 的重渲染則完全繼承 Vue 2.0 的依賴收集機(jī)制,它不管值來自哪里,只要用到的值變了,就可以重新渲染了。

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

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

而 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è)問題,就是完全依賴 Immutable 屬性。而在 Function Component 內(nèi)部創(chuàng)建函數(shù)時(shí),每次都會(huì)創(chuàng)建一個(gè)全新的對(duì)象,這個(gè)對(duì)象如果傳給子組件,必然導(dǎo)致子組件無法做性能優(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 入門》 - 永遠(yuǎn)對(duì)依賴誠(chéng)實(shí))。

回到 Vue 3.0,由于 setup 僅執(zhí)行一次,因此函數(shù)本身只會(huì)創(chuàng)建一次,不存在多實(shí)例問題,不需要 useCallback 的概念,更不需要使用 lint 插件 保證依賴書寫正確,這對(duì)開發(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ò)的問題,更不需要像 React 寫一個(gè) lint 插件保證依賴的正確性。(這也是筆者想對(duì) React Hooks 吐槽的點(diǎn),React 團(tuán)隊(duì)如何保障每個(gè)人都安裝了 lint?就算裝了 lint,如果 IDE 有 BUG,導(dǎo)致沒有生效,隨時(shí)可能寫出依賴不正確的 “危險(xiǎn)代碼”,造成比如死循環(huán)等嚴(yán)重后果)

4. 總結(jié)

通過對(duì)比 Vue Hooks 與 React Hooks 可以發(fā)現(xiàn),Vue 3.0 將 Mutable 特性完美與 Hooks 結(jié)合,規(guī)避了一些 React Hooks 的硬傷。所以我們可以說 Vue 借鑒了 React Hooks 的思想,但創(chuàng)造出來的確實(shí)一個(gè)更精美的藝術(shù)品。

但 React Hooks 遵循的 Immutable 也有好的一面,就是每次渲染中狀態(tài)被穩(wěn)定的固化下來了,不用擔(dān)心狀態(tài)突然變更帶來的影響(其實(shí)反而要注意狀態(tài)用不變更帶來的影響),對(duì)于數(shù)據(jù)記錄、程序運(yùn)行的穩(wěn)定性都有較高的可預(yù)期性。

最后,對(duì)于喜歡 Mutable 的開發(fā)者,Vue 3.0 是你的最佳選擇,基于 React + Mutable 搞的一些小輪子做到頂級(jí)可能還不如 Vue 3.0。對(duì)于 React 開發(fā)者來說,堅(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

如果你想?yún)⑴c討論,請(qǐng) 點(diǎn)擊這里,每周都有新的主題,周末或周一發(fā)布。前端精讀 - 幫你篩選靠譜的內(nèi)容。

關(guān)注 前端精讀微信公眾號(hào)

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/105178.html

相關(guān)文章

  • 精讀《前端未來展望》

    摘要:精讀前端可以從多個(gè)角度理解,比如規(guī)范框架語言社區(qū)場(chǎng)景以及整條研發(fā)鏈路。同是前端未來展望,不同的文章側(cè)重的格局不同,兩個(gè)標(biāo)題相同的文章內(nèi)容可能大相徑庭。作為使用者,現(xiàn)在和未來的主流可能都是微軟系,畢竟微軟在操作系統(tǒng)方面人才儲(chǔ)備和經(jīng)驗(yàn)積累很多。 1. 引言 前端展望的文章越來越不好寫了,隨著前端發(fā)展的深入,需要擁有非常寬廣的視野與格局才能看清前端的未來。 筆者根據(jù)自身經(jīng)驗(yàn),結(jié)合下面幾篇文章...

    MadPecker 評(píng)論0 收藏0
  • 模擬 vue3.0 rfcs `createComponent` api 中的`props`類型推導(dǎo)

    摘要:中類型推導(dǎo)部分預(yù)期想實(shí)現(xiàn)的效果在中對(duì)應(yīng)的類型是對(duì)應(yīng)的類型是對(duì)應(yīng)的類型是但是,我們想要實(shí)現(xiàn)的是轉(zhuǎn)換成小寫的所以我們寫個(gè)泛型來轉(zhuǎn)換預(yù)覽鏈接定義的類型留個(gè)泛型是給復(fù)雜類型做兼容復(fù)雜的類型定義函數(shù)接收的類型最關(guān)鍵的一步根據(jù)輸入的類型計(jì)算出來函 rfc 中類型推導(dǎo)部分 Type Inference 預(yù)期想實(shí)現(xiàn)的效果 createComponent({ props: { foo: {...

    wawor4827 評(píng)論0 收藏0
  • vue3.0 搭建項(xiàng)目總結(jié)

    摘要:環(huán)境配置項(xiàng)目中的不同開發(fā)環(huán)境有很多依賴配置,所以可以根據(jù)環(huán)境設(shè)置不同的配置,以免在不同環(huán)境經(jīng)常修改文件在根目錄下創(chuàng)建環(huán)境文件,可以在不同環(huán)境設(shè)置一些配置變量,如圖文件配置在文件里面有一個(gè)對(duì)象,可設(shè)置如圖配置在里面需在對(duì)象里面設(shè)置重點(diǎn)刪除默認(rèn) 1.環(huán)境配置 項(xiàng)目中的不同開發(fā)環(huán)境有很多依賴配置,所以可以根據(jù)環(huán)境設(shè)置不同的配置,以免在不同環(huán)境經(jīng)常修改文件 1 在根目錄下創(chuàng)建 `.env.[環(huán)...

    Youngdze 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

voyagelab

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<