最近、VUEの作者であるYou YuxiがRFCでRef構文シュガーの提案を提出し、コミュニティで論争を引き起こしました。
簡単に言うと、この提案では、単一ファイルコンポーネント(SFC)<script setup>
に新しいスクリプトタグ書き込み方法を導入します。これは、すべての最上位変数宣言をテンプレートに自動的に公開するように記述されています。同時に、<script setup>
構文シュガーが導入され、構文シュガーのref属性の値が、コンパイル中に通常のコードに自動的に構文シュガーを削除します。
たとえば、次のHTMLコード:
<script setup> // ref refにコンパイルされる変数を宣言します:count = 1 function inc(){ //変数は.value count ++なしで通常の値のように使用できます } //元の値に対応するために$プレフィックスを使用しますrefオブジェクト console.log($ count.value) </ script> <template> <button @ click = "inc"> {{count}} </ button> </ templat
このようにコンパイルされます:
<script setup> import {ref} from'vue ' export default { setup(){ const count = ref(1) function inc(){ count.value ++ } console.log(count.value) return { count、 inc } } } </ script> <template> <button @ click = "inc"> {{count}} </ button> </ templ
label:x = 1は引き続き有効なJS構文であることに注意してください(つまり、ラベル付き割り当てステートメントは、xに値を直接割り当てることと同等であり、xが厳密モードで定義されていない場合はエラーが報告されます)。これは、refラベル名のセマンティクスの特別な処理と同等です。
なぜあなたはこれをしたいのですか?
Yu Xi夫人は、トップレベルの可変自動露出によってコードの冗長性を減らすことができる一方で、ref:
文法を介してより効率的な参照を行うことができると述べました。
Composition APIの誕生以来、refオブジェクトとreactiveオブジェクトのどちらを使用するのがよいかについて誰もが議論してきました。refを使用すると、コードがどこにでも存在するようになります.value
。開発者がTypeScriptを使用しないと、書き込みを見逃すことがよくある.value
ため、多くの開発者はrefの処理方法を知りません。
実際、JS言語にはいくつかの問題があるため、refが存在します。オブジェクトに値をカプセル化しないと、JSの組み込みメソッドを使用してこの値を応答データに変換できません。つまり、JSのセマンティクスを変更しないと、通常の変数のようにrefを使用することはできません。さらに、You Yuxiは、彼がSvelteフレームワークに触発されたことも認めました。Svelteは以前にJSのセマンティクスを変更し、export
let
$
Svelteはより強力で便利な機能を提供しました。
「以前は、JSの魔法の変更によって問題が発生するため、JSの元のセマンティクスを可能な限り維持したいと考えていましたが、開発者により良い開発を提供するためにJSを変換するには、常に「カニを最初に食べる人」が必要です。経験。「あなたはYuxiが言った。
論争を引き起こす
この提案に対して、多くのコミュニティユーザーがこの提案に反対を表明しました。ほとんどの人が反対する理由は、この提案がJavaScriptの魔法の変更には深刻すぎるためです。彼らは、新しい構文を直接発明する代わりにタグ構文を使用する理由を疑問視しているため、ユーザーの精神的負担が増大します。などなど。
これらの質問に答えて、あなたYuxi自身が一つずつ答えました:
Magic ChangeJavaScriptについて
ref:count = 1は、構文レベルで有効なJavaScriptであるタグ構文を使用し、セマンティクスでcountという名前のグローバル変数を宣言している場合でも、非厳密モードで通常どおり実行できます。同時に、これは正当なTypeScript文法でもあり、型宣言と混同されることはありません(型宣言には必ずletとconstが必要です)。
もちろん、これは実際には文法の法的な側面にすぎず、実際には
ref:
、異なるセマンティクスが与えられたラベルに相当します。タグ構文自体はめったに使用されない機能であり、マーキングの実際の使用もref: count = 1
、そのような使用例として、サイクル(使用/フロントながら)として宣言されます。これは、役に立たない元のセマンティクスであるためです。リアクティブ変数宣言を取得するためにこのプリミティブセマンティクスを犠牲にすることは、価値のある交換であると私たちは考えています。
新しい構文を直接発明するのではなく、タグ構文を使用する理由
タグ構文の使用は確かにSvelteに触発されています。基本的な理由は、構文レベルでJSとの完全な互換性を維持することで、既存のJSツールのエコロジカルドッキングを可能な限り確保できるためです。ラベル構文は、タイプの推定やESLint変数関連のルールなどのセマンティクスが関係する場合にのみ、Babel、TSパーサー/トランスフォーマー(esbuild / swcなど)、Prettier、ESLint、およびIDEJavaScript構文の強調表示で直接サポートできます。ターゲットを絞った互換性のみが必要です。新しい非標準の構文を使用する場合は、上記のすべてのツールをパーサーレベルで変更する必要があることを意味しますが、これは基本的に実行不可能です。
精神的な負担が重くなった気がします
最下層はref()にコンパイルされた構文シュガーですが、実際、初心者はref()を使用する前に、ref()の存在を知る必要はありません。これは、基になるrefオブジェクトを取得する必要がないシナリオでは、ref:モデルは、letで宣言された変数のメンタルモデルとまったく同じです。ユーザーはref:をレスポンシブレットとして扱うだけで済みます。このモデルは、ほとんどのエントリーレベルの機能を実現するのに十分です。高度な後、ロジックの抽出と再利用を学び始めた場合にのみ、ref()の概念を知る必要があります。
すでにCompositionAPIを勉強しているユーザーにとっては、「もう1つのコンセプトが追加された」と感じるでしょう。同時に、RFCがコンパイルルールを詳細に説明しているため、「精神的負担が増加した」という幻想があります。実際、ずっと前にCoffeeScript、Babel、またはTSを使用したときも、使用する前にどのように見えるかを確認したいので、このように感じました。その結果、これを読んだ後、私は上位レベルの文法を使用し、それを下位レベルの文法に変換せざるを得なかったということです。しかし、これは本質的に、根底にある考え方に慣れた後の私たちの脳の一種の慣性です。この慣性は、新しい文法を一定期間使用した後すぐに消え、私たちの脳はまだ非常に順応性があります。最初にコンパイルの結果を気にしない場合は、この問題は発生しません(nullishの合体またはデコレータを使用する場合、babel / TSのコンパイルの結果について考えますか?)
上記のように、ゼロから始めるユーザーにとって、ref:は応答をトリガーする単なるレットであり、学習コストは非常に低くなります。
あなたYuxiの元の答え:https://www.zhihu.com/question/429036806/answer/1564223482
最後に、You Yuxiは、このRFC提案が公開される前に、それが多くの論争を引き起こすことを知っており、新しいテクノロジーに対する人々の最初の反応は「受け入れられない」ことを理解したと述べました。ただし、提案は必ずしも実施されない可能性があるとのことで、合理的に議論していただきたいと思います。同時に、RFCの全文とGitHubでの議論を読んでから質問をすることをお勧めします。
完全なRFC:https://github.com/vuejs/rfcs/blob/script-setup/active-rfcs/0000-script-setup.md