Vue3 のクイック スタート
1. Vue3 の紹介
1.パフォーマンスの向上
-
バンドルサイズを 41% 削減
-
初期レンダリングが 55% 高速化、更新レンダリングが 133% 高速化
-
54% 少ないメモリ
…
2. ソースコードのアップグレード
-
defineProperty の代わりに Proxy を使用して応答性を実現する
-
仮想 DOM と Tree-Shaking の実装を書き直す
…
3. TypeScript を採用する
- Vue3 は TypeScript をより適切にサポートできます
4. 新機能
-
コンポジション API (コンポジション API)
- セットアップ構成
- ref とリアクティブ
- watch と watchEffect
- 提供して注入する
- …
-
新しいビルトイン
- 断片
- テレポート
- サスペンス
-
その他の変更
- 新しいライフサイクル フック
- data オプションは常に関数として宣言する必要があります
- 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)。
- 真のオンデマンド コンパイル。アプリケーション全体がコンパイルされるのを待つ必要はありません。
## 创建工程
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.セットアップを開始する
- 理解: Vue3.0 の新しい構成項目で、値は関数です。
- 設定はすべてComposition API(コンポジションAPI)の「パフォーマンスステージ」です。
- コンポーネントで使用されるコンポーネント (データ、メソッドなど) は、セットアップで構成する必要があります。
- setup 関数の 2 つの戻り値:
- オブジェクトが返された場合、オブジェクトのプロパティとメソッドをテンプレートで直接使用できます。(集中!)
- レンダリング関数を返す場合: レンダリング コンテンツをカスタマイズできます。(学び)
- 注意点:
- Vue2.x 構成と混在しないようにしてください
- セットアップのプロパティとメソッドは、Vue2.x 構成 (データ、メソッド、計算済み...) でアクセスできます。
- ただし、 Vue2.x 構成 (データ、メソッド、計算済み...) にはsetup でアクセスできません。
- 重複する名前がある場合は、セットアップが優先されます。
- 戻り値はもはや戻りオブジェクトではなく promise であり、テンプレートは戻りオブジェクトのプロパティを認識できないため、setup を非同期関数にすることはできません。(後で Promise インスタンスを返すこともできますが、サスペンスと非同期コンポーネントの連携が必要です)
- Vue2.x 構成と混在しないようにしてください
2.ref関数
- 役割: レスポンシブ データを定義する
- 文法:
const xxx = ref(initValue)
- レスポンシブ データを含む参照オブジェクト (参照オブジェクト、略して ref オブジェクト)を作成します。
- JS でのデータ操作:
xxx.value
- テンプレート内のデータを読み取る: .value は必要ありません。直接:
<div>{ {xxx}}</div>
- 述べる:
- 受信データは、基本型またはオブジェクト型です。
- データの基本的なタイプ: リアクティブは依然として信頼性が高く
Object.defineProperty()
、get
完全ですset
。 - オブジェクト型データ: Vue3.0 の新しい関数 - function を内部的に「レスキュー」します
reactive
。
3. 反応機能
- 機能:レスポンシブ データのオブジェクト型を定義します(基本型には使用せず、
ref
関数を使用します)。 - 構文:
const 代理对象= reactive(源对象)
オブジェクト (または配列) を受け取り、プロキシ オブジェクト (プロキシ オブジェクトと呼ばれるプロキシのインスタンス オブジェクト)を返します。 - 反応によって定義される反応データは「深い」です。
- ES6 ベースの内部プロキシ実装は、プロキシ オブジェクトを介してソース オブジェクトの内部データを操作します。
4. Vue3.0 のレスポンシブ原則
vue2.x の応答性
-
実装原則:
-
オブジェクト タイプ:
Object.defineProperty()
属性の読み取りと変更によるインターセプト (データ ハイジャック)。 -
配列タイプ: インターセプトは、配列を更新する一連のメソッドをオーバーライドすることによって実現されます。(配列の変更メソッドはラップされます)。
Object.defineProperty(data, 'count', { get () { }, set () { } })
-
-
問題があります:
- 属性を追加または削除する場合、インターフェースは更新されません。
- 添字を使用して配列を直接変更すると、インターフェイスは自動的に更新されません。
Vue3.0 の応答性
- 実現原理:
- プロキシ経由 (プロキシ): 属性値の読み取りと書き込み、属性の追加、属性の削除などを含む、オブジェクト内の任意の属性の変更を傍受します。
- Through Reflect (反射): ソース オブジェクトのプロパティを操作します。
- Proxy と 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 は、基本型 dataを定義するために使用されます。
- リアクティブは、オブジェクト (または配列) 型のデータを定義するために使用されます。
- 備考: ref は、オブジェクト (または配列) 型のデータを定義するためにも使用できます。これは、内部で
reactive
プロキシオブジェクトに自動的に変換されます。
- 原理比較の観点から:
- ref はAND
Object.defineProperty()
を介して応答性 (データのハイジャック) を実装します。get
set
- Reactive は、 Proxyを使用して応答性 (データ ハイジャック) を実装し、 Reflectを介してソース オブジェクト内のデータを操作します。
- ref はAND
- 使用の観点から:
- ref で定義されたデータ:データ操作には必要です
.value
が、データ読み取り時のテンプレートでの直接読み取りには必要ありません.value
。 - Reactive: operation data と read data:どちらも必要ありません
.value
。
- ref で定義されたデータ:データ操作には必要です
6.セットアップ時の2つの注意点
-
セットアップ実行のタイミング
- beforeCreate の前に 1 回実行されますが、これは未定義です。
-
設定のパラメータ
- props: 値は次のものを含むオブジェクトです: コンポーネントの外部から渡され、コンポーネントの内部宣言によって受信されるプロパティ。
- コンテキスト: コンテキスト オブジェクト
- attrs: 値は次を含むオブジェクトです: コンポーネントの外部から渡されたが props 構成で宣言されていない属性
this.$attrs
。 - スロット: 受信したスロット コンテンツ
this.$slots
。 - emit: と同等のカスタム イベントをディスパッチする関数
this.$emit
。
- attrs: 値は次を含むオブジェクトです: コンポーネントの外部から渡されたが props 構成で宣言されていない属性
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 で定義されたレスポンシブデータを監視する場合、正しく取得できず、強制的にディープ監視が有効になります (ディープ設定は無効です)。
- リアクティブによって定義されたリアクティブ データ内の属性を監視する場合: ディープ コンフィギュレーションが有効です。
// 来自尚硅谷老师的代码,参考 //情况一:监视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のライフサイクルです
8.1 変更点
ライフサイクルはすべてセットアップに書かれています
- beforeDestroy は beforeUnmount に名前が変更されました
- 破壊された名前がマウントされていないに変更されました
- beforeCreate=> セットアップ
- 作成 => セットアップ
- beforeMount => onBeforeMount
- マウント => onMounted
- beforeUpdate => onBeforeUpdate
- 更新済み => onUpdated
- beforeUnmount => onBeforeUnmount
- アンマウント => onUnmounted
8.2 文法
setup() {
onMounted(() => {
console.log('mounted')
})
- 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.カスタムフック機能
-
フックとは?—— setup関数で使われるComposition APIをカプセル化した関数です。
-
vue2.x の mixin に似ています。
-
カスタム フックの利点: コードの再利用により、セットアップのロジックがより明確になり、理解しやすくなります。
10.toRef
-
機能: 値が別のオブジェクトの属性を指す参照オブジェクトを作成します。
-
文法:
const name = toRef(person,'name')
-
適用: レスポンシブ オブジェクトにプロパティを提供し、外部でのみ使用する場合。
-
拡張機能:関数
toRefs
と同じですが、複数の ref オブジェクトをバッチで作成できます。構文:toRef
toRefs(person)
3. その他の合成 API
1.shallowReactiveとshallowRef
-
shadowReactive: オブジェクトの最も外側のプロパティの応答 (浅い応答) のみを処理します。
-
shadowRef: オブジェクトの応答ではなく、基本的なデータ型の応答のみを処理します。
-
いつ使用するのですか?
- オブジェクトデータがあれば、構造は比較的深いですが、外側の属性だけが変わります===>shallowReactive。
- オブジェクト データがある場合、後続の関数はオブジェクト内のプロパティを変更しませんが、新しいオブジェクトを生成して ===>shallowRef を置き換えます。
2.readonlyとshallowReadonly
- readonly: リアクティブ データを読み取り専用 (深い読み取り専用) にします。
- shadowReadonly: レスポンシブ データを読み取り専用 (浅い読み取り専用) にします。
- アプリケーション シナリオ: データが変更されることが予想されない場合。
3. toRaw と markRaw
- toRaw:
- 機能:
reactive
ボットによって生成されたレスポンシブ オブジェクトを通常のオブジェクトに変換します。 - 使用シナリオ: レスポンシブ オブジェクトに対応する共通オブジェクトを読み取るために使用されます。この共通オブジェクトに対するすべての操作によって、ページが更新されることはありません。
- 機能:
- マーク生:
- 役割: オブジェクトをマークして、二度とレスポンシブ オブジェクトにならないようにします。
- アプリケーション シナリオ:
- 複雑なサードパーティ ライブラリなど、一部の値はレスポンシブに設定しないでください。
- リアクティブ変換をスキップすると、不変のデータ ソースを含む大きなリストをレンダリングするときにパフォーマンスが向上する可能性があります。
4.customRef
-
役割: 依存関係の追跡と更新のトリガーを明示的に制御するカスタム 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
このデータの使用を開始するオプションがあります -
具体的に書かれています:
-
親コンポーネントで:
setup(){ ...... let car = reactive({ name:'奔驰',price:'40万'}) provide('car',car) ...... }
-
子孫コンポーネント:
setup(props,context){ ...... const car = inject('car') return { car} ...... }
-
6. レスポンシブデータの判定
- isRef: 値が ref オブジェクトかどうかをチェックします
- isReactive: オブジェクトがリアクティブ プロキシによって
reactive
作成され - isReadonly: オブジェクトが読み取り専用プロキシによって
readonly
作成され - isProxy: オブジェクト
reactive
がreadonly
or メソッドによって作成されたプロキシかどうかを確認します
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 app.component Directive.view app.directive Vue.mixin app.mixin Vue.use app.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」であるという仮定を破るカスタム構文が必要であり、学習コストだけでなく実装コストもかかります! フィルターをメソッド呼び出しまたは計算されたプロパティに置き換えることをお勧めします。
最後に、技術的なルートをたどると、学習を続ける運命にあります。フロントエンドの学習ルートが付属!