📓
vue.jsの練習⑤(公式チュートリアルstep-6~step-10の2周目)
Vue.jsの練習④の続き
step-6 条件付きレンダリング(v-if,v-else)
<script setup>
import { ref } from 'vue'
const awesome = ref(true)
function toggle() {
awesome.value = !awesome.value
}
</script>
<template>
<button @click="toggle">Toggle</button>
<h1 v-if="awesome">Vue is awesome!</h1>
<h1 v-else>Oh no 😢</h1>
</template>
トグルで切り替える場合の一般的な書き方
awesome.value = !awesome.value
step-7 リストのレンダリング
v-forディレクティブを使用して、配列に基づいて要素をレンダリング
<script setup>
import { ref } from 'vue'
// give each todo a unique id
let id = 0
const newTodo = ref('')
const todos = ref([
{ id: id++, text: 'Learn HTML' },
{ id: id++, text: 'Learn JavaScript' },
{ id: id++, text: 'Learn Vue' }
])
function addTodo() {
todos.value.push({ id: id++, text: newTodo.value })
newTodo.value = ''
}
function removeTodo(todo) {
todos.value = todos.value.filter((t) => t !== todo)
}
</script>
<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo" required placeholder="new todo">
<button>Add Todo</button>
</form>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
<button @click="removeTodo(todo)">X</button>
</li>
</ul>
</template>
step-8 Computed Property(step-7の続き)
Computedを追加する
options & HTMLの場合とは異なり、以下のように記載する。
const filteredTodos = computed(() => {
return hideCompleted.value
? todos.value.filter((t) => !t.done)
: todos.value
})
Computedの動きは、options & HTMLの場合と同様である。
<script setup>
import { ref, computed } from 'vue'
let id = 0
const newTodo = ref('')
const hideCompleted = ref(false)
const todos = ref([
{ id: id++, text: 'Learn HTML', done: true },
{ id: id++, text: 'Learn JavaScript', done: true },
{ id: id++, text: 'Learn Vue', done: false }
])
const filteredTodos = computed(() => {
return hideCompleted.value
? todos.value.filter((t) => !t.done)
: todos.value
})
function addTodo() {
todos.value.push({ id: id++, text: newTodo.value, done: false })
newTodo.value = ''
}
function removeTodo(todo) {
todos.value = todos.value.filter((t) => t !== todo)
}
</script>
<template>
<form @submit.prevent="addTodo">
<input v-model="newTodo" required placeholder="new todo">
<button>Add Todo</button>
</form>
<ul>
<li v-for="todo in filteredTodos" :key="todo.id">
<input type="checkbox" v-model="todo.done">
<span :class="{ done: todo.done }">{{ todo.text }}</span>
<button @click="removeTodo(todo)">X</button>
</li>
</ul>
<button @click="hideCompleted = !hideCompleted">
{{ hideCompleted ? 'Show all' : 'Hide completed' }}
</button>
</template>
<style>
.done {
text-decoration: line-through;
}
</style>
step-9 ライフサイクルとテンプレートの参照
refの宣言
const pElementRef = ref(null) //NULLで初期化されていることに要注意
<script setup>
import { ref, onMounted } from 'vue'
const pElementRef = ref(null)
onMounted(() => {
pElementRef.value.textContent = 'mounted!'
})
</script>
<template>
<p ref="pElementRef">Hello</p>
</template>
step-10 ウォッチャー
数値が変更されたときにコンソールにログを記録する等の機能を実装したいときに用いる。
import { ref, watch } from 'vue'
const count = ref(0)
watch(count, (newCount) => {
// yes, console.log() is a side effect
console.log(`new count is: ${newCount}`)
})
上記コードであればwatch()により、countの値が変更されるたびにコールバックが起動される。
<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++" :disabled="!todoData">Fetch next todo</button>
<p v-if="!todoData">Loading...</p>
<pre v-else>{{ todoData }}</pre>
</template>
一言感想
前回よりも少し進んでみて、慣れていないからかもしれないがVue2との差を感じた。現時点では、Vue2のhtml形式より行数が減り、下に間延びしないのは良さそうと感じた。
学習コストが思ったよりも高いが、引き続き勉強していこうと思う。
また、公式チュートリアルに加えて、Udemy講座も購入したので合わせて学んでいきたい。
Discussion