🗂

Vue3チュートリアル

2023/10/21に公開

使うことになりそうなのでメモ。

SFC

単一ファイルコンポーネント
.vueがそれにあたる。テンプレートやロジックは1ファイルに書くと良い。

tsのサポート

defineComponent<script setup lang="ts">を使えばいい。後者のほうがスッキリしている。
https://ja.vuejs.org/guide/typescript/overview.html

tsのサポート

使うと双方向バインディングできる。
まずイベントリスナーを使いつつ値を更新することが思いつくが、v-modelによって簡易にできる。下記だとtextが共有されている。
スッキリするが、大規模アプリでわかりやすいかというと正直疑問。
https://qiita.com/tamago3keran/items/590d99288dcccf388798

<script setup>
import { ref } from 'vue'

const text = ref('')
</script>

<template>
  <input v-model="text" placeholder="Type here">
  <p>{{ text }}</p>
</template>

ref

const text = ref('')で宣言しておくと、状態を監視できる。

算出プロパティー

CompositionAPIからはcomputedは下記のように書く.
用途としては非表示リストをフィルタしたいときなど。リストの状態が変わると、自動で更新してくれる。
const filteredTodos = computed(() => {

ライフサイクル

onMounted(() => {
  // コンポーネントがマウントされました。
})

で書く。

ウォッチャー

watch()で値の監視をすることが可能。
下記では、watch(todoId, fetchData)によって監視を宣言しておく。
clickイベントでtodoIdが変わる->fetchData()関数がコールバックされる。
下記のようにAPI呼び出したいときや、変更前の値を使いたいときなどで使えそう。
computedとwatchの使い方の棲み分けは議論やレビューで確認しておくべき。

<script setup>
import { ref, watch } from 'vue'

const todoId = ref(1)
const todoData = ref(null)

async function fetchData() {
  todoData.value = null
  const res = await fetch(
    `https://jsonplaceholder.typicode.com/todos/${todoId.value}`
  )
  todoData.value = await res.json()
}

fetchData()

watch(todoId, fetchData)
</script>

<template>
  <p>Todo id: {{ todoId }}</p>
  <button @click="todoId++">Fetch next todo</button>
  <p v-if="!todoData">Loading...</p>
  <pre v-else>{{ todoData }}</pre>
</template>

Props

importしなくてもいいヤツ。definePropsを使うとpropsの宣言が可能。
stringではなく、Stringと書かないといけなかったりするし、tsのinterface宣言したほうが良いのではと思った。

jsなら、

<script setup>
const props = defineProps({
  msg: String
})
</script>

<template>
  <h2>{{ msg || 'No props passed yet' }}</h2>
</template>

<script setup lang="ts">
interface Props {
  msg: string;
};

const { msg } = defineProps<Props>();
</script>

<template>
  <h2>{{ msg || 'No props passed yet' }}</h2>
</template>

emit

defineEmitsを使う

スロット

テンプレートを差し込めるやつ。
ヘッダー・フッター・ライブラリ・最小単位のコンポーネント以外で個人的に多用されると辛い。
子側で<slot name="xxxx"></slot>でxxxxで待ち受けて、親側で<template v-slot:xxxx>TEST</ template>と渡すと、親側のTESTを使ってくれる。
propsでmessageとして渡さなくてもいいので、簡潔に書ける。
コンポーネントの責務がスタイルを提供することとして、メッセージ内容は親に任せたいときに使う。
https://qiita.com/Ryo_gk/items/4a01b17b93217fa63348

Discussion