回到部落格

2024-02-20

【React-Vue】輸入欄位的資料綁定 (v-model)

【React-Vue】輸入欄位的資料綁定 (v-model)

原文發表於 Medium

若網頁有使用者須輸入的欄位,則時常需要資料綁定的技術

我們時常需要依照輸入的內容更改網頁狀態(State)(如變換文字內容或背景顏色等)。在React中,若要綁定使用者輸入欄位的資料到狀態值上,我們可以這樣寫:

import React, { useState } from 'react'

const App = () => {  
  const [name, setName] = useState("比利")  
  
  function onChangeHandler(e){  
    setName(e.target.value)  
  }  
  
  return (  
  <>  
  <h1>你的名字是<span style={{color:"blue"}}>{name}</span></h1>  
    <input value={name} onChange={onChangeHandler}/>  
  </>  
  )  
}  
  
  
export default App

效果如上方GIF所示。只要改變<input>的內容,就會讓顯示出來的名字不同。

在這個非常簡單的程式碼中,可以很容易發現到,在<input>中有兩個屬性:valueonChange,前者是將<input>的值跟name綁在一起;後者則是讓<input>輸入時觸發onChangeHandler函數,之後在函數內將輸入的event值設定為name的狀態值。

這就是React的「雙向綁定」(two-way binding)。

另外一個前端大咖Vue.js大笑三聲說道:「太嫩了,我內建雙向綁定!才不需要寫這麼多東西呢!」

另外一個前端大咖Vue.js大笑三聲說道:「太嫩了,我內建雙向綁定!才不需要寫這麼多東西呢!」

且看Vue.js怎麼寫出相同的效果:

<template> <div> <h1>你的名字是 <span style="color: blue">{{ name }}</span></h1> <input v-model="name" /> </div> </template>
<script setup>  
import { ref } from 'vue';  
  
const name = ref('比利');  
  
</script>

天啊!確實是很簡潔有力的寫法!input裡面居然只有一個屬性v-model !然後在<script>中居然不需要任何handler函數來幫忙改變狀態值!!真的太方便了!

其實,v-model是個語法糖,為的是方便Vue的使用者進行資料綁定,在不使用它的時候 ,vue寫法也沒有高明到哪裡去:

<input
:value="name"
@input="event => name = event.target.value" />

{/*補充,上面的寫法已經是簡寫了,下面是不使用簡寫的情況  
    <input     
    v-bind:value="name"  
    v-on:input="event => name = event.target.value"  />  
*/}

從不斷簡化語法這件事情上,看得出來Vue框架的開發者真的非常貼心,讓開發方式更加平易近人,這樣的態度很值得React借鏡。

但建議Vue的學習者在過程中還是不要太貪快,隨時對程式碼的底層邏輯保持好奇心,因為不使用語法糖的原始寫法,有時可以應付一些特殊狀況,例如我也可以設定input不要雙向綁定:

<template> <div> <h1>你的名字是 <span style="color: blue">{{ name }}</span></h1> <input @input="event => name = event.target.value" /> <button @click="name=null">清除</button> </div> </template>
<script setup>  
import { ref } from 'vue';  
  
const name = ref('比利');  
  
</script>

我把原本input中的value屬性刪掉,然後在下方加了一個可以把name值清空的按鈕,整個網頁的運行狀況如下:

在按下清除按鈕後,標題的名字清除了,輸入欄位中的文字並沒有跟著清除,然後隨著新一波的鍵盤輸入,標題的欄位又會馬上重新呈現輸入欄位的內容。

你可能會說這是Bug,大部分時候這是對的,但萬一你的客戶就是要這樣的功能呢?又或者這個狀況就是你的前一手造成的,你不知道底層原理要怎麼修呢?下面是我們把:value屬性還給input之後的效果:

我們的清除按鈕總算有比較接近一般經驗中的功能了。

總結以上,由於Vue有v-model這個神器,因此它可以簡單地實現資料的雙向綁定,而不須像React一樣需要手動綁住value值跟輸入事件的觸發動作。但無論是使用哪個框架技術,我們都要理解資料綁定狀態的基礎邏輯與概念。這樣跨框架跟跳槽比較方便啦!(誤。

最後,其實v-model還不只這樣的用法,它還可以用作類似React Props的方式,來達成跨元件的資料傳輸。但因為篇幅的關係,期待在下一篇中跟大家好好討論一下。

如果覺得我的文章不錯的話,還請給我幾個掌聲,你的支持是我繼續寫下去的動力!!