Vue3 のコアノート



1. Vue3 の概要

2.Vue3 は何をもたらしますか?

1. パフォーマンスの向上

  • パックサイズが 41% 削減

  • 初期レンダリングは 55% 高速化、更新レンダリングは 133% 高速化

  • メモリが 54% 削減されました

2. ソースコードのアップグレード

  • 応答性を実装するには、defineProperty の代わりに Proxy を使用します。

  • 仮想 DOM と Tree-Shaking の実装の書き換え

3. TypeScript を採用する

  • Vue3 は TypeScript をより適切にサポートできるようになります

4.新機能

  1. 合成API

    • セットアップ構成
    • リファレンスとリアクティブ
    • 時計と時計効果
    • 提供して注入する
  2. 新しい内蔵コンポーネント

    • 断片
    • テレポート
    • サスペンス
  3. その他の変更点

    • 新しいライフサイクルフック
    • データオプションは常に関数として宣言する必要があります
    • v-on の修飾子としての keyCode サポートを削除

1.Vue3.0プロジェクトを作成する

1.vue-cliを使用して作成する

公式ドキュメント: https://cli.vuejs.org/zh/guide/creating-a-project.html#vue-create

## 查看@vue/cli版本,确保@vue/cli版本在4.5.0以上
vue --version
## 安装或者升级你的@vue/cli
npm install -g @vue/cli
## 创建
vue create vue_test
## 启动
cd vue_test
npm run serve

2.viteを使って作成する

公式ドキュメント: https://v3.cn.vuejs.org/guide/installation.html#vite

Vite公式サイト:https://vitejs.cn

  • ビタミンとは何ですか?——新世代のフロントエンド構築ツール。
  • 利点は次のとおりです。
    • 開発環境ではパッケージング作業が不要で素早いコールドスタートが可能です。
    • 軽量で高速なホットリロード (HMR)。
    • 真のオンデマンド コンパイル。アプリケーション全体がコンパイルされるのを待つ必要はありません。
  • 従来構造とVite構造の比較表

## 创建工程
npm init vite-app <project-name>
## 进入工程目录
cd <project-name>
## 安装依赖
npm install
## 运行
npm run dev

2. よく使用されるコンポジション API

公式ドキュメント: https://v3.cn.vuejs.org/guide/composition-api-introduction.html

1. 開始するセットアップ

  1. 理解: Vue3.0 の新しい設定項目、値は関数です。
  2. セットアップは、「すべてのコンポジション APIが実行されるステージです。
  3. コンポーネントで使用されるデータ、メソッドなどはセットアップで設定する必要があります。
  4. setup 関数の戻り値は 2 つあります。
    1. オブジェクトが返された場合、オブジェクト内のプロパティとメソッドをテンプレートで直接使用できます。(集中!)
    2. レンダリング関数が返された場合: レンダリングのコンテンツをカスタマイズできます。(学ぶ)
  5. 注意点:
    1. Vue2.x 構成と混合しないようにしてください。
      • セットアップ内のプロパティとメソッドには、Vue2.x 構成 (データ、メソッド、計算...) でアクセスできます。
      • ただし、 Vue2.x 構成 (データ、メソッド、計算済み...) にはsetup ではアクセスできません。
      • 名前が重複している場合は、セットアップが優先されます。
    2. 戻り値は戻りオブジェクトではなく Promise になり、テンプレートは戻りオブジェクトのプロパティを参照できないため、setup を非同期関数にすることはできません。(後で Promise インスタンスを返すこともできますが、それには Suspense コンポーネントと非同期コンポーネントの連携が必要です)

2.ref関数

  • 機能: レスポンシブデータを定義する
  • 文法:const xxx = ref(initValue)
    • 応答データを含む参照オブジェクト (参照オブジェクト、ref オブジェクトと呼ばれる)を作成します。
    • JS でのデータの操作:xxx.value
    • テンプレートからデータを読み取る: .value は必要ありません。直接:<div>{ {xxx}}</div>
  • 述べる:
    • 受信されるデータは、基本タイプまたはオブジェクト タイプです。
    • データの基本的なタイプ: 応答性は依然として完了Object.defineProperty()に依存しますgetset
    • オブジェクト型データ: Vue3.0 の新しい関数 (関数) を内部的に「支援」しましたreactive

3.リアクティブ機能

  • 機能:オブジェクト型の応答データを定義します (基本型には使用せず、ref関数を使用します)
  • 構文:const 代理对象= reactive(源对象)オブジェクト (または配列) を受け取り、プロキシ オブジェクト (プロキシのインスタンス オブジェクト。プロキシ オブジェクトと呼ばれます) を返します。
  • reactive で定義されるレスポンシブ データは「深い」です。
  • 内部プロキシ実装は ES6 に基づいており、ソース オブジェクトの内部データはプロキシ オブジェクトを通じて操作されます。

4.Vue3.0のレスポンシブ原理

vue2.xの応答性

  • 実装原則:

    • オブジェクトの種類:Object.defineProperty()属性の読み取りおよび変更による傍受 (データ ハイジャック)。

    • 配列タイプ: インターセプトは、配列を更新する一連のメソッドをオーバーライドすることによって実装されます。(配列変更メソッドはラップされています)。

      Object.defineProperty(data, 'count', {
              
              
          get () {
              
              }, 
          set () {
              
              }
      })
      
  • 問題があります:

    • 属性を追加または削除しても、インターフェイスは更新されません。
    • 添字を使用して配列を直接変更した場合、インターフェイスは自動的に更新されません。

Vue3.0の応答性

  • 実装原則:
    • プロキシ経由: 属性値の読み取りと書き込み、属性の追加、属性の削除など、オブジェクト内の属性の変更をインターセプトします。
    • Reflect 経由: ソース オブジェクトのプロパティを操作します。
    • プロキシとリフレクトについては、MDN ドキュメントで説明されています。
      • プロキシ:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy

      • Reflect:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Reflect

        new Proxy(data, {
                  
                  
            // 拦截读取属性值
            get (target, prop) {
                  
                  
                return Reflect.get(target, prop)
            },
            // 拦截设置属性值或添加新属性
            set (target, prop, value) {
                  
                  
                return Reflect.set(target, prop, value)
            },
            // 拦截删除属性
            deleteProperty (target, prop) {
                  
                  
                return Reflect.deleteProperty(target, prop)
            }
        })
        
        proxy.name = 'tom'   
        

5.リアクティブとリファレンス

  • 定義データの観点からの比較:
    • ref は、基本型データを定義するために使用されます。
    • Reactive は、オブジェクト (または配列) タイプのデータを定義するために使用されます。
    • 注: ref は、オブジェクト (または配列) 型のデータを定義するために使用することもできます。これは、内部で自動的にreactiveプロキシオブジェクトに変換されます
  • 原理的な観点からの比較:
    • ref は、ANDObject.defineProperty()を介して応答性 (データ ハイジャック) を実装します。getset
    • Reactive はProxyを使用して応答性 (データ ハイジャック) を実装し、 Reflectを通じてソース オブジェクト内のデータを操作します。
  • 使用の観点からの比較:
    • ref: で定義されたデータは、データを操作するために必要.valueですが、データを読み取るときにテンプレートから直接読み取る場合には必要ありません.value
    • reactive で定義されたデータ: 操作データと読み取りデータ:どちらも必要ありません.value

6.セットアップ時の2つの注意点

  • セットアップ実行のタイミング

    • beforeCreate の前に 1 回実行されますが、これは未定義です。
  • セットアップパラメータ

    • props: 値は、コンポーネントの外部から渡され、内部で宣言されたコンポーネントによって受け取られるプロパティを含むオブジェクトです。
    • コンテキスト:コンテキストオブジェクト
      • attrs: 値は、コンポーネントの外部から渡されるが、props 構成で宣言されていない属性を含むオブジェクトです。 と同等ですthis.$attrs
      • スロット: 受信したスロットの内容。 に相当しますthis.$slots
      • Emit: カスタム イベントを配布する関数。 と同等ですthis.$emit

7. 計算されたプロパティとモニタリング

1.計算関数

  • Vue2.x の計算された構成関数と一致します。

  • 書き方

    import {
          
          computed} from 'vue'
    
    setup(){
          
          
        ...
    	//计算属性——简写
        let fullName = computed(()=>{
          
          
            return person.firstName + '-' + person.lastName
        })
        //计算属性——完整
        let fullName = computed({
          
          
            get(){
          
          
                return person.firstName + '-' + person.lastName
            },
            set(value){
          
          
                const nameArr = value.split('-')
                person.firstName = nameArr[0]
                person.lastName = nameArr[1]
            }
        })
    }
    

2.ウォッチ機能

  • Vue2.x の監視設定機能と一致します。

  • 2 つの小さな「穴」:

    • reactive:oldValue で定義されたレスポンシブ データを監視する場合、oldValue が正しく取得できず、詳細監視が強制的に有効になります (詳細設定は失敗します)。
    • reactive: で定義されたリアクティブ データ内の属性を監視する場合、詳細設定が有効です。
    //情况一:监视ref定义的响应式数据
    watch(sum,(newValue,oldValue)=>{
          
          
    	console.log('sum变化了',newValue,oldValue)
    },{
          
          immediate:true})
    
    //情况二:监视多个ref定义的响应式数据
    watch([sum,msg],(newValue,oldValue)=>{
          
          
    	console.log('sum或msg变化了',newValue,oldValue)
    }) 
    
    /* 情况三:监视reactive定义的响应式数据
    			若watch监视的是reactive定义的响应式数据,则无法正确获得oldValue!!
    			若watch监视的是reactive定义的响应式数据,则强制开启了深度监视 
    */
    watch(person,(newValue,oldValue)=>{
          
          
    	console.log('person变化了',newValue,oldValue)
    },{
          
          immediate:true,deep:false}) //此处的deep配置不再奏效
    
    //情况四:监视reactive定义的响应式数据中的某个属性
    watch(()=>person.job,(newValue,oldValue)=>{
          
          
    	console.log('person的job变化了',newValue,oldValue)
    },{
          
          immediate:true,deep:true}) 
    
    //情况五:监视reactive定义的响应式数据中的某些属性
    watch([()=>person.job,()=>person.name],(newValue,oldValue)=>{
          
          
    	console.log('person的job变化了',newValue,oldValue)
    },{
          
          immediate:true,deep:true})
    
    //特殊情况
    watch(()=>person.job,(newValue,oldValue)=>{
          
          
        console.log('person的job变化了',newValue,oldValue)
    },{
          
          deep:true}) //此处由于监视的是reactive素定义的对象中的某个属性,所以deep配置有效
    

3.watchEffect関数

  • 監視のルーチンは次のとおりです。監視のプロパティだけでなく、監視のコールバックも指定します。

  • watchEffect のルーチンは、どの属性を監視するかを指定する必要はなく、監視コールバックでどの属性が使用され、どの属性を監視するかということです。

  • watchEffect は計算に少し似ています。

    • ただし、computed は計算値(コールバック関数の戻り値)に注目するため、戻り値を記述する必要があります。
    • WatchEffect は処理 (コールバック関数の関数本体) に注目するため、戻り値を記述する必要はありません。
    //watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
    watchEffect(()=>{
          
          
        const x1 = sum.value
        const x2 = person.age
        console.log('watchEffect配置的回调执行了')
    })
    

8. ライフサイクル

vue2.x のライフサイクル 画像の説明を追加してください
初期化
画像の説明を追加してください

テンプレートは初期化フェーズでは解析されません。ページに表示されるコンテンツはコード内のスタイルです。コードは書かれたとおりに表示されます。

vue3.0のライフサイクル
画像の説明を追加してください

  • Vue2.x のライフサイクル フックは Vue3.0 でも引き続き使用できますが、そのうち 2 つのフックの名前が変更されました。
    • beforeDestroyに名前を変更しますbeforeUnmount
    • destroyedに名前を変更しますunmounted
  • Vue3.0 では、Composition API の形式でライフサイクル フックも提供されており、Vue2.x のフックとの対応関係は次のとおりです。
    • beforeCreate===>setup()
    • created=======>setup()
    • beforeMount===>onBeforeMount
    • mounted=======>onMounted
    • beforeUpdate===>onBeforeUpdate
    • updated=======>onUpdated
    • beforeUnmount==>onBeforeUnmount
    • unmounted=====>onUnmounted

9. カスタムフック機能

  • フックとは何ですか? ——本質的には、セットアップ関数で使用されるComposition APIをカプセル化する関数です。

  • vue2.x の mixin に似ています。

  • カスタム フックの利点: コードを再利用することで、セットアップのロジックがより明確になり、理解しやすくなります。

10.toRef

  • 機能: 値が別のオブジェクトのプロパティを指す ref オブジェクトを作成します。

  • 文法:const name = toRef(person,'name')

  • 用途: 外部使用のみを目的として、レスポンシブ オブジェクトに特定のプロパティを提供したい場合。

  • 拡張機能:toRefs同じtoRef機能ですが、複数の ref オブジェクトをバッチで作成できます。構文:toRefs(person)

3. その他の合成 API

1.shallowReactiveとshallowRef

  • ShallowReactive: オブジェクトの最も外側のプロパティのみを処理するレスポンシブ スタイル (浅いレスポンシブ スタイル)。

  • ShallowRef: 基本データ型の応答処理のみを処理し、オブジェクトの応答処理は実行しません。

  • いつ使用しますか?

    • オブジェクトデータがある場合、構造は比較的深いですが、それが変更されると、外側の属性のみが変更されます ===>shallowReactive。
    • オブジェクト データがある場合、後続の関数はオブジェクト内のプロパティを変更しませんが、 ===> ShallowRef を置き換える新しいオブジェクトを生成します。

2.readonlyとshallowReadonly

  • readonly: リアクティブ データを読み取り専用 (ディープ読み取り専用) にします。
  • shallowReadonly: レスポンシブデータを読み取り専用(浅い読み取り専用)にします。
  • アプリケーション シナリオ: データを変更したくない場合 (特に、データが他のコンポーネントから取得された場合)。

3.toRaw と markRaw

  • toRaw:
    • 機能: 生成されたreactive応答オブジェクトを通常のオブジェクトに変換します
    • 使用シナリオ: 応答オブジェクトに対応する通常のオブジェクトを読み取るために使用されます。この通常のオブジェクトに対するすべての操作によってページが更新されることはありません。
  • マーク生:
    • 機能: オブジェクトが再び反応性オブジェクトにならないように、オブジェクトにマークを付けます。
    • アプリケーションシナリオ:
      1. 複雑なサードパーティ ライブラリなど、一部の値は応答性に設定すべきではありません。
      2. 応答性の高い変換をスキップすると、不変のデータ ソースを含む大きなリストをレンダリングする際のパフォーマンスが向上します。

4.カスタム参照

  • 機能: カスタム ref を作成し、その依存関係の追跡と更新トリガーを明示的に制御します。

  • 手ぶれ補正効果を得るには:

    <template>
    	<input type="text" v-model="keyword">
    	<h3>{
         
         {keyword}}</h3>
    </template>
    
    <script>
    	import {ref,customRef} from 'vue'
    	export default {
    		name:'Demo',
    		setup(){
    			// let keyword = ref('hello') //使用Vue准备好的内置ref
    			//自定义一个myRef
    			function myRef(value,delay){
    				let timer
    				//通过customRef去实现自定义
    				return customRef((track,trigger)=>{
    					return{
    						get(){
    							track() //告诉Vue这个value值是需要被“追踪”的
    							return value
    						},
    						set(newValue){
    							clearTimeout(timer)
    							timer = setTimeout(()=>{
    								value = newValue
    								trigger() //告诉Vue去更新界面
    							},delay)
    						}
    					}
    				})
    			}
    			let keyword = myRef('hello',500) //使用程序员自定义的ref
    			return {
    				keyword
    			}
    		}
    	}
    </script>
    

5.提供と注入

画像の説明を追加してください

  • 役割:祖先コンポーネントと子孫コンポーネント間の通信を実装する

  • ルーチン: 親コンポーネントにはprovideデータを提供するオプションがあり、子孫コンポーネントにはinjectデータの使用を開始するオプションがあります。

  • 具体的な書き方:

    1. 祖先コンポーネント内:

      setup(){
              
              
          ......
          let car = reactive({
              
              name:'奔驰',price:'40万'})
          provide('car',car)
          ......
      }
      
    2. 子孫コンポーネント内:

      setup(props,context){
              
              
          ......
          const car = inject('car')
          return {
              
              car}
          ......
      }
      

6. レスポンシブデータの判定

  • isRef: 値が ref オブジェクトであるかどうかを確認します。
  • isReactive: オブジェクトが、によってreactive作成されたリアクティブ プロキシであるかどうかを確認します。
  • isReadonly: オブジェクトが、によってreadonly作成された読み取り専用プロキシかどうかを確認します。
  • isProxy: オブジェクトがreactiveまたはメソッドによってreadonly作成されたプロキシであるかどうかを確認します

4. 構成APIのメリット

1. オプション API の問題

従来の OptionsAPI を使用して要件を追加または変更する場合は、データ、メソッド、および計算結果をそれぞれ変更する必要があります。

画像の説明を追加してください
画像の説明を追加してください

2. 構成APIのメリット

コードと関数をよりエレガントに整理できます。関連する関数のコードをより秩序立った方法でまとめて整理します。

画像の説明を追加してください
画像の説明を追加してください

5. 新しいコンポーネント

1.フラグメント

  • Vue2 の場合: コンポーネントにはルート タグが必要です
  • Vue3 の場合: コンポーネントにはルート タグを含めることはできず、複数のタグが内部的に Fragment 仮想要素に含まれます。
  • 利点: ラベル レベルを下げ、メモリ使用量を削減します。
    画像の説明を追加してください

2.テレポート

  • テレポートとは何ですか? ——コンポーネントのHTML構造を指定した場所にTeleport移動できる技術です。

    <teleport to="移动位置">
    	<div v-if="isShow" class="mask">
    		<div class="dialog">
    			<h3>我是一个弹窗</h3>
    			<button @click="isShow = false">关闭弹窗</button>
    		</div>
    	</div>
    </teleport>
    

画像の説明を追加してください

3.サスペンス

  • アプリケーションのユーザー エクスペリエンスを向上させるために、非同期コンポーネントを待機している間に追加のコンテンツをレンダリングします。

  • 使用手順:

    • コンポーネントを非同期的に導入する

      import {
              
              defineAsyncComponent} from 'vue'
      const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
      
    • Suspenseパッケージコンポーネントを使用してdefault設定します。fallback

      <template>
          <div class="app">
              <h3>我是App组件</h3>
              <Suspense>
                  <template v-slot:default>
                      <Child/>
                  </template>
                  <template v-slot:fallback>
                      <h3>加载中.....</h3>
                  </template>
              </Suspense>
          </div>
      </template>
      

6. その他

1.グローバルAPIの移管

  • Vue 2.x には、多くのグローバル API と構成があります。

    • 例: グローバル コンポーネントの登録、グローバル命令の登録など。

      //注册全局组件
      Vue.component('MyButton', {
              
              
        data: () => ({
              
              
          count: 0
        }),
        template: '<button @click="count++">Clicked {
              
              { count }} times.</button>'
      })
      
      //注册全局指令
      Vue.directive('focus', {
              
              
        inserted: el => el.focus()
      }
      
  • これらの API は Vue3.0 で調整されました。

    • グローバル API をVue.xxxアプリケーション インスタンスに合わせて調整します ( app)

      2.x グローバル API ( Vue) 3.x インスタンス API ( app)
      Vue.config.xxxx app.config.xxxx
      Vue.config.productionTip 取り除く
      Vue.component アプリコンポーネント
      View.ディレクティブ app.ディレクティブ
      Vue.mixin アプリミックスイン
      Vue.use アプリの使用
      Vue.プロトタイプ app.config.globalProperties

2. その他の変更点

  • data オプションは常に関数として宣言する必要があります。

  • 過度のクラス名の変更:

    • Vue2.xの書き方

      .v-enter,
      .v-leave-to {
              
              
        opacity: 0;
      }
      .v-leave,
      .v-enter-to {
              
              
        opacity: 1;
      }
      
    • Vue3.xの書き方

      .v-enter-from,
      .v-leave-to {
              
              
        opacity: 0;
      }
      
      .v-leave-from,
      .v-enter-to {
              
              
        opacity: 1;
      }
      
  • v-on の修飾子として keyCodeを削除し、サポートされなくなりました。config.keyCodes

  • v-on.native修飾子を削除する

    • 親コンポーネントのバインドイベント

      <my-component
        v-on:close="handleComponentEvent"
        v-on:click="handleNativeClickEvent"
      />
      
    • 子コンポーネントでカスタム イベントを宣言する

      <script>
        export default {
          emits: ['close']
        }
      </script>
      
  • フィルターを削除する

    フィルタ これは便利そうに見えますが、中括弧内の式が「単なる JavaScript」であるという前提を打ち破るカスタム構文が必要であり、学習コストだけでなく実装コストもかかります。フィルターをメソッド呼び出しまたは計算されたプロパティに置き換えることをお勧めします。

おすすめ

転載: blog.csdn.net/m0_53142039/article/details/132181996