Vue 入門之數據綁定


什么是雙向綁定?

Vue 框架很核心的功能就是雙向的數據綁定。 雙向是指:HTML 標簽數據 綁定到 Vue 對象,另外反方向數據也是綁定的。通俗點說就是,Vue 對象的改變會直接影響到 HTML 的標簽的變化,而且標簽的變化也會反過來影響 Vue 對象的屬性的變化。
這樣以來,就徹底變革了之前 Dom 的開發方式,之前 Dom 驅動的開發方式尤其是以 jQuery 為主的開發時代,都是 dom 變化后,觸發 js 事件,然后在事件中通過 js 代碼取得標簽的變化,再跟后台進行交互,然后根據后台返回的結果再更新 HTML 標簽,異常的繁瑣。有了 Vue 這種雙向綁定,讓開發人員只需要關心 json 數據的變化即可,Vue 自動映射到 HTML 上,而且 HTML 的變化也會映射回 js 對象上,開發方式直接變革成了前端由數據驅動的 開發時代,遠遠拋棄了 Dom 開發主導的時代了。

vue 雙向綁定

Vue 綁定文本

數據綁定最常見的形式就是使用 “Mustache” 語法(雙大括號)的文本插值,比如模板引擎:handlebars 中就是用的{{}}.
創建的 Vue 對象中的 data 屬性就是用來綁定數據到 HTML 的。參考如下代碼:

<span>Message: {{ msg }}</span>
<script>
  var app = new Vue({         // 創建Vue對象。Vue的核心對象。
    el: '#app',               // el屬性:把當前Vue對象掛載到 div標簽上,#app是id選擇器
    data: {                   // data: 是Vue對象中綁定的數據
      msg: 'Hello Vue!'   // message 自定義的數據
    }
  });
</script>

 

綁定數據中使用 JavaScript 表達式

對於所有的數據綁定, Vue.js 都提供了完全的 JavaScript 表達式支持。

<span>Message: {{ msg + ' - ' + name }}</span>
<script>
  var app = new Vue({         // 創建Vue對象。Vue的核心對象。
    el: '#app',               // el屬性:把當前Vue對象掛載到 div標簽上,#app是id選擇器
    data: {                   // data: 是Vue對象中綁定的數據
      msg: 'Hi',              // message 自定義的數據
      name: 'flydragon'       // name自定義的屬性,vue可以多個自定義屬性,屬性類型也可是復雜類型
    }
  });
</script>

 

結果:

Hi - flydragon

 

當然 Vue 還可以支持表達中的任何計算、函數處理等。參考下面的綜合點的案例。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue入門之數據綁定-表達式運算</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    {{ msg + ' - ' + name }}
    <p>
      {{ isOk ? '123' : '456' }}
    </p>
    <p>我的年齡是: {{ age *2 }}</p>
  </div>

  <script>
  var app = new Vue({         // 創建Vue對象。Vue的核心對象。
    el: '#app',               // el屬性:把當前Vue對象掛載到 div標簽上,#app是id選擇器
    data: {                   // data: 是Vue對象中綁定的數據
      msg: 'Hi',              // message 自定義的數據
      name: 'flydragon',
      isOk: true,
      age: 18
    }
  });
  </script>
</body>
</html>

 

Vue 屬性綁定

Vue 中不能直接使用{{ expression }} 語法進行綁定 html 的標簽屬性進行綁定,而是用它特有的 v-bind 指令(就是一種寫法,先按照格式走,具體指令是什么可以后續再了解)。

綁定的語法結構:

<標簽 v-bind:屬性名="要綁定的Vue對象的data里的屬性名"></標簽> 例如:
<span v-bind:id="menuId">{{ menuName }}</span>

 

 

參考如下代碼案例:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue入門之數據綁定--屬性綁定</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <div v-bind:id="MenuContaineId">
      <a href="#" v-bind:class="MenuClass">首頁</a>
      <a href="#" v-bind:class="MenuClass">產品</a>
      <a href="#" v-bind:class="MenuClass">服務</a>
      <a href="#" v-bind:class="MenuClass">關於</a>
    </div>
  </div>

  <script>
    var app = new Vue({
      el: '#app',
      data: {                   // data: 是Vue對象中綁定的數據
        MenuClass: 'top-menu',
        MenuContaineId: 'sitemenu'
      }
    });
  </script>
</body>
</html>

 

屬性綁定簡寫

由於v-bind 使用非常頻繁,所以 Vue 提供了簡單的寫法,可以去掉 v-bind 直接使用:即可。

例如:
<div :id="MenuContaineId"> 等價於
<div v-bind:id="MenuContaineId">

 

 

輸出純 HTML

由於 Vue 對於輸出綁定的內容做了提前 encode,保障在綁定到頁面上顯示的時候不至於被 xss 攻擊。但某些場景下,我們確保后台數據是安全的,那么我們就要在網頁中顯示原生的 HTML 標簽。Vue 提供了v-html指令。

<div id="app">
  <div v-bind:id="MenuContaineId" v-html="MenuBody">
  </div>
</div>
<script>
  var app = new Vue({
    el: '#app',
    data: {                   // data: 是Vue對象中綁定的數據
      MenuContaineId: 'menu',
      MenuBody: '<p>這里是菜單的內容</p>'
    }
  });
</script>

 

結果:

<div id="app">
  <div id="menu">
    <p>這里是菜單的內容</p>
  </div>
</div>

 

布爾類型值用於屬性綁定

標簽的布爾類型的特性(屬性),比如: disabled特性。這類屬性特點只要存在就表示 truev-bind 應用於這類屬性的時候,如果綁定值為真,則輸出掙錢的對應屬性。如果為假值,則不會渲染此特性。

<button v-bind:disabled="isButtonDisabled">按鈕</button>

 

如果 isButtonDisabled 的值是 nullundefined 或 false,則 disabled 特性甚至不會被包含在渲染出來的 <button> 元素中。 如果為真值:<button disabled="disabled">按鈕</button>

樣式綁定

對於普通的屬性的綁定,只能用上面的講的綁定屬性的方式。而 Vue 專門加強了 class 和 style 的屬性的綁定。可以有復雜的對象綁定、數組綁定樣式和類。

綁定樣式對象

經常我們需要對樣式進行切換,比如:div 的顯示和隱藏,某些標簽 active 等。Vue 提供的對象綁定樣式的方式就很容做這些事情。

代碼:
<div v-bind:class="{ active: isActive }"></div>

 

 解釋: 當 isActive為 true時, div就會具有了active樣式類,如果 isActive為false,那么div就去掉active樣式類。
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue入門之綁定樣式類</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
  <style>
  .active {
    background-color: #ccc;
  }
  </style>
</head>
<body>
  <div id="app">
    <div v-bind:id="MenuContaineId" v-bind:class="{ active: isActive }">
      綁定顏色類
    </div>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {                   // data: 是Vue對象中綁定的數據
        MenuContaineId: 'menu',
        isActive: true
      }
    });
  </script>
</body>
</html>

 

混合普通的 HTML 標簽樣式類及綁定樣式對象

v-bind:class 指令可以與普通的 class 屬性共存。

<div id="app">
  <div class="static"
     v-bind:class="{ active: isActive, 'text-danger': hasError }">
  </div>
</div>
<script>
  var app = new Vue({
    el: '#app',
    data: {          // data: 是Vue對象中綁定的數據
      isActive: true,
      hasError: false
    }
  });
</script>

 

結果:

<div id="app">
  <div class="static active">
  </div>  
</div>

 

綁定 data 中的樣式對象

直接在 html 屬性中的雙引號內寫對象,還是很不爽,也沒有智能提示,很容易寫錯。 Vue 可以讓我們直接把綁定的 class 字符串指向 data 的一個對象,這樣就非常方便了,既可以有智能提示,又可以很復雜進行編輯,不用擔心煩人的""了。

<div id="app">
  <div class="static"
     v-bind:class="classObject">
  </div>
</div>
<script>
  var app = new Vue({
    el: '#app',
    data: {
      classObject: {
        active: true,
        'text-danger': false
      }
    }
  });
</script>

 

結果:

<div id="app">
  <div class="static active">
  </div>
</div>

 

綁定樣式數組

其實綁定數組,就是綁定樣式對象的延續,看官網的例子代碼吧。

<div v-bind:class="[activeClass, errorClass]">

data: {
  activeClass: 'active',
  errorClass: 'text-danger'
}

 

當然還有很多其他很有趣的支持,就不贅述了。

例如:
<div v-bind:class="[isActive ? activeClass : '', errorClass]">
<div v-bind:class="[{ active: isActive }, errorClass]">

 

 

內聯樣式綁定

內聯樣式的綁定,非常類似於樣式類的操作。v-bind:style 的對象語法十分直觀——看着非常像 CSS ,其實它是一個 JavaScript 對象。 CSS 屬性名可以用駝峰式(camelCase)或短橫分隔命名(kebab-case)。

看個例子:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue入門之htmlraw</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <div v-bind:style="{fontSize: size + 'px', backgroundColor: bgcolor, width: width}">
      vue 入門系列教程
    </div>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        size: 19,
        width: 200,
        bgcolor: 'red'
      }
    });
  </script>
</body>
</html>

 

自動添加前綴
當 v-bind:style 使用需要特定前綴的 CSS 屬性時,如 transform ,Vue.js 會自動偵測並添加相應的前綴。

計算屬性

在做數據的綁定的時候,數據要進行處理之后才能展示到 html 頁面上,雖然 vue 提供了非常好的表達式綁定的方法,但是只能應對低強度的需求。比如: 把一個日期按照規定格式進行輸出,可能就需要我們對日期對象做一些格式化的出來,表達式可能就捉襟見肘了。

Vue 對象提供的 computed 屬性,可以讓我們開發者在里面可以放置一些方法,協助我們綁定數據操作,這些方法可以跟 data 中的屬性一樣用,注意這些方法用的時候不要加()。 例子來了:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue入門之htmlraw</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <table>
      <tr>
        <!-- computed里面的函數可以直接當成data里面的屬性用,非常方便,注意沒有括號!!!-->
        <td>生日</td><td>{{ getBirthday }}</td>
      </tr>
      <tr>
        <td>年齡</td><td>{{ age }}</td>
      </tr>
      <tr>
        <td>地址</td><td>{{ address }}</td>
      </tr>
    </table>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        birthday: 914228510514,     // 這是一個日期對象的值:1998年11月1日
        age: 19,
        address: '北京昌平區龍澤飛龍'
      },
      computed: {
        // 把日期換成 常見規格格式的字符串。
        getBirthday: function () {
          var m = new Date(this.birthday);
          return m.getFullYear() + '' + m.getMonth() +''+ m.getDay()+'';
        }
      }
    });
  </script>
</body>
</html>

 

綁定的數據過濾器

過濾器本質就是數據在呈現之前先進行過濾和篩選。官網上寫的不錯,我就不再贅述,下面是官網的描述。

Vue.js 允許你自定義過濾器,可被用於一些常見的文本格式化。過濾器可以用在兩個地方:雙花括號插值和 v-bind表達式 (后者從 2.1.0+ 開始支持)。過濾器應該被添加在 JavaScript 表達式的尾部,由“管道”符號指示:

<!-- 在雙花括號中 -->
{{ message | capitalize }}

<!-- 在 `v-bind` 中 -->
<div v-bind:id="rawId | formatId"></div>

 

你可以在一個組件的選項中定義本地的過濾器:

filters: {
  capitalize: function (value) {
    if (!value) return ''
    value = value.toString()
    return value.charAt(0).toUpperCase() + value.slice(1)
  }
}

 

或者在創建 Vue 實例之前全局定義過濾器:

Vue.filter('capitalize', function (value) {
  if (!value) return ''
  value = value.toString()
  return value.charAt(0).toUpperCase() + value.slice(1)
})

new Vue({
  // ...
})

 

下面這個例子用到了 capitalize 過濾器:

<div id="example-1" class="demo">
  <input type="text" v-model="message">
  <p>{{ message | capitalize }}</p>
</div>
<script>
  new Vue({
    el: '#example-1',
    data: function () {
      return {
        message: 'john'
      }
    },
    filters: {
      capitalize: function (value) {
        if (!value) return ''
        value = value.toString()
        return value.charAt(0).toUpperCase() + value.slice(1)
      }
    }
  })
</script>

 

過濾器函數總接收表達式的值 (之前的操作鏈的結果) 作為第一個參數。在上述例子中,capitalize 過濾器函數將會收到 message 的值作為第一個參數。

過濾器可以串聯:

{{ message | filterA | filterB }}

 

在這個例子中,filterA 被定義為接收單個參數的過濾器函數,表達式 message 的值將作為參數傳入到函數中。然后繼續調用同樣被定義為接收單個參數的過濾器函數 filterB,將 filterA 的結果傳遞到 filterB 中。

過濾器是 JavaScript 函數,因此可以接收參數:

{{ message | filterA('arg1', arg2) }}

 

這里,filterA 被定義為接收三個參數的過濾器函數。其中 message 的值作為第一個參數,普通字符串 'arg1'作為第二個參數,表達式 arg2 的值作為第三個參數。

核心:自動響應對象的變化到 HTML 標簽

上面的例子都是 數據對象是寫死在創建的 Vue 對像上,那如果數據(data)發生改變時會怎樣呢? 讓我們用 chrome 把上面例子的頁面打開,並打開發者工具控制台,輸入:app.age = 20 會有什么情況發生呢?


響應

在頁面中添加一個按鈕,動態的增加年齡:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue入門之htmlraw</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <table>
      <tr>
        <!-- computed里面的函數可以直接當成data里面的屬性用,非常方便,注意沒有括號!!!-->
        <td>生日</td><td>{{ getBirthday }}</td>
      </tr>
      <tr>
        <td>年齡</td><td>{{ age }}</td>
      </tr>
      <tr>
        <td>地址</td><td>{{ address }}</td>
      </tr>
    </table>
  </div>

  <!-- 添加下面這行代碼,動態增加 年齡,頁面會有怎樣的變化呢?? -->
  <button type="button" onclick="app.age+=1;" >加加</button>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        birthday: 914228510514,     // 這是一個日期對象的值:1998年11月1日
        age: 19,
        address: '北京昌平區龍澤飛龍'
      },
      computed: {
        // 把日期換成 常見規格格式的字符串。
        getBirthday: function () {
          var m = new Date(this.birthday);
          return m.getFullYear() + '' + m.getMonth() +''+ m.getDay()+'';
        }
      }
    });
  </script>
</body>
</html>

 

雙向數據綁定

上面的例子我們大多講的是單向的 js 對象向 HTML 數據進行綁定,那 HTML 怎樣向 js 進行反饋數據呢? HTML 中只有表達能接受用戶的輸入,最簡單的演示雙向綁定的就是文本框了。

Vue 提供了一個新的指令:v-model 進行雙向數據的綁定,注意不是 v-bind。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Vue入門之htmlraw</title>
  <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    <!-- v-model可以直接指向data中的屬性,雙向綁定就建立了 -->
    <input type="text" name="txt" v-model="msg">
    <p>您輸入的信息是:{{ msg }}</p>
  </div>
  <script>
    var app = new Vue({
      el: '#app',
      data: {
        msg: '雙向數據綁定的例子'
      }
    });
  </script>
</body>
</html>

 

最終的結果就是:你改變 input 文本框的內容的時候,p 標簽中的內容會跟着進行改變,哇是不是很神奇呢...

關於其他表單的綁定的語法我就不贅述了,還是參考官網吧,我這里大部分例子也是來自官網

數據綁定總結

vue 提供了大量的綁定的語法和方法,非常方便我們進行數據的綁定,尤其它是雙向的數據綁定,極大的減少了我們 dom 操作的麻煩程度。可能你越來越喜歡它了吧...

表單綁定詳解

你可以用 v-model 指令在表單 <input><textarea> 及 <select> 元素上創建雙向數據綁定。它會根據控件類型自動選取正確的方法來更新元素。盡管有些神奇,但 v-model 本質上不過是語法糖。它負責監聽用戶的輸入事件以更新數據,並對一些極端場景進行一些特殊處理。

v-model 會忽略所有表單元素的 valuecheckedselected 特性的初始值而總是將 Vue 實例的數據作為數據來源。你應該通過 JavaScript 在組件的 data 選項中聲明初始值。

對於需要使用輸入法 (如中文、日文、韓文等) 的語言,你會發現 v-model 不會在輸入法組合文字過程中得到更新。如果你也想處理這個過程,請使用 input 事件。

文本

<div id="example-1">
  <input v-model="message" placeholder="edit me">
  <p>Message is: {{ message }}</p>
</div>
<script>
new Vue({
  el: '#example-1',
  data: {
    message: ''
  }
})
</script>

 

多行文本

<div id="example-textarea">
  <span>Multiline message is:</span>
  <p style="white-space: pre-line;">{{ message }}</p>
  <br>
  <textarea v-model="message" placeholder="add multiple lines"></textarea>
</div>
<script>
new Vue({
  el: '#example-textarea',
  data: {
    message: ''
  }
})
</script>

 

在文本區域插值 (<textarea>{{text}}</textarea>) 並不會生效,應用 v-model 來代替。

復選框

單個復選框,綁定到布爾值:

<div id="example-2">
  <input type="checkbox" id="checkbox" v-model="checked">
  <label for="checkbox">{{ checked }}</label>
</div>
<script>
new Vue({
  el: '#example-2',
  data: {
    checked: false
  }
})
</script>

 

多個復選框,綁定到同一個數組:

<div id="example-3">
  <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>
  <br>
  <span>Checked names: {{ checkedNames }}</span>
</div>
<script>
new Vue({
  el: '#example-3',
  data: {
    checkedNames: []
  }
})
</script>

 

單選按鈕

<div id="example-4">
  <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>
  <br>
  <span>Picked: {{ picked }}</span>
</div>
<script>
new Vue({
  el: '#example-4',
  data: {
    picked: ''
  }
})
</script>

 

選擇框

單選時:

<div id="example-5">
  <select v-model="selected">
    <option disabled value="">請選擇</option>
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
  el: '#example-5',
  data: {
    selected: ''
  }
})
</script>

 

如果 v-model 表達式的初始值未能匹配任何選項,select 元素將被渲染為“未選中”狀態。在 iOS 中,這會使用戶無法選擇第一個選項。因為這樣的情況下,iOS 不會觸發 change 事件。因此,更推薦像上面這樣提供一個值為空的禁用選項。

多選時 (綁定到一個數組):

<div id="example-6">
  <select v-model="selected" multiple style="width: 50px;">
    <option>A</option>
    <option>B</option>
    <option>C</option>
  </select>
  <br>
  <span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
  el: '#example-6',
  data: {
    selected: []
  }
})
</script>

 

用 v-for 渲染的動態選項:

<div id="example-7">
  <select v-model="selected">
    <option v-for="option in options" v-bind:value="option.value">
      {{ option.text }}
    </option>
  </select>
  <span>Selected: {{ selected }}</span>
</div>
<script>
new Vue({
  el: '#example-7',
  data: {
    selected: 'A',
    options: [
      { text: 'One', value: 'A' },
      { text: 'Two', value: 'B' },
      { text: 'Three', value: 'C' }
    ]
  }
})
</script>

 

值綁定

對於單選按鈕,復選框及選擇框的選項,v-model 綁定的值通常是靜態字符串 (對於復選框也可以是布爾值):

<!-- 當選中時,`picked` 為字符串 "a" -->
<input type="radio" v-model="picked" value="a">

<!-- `toggle` 為 true 或 false -->
<input type="checkbox" v-model="toggle">

<!-- 當選中第一個選項時,`selected` 為字符串 "abc" -->
<select v-model="selected">
  <option value="abc">ABC</option>
</select>

 

但是有時我們可能想把值綁定到 Vue 實例的一個動態屬性上,這時可以用 v-bind 實現,並且這個屬性的值可以不是字符串。

復選框

<input
  type="checkbox"
  v-model="toggle"
  true-value="yes"
  false-value="no"
>

 

// 當選中時 vm.toggle === 'yes' // 當沒有選中時 vm.toggle === 'no'

這里的 true-value 和 false-value 特性並不會影響輸入控件的 value 特性,因為瀏覽器在提交表單時並不會包含未被選中的復選框。如果要確保表單中這兩個值中的一個能夠被提交,(比如“yes”或“no”),請換用單選按鈕。

單選按鈕

<input type="radio" v-model="pick" v-bind:value="a">

 

// 當選中時 vm.pick === vm.a

選擇框的選項

<select v-model="selected">
    <!-- 內聯對象字面量 -->
  <option v-bind:value="{ number: 123 }">123</option>
</select>

 

// 當選中時 typeof vm.selected // => 'object' vm.selected.number // => 123

修飾符

.lazy

在默認情況下,v-model 在每次 input 事件觸發后將輸入框的值與數據進行同步 (除了上述輸入法組合文字時)。你可以添加 lazy 修飾符,從而轉變為使用 change 事件進行同步:

<!-- 在“change”時而非“input”時更新 -->
<input v-model.lazy="msg" >

 

.number

如果想自動將用戶的輸入值轉為數值類型,可以給 v-model 添加 number 修飾符:

<input v-model.number="age" type="number">

 

這通常很有用,因為即使在 type="number" 時,HTML 輸入元素的值也總會返回字符串。

.trim

如果要自動過濾用戶輸入的首尾空白字符,可以給 v-model 添加 trim 修飾符:

<input v-model.trim="msg">

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM