ヒント: 記事を作成した後、目次を自動的に生成できます。生成方法は、右側のヘルプドキュメントを参照してください。
記事ディレクトリ
序文
この記事は私がVue3を学ぶ前にメモしたものに、公式サイトなどから補足を加えたものです。この記事を通じて、Vue3 の新機能をすぐに理解できます。
1.Vue3の作成方法
vue3 プロジェクトを作成する前に、新世代のフロントエンド構築ツールについて学ぶことができます。素早く, ここでは簡単に紹介します
1.Viteのメリット
1. ESM ベースの開発サービスの利点:
- プロジェクトのソースコードをパッケージ化する必要はありません
- 自然なオンデマンド読み込み
- ファイルレベルのブラウザキャッシュを利用できる
2. Esbuild に基づくコンパイル パフォーマンスの最適化
3. すぐに使える組み込みの Web 構築機能:
vite を理解した後、vite を使用してプロジェクトを作成します. vite について詳しく知りたい場合は、公式 Web サイトにアクセスしてください。
2.vue3プロジェクトを作成する
1. ここでは、Vite を使用してプロジェクトを構築することを選択します
// npm
npm create vite@latest
//Yarn
yarn create vite
//PNPM
pnpm create vite
2. テンプレートを作成してテンプレートを選択し (ここでは vue + JavaScript を選択します)、
続行します。
//进入项目文件夹
cd vite-project
//初始化项目
npm install
//运行项目
npm run dev
現時点では、プロジェクトは正常に実行されています
2. Vue3 の入門
1. 構成API
Vue3では、vue2のようにデータやメソッドを分割することなく、論理的なコードをまとめてフックを別途記述して導入できるComposition APIを提案しています。
以下は公式ウェブサイトからの引用です。
Comboposition API (Composition API) は、 options を宣言する代わりに関数を使用して Vue コンポーネントを作成できるようにする API のコレクションです
。これは、次の API をカバーする包括的な用語です。 リアクティブ API: ref() や
reactive() など、リアクティブな状態、計算されたプロパティ、およびリスナーを直接作成できます。ライフサイクル フック: onMounted() や onUnmounted() などを使用すると、コンポーネントのさまざまなライフサイクル段階でロジックを追加できます。
依存関係注入: Provide() や inject() など、リアクティブ API を使用するときに Vue の依存関係注入システムを利用できるようにします。
2.セットアップ
- 理解: Vue3.0 の新しい設定項目、値は関数です。
- セットアップは、すべてのコンポジション API (コンポジション API) の「パフォーマンスの段階」です。
- コンポーネントで使用されるコンポーネント (データ、メソッドなど) は、セットアップで構成する必要があります。
(1). Setupの実行順序は
Createより前に実行されて作成され、その中のthisは未定義と出力されます。
(2) セットアップで受け付けるパラメータ
セットアップ(プロップ、コンテキスト)
props: 親コンポーネントによって渡された値を受け取ります。
context: context オブジェクト。以前の this メソッドでアクセスできるプロパティを置き換えるために使用されます。
attrs: 値はオブジェクトです。コンポーネントの外部から渡されるが、props 構成で宣言されていない属性 (this.$attrs と同等)。
スロット: 受信したスロットの内容。this.$slots に相当します。
Emit: カスタム イベントを配布する関数。this.$emit と同等です。
(3) setup の戻り値
setup はオブジェクトを返します。このオブジェクトのデータはテンプレートで直接使用でき、setup で返される値はデータ構成項目の this.xxx からも取得できます。
三、ref関数とreactive関数
先ほど書いたデータはレスポンシブデータではありませんが、ref関数とreactiveでレスポンシブデータを定義することができ、利用する前に関数を導入する必要があります。
1. 参照関数
● 機能: レスポンシブデータの定義
● 構文: const xxx = ref(initValue)
○ レスポンシブデータを含む参照オブジェクト (参照オブジェクト、略して ref オブジェクト) を作成します。
○ JS でデータを操作する: xxx.value
○ テンプレートでデータを読み取る: .value は必要なく、直接: <div>{
{xxx}}</div>
述べる:
受信データは、基本タイプまたはオブジェクトタイプです。
データの基本的なタイプ: 応答性は、やはり Object.defineProperty() の取得と設定によって完了します。
オブジェクト型データ: Vue3.0 の新しい関数 (リアクティブ関数) を内部的に「リクエスト」します。したがって、レスポンシブなデータを定義するときは、reactive 関数を直接使用できます。
<script lang="js">
//引入ref函数
import {
defineComponent,ref} from "vue";
export default defineComponent({
name:'App',
data(){
return{
}
},
setup(props, context){
//定义一个响应式数据
let num = ref(0)
//定义方法
function add(){
console.log(1)
//在setup中要拿到ref定义的数据需要.value
num.value++
}
//把数据和方法返回出去,模板中才能使用
return {
num,add}
}
})
</script>
<template>
<div @click="add()">{
{
num}}</div>
</template>
2. リアクティブ機能
● 機能: リアクティブ データのオブジェクト タイプを定義します (基本タイプには使用せず、ref 関数を使用します)
● 構文: const proxy object = reactive (source object) はオブジェクト (または配列) を受け取り、プロキシ オブジェクト (プロキシのインスタンス オブジェクト。プロキシ オブジェクトと呼ばれます)
● reactive で定義されるリアクティブ データは「深いレベル」です。
● ES6 ベースの内部プロキシ実装は、プロキシ オブジェクトを通じてソース オブジェクトの内部データを操作します。
<script lang="js">
//引入reactive
import {
defineComponent,ref,reactive} from "vue";
export default defineComponent({
name:'App',
data(){
return{
}
},
setup(props, context){
let objs = reactive({
name:'ld',
age:20
})
function updata(){
//读取reactive定义的数据的时候不需要.cvalue
objs.age = 28
}
return {
objs,updata}
}
})
</script>
<template>
<div @click="updata()">{
{
objs}}</div>
</template>
3. リアクティブとリファレンス
● データ定義の観点からの比較:
ref: 基本型データを定義するために使用されます。
reactive: オブジェクト (または配列) 型のデータを定義するために使用されます。
備考: ref は、オブジェクト (または配列) 型のデータを定義するために使用することもできます。このデータは、内部でリアクティブを通じてプロキシ オブジェクトに自動的に変換されます。
● 原理の観点からの比較:
ref は、Object.defineProperty() の get および set を通じて応答性 (データ ハイジャック) を実装します。○
reactive は、Proxy を使用して応答性 (データ ハイジャック) を実装し、Reflect を通じてソース オブジェクト内のデータを操作します。
● 使用の観点からの比較:
データを操作するにはref:.valueで定義されたデータが必要ですが、データ読み込み時にテンプレートに直接読み込む場合は.valueは必要ありません。
reactive で定義されるデータ: 操作データと読み取りデータ: どちらも .value は必要ありません。
4. 拡張機能: ref を使用して vue3 で dom を取得します
vue2 では ref を使用して要素を取得できますが、vue3 でも同じことができますが、使い方が異なります。
//拿到单个DOM
<script lang="js">
import {
defineComponent,ref,reactive} from "vue";
export default defineComponent({
name:'App',
setup(props, context){
let item = ref(null)
console.log(item)
return {
item}
}
})
</script>
<template>
<div ref="item" id="item">20</div>
</template>
//获取多个DOM
<script lang="js">
import {
defineComponent,ref,nextTick} from "vue";
export default defineComponent({
name:'App',
setup(props, context){
// 存储dom数组
const myRef = ref([]);
const setRef = (el) => {
myRef.value.push(el);
};
//下一个DOM 更新周期之后执行
nextTick(() => {
console.dir(myRef.value);
});
return {
setRef}
}
})
</script>
<template>
<div v-for="(item,index) in 3" :ref="setRef">10</div>
</template>
複数の ref レンダリングを取得します。
4、計算して見る
1. 計算された
vue2の設定方法と一致
import {
defineComponent,reactive,computed} from "vue";
...
setup(){
let pers = reactive({
name:'dlh',
age:38
})
//计算属性——简写
let compName = computed(()=>{
return pers.name + '-' + pers.age
})
//计算属性——完整
let compNames = computed({
//读取
get(){
return pers.name + '-' + pers.age
},
//修改
set(value){
const nameArr = value.split('-')
pers.name= nameArr[0]
pers.age = nameArr[1]
}
})
return {
compName,compNames
}
}
2.時計
vue2の設定方法と一致
watch(data,handler,object)
data:監視対象データ
handler(newValue,oldValue):コールバック関数(変更後の値、変更前の値)
object:任意の設定項目 { immediate: true, deep: true }
import {
watch,ref,reactive} from "vue";
...
setup(){
let num=ref(5),num2=ref(10)
let person = reactive({
name:'5465',
age:18
}
//情况一:监视ref定义的响应式数据
watch(num,(newValue,oldValue)=>{
console.log('num变化了',newValue,oldValue)
},{
immediate:true})
}
//情况二:监视多个ref定义的响应式数据[数组方式]
watch([num,num2],(newValue,oldValue)=>{
console.log('num或num2变化了',newValue,oldValue)
})
/*
情况三:监视reactive定义的响应式数据,无法正确获得oldValue,并且强制开启了深度监视
*/
watch(person,(newValue,oldValue)=>{
console.log('person变化了',newValue,oldValue)
},{
immediate:true)
//情况四:监视reactive定义的响应式数据中的某个属性(参数以函数返回值的形式传递)
watch(()=>person.num,(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{
immediate:true,deep:true})
//情况五:监视reactive定义的响应式数据中的多个数据[数组]
watch([()=>person.num,()=>person.age],(newValue,oldValue)=>{
console.log('person的job变化了',newValue,oldValue)
},{
immediate:true,deep:true})
3.watchEffect関数
watchでは監視対象の属性と監視対象のコールバックを指定する必要がありますが、watchEffectではどの属性を監視するか、監視対象のコールバックでどの属性を使用してどの属性を監視するかを指定する必要はありません。
//watchEffect所指定的回调中用到的数据只要发生变化,则直接重新执行回调。
watchEffect(()=>{
const num1 = sum.value
const num2 = person.age
console.log('watchEffect配置的回调执行了')
})
5. ライフサイクル
ライフサイクルはインポートを通じてインポートしてセットアップ関数で使用する必要がありますが、Vue3 のライフサイクルは Vue2.X よりも高速です。
ビュー2.X | ビュー 3 |
---|---|
作成前 | 設定() |
作成した | 設定() |
マウント前 | onBeforeMount |
取り付けられた | マウント済み |
更新前 | onBeforeUpdate |
更新しました | 更新済み |
前に破壊する | onBeforeUnmount |
破壊されました | アンマウント済み |
エラーがキャプチャされました | onErrorCaptured |
' | onRenderTracked (新規) |
' | onRenderTriggered (新規) |
2 つの新しいフックを追加しました
onRenderTriggered は、仮想 DOM の再レンダリングが追跡されるときに呼び出されます。
onRenderTracked は、仮想 DOM の再レンダリングがトリガーされるときに呼び出されます。
セットアップでのライフサイクルフックの使用
import {
defineComponent,onMounted} from "vue";
...
setup(){
onMounted(()=>{
console.log('Mounted !!')
})
}
6. カスタムフック機能
vue3 のフック関数は、vue2 の mixin に相当します。フックの本質は関数です。
ファイルのいくつかの個々の関数の js コードを抽出し、別の js ファイルに配置することです。その利点は、次のことができることです。コードを再利用して、セットアップのロジックをより明確かつ理解しやすくします。
マウスの位置を監視するフックをカプセル化します。
// src/hooks/useMove.js
import {
ref} from 'vue'
export default function(){
//创建2个响应式变量来储存用户鼠标x轴和y轴的位置
let pageX = ref(0) , pageY = ref(0)
window.addEventListener('mousemove',(event)=>{
pageX.value = event.pageX
pageY.value = event.pageY
})
return {
pageX,
pageY
}
}
//组件中引入使用
<script setup>
import useMove from "./hooks/useMove"
const {
pageX, pageY} = useMove()
</script>
<template>
<div>
X: {
{
pageX }} Y:{
{
pageY }}
</div>
</template>
<style scoped>
</style>
八、提供して注入する
祖先コンポーネントと子孫コンポーネント間の通信を実装します。
親コンポーネントにはデータを提供するための Provide オプションがあり、子孫コンポーネントにはこのデータの使用を開始するための Inject オプションがあります。
//祖组件
import {
defineComponent, provide, reactive} from "vue";
...
setup(){
let hobby = reactive({
name:'爱好',price:'无价'})
provide('hobby',hobby)
}
//后代组件
import {
inject, ref} from 'vue'
...
setup(){
const hobby = inject('hobby')
return{
hobby
}
}
9. テレポート - 任意のポータル
特定の HTML テンプレートは Dom 内のどこにでも配信できます
テレポートには必須のプロパティが 1 つあります。 to to には prop が必要です。有効なクエリ セレクターまたは HTMLElement である必要があります。
<teleport to='#portal'>
<div v-if="isShow" class='doms'>
Hello ! teleport
</div>
</teleport>
次に、用途を明確にするためにケースを書きます。
まず、index.html ファイルを見つけます。
//在</body>前面添加<div id='portal'></div>
<body>
<div id="app"></div>
<div id='portal'></div>
<script type="module" src="/src/main.js"></script>
</body>
子コンポーネント内で
<script lang="js">
import {
ref } from 'vue'
export default {
setup () {
//控制隐藏的变量
const isShow = ref(false)
//定时器id
let closeTime = null;
//当用户点击弹出
const showNotification = () => {
isShow.value = true
clearTimeout(closeTime)
closeTime = setTimeout(() => {
isShow.value = false
}, 2000)
}
return {
isShow,
showNotification
}
}
}
</script>
<template>
<div class='portals'>
<button @click='showNotification'> 显示 </button>
//需要传送的内容写在teleport里面并且to的地址为前面index文件中的id
<teleport to='#portal'>
<div v-if="isShow" class='doms'>
Hello ! teleport
</div>
</teleport>
</div>
</template>
<style scoped>
.doms {
position: fixed;
bottom: 20px;
left: 20px;
width: 120px;
padding: 30px;
color: #1a1a1a;
background-color: #fff;
border-radius: 10px;
}
</style>
最終的な効果: ユーザーがクリックすると、プロンプト ボックスが左下に表示され、2 秒後に消えます。
10. レスポンシブデータの判定
- isRef: 値が ref オブジェクトかどうかを確認します
- isReactive: オブジェクトが reactive によって作成されたリアクティブ プロキシであるかどうかを確認します。
- isReadonly: オブジェクトが readonly によって作成された読み取り専用プロキシであるかどうかを確認します
- isProxy: オブジェクトが eactive メソッドまたは readonly メソッドによって作成されたプロキシであるかどうかを確認します。
11. 他のいくつかの合成 API
1.toRawとmarkRaw
toRaw:
機能: reactive で生成された reactive オブジェクトを通常のオブジェクトに変換します。
使用シナリオ: 応答オブジェクトに対応する共通オブジェクトを読み取るために使用されます。この共通オブジェクトに対するすべての操作によってページが更新されることはありません。
import {
defineComponent,reactive,toRaw} from "vue";
export default defineComponent({
setup(){
let obj = reactive({
name:'段',
age:20
})
let objToRaw = toRaw(obj)
console.log(obj,objToRaw)
return{
obj,
objToRaw
}
}
})
このとき、2番目のデータは通常のデータとなる。
マーク生:
役割: オブジェクトが再び応答オブジェクトにならないように、オブジェクトにマークを付けます。
アプリケーション シナリオ:
1. 複雑なサードパーティ ライブラリなど、一部の値は応答性として設定すべきではありません。
2. 不変のデータ ソースを含む大きなリストをレンダリングする場合、リアクティブな変換をスキップするとパフォーマンスが向上する可能性があります。
2.shallowReactiveとshallowRef
ShallowReactive : オブジェクトの最も外側のプロパティの応答性 (つまり、浅い応答性) のみを処理します。
使用シナリオ: 複数のネスト層を持つオブジェクト構造がある場合、要件は最も外側のデータを変更することのみであるため、内部のすべてのネストされた構造をレスポンシブに変換する必要はなく、最も外側の属性を に設定するだけで済みます。応答性 これによりパフォーマンスが向上する可能性があります。
ShallowRef : オブジェクトの応答性ではなく、基本的なデータ型の応答性のみを処理します。
使用シナリオ: オブジェクト データがある場合、後続の関数はオブジェクト内のプロパティを変更しませんが、それを置き換える新しいオブジェクトを生成し、それを使用できます。
3.readonlyとshallowReadonly
readonly : リアクティブ データを読み取り専用 (ディープ読み取り専用) にします。
内層の各属性は読み取り専用に設定されており、変更操作を実行するとエラーが報告されます。
shallowReadonly: レスポンシブデータを読み取り専用(浅い読み取り専用)にします。
浅い場合は、最外層のみが対象となり、内層を変更してもエラーは報告されません。
アプリケーションシナリオ: データを変更したくない場合に使用し、さまざまな程度に応じて API を選択します
12. グローバルAPIの変更点
Vue 2 には多くのグローバル API と設定があり、Vue3 ではこれらの API にいくつかの調整が加えられています。
2.x グローバル API (Vue) | 3.x インスタンス API (アプリ) |
---|---|
Vue.config.xxxx | app.config.xxxx |
Vue.config.productionTip | 取り除く |
Vue.component | アプリコンポーネント |
ディレクティブ.view | app.ディレクティブ |
Vue.mixin | アプリミックスイン |
Vue.use | アプリの使用 |
Vue.プロトタイプ | app.config.globalProperties |
たとえば、$api をプロトタイプにマウントします。
import {
createApp } from 'vue'
import './style.css'
import App from './App.vue'
import API from '@/api/api';
const app = createApp(App)
app.config.globalProperties.$API = API;
app.mount('#app')
要約する
以上が今日お話したい内容です. この記事では vue3 の機能の一部を簡単に紹介するだけです. 詳細については公式ドキュメントを参照してください. このメモがあなたのお役に立てれば幸いです.