2024-09-27|閱讀時間 ‧ 約 21 分鐘

EP19 - ex5. Form Bindings

終於來到第五個範例表格綁定摟!
表格的所有應用都可以綁定~
這次範例可以看到很多表單元件摟!
<script setup>
import { ref } from 'vue'

const text = ref('Edit me')
const checked = ref(true)
const checkedNames = ref(['Jack'])
const picked = ref('One')
const selected = ref('A')
const multiSelected = ref(['A'])
</script>

<template>
<p>Example 5:</p>
<h2>Text Input</h2>
<input v-model="text">
<p>{{ text }}</p>

<h2>Checkbox</h2>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">Checked: {{ checked }}</label>

<!--
multiple checkboxes can bind to the same
array v-model value
-->
<h2>Multi Checkbox</h2>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<p>Checked names: {{ checkedNames }}</p>

<h2>Radio</h2>
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<p>Picked: {{ picked }}</p>

<h2>Select</h2>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>Selected: {{ selected }}</p>

<h2>Multi Select</h2>
<select v-model="multiSelected" multiple style="width:100px">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>Selected: {{ multiSelected }}</p>
</template>

<script setup>

  • script setup 是 Vue 3 的組件語法糖,可以更簡潔地撰寫組件的邏輯。
  • vue 導入 ref 函數,ref 用於創建響應式的變數。

使用 ref 創建響應式變數:

<script setup>
import { ref } from 'vue'
const text = ref('Edit me')
const checked = ref(true)
const checkedNames = ref(['Jack'])
const picked = ref('One')
const selected = ref('A')
const multiSelected = ref(['A'])
</script>
  1. text 初始化為 'Edit me'
  2. checked 初始化為 true
  3. checkedNames 初始化為包含 'Jack' 的陣列。
  4. picked 初始化為 'One'
  5. selected 初始化為 'A'
  6. multiSelected 初始化為包含 'A' 的陣列。

<template>

  • template 區塊內是組件的 HTML 結構。

Text Input

<h2>Text Input</h2>
<input v-model="text">
<p>{{ text }}</p>
  1. 使用 <h2> 標籤顯示 "Text Input" 標題。
  2. 使用 <input> 標籤與 v-model 雙向綁定 text 變數,使其成為可編輯的輸入框。
  3. 使用 <p> 標籤顯示 text 變數的當前值。

Checkbox

<h2>Checkbox</h2>
<input type="checkbox" id="checkbox" v-model="checked">
<label for="checkbox">Checked: {{ checked }}</label>
  1. 使用 <h2> 標籤顯示 "Checkbox" 標題。
  2. 使用 <input> 標籤創建一個 checkbox,v-model 雙向綁定 checked 變數。
  3. 使用 <label> 標籤顯示 checked 變數的當前值。

Multi Checkbox

<h2>Multi Checkbox</h2>
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<label for="jack">Jack</label>
<input type="checkbox" id="john" value="John" v-model="checkedNames">
<label for="john">John</label>
<input type="checkbox" id="mike" value="Mike" v-model="checkedNames">
<label for="mike">Mike</label>
<p>Checked names: {{ checkedNames }}</p>
  1. 使用 <h2> 標籤顯示 "Multi Checkbox" 標題。
  2. 使用多個 <input> 標籤創建多個 checkbox,每個 checkbox 的 value 屬性設定不同的名字,並且 v-model 雙向綁定 checkedNames 陣列。這允許多個 checkbox 共享同一個數組。
  3. 使用多個 <label> 標籤顯示對應 checkbox 的名稱。
  4. 使用 <p> 標籤顯示 checkedNames 陣列的當前值。

Radio

<h2>Radio</h2>
<input type="radio" id="one" value="One" v-model="picked">
<label for="one">One</label>
<br>
<input type="radio" id="two" value="Two" v-model="picked">
<label for="two">Two</label>
<p>Picked: {{ picked }}</p>
  1. 使用 <h2> 標籤
  2. 顯示 "Radio" 標題。
  3. 使用多個 <input> 標籤創建多個 radio 按鈕,每個 radio 按鈕的 value 屬性設定不同的值,並且 v-model 雙向綁定 picked 變數。這允許在多個 radio 按鈕中選擇一個。
  4. 使用多個 <label> 標籤顯示對應 radio 按鈕的選項。
  5. 使用 <br> 標籤換行。
  6. 使用 <p> 標籤顯示 picked 變數的當前值。

Select

<h2>Select</h2>
<select v-model="selected">
<option disabled value="">Please select one</option>
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>Selected: {{ selected }}</p>
  1. 使用 <h2> 標籤顯示 "Select" 標題。
  2. 使用 <select> 標籤創建一個下拉選單,v-model 雙向綁定 selected 變數。
  3. 使用多個 <option> 標籤定義選項,包括一個禁用的提示選項和三個有效選項 ABC
  4. 使用 <p> 標籤顯示 selected 變數的當前值。

Multi Select

<h2>Multi Select</h2>
<select v-model="multiSelected" multiple style="width:100px">
<option>A</option>
<option>B</option>
<option>C</option>
</select>
<p>Selected: {{ multiSelected }}</p>
  1. 使用 <h2> 標籤顯示 "Multi Select" 標題。
  2. 使用 <select> 標籤創建一個多選下拉選單,v-model 雙向綁定 multiSelected 陣列,multiple 屬性允許多選,並設置樣式使其寬度為 100px。
  3. 使用多個 <option> 標籤定義選項 ABC
  4. 使用 <p> 標籤顯示 multiSelected 陣列的當前值。
看過表單的綁定之後,更有感覺了!
好像真的不難~只是一開始的不習慣而已www
至少v-model好像比較懂了www

[補充] v-model還有什麼用處?修飾符

除了基本的雙向綁定功能,v-model 還有一些特別的特性和用法:

  • .lazy:只在 change 事件後同步數據,而不是在每次 input 事件後立即同步。
  • .number:將輸入值自動轉換為數字。
  • .trim:自動過濾輸入值兩端的空格。
<input v-model.lazy="text">
<input v-model.number="age">
<input v-model.trim="name">

[補充] 自定義組件上的 v-model

在 Vue 3 中,v-model 不僅可以用在原生表單元素上,還可以用在自定義組件上。當你使用 v-model 綁定一個自定義組件時,實際上是綁定了組件的一個特殊的 modelValue 屬性,並且該組件需要觸發一個 update:modelValue 事件來通知父組件值的變化。

父組件的使用方式

在父組件中,我們可以這樣使用 v-model 綁定自定義組件:

<MyComponent v-model="myData"></MyComponent>

這樣 v-model 會綁定 MyComponent 組件的 modelValue 屬性,並且父組件中的 myData 變數將與子組件中的值進行雙向綁定。

子組件的實現方式

在子組件中,我們需要做以下幾件事:

  1. 聲明 modelValue 屬性:這是用來接收父組件傳遞過來的值。
  2. 監聽輸入變化並觸發 update:modelValue 事件:當輸入值改變時,觸發該事件來通知父組件更新值。

這是子組件的具體實現:

<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</template>

<script>
export default {
props: {
modelValue: {
type: String,
required: true
}
}
}
</script>


父組件:

<MyComponent v-model="myData"></MyComponent>

子組件:

<template>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
</template>

<script>
export default {
props: {
modelValue: String
}
}
</script>

完整示例

父組件

<template>
<div>
<h1>父組件</h1>
<p>父組件中的值: {{ parentData }}</p>
<MyComponent v-model="parentData"></MyComponent>
</div>
</template>

<script>
import { ref } from 'vue'
import MyComponent from './MyComponent.vue'

export default {
components: {
MyComponent
},
setup() {
const parentData = ref('')

return {
parentData
}
}
}
</script>

子組件 (MyComponent.vue)

<template>
<div>
<h2>子組件</h2>
<input :value="modelValue" @input="$emit('update:modelValue', $event.target.value)">
<p>子組件中的值: {{ modelValue }}</p>
</div>
</template>

<script>
export default {
props: {
modelValue: {
type: String,
required: true
}
}
}
</script>
  1. 父組件
    • parentData 是一個響應式變數,用於存儲父組件中的數據。
    • 使用 v-modelparentData 綁定到 MyComponent 組件。
  2. 子組件
    • 定義了一個 modelValue 屬性,這是 v-model 自動綁定的屬性。
    • <input> 標籤中,使用 :value="modelValue"modelValue 的值綁定到輸入框。
    • 當輸入框的值變化時,觸發 @input="$emit('update:modelValue', $event.target.value)",這將 input 事件的值發送給父組件,更新 parentData 的值。

這樣,父組件中的 parentData 和子組件中的 modelValue 就實現了雙向綁定。當子組件的輸入框中的值發生變化時,父組件中的 parentData 會自動更新,反之亦然。

啥咪父子?霧煞煞

在 Vue 中使用 v-model 時,是父組件控制和使用子組件的資料。具體來說,父組件將資料傳遞給子組件,子組件通過 v-model 的雙向綁定機制,將資料變動反饋給父組件。這樣就實現了父子組件之間的數據同步。

父組件使用子組件的資料

父組件傳遞初始資料給子組件,然後監聽子組件的變動,這是一個自上而下的資料流。

總結:

  • 父組件 負責傳遞資料給 子組件
  • 子組件 通過 v-model 將資料的變動反饋給 父組件
由於物件導向觀念是會先有父類別才會有子類別,
而這邊的父子跟那邊是不一樣的唷www
父組件和子組件之間的關係更像是一種組合(Composition),而不是繼承(Inheritance)。
分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.