前一篇中,筆者與各位初次接觸了Vue.js的SFC檔案格式以及它的宣告式渲染功能,今日將來一起學習Vue.js的各種綁定方式(Bindings)。那麼廢話不多說,就直接開始吧!
v-
之前我們使用了大括號來將變數資料顯示於網頁之中,但如果我們想要以同樣的方式,將變數設為 HTML 各個標籤的屬性,要怎麼實作呢?
<script setup>
import { ref } from 'vue'
const greeting = ref('Hello World!')
</script>
<template>
// 使用 {{ }} 來使用 greeting 變數
<p class="greeting">{{ greeting }}</p>
</template>
<style>
.greeting {
color: red;
font-weight: bold;
}
</style>
有一點需要注意的是,大括號(亦可稱作mustache)僅能將數值插入文字之中 (text interpolation),想要將它用在其他地方的話,便要用到各種 Vue.js 的特殊指令 v-
以上面的程式碼為例,如果我們希望也將 <p>
標籤的類別 (class) 跟上面的變數 greetings 做綁定,我們可以使用 v-bind
的指令來表示:
<script setup>
import { ref } from 'vue'
const greeting = ref('Hello World!')
</script>
<template>
<p v-bind:id="greeting">{{ greeting }}</p>
</template>
從程式範例可以看出,這個特殊指令的語法為 v-bind:attribute(屬性)
,而冒號後的資訊便是這個指令的「參數」了。不過如果每次使用都要打 v-bind:
似乎有點麻煩,在加上這個指令經常使用,如此一來程式也容易顯得冗長。因此在使用時,我們也可以直接只打冒號代替:
<p :id="greeting">{{ greeting }}</p>
如果有需要,我們也可以用以下這種方式來一次綁定多個屬性:
const objectOfAttrs = {
id: 'container',
class: 'wrapper',
style: 'background-color:green'
}
// ...
<div v-bind="objectOfAttrs"></div>
如果我們想要對不再是屬性,而是有著事件變化的物件做綁定時時,我們可以使用 v-on
,或者是 @
做縮寫的特殊指令,如下方程式所示:
<script setup>
import { ref } from 'vue'
const count = ref(0)
function increment() {
count.value++
}
</script>
<template>
// v-on: 與 @ 的功能完全相同,可任選使用
<button @click="increment">Count is: {{ count }}</button>
</template>
考量到 v-on
經常與 v-bind
同時出現,且使用到的資料往往相同,我們可以使用 v-model
來一次結合兩者的作用:
<script setup>
import { ref } from 'vue'
const text = ref('')
function onInput(e) {
text.value = e.target.value
}
</script>
<template>
// 下方使用 v-model 代替「:value="text" @input="onInput"」
// 因兩者皆與 text 物件相關
<input v-model="text" placeholder="Type here">
<p>{{ text }}</p>
</template>
寫過程式的人肯定都對 if-else
判斷式感到很熟悉吧,Vue.js 在顯示html元件時也可以加入類似的判斷式,也就是特殊指令 v-if
與 v-else
。前者將會判斷其參數的真值,若為真(true)便會顯示該元件,反之則不顯示。如果 v-if
的元件未顯示,v-else
的才會出現在畫面之中。順待一題,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>
既然有了判斷式,那麼想必也將少不了迴圈了!沒錯,Vue.js 有著 v-for
迴圈的指令,語法與其他語言相似,筆者就不做細部說明了。
<script setup>
import { ref } from 'vue'
// give each todo a unique id
let id = 0
const todos = ref([
{ id: id++, text: 'Learn HTML' },
{ id: id++, text: 'Learn JavaScript' },
{ id: id++, text: 'Learn Vue' }
])
</script>
<template>
<ul>
<li v-for="todo in todos" :key="todo.id">
{{ todo.text }}
</li>
</ul>
</template>
陣列往往與迴圈一併出現,因此筆者在此給出了一個簡單的陣列新增與刪除的小範例(參考了Vue.js官方的 Tutorial | List Rendering ):
<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.id != todo.id)
}
</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>