# v-model(資料雙向綁定) ## input ex: 當 v-model 與不同類型搭配時,所產生的資料格式也不太相同。 ``` ##<h3>input</h3> <input type="text" class="form-control" v-model="name"> {{ name }} <!-- input 直接綁定 v-model="name" 時, 可以直接對應到 data 的值 , 所以當 input 做變更時,資料就會直接雙向綁定(同時做更動);如下圖--> ``` ![](https://i.imgur.com/Vd0jfoD.jpg) ``` <script> const App = { data() { return { name: '小明', } }, }; Vue.createApp(App) .component('list-item', { template: ` <li> {{ item.name}} / {{ item.price }} 元 </li> `, props: ['item'] }).mount('#app'); </script> ``` --------------------------------------------------------------------------- ## textarea ``` ##<h3>textarea</h3> <textarea cols="30" rows="3" class="form-control" v-model="text"> </textarea> {{ text }} <!-- 同 input 一樣 --> ``` ![](https://i.imgur.com/TmU4zRB.jpg) ``` <script> const App = { data() { return { text: '一段文字敘述', } }, }; Vue.createApp(App) .component('list-item', { template: ` <li> {{ item.name}} / {{ item.price }} 元 </li> `, props: ['item'] }).mount('#app'); </script> ``` --------------------------------------------------------------------------- ## checkbox 單選框 ``` ##<h3>checkbox 單選框</h3> <p>小明,你是吃飽沒?</p> <p>{{ checkAnswer ? '吃飽了' : '還沒'}}</p> // 三元運算子: checkAnswer ?(是否成立) '吃飽了(true)':'還沒(false)') <p>{{ checkAnswer}}</p> <div class="form-check"> <input type="checkbox" v-model="checkAnswer" class="form-check-input" id="check1" > <!-- 若是綁定到單一一個 <input type="checkbox" >的話,會以布林值的方式作呈現(true || false) ; 所以當 v-model=" " 代入 checkAnswer 時,會是 (true || false) 的結果,在利用 input 本身 有 onchange event 特性,做 (true || false) 切換--> <label class="form-check-label" for="check1">小明回覆</label> </div> ``` ps.當為 true 時,則是 `<input type="checkbox" >` 為 打勾 狀態:如下圖 ![](https://i.imgur.com/gSdk8dL.jpg) 反之 ![](https://i.imgur.com/EWsln9X.jpg) --- ``` ##<h3>checkbox 單選延伸</h3> <p>小明,你是吃飽沒?</p> <p>{{ checkAnswer2 }}</p> <div class="form-check"> <input type="checkbox" v-model="checkAnswer2" true-value="吃飽了" false-value="還沒" class="form-check-input" id="check2" > <!-- 也可以利用 true-value="吃飽了" 以及 false-value="還沒" 的方式,將文字進行單選的切換 ; 同樣可以獲得一樣的效果 --> <label class="form-check-label" for="check2">小明回覆</label> </div> ``` ps. data()內的 checkAnswer2 須先預設為空字串 ; 如右: checkAnswer2: '' ``` <script> const App = { data() { return { checkAnswer: false, checkAnswer2: '', } }, }; Vue.createApp(App) .component('list-item', { template: ` <li> {{ item.name}} / {{ item.price }} 元 </li> `, props: ['item'] }).mount('#app'); </script> ``` --------------------------------------------------------------------------- ## checkbox 複選框 ex: 當 checkbox 遇到複選時?? ``` ##<h3>checkbox 複選框</h3> <p>你還要吃什麼?</p> <p>{{ checkAnswer3.join('、') }}</p> <div class="form-check"> <input type="checkbox" v-model="checkAnswer3" class="form-check-input" id="check3" **value="蛋"** > <label class="form-check-label" for="check3">蛋餅</label> </div> <div class="form-check"> <input type="checkbox" v-model="checkAnswer3" class="form-check-input" id="check4" **value="蘿蔔"** > <label class="form-check-label" for="check4">蘿蔔糕</label> </div> <div class="form-check"> <input type="checkbox" v-model="checkAnswer3" class="form-check-input" id="check5" **value="漿"** > <label class="form-check-label" for="check5">豆漿</label> </div> ※ 在複選上是對應 value=" " 這個裡面的值,所以可將 v-model=" " 綁定的資料格式設為空陣列,如右: checkAnswer3: []。 ; 所以當勾選 <input type="checkbox"> 這個選項時,裡面的值就會被代入到 checkAnswer3: [] 這個空陣列內;反之當取消勾選時,也會自動移除(如下圖) ``` ![](https://i.imgur.com/Y2mHKoj.jpg) ``` <script> const App = { data() { return { checkAnswer3: [], } }, }; Vue.createApp(App) .component('list-item', { template: ` <li> {{ item.name}} / {{ item.price }} 元 </li> `, props: ['item'] }).mount('#app'); </script> ``` --- ## radio 單選框 ``` ##<h3>radio 單選框</h3> <p>你還要吃什麼?</p> <p>{{ radioAnswer }}</p> <div class="form-check"> <input type="radio" v-model="radioAnswer" class="form-check-input" id="radio1" value="餅" > <label class="form-check-label" for="radio1">蛋餅</label> </div> <div class="form-check"> <input type="radio" v-model="radioAnswer" class="form-check-input" id="radio2" value="糕" > <label class="form-check-label" for="radio2">蘿蔔糕</label> </div> <div class="form-check"> <input type="radio" v-model="radioAnswer" class="form-check-input" id="radio3" value="豆" > <label class="form-check-label" for="radio3">豆漿</label> </div> ``` PS. radio 跟 checkbox 不同的地方在於, radio 是屬於單選框,而 checkbox 是屬於複選框; 當 radio 出現時,data() 定義的資料為單一個值。 假設我在資料結構內先預設 radioAnswer: '蛋餅'時,他在畫面上的預設值就是 蛋餅 :如下圖 ![](https://i.imgur.com/O7tBi8R.jpg) 當我選擇其他選項時,他不是以陣列的方式加入到這個欄位裡 `<p>{{ radioAnswer }}</p>` ; 而是用 複寫的方式將原有的資料欄位覆寫過去:如下圖 ![](https://i.imgur.com/7uyOqj4.jpg) ``` <script> const App = { data() { return { radioAnswer: '蛋餅', } }, }; Vue.createApp(App) .component('list-item', { template: ` <li> {{ item.name}} / {{ item.price }} 元 </li> `, props: ['item'] }).mount('#app'); </script> ``` --- ## select 單選 ``` ##<h3>select 單選</h3> <p>你還要吃什麼?</p> <p>{{ selectAnswer }}</p> <select class="form-select" v-model="selectAnswer"> <!-- 將 v-model 綁定到 select 資料欄位上 --> <option value="" disabled>說吧,你要吃什麼?</option> <option :value="it.name" v-for="it in products" :key="it.name" >{{it.name}}/{{it.price}}</option> <!-- select 的資料欄位是在 option 標籤 value=" " 裡,所以當 select 在做選擇時, 他其實是把 option 標籤裡的 value="值" , 加入到 data()資料的 selectAnswer:' ' 裡面, 並將其值代出--> </select> ``` PS.可將 option 標籤使用 v-for="it in products",代出 products 裡面的資料並賦予到 it 參數上,作為 option 的選項;如下圖 ![](https://i.imgur.com/7x3QFYc.png) 必須特別注意一點的是,只要有使用 v-for 就要加上 :key= " "的值(綁定的 key 必須是唯一值),之後在定義一個 value 的值,將其綁定後;畫面上渲染的部分就會呈現 name 屬性名稱的值: 如下圖 ![](https://i.imgur.com/KXzwcMx.jpg) 為什麼使用 v-for 時,需要綁定 key 值呢? ** 因為在用 v-for 迴圈常會搭配 key 綁值, key 的用途就是用來辨識 virtual DOM 的更新情況,其中 virtual DOM 的特性之一就是會重複使用原本的組件,要更新時不會整個組件的 DOM 元素砍掉然後再全部渲染一次,而是只更新部分資料,這樣做可以提升效能。 ** ``` <script> const App = { data() { return { selectAnswer: '', products: [ { name: '蛋餅', price: 30, vegan: false }, { name: '飯糰', price: 35, vegan: false }, { name: '小籠包', price: 60, vegan: false }, { name: '蘿蔔糕', price: 30, vegan: true }, ], } }, methods: { reverseArray: function () { this.products.reverse(); }, }, }; Vue.createApp(App) .component('list-item', { template: ` <li> {{ item.name}} / {{ item.price }} 元 </li> `, props: ['item'] }).mount('#app'); </script> ``` --- ## select 多選 ``` <h3>select 多選</h3> <p>你還要吃什麼?</p> <p>{{ selectAnswer2 }}</p> <select class="form-select" v-model="selectAnswer2" multiple> <!-- 將data()資料的 selectAnswer2:'[ ]' 設為一個空陣列,並將其綁定在 select 的資料欄位上 v-model="selectAnswer2" ; 若要將 select 改為多選的情況下,只須將欄位內添加 **multiple** 之後就會變成多選的選項,那他的資料結果就是一個陣列形式--> <option selected disabled value="">說吧,你要吃什麼?</option> <option :value="item.name" v-for="item in products" :key="item.name"> {{item.name}} / {{item.price}} 元</option> </select> ``` ![](https://i.imgur.com/5UeaNjI.jpg) ``` <script> const App = { data() { return { selectAnswer2: [], products: [ { name: '蛋餅', price: 30, vegan: false }, { name: '飯糰', price: 35, vegan: false }, { name: '小籠包', price: 60, vegan: false }, { name: '蘿蔔糕', price: 30, vegan: true }, ], } }, methods: { reverseArray: function () { this.products.reverse(); }, }, }; Vue.createApp(App) .component('list-item', { template: ` <li> {{ item.name}} / {{ item.price }} 元 </li> `, props: ['item'] }).mount('#app'); </script> ``` --- # v-model修飾符 修飾符是在 v-model 的後方增加一個 點 再加上特定的字串;如右 : v-model.xxx = " " 第一個: v-model.lazy = " " 其用途: 當輸入文字時,資料庫不會馬上綁定(同步),需 點擊 外部區域或按壓 enter 後,判斷已完成輸入框事件時,才會作動 第二個: v-model.number = " " 其用途: 確保輸入內容為存數值型別時,可以加上在 v-model 後方加上 number ;就可以確實轉為數值型別,但需要確定 `<input 的 type="number">`,他的運作才會比較正常。 第三個: v-model.trim = " " 其用途: 將資料內容的前後空白字元自動刪除