Heim  >  Artikel  >  Web-Frontend  >  Beachten Sie, dass der reaktive syntaktische Zucker von Vue veraltet ist!

Beachten Sie, dass der reaktive syntaktische Zucker von Vue veraltet ist!

藏色散人
藏色散人nach vorne
2023-03-06 15:51:512842Durchsuche

In diesem Artikel geht es hauptsächlich um den responsiven Syntaxzucker in Vue. Ich hoffe, dass er für alle hilfreich ist.

Beachten Sie, dass der reaktive syntaktische Zucker von Vue veraltet ist!

Einführung

Seit der Einführung des Konzepts der zusammengesetzten APIs ist eine große ungelöste Frage, welches zwischen ref und reactive verwendet werden soll. reactive hat das Problem, dass die Reaktionsfähigkeit aufgrund der Dekonstruktion verloren geht, während ref überall .value verwenden muss, was sich sehr umständlich anfühlt und ohne nicht funktioniert die Hilfe des Typsystems. Es ist leicht, .value zu übersehen. 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
  2. Zum Beispiel der folgende Zähler:
import { $ref } from 'vue/macros'

let count = $ref(0)

verwendet ref, um die Variable count und die Methode increment zu definieren:

rrreee
    unter Verwendung von reaktiv Syntax Sugar können wir Code wie diesen schreiben:
  • rrreee

      Vues responsiver Syntax Sugar ist ein Konvertierungsschritt zur Kompilierungszeit, und die Methode $ref() ist ein Makrobefehl zur Kompilierungszeit Es handelt sich nicht um eine echte Methode, die zur Laufzeit aufgerufen wird, sondern als Flag für den Vue-Compiler verwendet wird, um anzuzeigen, dass die endgültige count-Variable eine

      reaktive Variable
  • sein muss.
  • Reaktive Variablen können wie gewöhnliche Variablen aufgerufen und neu zugewiesen werden, aber diese Operationen werden nach der Kompilierung zu ref mit .value. Daher wird der Code im obigen Beispiel auch in die mit ref definierte Syntax kompiliert. Jede reaktive API, die ref zurückgibt, verfügt über eine entsprechende Makrofunktion mit dem Präfix $. Einschließlich der folgenden APIs:

    • ref -> $computed

      shallowRef

      customRef ->

      Sie können das Makro $() verwenden, um eine vorhandene ref in eine reaktive Variable umzuwandeln.

      rrreee

        Sie können das Makro $$() verwenden, um jeden Verweis auf eine reaktive Variable als Verweis auf den entsprechenden ref beizubehalten .

        🎜rrreee🎜$$() funktioniert auch mit destrukturierten props, da es sich auch um reaktive Variablen handelt. Der Compiler führt die Konvertierung effizient über toRef durch: 🎜rrreee🎜Configuration🎜🎜Responsive syntaktischer Zucker ist eine spezifische Funktion der 🎜Composition API🎜 und muss während des Build-Schritts verwendet werden. 🎜
          🎜Erforderlich, erfordert @vitejs/plugin-vue@>=2.0.0, wird auf SFC- und js(x)/ts(x)-Dateien angewendet. 🎜🎜rrreee
        🎜Beachten Sie, dass reactivityTransform jetzt eine Option der obersten Ebene eines Plugins ist und sich nicht mehr in script.refSugar befindet, da dies nicht nur der Fall ist für SFC Wirksam werden. 🎜🎜🎜Wenn es mit vue-cli erstellt wurde, ist vue-loader@>=17.0.0 erforderlich. Derzeit funktioniert es nur für SFC. 🎜rrreee🎜Wenn es mit webpack + vue-loader erstellt wird, ist vue-loader@>=17.0.0 erforderlich, derzeit nur für SFC-Effekt. 🎜rrreee
        🎜Optional, fügen Sie den folgenden Code zur Datei tsconfig.json hinzu, andernfalls wird ein Fehler gemeldet TS2304: Name „$ref“ kann nicht gefunden werden. , obwohl dies keinen Einfluss auf die Verwendung hat, wirkt es sich jedoch auf die Entwicklungserfahrung aus: 🎜🎜rrreee
          🎜Optional, fügen Sie den folgenden Code zu eslintrc.cjs hinzu Datei, andernfalls wird ESLint : '$ref' ist nicht definiert.(no-undef):🎜🎜rrreee
            🎜Wenn responsive Syntax-Zucker aktiviert ist, werden diese Makros angezeigt Funktionen sind global verfügbar und es ist keine manuelle Arbeit erforderlich. Importieren. Sie können vue/macros auch explizit in die Vue-Datei einfügen, sodass Sie tsconfig.json und eslintrc nicht konfigurieren müssen der zweite und dritte Schritt. 🎜🎜rrreee🎜Veraltete experimentelle Funktion🎜🎜🎜🎜Responsive Syntax Sugar war einst eine experimentelle Funktion und ist veraltet. Bitte lesen Sie 🎜Grund für die Ablehnung🎜. 🎜🎜🎜🎜Es wird in einem zukünftigen Nebenversionsupdate aus dem Vue-Kern entfernt. Wenn Sie es weiterhin verwenden möchten, verwenden Sie bitte das Plugin 🎜Vue Macros🎜. 🎜🎜🎜🎜Grund für den Abbruch🎜🎜Sie Yuxi haben vor 2 Wochen (21. Februar 2023, 10:05 Uhr GMT+8) persönlich den Grund für den Abbruch angegeben: 🎜🎜Genau wie viele von Ihnen als Menschen Wie ich bereits weiß, haben wir diesen RFC im Konsens des Teams offiziell aufgegeben. 🎜🎜🎜Gründe🎜🎜

            Das ursprüngliche Ziel von Reactivity Transform bestand darin, das Entwicklererlebnis durch die Bereitstellung einer saubereren Syntax beim Umgang mit reaktiven Zuständen zu verbessern. Wir veröffentlichen es als experimentelles Produkt, um Feedback aus der Praxis zu sammeln. Trotz dieser vorgeschlagenen Vorteile haben wir die folgenden Probleme festgestellt:

      • Der Verlust von .value macht es schwieriger zu erkennen, was verfolgt wird und welche Zeile den reaktiven Effekt auslöst. Dieses Problem ist bei kleinen SFCs weniger offensichtlich, aber bei großen Codebasen wird der mentale Aufwand deutlicher, insbesondere wenn die Syntax auch außerhalb von SFCs verwendet wird. .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()
      • Aufgrund (1) entscheiden sich einige Benutzer dafür, die Reaktivitätstransformation nur innerhalb von SFC zu verwenden, was zu Inkonsistenzen und Kosten für den Kontextwechsel zwischen verschiedenen mentalen Modellen führt. Das Dilemma besteht also darin, dass die Verwendung nur innerhalb von SFC zu Inkonsistenzen führt, die Verwendung außerhalb von SFC jedoch die Wartbarkeit beeinträchtigt.
      • Da es weiterhin externe Funktionen geben wird, die die Verwendung von Rohreferenzen erwarten, ist die Konvertierung zwischen reaktiven Variablen und Rohreferenzen unvermeidlich. Dies führte letztendlich zu mehr Lerninhalten und zusätzlicher mentaler Belastung, was unserer Meinung nach für Anfänger verwirrender war als die normale Composition API.

      Am wichtigsten ist das potenzielle Risiko einer Fragmentierung. Obwohl es sich dabei um eine ausdrückliche Zustimmung handelt, haben einige Benutzer entschiedenen Widerstand gegen den Vorschlag geäußert, da sie befürchten, dass sie mit unterschiedlichen Codebasen arbeiten müssen, während einige sich für die Verwendung entschieden haben und andere nicht. Dies ist ein berechtigtes Anliegen, da die Reaktivitätstransformation ein anderes mentales Modell erfordert und die JavaScript-Semantik verzerrt (Variablenzuweisungen können reaktive Effekte auslösen).

      Alles in allem sind wir der Meinung, dass die Verwendung dieser Funktion als stabile Funktion mehr Probleme als Vorteile mit sich bringt und daher kein guter Kompromiss ist.
      🎜Migrationsplan🎜

      Das obige ist der detaillierte Inhalt vonBeachten Sie, dass der reaktive syntaktische Zucker von Vue veraltet ist!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

      Stellungnahme:
      Dieser Artikel ist reproduziert unter:juejin.im. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen