banner
Chenh

Chenh

js関数とイベントコールバック

js 中の関数オブジェクト#

funcName()funcName を区別することに注意してください。

関数を定義する場合、

function addOne(num){
  return num++
}

addOne(1) は、その関数を実行することを意味します。

一方、addOne は関数オブジェクト自体を表します。例を挙げると、

let tempFunc = addOne  // tempFunc も関数で、addOne と同じです
let tempResult = addOne(5) // tempResult は 6 です

引数のない関数の場合、これらの場合を区別するのはより困難です。

function printHello(){
  console.log("Hello")
}
// ---------
printHello() // 1 回関数を実行し、Hello を出力します
let great = printHello // great は printHello と同じです
great() // 1 と同じです

この違いは、Web イベント処理において非常に重要です。例を挙げると(Vue)

<script setup>
function handleMyEvent(){
  console.log("hello")
}
</script>

<template>
	<!-- ここではカスタムコンポーネントがあり、内部で myEvent イベントを発行しています -->
	<myComponent @myEvent="handleMyEvent"></myComponent>
	<myComponent @myEvent="handleMyEvent()"></myComponent>
	<myComponent @myEvent="console.log('hello')"
</template>

上記のコードでは、最初のコンポーネントはイベントにコールバック関数をバインドし、2 番目のコンポーネントはイベントが発生した後に関数本体(hello を出力)を実行します。これは 3 番目のコンポーネントと同等です。

また、コンポーネント内で発生するイベントには引数を指定することもできます。イベントに引数を指定する場合、最初の方法のみが正しく引数を受け取ることができます。この場合、handleMyEvent(id) 関数定義時に引数を受け取る必要があります。

以下はいくつかの方法の違いの解説です。

<script setup>
const id = ref(1)
const name = ref("David")
function handleEvent(id, name){
  console.log(id + ' ' + name)
}
</script>
<template>
	<!-- 子コンポーネントで defineEmits(['myEvent', id, name]) としています -->
	<myComponent @myEvent="handleEvnet"></myComponent> <!--✅-->
	<myComponent @myEvent="handleEvnet(id,name)"></myComponent> <!-- ❌ -->
	<myComponent :id="id" :name="name" @myEvent="handleEvent(id,name)"></myComponen> 
	<myComponent :id="id" :name="name" @myEvent="handleEvent"></myComponen>
</template>

3 番目の方法は正常に動作しますが、イベントが発生すると、引数はコンポーネント内から直接渡されるのではなく、このレベルのコンポーネントのidnameが直接引数として関数本体に渡されます。

4 番目の方法は、子コンポーネント内部から渡された引数を受け取ります。

結論#

親子コンポーネント間でデータを渡す場合、冗長なデータの受け渡しを行わないように注意してください。4 番目の方法は正常に動作しますが、もし情報がサブコンポーネント内にある場合、3 番目の方法の方が優れています。

Vue のリスナー#

⚠️ コンポーネントのプロパティを監視する場合、getter を渡す必要があります。props.name のように直接使用することはできません。

<script setup>
const props = defineProps(['id','name'])
watch(()=>props.id, function(newValue, oldValue){
  // ... 
})
</script>
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。