首頁 >web前端 >Vue.js >注意,Vue響應性語法糖已廢棄!

注意,Vue響應性語法糖已廢棄!

藏色散人
藏色散人轉載
2023-03-06 15:51:512870瀏覽

這篇文章為大家帶來了關於Vue的最新情況,其中主要跟大家聊一聊Vue中的響應性語法糖,感興趣的朋友下面一起來看一下吧,希望對大家有幫助。

注意,Vue響應性語法糖已廢棄!

介紹

自從引入組合式API 的概念以來,一個主要的未解決的問題就是refreactive 到底用哪一個。 reactive 有解構失去回應性的問題,而ref 需要到處使用 .value 則感覺很繁瑣,並且在沒有類型系統的幫助時很容易漏掉 .value

例如,下面的計數器:

<template>
  <button @click="increment">{{ count }}</button>
</template>

使用ref 定義count 變數和increment 方法:

let count = ref(0)

function increment() {
  count.value++
}

而使用回應性語法糖,我們可以像這樣書寫程式碼:

let count = $ref(0)

function increment() {
  count++
}
  1. Vue 的回應性語法糖是一個編譯時的轉換步驟,$ref() 方法是一個編譯時的巨集指令,它不是一個真實的、在執行時會呼叫的方法,而是用來當作Vue 編譯器的標記,表示最終的 count變數需要是一個響應式變數
  2. 響應式的變數可以像普通變數一樣被存取和重新賦值,但這些運算在編譯後都會變成帶有 .value 的 ref。所以上面範例中的程式碼也會被編譯成使用 ref 定義的語法。
  3. 每一個會回傳 ref 的響應式 API 都有一個相對應的、以 $ 為前綴的巨集函數。包括以下這些API:
  • ref -> $ref
  • #computed -> $computed
  • shallowRef -> $shallowRef
  • customRef -> $customRef
  • toRef -> $toRef
  1. 可以使用 $() 宏來將現存的ref 轉換為響應式變數。
const a = ref(0)
let count = $(a)
count++
console.log(a.value) // 1
  1. 可以使用 $$() 宏來將任何對響應式變數的參考都會保留為對應 ref 的參考。
let count = $ref(0)
console.log(isRef($$(count))) // true

$$() 也適用於已解構的 props,因為它們也是反應式的變數。編譯器會有效率地透過 toRef 來做轉換:

const { count } = defineProps<{ count: number }>()
passAsRef($$(count))

設定

回應性語法糖是組合式API 特有的功能,且必須透過建置步驟使用。

  1. 必須,需要 @vitejs/plugin-vue@>=2.0.0,將套用至 SFC 和 js(x)/ts(x) 檔案。
// vite.config.js
export default {
  plugins: [
    vue({
      reactivityTransform: true
    })
  ]
}
  • 注意 reactivityTransform 現在是一個插件的頂層選項,而不再是位於 script.refSugar# 之中了,因為它不僅僅只對SFC 起效。

如果是 vue-cli 構建,需要 vue-loader@>=17.0.0,目前僅對 SFC 起效。

// vue.config.js
module.exports = {
  chainWebpack: (config) => {
    config.module
      .rule('vue')
      .use('vue-loader')
      .tap((options) => {
        return {
          ...options,
          reactivityTransform: true
        }
      })
  }
}

如果是webpack   vue-loader 構建,需要 vue-loader@>=17.0.0,目前僅對SFC 起效。

// webpack.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: {
          reactivityTransform: true
        }
      }
    ]
  }
}
  1. 可選,tsconfig.json 檔案中加入以下程式碼, 否則會錯誤 TS2304: Cannot find name '$ref'.,雖然不影響使用,但是會影響開發體驗:
"compilerOptions":{ "types": ["vue/ref-macros"] }
  1. 可選,eslintrc.cjs 檔案中加入如下程式碼,不然會提示ESLint: '$ ref' is not defined.(no-undef)
module.exports = { ...globals: {
    $ref: "readonly",
    $computed: "readonly",
    $shallowRef: "readonly",
    $customRef: "readonly",
    $toRef: "readonly",
  }
};
  1. 當啟用響應性語法糖時,這些巨集函數都是全域可用的、無需手動匯入。也可以在 vue 檔案中明確引入 vue/macros,這樣就不用設定第二和第三步驟中的 tsconfig.jsoneslintrc 了。
import { $ref } from 'vue/macros'

let count = $ref(0)

已廢棄的實驗性功能

  • 響應性語法糖曾經是一個實驗性功能,且已被廢棄,請閱讀廢棄原因

  • 在未來的一個小版本更新中,它將會從 Vue core 中移除。如欲繼續使用,請透過 Vue Macros 外掛程式。

廢棄原因

尤雨溪在2個星期前(2023 年2 月21 日上午10:05 GMT 8),親自給出了廢棄的原因,翻譯如下:

正如你們中的許多人已經知道的那樣,我們在團隊一致同意的情況下正式放棄了這個RFC。

理由

#

Reactivity Transform 的最初目標是透過在處理反應狀態時提供更簡潔的語法來改善開發人員的體驗。我們將其作為實驗性產品發布,以收集來自現實世界使用情況的回饋。儘管提出了這些好處,我們還是發現了以下問題:

  • 失去.value 使得更難分辨正在追蹤的內容以及哪條線觸發了反應效果。這個問題在小型 SFC 中並不那麼明顯,但在大型程式碼庫中,心理開銷變得更加明顯,特別是如果語法也在 SFC 之外使用。

  • 由於 (1),有些使用者選擇僅在 SFC 內部使用 Reactivity Transform,這會在不同心智模型之間造成不一致和上下文轉換成本。因此,困境在於僅在 SFC 內部使用它會導致不一致,但在 SFC 外部使用它會損害可維護性。

  • 由於仍然會有外部函數期望使用原始引用,因此反應變數和原始引用之間的轉換是不可避免的。這最終增加了更多的學習內容和額外的精神負擔,我們注意到這比普通的 Composition API 更讓初學者感到困惑。

最重要的是,碎片化的潛在風險。儘管這是明確的選擇加入,但一些用戶對該提案表示強烈反對,因為他們擔心他們將不得不與不同的程式碼庫一起工作,在這些程式碼庫中,有些人選擇了使用它,而有些人則沒有。這是一個合理的擔憂,因為 Reactivity Transform 需要一種不同的心智模型,它會扭曲 JavaScript 語意(變數賦值能夠觸發反應效果)。

考慮到所有因素,我們認為將其作為一個穩定的功能使用會導致問題多於收益,因此不是一個好的權衡。

遷移計畫

  • 該功能已經透過 Vue Macros 以外部套件的形式得到支援。
  • 3.3:此功能將被標記為已棄用。它將繼續工作,但您應該在此期間遷移到 Vue Macros。
  • 3.4:此功能將從核心中刪除,除非使用 Vue Macros,否則將不再有效。

留言

  • 雖然 Reactivity Transform 會從官方套件中移除,但我認為這是一個很好的嘗試。
  • 寫得好。我喜歡詳細的 RFC 和基於使用者回饋的客觀評估。最後的結論很有道理。不要讓完美成為優秀的敵人。
  • 雖然我很享受這個功能帶來的便利,但我在實際使用中確實發現了這個潛在的碎片問題。在未來的版本中刪除此功能可能不太情願,但工程師應該認真對待。 ?
  • 您是刪除所有功能還是僅刪除 ref.value 進行轉換的部分?響應式 props 解構呢,它會留下來嗎?
  • 我一直在將它用於中等規模的電子商務網站,沒有任何問題。我理解刪除它背後的基本原理,但在實踐中我發現它確實是一個很大的改進。所以我的問題是:現在怎麼辦?
  • 是否建議那些討厭 .value 的人現在盡可能避免使用 ref() 並且像以前那樣使用 reactive()
  • .value 是必要的複雜性。就像任何其他響應式庫 xxx.set() 一樣。
  • 建立一個轉換所有 Reactivity Transform 程式碼的套件應該很容易吧?我也喜歡按照推薦的方式做事。
  • ...

推薦學習:《vue.js影片教學

以上是注意,Vue響應性語法糖已廢棄!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:juejin.im。如有侵權,請聯絡admin@php.cn刪除