1. 程式人生 > >前端開發之vue之資料繫結

前端開發之vue之資料繫結

 

2.1. 什麼是雙向繫結?

Vue框架很核心的功能就是雙向的資料繫結。 雙向是指:HTML標籤資料 繫結到 Vue物件,另外反方向資料也是繫結的。通俗點說就是,Vue物件的改變會直接影響到HTML的標籤的變化,而且標籤的變化也會反過來影響Vue物件的屬性的變化。


這樣一來,就徹底變革了之前Dom的開發方式,之前Dom驅動的開發方式尤其是以jQuery為主的開發時代,都是dom變化後,觸發js事件,然後在事件中通過js程式碼取得標籤的變化,再跟後臺進行互動,然後根據後臺返回的結果再更新HTML標籤,異常的繁瑣。有了Vue這種雙向繫結,讓開發人員只需要關心json資料的變化即可,Vue自動對映到HTML上,而且HTML的變化也會映射回js物件上,開發方式直接變革成了前端由資料驅動的 開發時代,遠遠拋棄了Dom開發主導的時代了。

2.2. 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>

2.3. 繫結資料中使用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>

2.4. 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>

2.5. 屬性繫結簡寫

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

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

2.6. 輸出純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>

2.7. 樣式繫結

對於普通的屬性的繫結,只能用上面的講的繫結屬性的方式。而Vue專門加強了class和style的屬性的繫結。可以有複雜的物件繫結、陣列繫結樣式和類。

2.7.1. 繫結樣式物件

經常我們需要對樣式進行切換,比如: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>

2.7.2. 混合普通的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>

2.7.3. 繫結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>

2.7.4. 繫結樣式陣列

其實繫結陣列,就是繫結樣式物件的延續,看官網的例子程式碼吧。

<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]">

2.7.5. 內聯樣式繫結

內聯樣式的繫結,非常類似於樣式類的操作。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 會自動偵測並新增相應的字首。

2.8. 計算屬性

在做資料的繫結的時候,資料要進行處理之後才能展示到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>

2.9. 繫結的資料過濾器

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

Vue.js 允許你自定義過濾器,被用作一些常見的文字格式化。過濾器應該被新增在 mustache 插值的尾部,由“管道符”指示:

{{ message | capitalize }}
<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>
Vue 2.x 中,過濾器只能在 mustache 繫結和 v-bind 表示式(從 2.1.0 開始支援)中使用,因為過濾器設計目的就是用於文字轉換。為了在其他指令中實現更復雜的資料變換,你應該使用計算屬性。

過濾器函式總接受表示式的值作為第一個引數。
new Vue({
  // ...
  filters: {
    capitalize: function (value) {
      if (!value) return ''
      value = value.toString()
      return value.charAt(0).toUpperCase() + value.slice(1)
    }
  }
})
過濾器可以串聯:
{{ message | filterA | filterB }}
過濾器是 JavaScript 函式,因此可以接受引數:
{{ message | filterA('arg1', arg2) }}
這裡,字串 'arg1' 將傳給過濾器作為第二個引數, arg2 表示式的值將被求值然後傳給過濾器作為第三個引數。

2.10. 核心:自動響應物件的變化到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>

2.11. 雙向資料繫結

上面的例子我們大多講的是單向的 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標籤中的內容會跟著進行改變,哇是不是很神奇呢...

關於其他表單的繫結的語法我就不贅述了,還是參考官網咖,我這裡大部分例子也是來自官網

2.12. 資料繫結總結

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