在第五天,我要示範如何將輸入欄位和核取方塊(checkbox)雙向綁定到響應式(reactive)狀態。當你在輸入欄位編輯數值時,對應的狀態會即時更新並顯示在畫面上。
在 script 區塊中,新增要綁定的 ref 變數。newItem 會綁定到輸入欄位,newItemHighPriority 則綁定到勾選方塊。
<script setup lang="ts">
import { Icon } from "@iconify/vue";
import { ref } from 'vue';
const newItem = ref('');
const newItemHighPriority = ref(false);
</script>
<template>
  <input v-model.trim="newItem" name="newItem" />
  {{ newItem }}
  <label>
    <input type="checkbox" v-model="newItemHighPriority" name="newItemHighPriority" />
    High Priority
  </label>
  {{ newItemHighPriority }}
</template>
v-model.trim 指令會在將值賦予 newItem 這個 ref 之前,先對文字輸入進行去除前後空白的處理。臨時加入的 mustache 語法 {{ newItem }} 是用來驗證的。當文字輸入欄位收到新值時,newItem 也會隨之更新。
v-model 指令則綁定到核取方塊。因為 newItemHighPriority 的初始值是 false,核取方塊預設未被勾選。當核取方塊被勾選時,newItemHighPriority 會更新為 true,且 {{ newItemHighPriority }} 會顯示 true。
在 script 區塊中宣告兩個 $state 變數,分別代表輸入內容和勾選狀態。
<script lang="ts">
let newItem = $state('');
let newItemHighPriority = $state(false);
</script>
<input bind:value={newItem} name="newItem" />
{ newItem }
<label>
  <input type="checkbox" name="newItemHighPriority" bind:checked={newItemHighPriority} />
  High Priority
</label>
{ newItemHighPriority }
bind:value 語法會將文字輸入欄位綁定到 newItem 這個 rune。暫時加入的 { newItem } 表達式是用來驗證。當文字輸入欄位收到新值時,newItem 也會同步更新。
bind:checked 指令則綁定到 newItemHighPriority 這個 rune。因為該 rune 的初始值是 false,核取方塊預設未勾選。當核取方塊被勾選時,newItemHighPriority rune 的值會更新為 true,且 { newItemHighPriority } 會顯示 true。
在 ShoppingCartComponent 裡聲明 newItem 和 newItemHighPriority 兩個 signals,型別分別為 string 及 boolean。getter 函式可以取得目前狀態並顯示在畫面上。
import { ChangeDetectionStrategy, Component, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
@Component({
  selector: 'app-shopping-cart',
  imports: [FormsModule],
  viewProviders: [],
  template: `
    <input type="text" name="newItem" [(ngModel)]="newItem" /> {{ newItem() }}
    <label>
      <input type="checkbox" [(ngModel)]="newItemHighPriority" name="newItemHighPriority" />
      High Priority
    </label>
    {{ newItemHighPriority() }}
  `,
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class ShoppingCartComponent {
  newItem = signal('');
  newItemHighPriority = signal(false);
}
在 ShoppingCartComponent 類別中,我從 @angular/forms 匯入了 FormsModule。Component 裝飾器的 imports 陣列中加入 FormsModule,使 HTML 輸入欄位能夠綁定到 signals。[(ngModel)]="newItem" 將文字輸入欄綁定到 newItem,而 [(ngModel)]="newItemHighPriority" 將核取方塊綁定到 newItemHighPriority。
當 HTML 輸入欄位收到新值時,mustache 語法會顯示 signal 的當前值。
現在我們成功在購物車元件中,分別以不同框架(Vue、Svelte、Angular)實作了表單輸入欄位與勾選框的雙向綁定,以及響應式狀態顯示。