viteプロジェクト(デモプロジェクト)を作成
yarn create vite
package.json内 scriptsセクションのコマンドを実行
localhostでページを開く
yarn dev
Vueプロジェクトの構成
App.vue
:サンプルページの描画を行う
main.ts
import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
createApp(App).mount('#app') // index.htmlのappタグの付いた部分にApp.vueを挿入
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + Vue + TS</title>
</head>
<body>
<div id="app"></div> // app.vueが挿入される
<script type="module" src="/src/main.ts"></script>
</body>
</html>
Vueファイルの構成
- script
- javascriptを記載するセクション
- templateセクション内で参照する
- template
- htmlを記載するセクション
- style
- CSSを記載するセクション
- 独自クラスの定義も可能
-
<style scoped></script>
で他のVueファイルとsytleを共有しなくなる
example
<script setup lang="ts">
const word = "Qiita";
</script>
<template>
<div class="title">{{ word }}</div>
</template>
<style scoped>
.title{ color:lawngreen;
font-size: 20px;
}
</style>
v-bind
変数をHTMLタグの属性に値を渡す
NG
<script setup lang="ts">
const url = 'https://www.google.com/'
</script>
<template>
<a href="url">LINK</a>
</template>
v-bind
<script setup lang="ts">
const url = 'https://www.google.com/'
</script>
<template>
<a v-bind:href="url">LINK</a>
</template>
v-on
クリックなどのイベント処理の関数を渡す
v-on
<script setup lang="ts">
const user = "Mike";
const hello = (user:string) => {
alert('Hello ' + user + '!')
}
</script>
<template>
<button v-on:click="hello(user)">HELLO</button>
</template>
Ref / reactive
リアクティブシステム
:Vue.jsの仕組み。データが変化した時、変化内容が即座にDOM(テンプレート)に反映される
NG
<script setup lang="ts">
let itemName = "Qiita";
const input = (event: any) => {
// 変数が変わってもテンプレートは更新されない
itemName = event.target.value;
}
</script>
<template>
<input v-on:input="input"/>
<label>{{ itemName }}</label>
</template>
単一の値をリアクティブにするにはRefを使用
Ref
<script setup lang="ts">
import { ref } from 'vue'
const itemName = ref<string>('Qiita');
const input = (event: any) => {
itemName1.value = event.target.value;
}
</script>
<template>
<input v-on:input="input"/>
<label>{{ itemName }}</label>
</template>
オブジェクトをリアクティブにするにはreactive関数を使用
reactive
<script setup lang="ts">
import { reactive } from 'vue'
const item = reactive({
name: 'Qiita'
})
const input = (event: any) => {
item.name = event.target.value;
}
</script>
<template>
<input v-on:input="input"/>
<label>{{ item.name }}</label>
</template>
双方向データバインディング v-model
inputフィールドが双方向にバインドする場合は、v-modelディレクティブを使用する
(Clearボタンでlabelのだけではなく、inputフィールドの値も削除する)
v-model
<script setup lang="ts">
import { reactive } from 'vue'
const item = reactive({
name: 'Qiita'
})
const input = (event: any) => {
item.name = event.target.value;
}
const clear = () => {
item.name = ''
}
</script>
<template>
<input v-model="item.name"/>
<!-- valueでオブジェクトを参照した時と同じ処理になる -->
<!-- <input v-on:input="input" v-bind:value="item.name"/> -->
<button v-on:click="clear">Clear</button>
<label>{{ item.name }}</label>
</template>
算出プロパティ computed
条件を基に値を生成する場合、computedを使用する。
computedを使用することで、vue内でキャッシュ等最適化される。
これでも動くが、vueではテンプレート内にロジックを持たせないように記載する
NG
<template>
<label>{{ item.name == "Jack" ? "It's Jack" : "Not Jack"}}</label>
</template>
computed
<script setup lang="ts">
import { computed } from 'vue'
const nameLabel = computed(() => {
if (item.name == "Jack") {
return "It's Jack";
} else {
return "Not Jack";
}
})
</script>
<template>
<label>{{ nameLabel }}</label>
</template>
監視プロパティ watch
こちらでもcomputed同様の処理が可能。
watch
<script setup lang="ts">
const nameLabel = ref<string>(item.name)
// 要素をリアクティブな値で返す
const { name } = toRefs(item)
// 第一引数:watchしたいリアクティブな値
// 第二引数:値が変更された時の処理
watch(name, () => {
if (name.value == "Jack") {
nameLabel.value = "It's Jack";
} else {
nameLabel.value = "Not Jack";
}
})
</script>
備考:eventの中身を見る
event
<script setup lang="ts">
const input = (event: any) => {
console.log(event);
console.log(event.target.value);
}
</script>
<template>
<input v-on:input="input"/>
</template>
参考