iT邦幫忙

2021 iThome 鐵人賽

DAY 29
0
Modern Web

Vue.js 什麼意思系列 第 29

Day 29:神奇語法糖-v-model

整個系列都快要完結篇了,怎麼可能獨漏 Vue 的神奇語法糖—— v-model 呢?我們已經知道 Vue 基於 MVVM 架構模式,最大的特色就是可以將資料與畫面進行雙向綁定並同步更新,而 v-model 正是運用在表單元素如 <input>、<textarea>、<select> 的神奇連動語法,使用之前先來了解一下概念與規則:

  • 需在元件內的 data 聲明初始值:v-model 會忽略表單元素的初始值如 value、checked 等,因此需在 data 聲明初始值作為 v-model 的綁定值

    data() {
      return {
        inputText: "",
      };
    },
    
  • 一般在元件內的 <input> 使用 v-model

    <pre>@input 即時顯示輸入內容:{{ inputText }}</pre>
    <label>搜尋:
        <input type="text" v-model="inputText" />
    </label>
    

    相當於 v-model = v-on:input + v-bind:value:監聽表單元素的即時變化

    <input type="text" :value="inputText" @input="value = $event.target.value" />
    

    input

  • 結尾加上修飾符的 v-model.lazy

    <pre>@change 失去聚焦後才確認輸入內容:{{ inputText }}</pre>
    <label>搜尋:
        <input type="text" v-model.lazy="inputText" />
    </label>
    

    相當於 v-model = v-on:change + v-bind:value:監聽表單元素失去聚焦後的變化

    <input type="text" :value="inputText" @change="value = $event.target.value" />
    

    before change
    after change

在元件上使用 v-model

以我們現有在 BookList.vue 中的搜尋欄位為例,原本在 Day 23 中示範將事件從子元件 $emit 拋給父元件處理:

<!-- 子元件 -->
<label>搜尋書本:
	<input
		type="text"
		:value="inputText"
		@input="$emit('searchBook', $event)"
	/>
</label>

<!-- 父元件 -->
<BookList
	navTitle="All"
	:bookList="books"
	:inputText="searchText"
	@searchBook="searchText = $event.target.value"
/>

若改為在父元件使用 v-model,則需將子元件的 $emit 事件名稱修改為原始的 input 事件,綁定值也是原始的 value,以供父元件透過 v-model 監聽 input 事件,再將監聽結果更新到 value,再 prop 給子元素渲染出結果。

<!-- 子元件 -->
<label>搜尋書本:
	<input
		type="text"
		:value="value"
		@input="$emit('input', $event.target.value)"
	/>
</label>

<!-- 父元件 -->
<BookList
	navTitle="All"
	:bookList="books"
	v-model="searchText"
/>

補充:update:myPropName

v-model 使用起來確實很方便,但每個人對於語法的掌握度和使用上的熟練程度不同,都會影響偏好的方式;若是習慣拆分成 v-onv-bind 使用上也相對靈活,方便處理細部的調整,個別對事件和資料進行設定的主控性相對較高。

至於 v-onv-bind 的管理,Vue 也有推薦可以使用 update:myPropName 模式為事件命名,這樣便能讓事件名稱和 prop 相互呼應,在元件中使用也可以一目了然兩者之間的關聯性。

<!-- 子元件 -->
<label>搜尋書本:
	<input
		type="text"
		:value="keyword"
        @input="$emit('update:keyword', $event)"
	/>
</label>

<!-- 父元件 -->
<BookList
	navTitle="All"
	:bookList="books"
	:keyword="searchText"
    @update:keyword="searchText = $event.target.value"
/>

參考資料


上一篇
Day 28:順手挖洞給 i 跳-vue-i18n
下一篇
Day 30:Keep Going 的意思
系列文
Vue.js 什麼意思30

尚未有邦友留言

立即登入留言