著者:大津 真
JavaScriptフレームワークの中でも、学びやすさと柔軟さで人気を集めている「Vue.js」。本連載では、Vue.jsの基礎から実践的な使い方までを、分かりやすく丁寧に解説していきます。一緒にフロントエンド開発の楽しさを体験してみましょう。第4回では、v-onディレクティブの活用と、VueアプリケーションからDOM(Document Object Model)を操作する方法について説明します。
シェルスクリプトマガジン Vol.99は以下のリンク先でご購入できます。![]()
![]()
図1 「event-props/src/App.vue」ファイルのコード
<script setup>
import { ref } from 'vue'
function eventTest(e) {
console.log(e)
}
</script>
<template>
<button @click="eventTest">Click me</button>
</template>
図1 「event-props/src/App.vue」ファイルのコード
<script setup>
import { ref } from 'vue'
const event = ref(null)
function eventTest(e) {
event.value = e
}
</script>
<template>
<div id="back" @click="eventTest" @dblclick="eventTest">
<h1>Event Test</h1>
<div id="box" @mouseover="eventTest" @mouseout="eventTest">
<p>My Box</p>
</div>
<p>Event type: {{ event?.type }}</p>
<p>x:{{ event?.clientX }} y: {{ event?.clientY }}</p>
</div>
</template>
<style scoped>
#back {
width: 100vw;
height: 100vh;
}
#box {
width: 100px;
height: 100px;
background-color: #f00;
margin: 0 auto;
}
</style>
図6 「src/style.css」ファイルの変更例
(略)
#app {
max-width: 1280px;
margin: 0 auto;
/* padding: 2rem; */ ←コメントにする
text-align: center;
}
(略)
図7 useTemplateRef関数でDOM要素を取得するコードの例
<template>
(略)
<img ref="fish" id="fish" src="./assets/fish1.jpg" />
(略)
</template>
<script setup>
(略)
const fish = useTemplateRef("fish");
(略)
</script>
図8 「event-test2/src/App.vue」ファイルのコード
<!-- App.vue -->
<template>
<div id="back" @click="moveImg">
<img ref="fish" id="fish" src="./assets/fish1.jpg" />
</div>
</template>
<script setup>
import { useTemplateRef, onMounted } from 'vue'
// テンプレート参照を取得
const fish_ref = useTemplateRef("fish")
function moveImg(e) {
// transitionの設定
const duration = "1s" // 移動時間
fish_ref.value.style.transition = \
left ${duration} ease, top ${duration} ease, \
transform 0.3s ease
// クリック位置に移動
const x = e.clientX - fish_ref.value.width / 2
const y = e.clientY - fish_ref.value.height / 2
fish_ref.value.style.left = ${x}px
fish_ref.value.style.top = ${y}px
// クリック方向に応じて向きを変える
if (e.clientX < fish_ref.value.offsetLeft) {
fish_ref.value.style.transform = 'scaleX(-1)' // 左向き
} else {
fish_ref.value.style.transform = 'scaleX(1)' // 右向き
}
}
</script>
<style scoped>
#back {
position: fixed;
inset: 0;
}
#fish {
position: absolute;
width: 100px;
left: 100px; /* 初期位置 X */
top: 100px; /* 初期位置 Y */
}
</style>
図10 HTMLテンプレート部分の変更箇所
(略)
<div id="back" @click="moveImg(false, $event)"
@contextmenu="moveImg(true, $event)">
<img ref="fish" id="fish" src="./assets/fish1.jpg" />
</div>
(略)
図11 JavaScript部分の変更箇所(抜粋)
(略)
function moveImg(isFast, e) {
e.preventDefault(); // 右クリックメニューを防ぐ
(略)
const duration = isFast ? "0.3s" : "0.8s";
el.style.transition = left ${duration} ease, \
top ${duration} ease, \
transform 0.3s ease;
(略)
図12 不適切なコードの例
(略)
<script setup>
import { useTemplateRef, onMounted } from 'vue';
const fish = useTemplateRef("fish");
const el = fish.value
el.style.left = '100px' // 左端の座標を設定
el.style.top = '100px' // 上端の座標を設定
(略)
図13 書き換えた部分のコード
onMounted(() => {
const el = fish.value;
if (el) {
// 親要素の位置とサイズを取得
const parentRect = el.offsetParent.getBoundingClientRect();
// 初期位置を画面中央に設定
const x = parentRect.width / 2 - el.width / 2;
const y = parentRect.height / 2 - el.height / 2;
el.style.left = ${x}px;
el.style.top = ${y}px;
}
});
※「< 」を「<」に置き換えてください。