Vue.js資料繫結

by vivid 26. 六月 2019 00:42

.NET Magazine國際中文電子雜誌
作 者:許薰尹
審 稿:張智凱
文章編號:
N190620802
出刊日期:2019/6/26

本文將延續本站《Vue.js入門》系列文章,介紹基本的資料繫結概念、各種表單欄位資料繫結,例如文字方塊、多行文字方塊、核取方塊、圓型按鈕、清單方塊等等繫結,以便讓你的網頁應用程式資料與DOM能夠同步,並進行雙向更新的動作。

 

雙向資料繫結

表單輸入項目、清單方塊、多行文字方塊等項目,可以利用「v-model」關鍵字建立與Vue之間的雙向繫結功能,設定「v-model」之後,Vue便會監聽輸入事件來更新資料,預設根據輸入項目的不同,將監聽不同的事件,例如:

  • 文字方塊(text)與多行文字方塊(textarea)項目:自動監聽「input」事件來更新「value」屬性。
  • 核取方塊(checkbox)與圓形按鈕(radiobutton):自動監聽「change」事件來更新「checked」屬性。
  • 清單方塊(select):自動監聽「change」事件來更新「value」屬性。

此外,我們也可以透過修飾詞(Modifier),例如「.lazy」來變更要監聽的事件,稍後再敘。

「v-model」關鍵字是使用靜態字串進行繫結,先讓我們看一個使用「v-model」關鍵字繫結的範例程式,參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Input data :
      <input type="text" v-model="msg" placeholder="請輸入訊息" value="Hello"/>
    </div>
    <br />
    <div> Message : {{msg}} </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>

    var vm = new Vue({
      el: '#divResult',
      data: { msg: null }
    });
  </script>
</body>

</html>


 

這個範例中包含一個文字方塊(<input type="text"/>)與一個<div>標籤,文字方塊與Vue實體的「msg」屬性建立了資料繫結動作。一旦建立了資料繫結,原來的文字方塊「value」設定的值就會被忽略掉,Vue實體會使用「msg」屬性的值,來蓋掉原來的文字方塊「value」預設的「Hello」字串,這個範例程式的執行結果請參考下圖所示:

clip_image002

圖 1:繫結到簡單的文字方塊範例。

網頁程式執行時,當你在文字方塊中輸入字串,輸入的字串馬上會出現在下方<div>標籤所在的位置,因為雙向繫結資料會自動同步,請參考下圖所示:

clip_image004

圖 2:雙向繫結資料會自動同步。

若想要設定文字方塊的預設值,則可修改「msg」屬性,例如將上例改寫如下,設定預設值為「hi」字串:

var vm = new Vue({
      el: '#divResult',
      data: { msg: 'hi' }
    });

 

網頁程式執行時,預設將看到以下畫面:

clip_image006

圖 3:設定繫結預設值。

多行文字方塊(textarea)繫結

除了可以繫結到單行文字方塊之外,Vue也支援多行文字方塊(textarea)繫結,下面的範例則展示如何使用「v-model」關鍵字繫結到多行文字方塊:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Input data :
      <textarea  v-model="msg" placeholder="請輸入多行訊息" rows='5'></textarea>
    </div>
    <br />
    <div> Message : {{msg}} </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>

    var vm = new Vue({
      el: '#divResult',
      data: { msg: undefined }
    });
  </script>
</body>

</html>

 

這個範例程式的執行結果參考如下,一開始網頁將會顯示多行文字方塊:

clip_image008

圖 4:多行文字方塊繫結範例。

在多行文字方塊「textarea」輸入多行文字資料之後,參考畫面呈現如下:

clip_image010

圖 5:多行文字方塊繫結。

核取方塊(checkbox)繫結

「checkbox」可在網頁上顯示方形的核取方塊,讓使用者以選擇方式取代輸入,讓使用者在 「true」 和「false」 兩種情況中二選一,或用在「on」或「off」情境。

以下的範例程式碼則展示如何使用「v-model」關鍵字繫結到一個核取方塊,來描述員工個婚姻狀況(Marital Status)是已婚(true)或未婚(false):

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input type="text" v-model="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Employee Info : {{ showInfo() }} </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus :true
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          return this.empId + "," + this.empName +"," + this.maritalStatus;
        }
      }
    });
  </script>

</body>

</html>

 

我們額外設計一個「showInfo」函式,將員工的「empId」、「empName」與「maritalStatus」屬性值串接成字串,並讓網頁下方的<div>顯示函式執行的結果。並利用「v-if」與「v-else」來決定:若「maritalStatus」屬性值為「true」時,將顯示「married」字串;若「maritalStatus」屬性值為「false」時,將顯示「unmarried」字串。這個範例程式的執行結果請參考下圖所示:

clip_image012

圖 6:核取方塊(checkbox)繫結範例。

核取方塊陣列(checkbox)繫結

若網頁表單畫面中需要使用多個核取方塊來設計多選的功能,你可以使用「v-model」關鍵字將多個核取方塊繫結到相同的陣列型別變數,參考以下範例程式碼,員工資料中包含了三個核取方塊描述員工興趣,它們都繫結到相同的「interests」陣列:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input type="text" v-model="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Interests :
      <input type="checkbox" id="interest1" value="swimming" v-model="interests">
      <label for="interest1"> Swimming </label>
      <input type="checkbox" id="interest2" value="reading" v-model="interests">
      <label for="interest2"> Reading </label>
      <input type="checkbox" id="interest3" value="walking" v-model="interests">
      <label for="interest3"> Walking </label>
    </div>
    <br />
    <div>
      <hr />
      Employee Info :
      <div v-html="showInfo()"> </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus: true,
      interests: []
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          return `Employee Id : ${this.empId} <br/>
            Employee Name : ${this.empName} <br/>
            Marital Status : ${this.maritalStatus} <br/>
            Interests : ${this.interests}`;
        }
      }
    });
  </script>

</body>

</html>

 

這個範例程式的執行結果請參考下圖所示,當核取員工的任一個興趣,便透過「showInfo」函式顯示在網頁下方:

clip_image014

圖 7:核取方塊陣列(checkbox)繫結範例。

圓型按鈕(radio)繫結

「radio」顯示圓形的按鈕,用來設計從一堆選項中,進行單選的動作。也因為同一群組的圓型按鈕,有互斥效果,僅能選擇一個,通常用來當作單選的問題選項,例如婚姻狀況選項。你可以使用「v-model」關鍵字將多個圓型按鈕繫結到相同的變數,參考以下範例程式碼,員工資料中包含二個圓型按鈕描述員工性別,它們都繫結到相同的「gender」變數,僅能夠做單選:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input type="text" v-model="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Interests :
      <input type="checkbox" id="interest1" value="swimming" v-model="interests">
      <label for="interest1"> Swimming </label>
      <input type="checkbox" id="interest2" value="reading" v-model="interests">
      <label for="interest2"> Reading </label>
      <input type="checkbox" id="interest3" value="walking" v-model="interests">
      <label for="interest3"> Walking </label>
    </div>
    <br />
    <div> Gender :
        <input type="radio" id="gender1" value="Male" v-model="gender">
        <label for="gender1"> Male </label>
        <input type="radio" id="gender2" value="Female" v-model="gender">
        <label for="gender2"> Female </label>
      </div>
      <br />
    <div>
      <hr />
      Employee Info :
      <div v-html="showInfo()"> </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus: true,
      interests: [],
      gender : 'Male'
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          return `Employee Id : ${this.empId} <br/>
            Employee Name : ${this.empName} <br/>
            Marital Status : ${this.maritalStatus} <br/>
            Interests : ${this.interests} <br/>
            Gender : ${this.gender}
            `;
        }
      }
    });
  </script>

</body>

</html>

 

這個範例程式的執行結果請參考下圖所示,當核取員工的性別,便透過「showInfo」函式顯示在網頁下方:

clip_image016

圖 8:圓型按鈕(radio)繫結範例。

清單方塊(select)繫結 - 單選

「select」清單方塊可以包含多個項目,並且在網頁上顯示一個清單方塊,能夠讓使用者選擇其中的一個或多個項目。參考以下範例程式碼,為員工資料提供一個「select」清單,以輸入員工最高教育程度(Highest Education Level),此清單繫結到「education」屬性,僅能從清單中做單選:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input type="text" v-model="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Interests :
      <input type="checkbox" id="interest1" value="swimming" v-model="interests">
      <label for="interest1"> Swimming </label>
      <input type="checkbox" id="interest2" value="reading" v-model="interests">
      <label for="interest2"> Reading </label>
      <input type="checkbox" id="interest3" value="walking" v-model="interests">
      <label for="interest3"> Walking </label>
    </div>
    <br />
    <div> Gender :
        <input type="radio" id="gender1" value="Male" v-model="gender">
        <label for="gender1"> Male </label>
        <input type="radio" id="gender2" value="Female" v-model="gender">
        <label for="gender2"> Female </label>
      </div>
    <br />
    <div> Highest Education Level :
        <select v-model="education">
            <option disabled value="">Please select one</option>
            <option>Bachelor</option>
            <option>Master</option>
            <option>Doctoral Degree</option>
          </select>
      </div>
      <br />
    <div>
      <hr />
      Employee Info :
      <div v-html="showInfo()"> </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus: true,
      interests: [],
      gender : 'Male',
      education: ''
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          return `Employee Id : ${this.empId} <br/>
            Employee Name : ${this.empName} <br/>
            Marital Status : ${this.maritalStatus} <br/>
            Interests : ${this.interests} <br/>
            Gender : ${this.gender} <br/>
            Highest Education Level  : ${this.education} <br/>
            `;
        }
      }
    });
  </script>

</body>

</html>

 

這個範例程式的執行結果請參考下圖所示:

clip_image018

圖 9:清單方塊(select)繫結 - 單選範例。

清單方塊(select)繫結 - 多選

「select」也可以設計多選的操作界面,預設的外觀如一個下拉式清單,讓使用者能夠從下拉式清單中選取某個項目,只要在「select」標籤設定「multiple」,它的外觀就會轉變成方形的清單方塊,可以按CTRL鍵做多選的功能。參考以下範例程式碼,為員工資料提供一個駕照的清單(Driver Licence),繫結到「licence」,讓使用者複選員工的多種駕照資料:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input type="text" v-model="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Interests :
      <input type="checkbox" id="interest1" value="swimming" v-model="interests">
      <label for="interest1"> Swimming </label>
      <input type="checkbox" id="interest2" value="reading" v-model="interests">
      <label for="interest2"> Reading </label>
      <input type="checkbox" id="interest3" value="walking" v-model="interests">
      <label for="interest3"> Walking </label>
    </div>
    <br />
    <div> Gender :
        <input type="radio" id="gender1" value="Male" v-model="gender">
        <label for="gender1"> Male </label>
        <input type="radio" id="gender2" value="Female" v-model="gender">
        <label for="gender2"> Female </label>
      </div>
    <br />
    <div> Highest Education Level :
        <select v-model="education">
            <option disabled value="">Please select one</option>
            <option>Bachelor</option>
            <option>Master</option>
            <option>Doctoral Degree</option>
          </select>
      </div>
    <br />
    <div> Driver Licence  :
        <select v-model="licence" multiple>
            <option>Car license </option>
            <option>Motorcycle license</option>
          </select>
      </div>
      <br />
    <div>
      <hr />
      Employee Info :
      <div v-html="showInfo()"> </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus: true,
      interests: [],
      gender : 'Male',
      education: '',
      licence:[]
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          return `Employee Id : ${this.empId} <br/>
            Employee Name : ${this.empName} <br/>
            Marital Status : ${this.maritalStatus} <br/>
            Interests : ${this.interests} <br/>
            Gender : ${this.gender} <br/>
            Highest Education Level  : ${this.education} <br/>
            Car license  : ${this.licence} <br/>
            `;
        }
      }
    });
  </script>

</body>

</html>

 

這個範例程式的執行結果請參考下圖所示:

clip_image020

圖 10:清單方塊(select)繫結 - 多選範例。

動態產生多選清單方塊

若清單方塊的資料來自於遠端服務,或複雜運算的結果,我們可以動態產生多選清單方塊。通常會將要顯示的清單項目放在陣列之中,再利用「v-for」關鍵字跑迴圈,動態產生清單中的選項,參考以下範例程式碼,我們改寫上個駕照清單的範例,清單方塊的資料來源是「licenceOption」陣列:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input type="text" v-model="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Interests :
      <input type="checkbox" id="interest1" value="swimming" v-model="interests">
      <label for="interest1"> Swimming </label>
      <input type="checkbox" id="interest2" value="reading" v-model="interests">
      <label for="interest2"> Reading </label>
      <input type="checkbox" id="interest3" value="walking" v-model="interests">
      <label for="interest3"> Walking </label>
    </div>
    <br />
    <div> Gender :
      <input type="radio" id="gender1" value="Male" v-model="gender">
      <label for="gender1"> Male </label>
      <input type="radio" id="gender2" value="Female" v-model="gender">
      <label for="gender2"> Female </label>
    </div>
    <br />
    <div> Highest Education Level :
      <select v-model="education">
        <option disabled value="">Please select one</option>
        <option>Bachelor</option>
        <option>Master</option>
        <option>Doctoral Degree</option>
      </select>
    </div>
    <br />
    <div> Driver Licence :
      <select v-model="licence" multiple>
        <option v-for="o in licenceOption" v-bind:value="o.value">{{ o.text }}</option>
      </select>
    </div>
    <br />
    <div>
      <hr />
      Employee Info :
      <div v-html="showInfo()"> </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus: true,
      interests: [],
      gender: 'Male',
      education: '',
      licence: [],
      licenceOption: [{ text: 'Car license', value:'1' }, { text: 'Motorcycle license', value:'2' }]
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          return `Employee Id : ${this.empId} <br/>
            Employee Name : ${this.empName} <br/>
            Marital Status : ${this.maritalStatus} <br/>
            Interests : ${this.interests} <br/>
            Gender : ${this.gender} <br/>
            Highest Education Level  : ${this.education} <br/>
            Car license  : ${this.licence} <br/>
            `;
        }
      }
    });
  </script>

</body>

</html>

 

這個範例程式的執行結果請參考下圖所示:

clip_image022

圖 11:動態產生多選清單方塊範例。

使用「v-bind」關鍵字繫結

Vue還提供一個「v-bind」關鍵字,也可用於資料繫結。「v-model」繫結的行為實際上等同於使用「v-bind」關鍵字繫結再加上「v-on」關鍵字註冊相關事件。例如本文的第一個使用「v-model」關鍵字進行表單項目雙向繫結的範例,可以將之改寫如下,使用「v-bind」、「v-on」關鍵字,將會得到一樣的執行結果:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Input data :
      <input type="text" placeholder="請輸入訊息" v-bind:value="msg" v-on:input="msg = $event.target.value" />
    </div>
    <br />
    <div> Message : {{msg}} </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#divResult',
      data: { msg: null }
    });
  </script>
</body>

</html>

 

「v-on」關鍵字註冊了「input」事件,在文字方塊輸入的內容變動時,就會觸發「input」事件,再透過「msg = $event.target.value」這行JavaScript程式碼,將文字方塊輸入的值同步到「msg」屬性。換言之,「v-bind:value」類似單向資料繫結,「msg」的值會更新到文字方塊,若沒有註冊「input」事件,文字方塊輸入的內容,將不會更新回「msg」。這個範例程式的執行結果請參考圖一。

繫結到HTML Attribute

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <ul>
      <li>
        <a v-bind:href="href[0]"> Google </a>
      </li>
      <li>
        <a v-bind:href="href[1]"> Microsoft </a>
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#divResult',
      data: { href: ['http://www.google.com', 'http://www.microsoft.com'] }
    });
  </script>
</body>

</html>

這個範例程式的執行結果參考如下:

clip_image024

圖 12:繫結到HTML Attribute範例。

「v-bind」簡寫語法

「v-bind」關鍵字有一個替代性的簡寫語法,使用「:」符號,參考以下範例程式碼,改寫上個範例,這個範例程式的執行結果同上圖。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <ul>
      <li>
        <a :href="href[0]"> Google </a>
      </li>
      <li>
        <a :href="href[1]"> Microsoft </a>
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#divResult',
      data: { href: ['http://www.google.com', 'http://www.microsoft.com'] }
    });
  </script>
</body>

</html>

 

繫結到CSS樣式

使用「v-bind:class」語法可以繫結到HTML 項目的「class」 attribute,用來設定CSS自訂類別。參考以下範例程式碼,在<style>區塊中定義一個CSS自訂類別「myclass」:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
    .myclass {
      background-color: lightblue;
    }
  </style>
</head>

<body>
  <div id="divResult">
    <ul>
      <li v-bind:class="{myclass:setBgColor}">
        <a :href="href[0]"> Google </a>
      </li>
      <li v-bind:class="{myclass:!setBgColor}">
        <a :href="href[1]"> Microsoft </a>
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#divResult',
      data: {
        href: ['http://www.google.com', 'http://www.microsoft.com'],
        setBgColor: true
      }
    });
  </script>
</body>

</html>

 

網頁中的<li>項目建立了與「setBgColor」屬性之間的繫結,當「setBgColor」的值為「true」時,這段程式碼「v-bind:class="{myclass:true}"」會套用「myclass」類別,當「v-bind:class="{myclass:false}"」時便不會套用「myclass」類別,這個範例程式的執行結果請參考下圖所示:

clip_image026

圖 13:繫結到CSS樣式範例。

繫結到多個CSS樣式

若要套用兩個以上的CSS類別,可以將一個物件指派給「v-bind:class」,在這個物件中可以同時設定多個CSS屬性,參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
    .myclass {
      background-color: lightblue;
    }

    .myborder {
        border:  1px solid blue;
    }
  </style>
</head>

<body>
  <div id="divResult">
    <ul>
      <li v-bind:class="{myclass:setBgColor, myborder:setBorder}">
        <a :href="href[0]"> Google </a>
      </li>
      <li v-bind:class="{myclass:!setBgColor, myborder:setBorder}">
        <a :href="href[1]"> Microsoft </a>
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#divResult',
      data: {
        href: ['http://www.google.com', 'http://www.microsoft.com'],
        setBgColor: true,
        setBorder :true
      }
    });
  </script>
</body>

</html>

 

這個範例程式的執行結果請參考下圖所示,你可以看到兩個自訂樣式都套用在<li>項目上:

clip_image028

圖 14:繫結到多個CSS樣式範例。

另一種寫法則是指派一個包含自訂類別名稱的陣列給「v-bind:class」,參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
  <style>
    .myclass {
      background-color: lightblue;
    }
    .myborder {
      border: 1px solid blue;
    }
  </style>
</head>

<body>
  <div id="divResult">
    <ul>
      <li v-bind:class="[setBgColor,setBorder]">
        <a :href="href[0]"> Google </a>
      </li>
      <li v-bind:class="[setBgColor,setBorder]">
        <a :href="href[1]"> Microsoft </a>
      </li>
    </ul>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var vm = new Vue({
      el: '#divResult',
      data: {
        href: ['http://www.google.com', 'http://www.microsoft.com'],
        setBgColor: 'myclass',
        setBorder: 'myborder'
      }
    });
  </script>
</body>

</html>

 

使用修飾詞(Modifier)

Vue還提供三個修飾詞(Modifier)用來變更資料繫結的行為,包含以下:

  • 「.number」:用來將資料轉換成數值。
  • 「.trim」:去掉字串左右空白。
  • 「.lazy」:變更監聽的HTML項目事件,從預設的「input」事件,改為「change」事件。

我們先來看一下「.number」與「.trim」範例,參考以下範例程式碼:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input  v-model.number="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model.trim="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Interests :
      <input type="checkbox" id="interest1" value="swimming" v-model="interests">
      <label for="interest1"> Swimming </label>
      <input type="checkbox" id="interest2" value="reading" v-model="interests">
      <label for="interest2"> Reading </label>
      <input type="checkbox" id="interest3" value="walking" v-model="interests">
      <label for="interest3"> Walking </label>
    </div>
    <br />
    <div> Gender :
      <input type="radio" id="gender1" value="Male" v-model="gender">
      <label for="gender1"> Male </label>
      <input type="radio" id="gender2" value="Female" v-model="gender">
      <label for="gender2"> Female </label>
    </div>
    <br />
    <div> Highest Education Level :
      <select v-model="education">
        <option disabled value="">Please select one</option>
        <option>Bachelor</option>
        <option>Master</option>
        <option>Doctoral Degree</option>
      </select>
    </div>
    <br />
    <div> Driver Licence :
      <select v-model="licence" multiple>
        <option v-for="o in licenceOption" v-bind:value="o.value">{{ o.text }}</option>
      </select>
    </div>
    <br />
    <div>
      <hr />
      Employee Info :
      <div v-html="showInfo()"> </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus: true,
      interests: [],
      gender: 'Male',
      education: '',
      licence: [],
      licenceOption: [{ text: 'Car license', value: '1' }, { text: 'Motorcycle license', value: '2' }]
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          console.log(typeof this.empId)
          console.log(this.empId)
          return `Employee Id : ${this.empId} <br/>
            Employee Name : [${this.empName}] <br/>
            Employee Age : ${this.age} <br/>
            Marital Status : ${this.maritalStatus} <br/>
            Interests : ${this.interests} <br/>
            Gender : ${this.gender} <br/>
            Highest Education Level  : ${this.education} <br/>
            Car license  : ${this.licence} <br/>
            `;
        }
      }
    });
  </script>
</body>
</html>

 

「v-model.number」可以將字串轉型成數值型別,例如範例中顯示「empId」的「input」欄位沒有設定「type」,當你在文字方塊中輸入資料時,便自動利用「parseFloat」函式將之轉型,並回傳數值。我們在「showInfo」函式中,從印出除錯訊息可以知道目前「empId」的型別為「number」型別,這個範例程式的執行結果請參考下圖所示:

clip_image030

圖 15:使用修飾詞(Modifier)範例。

若文字方塊輸入的值,包含文字,例如「1a」,則回傳數值「1」,等同於叫用「parseFloat('1a')」函式得到數值「1」。若輸入文字方塊的值,無法透過「parseFloat」函式轉換,則回傳原始輸入的值,例如「parseFloat('a1')」的結果是「NaN」,因此當你在文字方塊輸入「1a」時,印出的型別會是「string」,印出的資料會是你輸入的「1a」,請參考下圖所示:

clip_image032

圖 16:使用修飾詞(Modifier)轉數值範例。

而「empName」則套用了「v-model.trim」修飾詞,因此在「Input」方塊中輸入員工名稱時,若前後有空白,則自動去除,這個範例程式的執行結果參考如下,網頁下方印出的員工名稱前後不含空白:

clip_image034

圖 17:使用修飾詞(Modifier)去左右空白。

因預設是監聽文字方塊的「Input」事件,因此這個範例只要在員工名稱輸入員工名稱,網頁下方會自動同步,顯示最新的員工名稱。最後我們再修改一下這個範例,在員工名稱「Input」方塊套用「.lazy」:

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title> Document </title>
</head>

<body>
  <div id="divResult">
    <div> Employee Id :
      <input  v-model.number="empId">
    </div>
    <br />
    <div> Employee Name :
      <input type="text" v-model.trim.lazy="empName">
    </div>
    <br />
    <div> Marital Status :
      <input type="checkbox" v-model="maritalStatus">
      <label v-if="maritalStatus"> married </label>
      <label v-else> unmarried </h1>
    </div>
    <br />
    <div> Interests :
      <input type="checkbox" id="interest1" value="swimming" v-model="interests">
      <label for="interest1"> Swimming </label>
      <input type="checkbox" id="interest2" value="reading" v-model="interests">
      <label for="interest2"> Reading </label>
      <input type="checkbox" id="interest3" value="walking" v-model="interests">
      <label for="interest3"> Walking </label>
    </div>
    <br />
    <div> Gender :
      <input type="radio" id="gender1" value="Male" v-model="gender">
      <label for="gender1"> Male </label>
      <input type="radio" id="gender2" value="Female" v-model="gender">
      <label for="gender2"> Female </label>
    </div>
    <br />
    <div> Highest Education Level :
      <select v-model="education">
        <option disabled value="">Please select one</option>
        <option>Bachelor</option>
        <option>Master</option>
        <option>Doctoral Degree</option>
      </select>
    </div>
    <br />
    <div> Driver Licence :
      <select v-model="licence" multiple>
        <option v-for="o in licenceOption" v-bind:value="o.value">{{ o.text }}</option>
      </select>
    </div>
    <br />
    <div>
      <hr />
      Employee Info :
      <div v-html="showInfo()"> </div>
    </div>
  </div>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.6.10/dist/vue.js"></script>
  <script>
    var o = {
      empId: 1,
      empName: 'Mary',
      maritalStatus: true,
      interests: [],
      gender: 'Male',
      education: '',
      licence: [],
      licenceOption: [{ text: 'Car license', value: '1' }, { text: 'Motorcycle license', value: '2' }]
    };
    var vm = new Vue({
      el: '#divResult',
      data: o,
      methods: {
        showInfo: function () {
          console.log(typeof this.empId)
          console.log(this.empId)

          return `Employee Id : ${this.empId} <br/>
            Employee Name : [${this.empName}] <br/>
            Employee Age : ${this.age} <br/>
            Marital Status : ${this.maritalStatus} <br/>
            Interests : ${this.interests} <br/>
            Gender : ${this.gender} <br/>
            Highest Education Level  : ${this.education} <br/>
            Car license  : ${this.licence} <br/>
            `;
        }
      }
    });

  </script>
</body>
</html>

這個範例程式執行時,要等到游標移到其它輸入方塊,最新的員工名稱才會更新在網頁下方,只要套用了「.lazy」,就會監聽「change」事件,在此事件觸發時,才會同步員工名稱。

Tags:

.NET Magazine國際中文電子雜誌 | JavaScript | 許薰尹Vivid Hsu

新增評論




  Country flag
biuquote
  • 評論
  • 線上預覽
Loading






NET Magazine國際中文電子雜誌

NET Magazine國際中文電子版雜誌,由恆逸資訊創立於2000,自發刊日起迄今已發行超過500篇.NET相關技術文章,擁有超過40000名註冊讀者群。NET Magazine國際中文電子版雜誌希望藉於電子雜誌與NET Developer達到共同學習與技術新知分享,歡迎每一位對.NET 技術有興趣的朋友們多多支持本雜誌,讓作者群們可以有持續性的動力繼續爬文。<請加入免費訂閱>

月分類Month List