@[目次](独習フロントエンド開発 - VUEフレームワーク(3)よく使うタグ命令、オプションAPI、組み合わせAPI)
vue でよく使用されるラベル命令
このディレクティブは実際にはラベルの属性であり、v-
vue によって提供される特別な属性であることを示す接頭辞 が付いています。これらは、レンダリングされた DOM に特別な応答動作を適用します。
v-html
v-html
このディレクティブは、現在のコンポーネント インスタンス上でこの要素の innerHTML プロパティと rawHtml プロパティの同期を維持することを意味します。
<p>Using text interpolation: {
{ rawHtml }}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>
span
rawHtml
のコンテンツは属性の値に置き換えられ、プレーン HTML に補間されます。データ バインディングは無視されます。v-html
Vue は文字列ベースのテンプレート エンジンではないため、結合されたテンプレートを結合するために を使用することはできないことに注意してください。Vue を使用する場合は、UI の再利用と構成の基本単位としてコンポーネントを使用する必要があります。
v-テキスト
v-text
要素の textContent プロパティを設定することで機能し、要素内の既存のコンテンツが上書きされます。テキスト補間と同等。
<span v-text="msg"></span>
<!-- 等同于 -->
<span>{
{msg}}</span>
vバインド
v-bind
ディレクティブは、1 つまたは複数のプロパティを要素オブジェクトにバインドします。
<div v-bind:id="dynamicId"></div>
v-bind
このディレクティブは、要素のid
プロパティをコンポーネントのプロパティとdynamicId
一致させるように Vue に指示します。バインドされた値がnull
または の場合undefined
、プロパティはレンダリングされた要素から削除されます。
次のように省略することもできます。
<div :id="dynamicId"></div>
v-bind
命令によってバインドされた属性については、それが無効、非表示などのブール属性の場合、次のように使用できます。
<button :disabled="isButtonDisabled">Button</button>
isButtonDisabled
が true または空の文字列 (すなわち)の場合<button disabled="">
、要素にはこの無効な属性が含まれます。それ以外の場合、プロパティは無視されます。
v-bind
ディレクティブがパラメータを取らない場合、ディレクティブに含まれる複数のプロパティが要素オブジェクトにバインドされます。
data() {
return {
objectOfAttrs: {
id: 'container',
class: 'wrapper'
}
}
}
<div v-bind="objectOfAttrs"></div>
使用できる修飾子は次のとおりです。
- .camel - ダッシュ名のプロパティをキャメルケースの名前に変換します。
- .prop - DOM メンバーとして強制的にバインドします。
- .attr - DOM 属性として強制的にバインドします。
参考例:
<!-- 绑定 attribute -->
<img v-bind:src="imageSrc" />
<!-- 动态 attribute 名 -->
<button v-bind:[key]="value"></button>
<!-- 缩写 -->
<img :src="imageSrc" />
<!-- 缩写形式的动态 attribute 名 -->
<button :[key]="value"></button>
<!-- 内联字符串拼接 -->
<img :src="'/path/to/images/' + fileName" />
<!-- class 绑定 -->
<div :class="{ red: isRed }"></div>
<div :class="[classA, classB]"></div>
<div :class="[classA, { classB: isB, classC: isC }]"></div>
<!-- style 绑定 -->
<div :style="{ fontSize: size + 'px' }"></div>
<div :style="[styleObjectA, styleObjectB]"></div>
<!-- 绑定对象形式的 attribute -->
<div v-bind="{ id: someProp, 'other-attr': otherProp }"></div>
<!-- prop 绑定。“prop” 必须在子组件中已声明。 -->
<MyComponent :prop="someThing" />
<!-- 传递子父组件共有的 prop -->
<MyComponent v-bind="$props" />
<!-- XLink -->
<svg><a :xlink:special="foo"></a></svg>
ヴオン
v-on
このコマンドは DOM イベントをリッスンし、パラメーターは監視する必要があるイベントです。通常の要素で使用すると、ネイティブ DOM イベントのみがリッスンされます。カスタム要素コンポーネントで使用すると、子コンポーネントによってトリガーされるカスタム イベントをリッスンします。
ネイティブ DOM イベントをリッスンする場合、メソッドはネイティブ イベントを唯一のパラメーターとして受け取ります。インライン宣言が使用されている場合、その宣言は特殊$event
変数にアクセスできますv-on:click="handle('ok', $event)"
。
<!-- 方法处理函数 -->
<button v-on:click="doThis"></button>
<!-- 动态事件 -->
<button v-on:[event]="doThis"></button>
<!-- 内联声明 -->
<button v-on:click="doThat('hello', $event)"></button>
<!-- 缩写 -->
<button @click="doThis"></button>
<!-- 使用缩写的动态事件 -->
<button @[event]="doThis"></button>
<!-- 停止传播 -->
<button @click.stop="doThis"></button>
<!-- 阻止默认事件 -->
<button @click.prevent="doThis"></button>
<!-- 不带表达式地阻止默认事件 -->
<form @submit.prevent></form>
<!-- 链式调用修饰符 -->
<button @click.stop.prevent="doThis"></button>
<!-- 按键用于 keyAlias 修饰符-->
<input @keyup.enter="onEnter" />
<!-- 点击事件将最多触发一次 -->
<button v-on:click.once="doThis"></button>
<!-- 对象语法 -->
<button v-on="{ mousedown: doThis, mouseup: doThat }"></button>
使用できる修飾子:
- .stop と呼ばれます
event.stopPropagation()
。 - .prevent - 呼び出し
event.preventDefault()
。 - .capture – キャプチャ モードでイベント リスナーを追加します。
- .self – ハンドラーは、イベントが要素自体から発生した場合にのみトリガーされます。
- .{keyAlias} - 特定のキーでのみハンドラーをトリガーします。
- .once - 処理関数を最大 1 回トリガーします。
- .left - マウスの左ボタン イベントでハンドラー関数のみをトリガーします。
- .right - マウスの右ボタン イベントでのみハンドラー関数をトリガーします。
- .middle - マウスの中ボタン イベントでのみハンドラー関数をトリガーします。
- .passive - {passive: true } を介して DOM イベントをアタッチします。
v モデル
v-model
この命令は、フォーム要素の value 属性をデータ モデルに双方向にバインドします。たとえば、ユーザーが要素オブジェクトの値を変更すると、データ モデルの値も同時に変更されます。
<div id="app">
<p>{
{ num }}</p>
<input type="text" v-model="num">
</div>
<script>
const {
createApp} = Vue
let vm = Vue.createApp({
data() {
return {
num: 0
}
},
mounted() {
setInterval(() => {
this.num++;
}, 1000)
}
}).mount('#app')
</script>
修飾子が使用可能
- .lazy - 入力の代わりに変更イベントをリッスンします
- .number - 入力された有効な文字列を数値に変換します
- .trim - 入力コンテンツの両端のスペースを削除します
のために
この要素とそのすべての子のコンパイルはスキップされ、そのまま保存されてレンダリングされます。最も一般的な使用例は、元の二重中括弧タグとコンテンツを表示することです。
<span v-pre>{
{ this will not be compiled }}</span>
v-once
要素とコンポーネントを一度だけレンダリングし、それ以降の更新をスキップします。その後の再レンダリングでは、要素/コンポーネントとそのすべての子は静的コンテンツとして扱われ、レンダリングがスキップされます。これを使用して、更新時のパフォーマンスを最適化できます。
<!-- 单个元素 -->
<span v-once>This will never change: {
{msg}}</span>
<!-- 带有子元素的元素 -->
<div v-once>
<h1>comment</h1>
<p>{
{msg}}</p>
</div>
<!-- 组件 -->
<MyComponent v-once :comment="msg" />
<!-- `v-for` 指令 -->
<ul>
<li v-for="i in list" v-once>{
{i}}</li>
</ul>
v-メモ
テンプレートのサブツリーをキャッシュします。要素とコンポーネントの両方で使用できます。キャッシュを実装するには、この命令は比較のために依存関係値の固定長配列を渡す必要があります。配列内のすべての値が最後のレンダリングと同じである場合、サブツリー全体の更新はスキップされます。例えば:
<div v-memo="[valueA, valueB]">
...
</div>
コンポーネントが再レンダリングされるとき、valueA と valueB の両方が変更されていない場合、<div>
このコンポーネントとその子に対するすべての更新はスキップされます。実際、サブツリーのキャッシュされたコピーは再利用できるため、仮想 DOM の vnode の作成もスキップされます。
キャッシュ配列を正しく指定することが重要です。正しく指定しないと、有効になるはずの更新がスキップされる可能性があります。v-memo を空の依存関係配列 ( ) に渡すと、と同じ効果がv-memo="[]"
あります。v-once
v-memo は v-for とともに使用されます
v-memo
パフォーマンスが重要なシナリオでの小規模な最適化としてのみ使用し、必要になることはほとんどありません。最も一般的なケースは、おそらく大規模なv-for
リスト (1000 を超えるリスト) をレンダリングする場合に役立ちます。
<div v-for="item in list" :key="item.id" v-memo="[item.id === selected]">
<p>ID: {
{ item.id }} - selected: {
{ item.id === selected }}</p>
<p>...more child nodes</p>
</div>
コンポーネントの選択された状態が変化すると、デフォルトで多数の vnode が再作成されますが、そのほとんどは以前とまったく同じになります。v-memo
ここで使用されているのは、基本的に「項目の選択されたステータスが変更された場合にのみ更新する必要がある」ということです。これにより、選択ステータスが変更されていない各項目は、以前の vnode を完全に再利用し、差分比較をスキップできます。Vue はitem にも基づいて:key
判断するため、ここで item.id をメモの依存関係配列に含める必要はないことに注意してください。v-for
togetherを使用する場合はv-memo
、両方が同じ要素にバインドされていることを確認してください。v-memo
内部では使用できませんv-for
。
vue で一般的に使用されるオプションの API オプション
ステータスオプション
データ
データ オプションは Vue のデフォルトデータ モデルであり、関数から返されたデータ オブジェクトを受け取り、それをテンプレートにレンダリングします。
<div id="app">
<p>{
{ message }}</p>
</div>
<script>
let vm = Vue.createApp({
data() {
return {
message: 'Hello Vue!'
}
}
}).mount('#app')
</script>
ページのレンダリングは、そのデータを変更することで更新できます。
vm.$data.message = 'Hello World!'
data で宣言されたすべてのデータは、vm オブジェクトによってトラバースされ、その属性として vm オブジェクトに割り当てられます。したがって、次のようにデータを変更することもできます。
vm.message = 'Hello World!'
計算された
計算されたオプション (計算されたプロパティ) はオブジェクトであり、オブジェクト内のプロパティは、リアクティブ状態に依存する複雑なロジックを記述するために使用されるゲッター メソッドです。計算されたオプションのライフのプロパティ (ゲッター メソッド) も、アプリケーションのインスタンス化時にデータによって宣言されたプロパティと同様に、アプリケーションのプロパティになります。
export default {
data() {
return {
author: {
name: 'John Doe',
books: [
'Vue 2 - Advanced Guide',
'Vue 3 - Basic Guide',
'Vue 4 - The Mystery'
]
}
}
},
computed: {
// 一个计算属性的 getter
publishedBooksMessage() {
// `this` 指向当前组件实例
return this.author.books.length > 0 ? 'Yes' : 'No'
}
}
}
<p>Has published books:</p>
<!-- 因为 computed 的成员是 getter 方法,所以所有成员可以像变量一样直接使用 -->
<span>{
{ publishedBooksMessage }}</span>
計算されたプロパティは読み取り専用であり、書き込みを試みると実行時警告が表示されます。本当に記述する必要がある場合は、getter と setter の両方を提供して作成する必要があります。
export default {
data() {
return {
firstName: 'John',
lastName: 'Doe'
}
},
computed: {
fullName: {
// getter
get() {
return this.firstName + ' ' + this.lastName
},
// setter
set(newValue) {
// 注意:这里使用的是解构赋值语法
[this.firstName, this.lastName] = newValue.split(' ')
}
}
}
}
メソッド
Methods はメソッド オプションです。計算コンポーネントと同様に、これもオブジェクトです。オブジェクト内の各プロパティは、テンプレート内で呼び出すことができるメソッドです。
2 つの違いは、計算されたプロパティ値がそのリアクティブな依存関係に基づいてキャッシュされることです。つまり、計算されたプロパティは、そのリアクティブな依存関係が更新された場合にのみ再計算されます。メソッド コンポーネントは呼び出されるたびに再計算されます。
// 计算属性永远不会更新,因为 Date.now() 不是响应式依赖。所以应该使用方法组件。
computed: {
now() {
return Date.now()
}
}
Vue はこれをメソッド内のメソッドに自動的にバインドし、常にコンポーネント インスタンスを指します。これにより、イベント リスナーまたはコールバック関数として機能するときに、メソッドが常に正しい this を維持することが保証されます。アロー関数には独自の this コンテキストがないため、メソッドを定義するときにアロー関数を使用しないでください。
時計
watch オプションは、データが変更されたときに呼び出されるリスニング コールバックを宣言するために使用されます。watch オプションにはメソッドまたはオブジェクトが必要です。メソッドの場合、メソッド名はコンポーネントのサンプル プロパティ名で、メソッド パラメータには古い値と新しい値が含まれ、メソッドの内容はコールバック関数です。オブジェクトの場合、キーはリッスンする必要があるリアクティブ コンポーネント インスタンスのプロパティ (たとえば、データ経由で宣言されたプロパティや計算されたプロパティ) であり、値は対応するコールバック関数です。このコールバック関数は、リッスンしているソースの新しい値と古い値を受け入れます。
ルートレベルの属性に加えて、キー名を単純なドット区切りのパスにすることもできます (例: ) a.b.c
。この使用法では複雑な式はサポートされず、ドットで区切られたパスのみがサポートされることに注意してください。複雑なデータ ソースをリッスンする必要がある場合は、命令型$watch()
API を使用できます。
値は、メソッド名を含む文字列 (メソッド経由で宣言)、または追加のオプションを含むオブジェクトにすることもできます。オブジェクト構文を使用する場合、ハンドラー内でコールバック関数を宣言する必要があります。追加のオプションには次のものがあります。
- 即時: リスナーが作成されるとすぐにコールバックがトリガーされます。初めて呼び出されるとき、古い値は未定義になります。
- deep: ソースがオブジェクトまたは配列の場合、深さが変更されたときにコールバックがトリガーされるように、ソースの深いトラバースを強制します。
- flash: コールバックの更新タイミングを調整します。たとえば、「post」は DOM が更新された後にコールバックします (デフォルトでは、DOM が更新される前にコールバックします)。
- onTrack/onTrigger: リスナーの依存関係をデバッグします。
リスナー コールバックを宣言するときは、アロー関数を使用してコンポーネント インスタンスにアクセスできないため、アロー関数の使用を避けてください。
export default {
data() {
return {
a: 1,
b: 2,
c: {
d: 4
},
e: 5,
f: 6
}
},
watch: {
// 侦听根级属性
a(val, oldVal) {
console.log(`new: ${
val}, old: ${
oldVal}`)
},
// 字符串方法名称
b: 'someMethod',
// 该回调将会在被侦听的对象的属性改变时调动,无论其被嵌套多深
c: {
handler(val, oldVal) {
console.log('c changed')
},
deep: true
},
// 侦听单个嵌套属性:
'c.d': function (val, oldVal) {
// do something
},
// 该回调将会在侦听开始之后立即调用
e: {
handler(val, oldVal) {
console.log('e changed')
},
immediate: true
},
// 你可以传入回调数组,它们将会被逐一调用
f: [
'handle1',
function handle2(val, oldVal) {
console.log('handle2 triggered')
},
{
handler: function handle3(val, oldVal) {
console.log('handle3 triggered')
}
/* ... */
}
]
},
methods: {
someMethod() {
console.log('b changed')
},
handle1() {
console.log('handle 1 triggered')
}
},
created() {
this.a = 3 // => new: 3, old: 1
}
}
ライフサイクル オプション (フック)
作成した
作成されたオプションは、コンポーネント インスタンスが状態に関連するすべてのオプションを処理した後に呼び出されます。
このフックが呼び出されると、リアクティブ データ、計算されたプロパティ、メソッド、およびリスナーがセットアップされます。ただし、マウントフェーズがまだ開始されていないため、$el
プロパティはまだ使用できません。
取り付けられた
マウントされたオプションは、コンポーネントがマウントされた後に呼び出される関数を受け入れます。
<div id='app'>
<p>count = {
{ count }}</p>
<div>
<script>
let vm = Vue.createApp({
data() {
return{
count: 0
}},
mounted() {
setInterval(()=>{
this.count++;
// 在 vm 外部,可以使用 vm.$data.count 改变绑定的数据
// 也可以使用 vm.count 来改变绑定的数据
},1000)
}
}).mount('#app')
</script>
更新しました
updated オプションは、リアクティブな状態の変化によりコンポーネントが DOM ツリーを更新した後に呼び出される関数を受け入れます。親コンポーネントの更新フックは、その子コンポーネントの更新フックの後に呼び出されます。このフックは、さまざまな状態変化によって引き起こされる可能性のあるコンポーネントの DOM 更新後に呼び出されます。特定の状態が変化した後に更新された DOM にアクセスする必要がある場合は、代わりにそれを使用できますnextTick()
。注: このフックは、サーバー側のレンダリング中には呼び出されません。
アンマウントされた
アンマウント オプションは、コンポーネント インスタンスがアンマウントされた後に呼び出される関数を受け入れます。コンポーネントは、次の場合にアンインストールされたとみなされます。
- すべてのサブコンポーネントがアンインストールされました。
- 関連するすべてのリアクティブ アクション (レンダリング アクション、計算されたプロパティ、および
setup()
その時点で) が停止されました。
タイマー、DOM イベント リスナー、サーバーへの接続などの一部の副作用は、このフックで手動でクリーンアップできます。このフックは、サーバー側のレンダリング中に呼び出されません。
vue の一般的に使用される組み合わせ API 関数
設定
setup()
フックはコンポーネントで合成 API を使用するためのエントリ ポイントであり、通常は次の状況でのみ使用されます。
- 単一ファイル以外のコンポーネントで複合 API を使用する必要がある場合。
- オプションの API に基づいたコンポーネントに、コンポジション API に基づいたコードを統合する必要がある場合。
それ以外の場合はすべて、構文が優先される必要があります<script setup>
。
結合された API もアプリケーション インスタンスに基づいているため、最初にアプリケーション インスタンスを作成する必要があります。オプション API とは異なり、アプリケーション インスタンスを作成するときに、オプション API は複数のオプションで構成されるオブジェクトを渡しますが、結合 API は主にセットアップ関数オブジェクトを渡します。オプション API のすべてのオプション関数は、setup 関数内に記述されます。
<div id="app">
<p @click="increment">{
{ num }}</p>
</div>
<script>
const {
createApp, ref} = Vue;
let app = createApp({
setup() {
// 响应式状态
let num = ref(0);
// 用来修改状态、触发更新的函数
function increment() {
num.value++
}
// 返回值会暴露给模板和其他的选项式 API 钩子
return {
num, increment}
}
}).mount('#app')
</script>
テンプレート内のセットアップから返された ref にアクセスすると、自動的に浅くアンラップされるため、テンプレートに .value を記述する必要がなくなることに注意してください。これ経由でアクセスすると、同じ解凍が行われます。
参照
内部値を受け入れ、その内部値を指すプロパティが 1 つだけある応答性の変更可能な ref オブジェクトを返します.value
。ref オブジェクトは変更可能です。つまり、.value
新しい値を割り当てることができます。また、リアクティブでもあります。つまり、すべての.value
操作が追跡され、書き込みによりそれに関連する副作用がトリガーされます。
オブジェクトが ref に割り当てられている場合、そのオブジェクトはreactive()
応答性の高いオブジェクトに変換されます。これは、オブジェクトにネストされた参照が含まれている場合、それらが深くラップ解除されることも意味します。このような深い変換を回避するには、shallowRef()
代わりに を使用します。
const count = ref(0)
console.log(count.value) // 0
count.value++
console.log(count.value) // 1
計算された
getter 関数を受け入れ、読み取り専用のリアクティブ ref オブジェクトを返します。この参照は、.value
ゲッター関数の戻り値を公開します。また、get 関数と set 関数を使用してオブジェクトを受け入れて、書き込み可能な ref オブジェクトを作成することもできます。
読み取り専用の計算プロパティ参照を作成します。
const count = ref(1)
const plusOne = computed(() => count.value + 1)
console.log(plusOne.value) // 2
plusOne.value++ // 错误
書き込み可能な計算プロパティ参照を作成します。
const count = ref(1)
const plusOne = computed({
get: () => count.value + 1,
set: (val) => {
count.value = val - 1
}
})
plusOne.value = 1
console.log(count.value) // 0
反応的な
オブジェクトのリアクティブ プロキシを返します。リアクティブ変換は「深い」ものであり、ネストされたすべてのプロパティに影響します。リアクティブ オブジェクトは、応答性を維持しながら、あらゆる ref プロパティを深くアンラップします。
リアクティブ配列や Map などのネイティブ コレクション型の ref 要素にアクセスする場合、ref のアンパックは実行されないことに注意してください。深いリアクティブな変換を避け、このオブジェクトへのトップレベルのアクセスの応答性のみを維持したい場合は、shallowReactive()
代わりに を使用できます。返されたオブジェクトとその中にネストされたオブジェクトは ES プロキシによってラップされるため、ソース オブジェクトと等しくありません。リアクティブ プロキシのみを使用し、元のオブジェクトの使用を避けることをお勧めします。
と比較するとref()
、 reactive で作成されたリアクティブ プロキシ オブジェクトは、.value
を使用せずにそのメンバーを正しく使用できます。したがって、基本的なデータの使用にはref()
、反応状態を変換するための配列またはオブジェクトに使用しますreactive()
。
時計
1 つ以上のリアクティブ データ ソースをリッスンし、データ ソースが変更されたときに指定されたコールバック関数を呼び出します。watch(source,callback,options)
デフォルトは遅延リスニングです。つまり、コールバック関数はリスニング ソースが変更された場合にのみ実行されます。
最初のパラメータはリスナーのソースです。このソースは次のいずれかになります。
- 値を返す関数
- 参照者
- 反応性のあるオブジェクト
- ...または上記の型の値で構成される配列
2 番目のパラメーターは、変更が発生したときに呼び出されるコールバック関数です。このコールバック関数は、新しい値、古い値、および副作用クリーンアップを登録するためのコールバック関数の 3 つのパラメータを受け入れます。このコールバック関数は、次回副作用が再実行される前に呼び出され、非同期リクエストの待機などの無効な副作用をクリアするために使用できます。複数のソースをリッスンする場合、コールバック関数は、ソース配列内の新しい値と古い値に対応する 2 つの配列を受け入れます。
3 番目のオプションのパラメーターは、次のオプションをサポートするオブジェクトです。
- 即時: リスナーが作成されるとすぐにコールバックがトリガーされます。最初に呼び出されたとき、古い値は未定義でした。
- deep: ソースがオブジェクトの場合、深いレベルが変更されたときにコールバックがトリガーされるように、深いトラバーサルを強制します。ディープリスナーを参照してください。
- flash: コールバック関数のリフレッシュタイミングを調整します。コールバックとwatchEffect()のリフレッシュタイミングを参照してください。
- onTrack/onTrigger: リスナーの依存関係をデバッグします。「デバッグ リスナー」を参照してください。
と比較してwatchEffect()
、watch() では次のことが可能になります。
- 副作用の遅延実行。
- どの状態がリスナーの再実行をトリガーすべきかがより明確になります。
- リッスン状態の以前の値と現在の値にアクセスできます。
ゲッター関数をリッスンします。
const state = reactive({
count: 0 })
watch(
() => state.count,
(count, prevCount) => {
/* ... */
}
)
参照を聞いてください:
const count = ref(0)
watch(count, (count, prevCount) => {
/* ... */
})
複数のソースをリッスンする場合、コールバック関数は、ソース配列の新しい値と古い値に対応する 2 つの配列を受け入れます。
watch([fooRef, barRef], ([foo, bar], [prevFoo, prevBar]) => {
/* ... */
})
ゲッター関数をソースとして使用する場合、コールバックは、この関数の戻り値が変更された場合にのみ起動されます。{ deep: true }
深いレベルの変更でもコールバックを起動したい場合は、リスナーを強制的に深いレベル モードにする必要があります。ディープレベル モードでは、ディープレベルの変更によりコールバック関数がトリガーされた場合、新しい値と古い値は同じオブジェクトになります。
const state = reactive({
count: 0 })
watch(
() => state,
(newValue, oldValue) => {
// newValue === oldValue
},
{
deep: true }
)
リアクティブ オブジェクトを直接リッスンする場合、リスナーは自動的にディープ モードを有効にします。
const state = reactive({
count: 0 })
watch(state, () => {
/* 深层级变更状态所触发的回调 */
})