国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

JavaScript的Vue.js庫入門學習教程

2019-11-20 09:57:04
字體:
來源:轉載
供稿:網友

Vue是一個小巧輕便的javascript庫。它有一個簡單易懂的API,能夠讓開發者在開發web應用的時候更加簡易便捷。實際上,一直讓Vue引以為豪的是它的便捷性、執行力、靈活性。

這篇教程的目的就是通過一些例子,讓你能夠概覽一些基本的概念和特性。在接下來的其他教程里,你會學到Vue更多的有用的特性,從而用Vue搭建一個可擴展的項目。

MVVM 數據綁定

MVVM的本質是通過數據綁定鏈接View和Model,讓數據的變化自動映射為視圖的更新。Vue.js在數據綁定的API設計上借鑒了Angular的指令機制:用戶可以通過具有特殊前綴的HTML 屬性來實現數據綁定,也可以使用常見的花括號模板插值,或是在表單元素上使用雙向綁定:

<!-- 指令 --><span v-text="msg"></span><!-- 插值 --><span>{{msg}}</span><!-- 雙向綁定 --><input v-model="msg"> 

插值本質上也是指令,只是為了方便模板的書寫。在模板的編譯過程中,Vue.js會為每一處需要動態更新的DOM節點創建一個指令對象。每當一個指令對象觀測的數據變化時,它便會對所綁定的目標節點執行相應的DOM操作。基于指令的數據綁定使得具體的DOM操作都被合理地封裝在指令定義中,業務代碼只需要涉及模板和對數據狀態的操作即可,這使得應用的開發效率和可維護性都大大提升。

2016523165650774.jpg (600×287)

與Angular不同的是,Vue.js的API里并沒有繁雜的module、controller、scope、factory、service等概念,一切都是以“ViewModel 實例”為基本單位:

<!-- 模板 --><div id="app">  {{msg}}</div>// 原生對象即數據var data = {  msg: 'hello!'}// 創建一個 ViewModel 實例var vm = new Vue({  // 選擇目標元素  el: '#app',  // 提供初始數據  data: data})

渲染結果:


<div id="app">  hello!</div> 

在渲染的同時,Vue.js也已經完成了數據的動態綁定:此時如果改動data.msg的值,DOM將自動更新。是不是非常簡單易懂呢?除此之外,Vue.js對自定義指令、過濾器的API也做了大幅的簡化,如果你有Angular的開發經驗,上手會非常迅速。

數據觀測的實現

Vue.js的數據觀測實現原理和Angular有著本質的不同。了解Angular的讀者可能知道,Angular的數據觀測采用的是臟檢查(dirty checking)機制。每一個指令都會有一個對應的用來觀測數據的對象,叫做watcher;一個作用域中會有很多個watcher。每當界面需要更新時,Angular會遍歷當前作用域里的所有watcher,對它們一一求值,然后和之前保存的舊值進行比較。如果求值的結果變化了,就觸發對應的更新,這個過程叫做digest cycle。臟檢查有兩個問題:

任何數據變動都意味著當前作用域的每一個watcher需要被重新求值,因此當watcher的數量龐大時,應用的性能就不可避免地受到影響,并且很難優化。
當數據變動時,框架并不能主動偵測到變化的發生,需要手動觸發digest cycle才能觸發相應的DOM 更新。Angular通過在DOM事件處理函數中自動觸發digest cycle部分規避了這個問題,但還是有很多情況需要用戶手動進行觸發。
Vue.js采用的則是基于依賴收集的觀測機制。從原理上來說,和老牌MVVM框架Knockout是一樣的。依賴收集的基本原理是:

將原生的數據改造成 “可觀察對象”。一個可觀察對象可以被取值,也可以被賦值。
在watcher的求值過程中,每一個被取值的可觀察對象都會將當前的watcher注冊為自己的一個訂閱者,并成為當前watcher的一個依賴。
當一個被依賴的可觀察對象被賦值時,它會通知所有訂閱自己的watcher重新求值,并觸發相應的更新。
依賴收集的優點在于可以精確、主動地追蹤數據的變化,不存在上述提到的臟檢查的兩個問題。但傳統的依賴收集實現,比如Knockout,通常需要包裹原生數據來制造可觀察對象,在取值和賦值時需要采用函數調用的形式,在進行數據操作時寫法繁瑣,不夠直觀;同時,對復雜嵌套結構的對象支持也不理想。
Vue.js利用了ES5的Object.defineProperty方法,直接將原生數據對象的屬性改造為getter和setter,在這兩個函數內部實現依賴的收集和觸發,而且完美支持嵌套的對象結構。對于數組,則通過包裹數組的可變方法(比如push)來監聽數組的變化。這使得操作Vue.js的數據和操作原生對象幾乎沒有差別[注:在添加/刪除屬性,或是修改數組特定位置元素時,需要調用特定的函數,如obj.$add(key, value)才能觸發更新。這是受ES5的語言特性所限。],數據操作的邏輯更為清晰流暢,和第三方數據同步方案的整合也更為方便。

2016523165740081.jpg (647×334)

組件系統

在大型的應用中,為了分工、復用和可維護性,我們不可避免地需要將應用抽象為多個相對獨立的模塊。在較為傳統的開發模式中,我們只有在考慮復用時才會將某一部分做成組件;但實際上,應用類 UI 完全可以看作是全部由組件樹構成的:

2016523165817215.jpg (652×213)

因此,在Vue.js的設計中將組件作為一個核心概念。可以說,每一個Vue.js應用都是圍繞著組件來開發的。

注冊一個Vue.js組件十分簡單:

Vue.component('my-component', {  // 模板  template: '<div>{{msg}} {{privateMsg}}</div>',  // 接受參數  props: {    msg: String<br>    },  // 私有數據,需要在函數中返回以避免多個實例共享一個對象  data: function () {    return {      privateMsg: 'component!'    }  }})

注冊之后即可在父組件模板中以自定義元素的形式調用一個子組件:

<my-component msg="hello"></my-component>

渲染結果:

<div>hello component!</div>

Vue.js的組件可以理解為預先定義好了行為的ViewModel類。一個組件可以預定義很多選項,但最核心的是以下幾個:

  • 模板(template):模板聲明了數據和最終展現給用戶的DOM之間的映射關系。
  • 初始數據(data):一個組件的初始數據狀態。對于可復用的組件來說,這通常是私有的狀態。
  • 接受的外部參數(props):組件之間通過參數來進行數據的傳遞和共享。參數默認是單向綁定(由上至下),但也可以顯式地聲明為雙向綁定。
  • 方法(methods):對數據的改動操作一般都在組件的方法內進行。可以通過v-on指令將用戶輸入事件和組件方法進行綁定。
  • 生命周期鉤子函數(lifecycle hooks):一個組件會觸發多個生命周期鉤子函數,比如created,attached,destroyed等等。在這些鉤子函數中,我們可以封裝一些自定義的邏輯。和傳統的MVC相比,可以理解為 Controller的邏輯被分散到了這些鉤子函數中。
  • 私有資源(assets):Vue.js當中將用戶自定義的指令、過濾器、組件等統稱為資源。由于全局注冊資源容易導致命名沖突,一個組件可以聲明自己的私有資源。私有資源只有該組件和它的子組件可以調用。
  • 除此之外,同一顆組件樹之內的組件之間還可以通過內建的事件API來進行通信。Vue.js提供了完善的定義、復用和嵌套組件的API,讓開發者可以像搭積木一樣用組件拼出整個應用的界面。這個思路的可行性在Facebook開源的React當中也得到了印證。

基于構建工具的單文件組件格式

Vue.js的核心庫只提供基本的API,本身在如何組織應用的文件結構上并不做太多約束。但在構建大型應用時,推薦使用Webpack+vue-loader這個組合以使針對組件的開發更高效。

Webpack是由Tobias Koppers開發的一個開源前端模塊構建工具。它的基本功能是將以模塊格式書寫的多個JavaScript文件打包成一個文件,同時支持CommonJS和AMD格式。但讓它與眾不同的是,它提供了強大的loader API來定義對不同文件格式的預處理邏輯,從而讓我們可以將CSS、模板,甚至是自定義的文件格式當做JavaScript模塊來使用。Webpack 基于loader還可以實現大量高級功能,比如自動分塊打包并按需加載、對圖片資源引用的自動定位、根據圖片大小決定是否用base64內聯、開發時的模塊熱替換等等,可以說是目前前端構建領域最有競爭力的解決方案之一。

我在Webpack的loader API基礎上開發了vue-loader插件,從而讓我們可以用這樣的單文件格式 (*.vue) 來書寫Vue組件:

<style>.my-component h2 { color: red;}</style><template> <div class="my-component">  <h2>Hello from {{msg}}</h2>  <other-component></other-component> </div></template><script>// 遵循 CommonJS 模塊格式var otherComponent = require('./other-component')// 導出組件定義module.exports = { data: function () {  return {   msg: 'vue-loader'  } }, components: {  'other-component': otherComponent }}</script>

同時,還可以在*.vue文件中使用其他預處理器,只需要安裝對應的Webpack loader即可:

<style lang="stylus">.my-component h2 color red</style><template lang="jade">div.my-component h2 Hello from {{msg}}</template><script lang="babel">// 利用 Babel 編譯 ES2015export default { data () {  return {   msg: 'Hello from Babel!'  } }}</script>

這樣的組件格式,把一個組件的模板、樣式、邏輯三要素整合在同一個文件中,即方便開發,也方便復用和維護。另外,Vue.js本身支持對組件的異步加載,配合Webpack的分塊打包功能,可以極其輕松地實現組件的異步按需加載。

其他特性

Vue.js還有幾個值得一提的特性:

  • 異步批量DOM更新:當大量數據變動時,所有受到影響的watcher會被推送到一個隊列中,并且每個watcher只會推進隊列一次。這個隊列會在進程的下一個 “tick” 異步執行。這個機制可以避免同一個數據多次變動產生的多余DOM操作,也可以保證所有的DOM寫操作在一起執行,避免DOM讀寫切換可能導致的layout。
  • 動畫系統:Vue.js提供了簡單卻強大的動畫系統,當一個元素的可見性變化時,用戶不僅可以很簡單地定義對應的CSS Transition或Animation效果,還可以利用豐富的JavaScript鉤子函數進行更底層的動畫處理。
  • 可擴展性:除了自定義指令、過濾器和組件,Vue.js還提供了靈活的mixin機制,讓用戶可以在多個組件中復用共同的特性。

利用new Vue()創建一個Vue實例

我們可以先初始化一個html頁面,然后我們需要引入Vue 的 JS 文件。引入的方式有很多,我們可以在script中引入Vue的cdn,或者去官網上下載Vue的min.js,或者用 npm 安裝一個Vue的依賴。方便起見,本文中就用cdn引入。

<!DOCTYPE html>   <html>      <head>         <title>從零開始學Vue</title>      </head>   <body>      <script src="http://cdn.jsdelivr.net/vue/1.0.16/vue.js"></script>   </body></html>

當你在開發過程中,確保你使用的是沒有壓縮過的版本,因為沒有壓縮的版本會提供有用的詳細的警告,將會給你的代碼書寫節省很多時間。

我們先在body里面寫入一個div,并且創建一個Vue實例,然后將實例和div綁定起來。
當你創建一個新的Vue實例的時候要使用Vue()構造器,然后在你的實例中指出你的掛載點。這個掛載點就是你想要劃分出來的Vue實例的邊界。掛載點和實例邊界是一一對應的,你只能在掛載點上處理你實例邊界內的事務,而不能在你的掛載點上處理實例邊界外的事務。
在Vue實例中設置掛載點的參數是 “ el ”,el 的值可以用dom元素定義。

<!DOCTYPE html>   <html>      <head>         <title>從零開始學Vue</title>      </head>   <body>      <div id="vueInstance">這中間就是實例掛載點的實例邊界</div>      <script src="http://cdn.jsdelivr.net/vue/1.0.16/vue.js"></script>      <script>         // 創建一個新的Vue實例,并設置掛載點         var V = new Vue({            el : '#vueInstance'         });      </script>   </body></html>

就像你在上面看到的那樣,new一個Vue()就能創建一個新的實例,然后指定一個DOM元素作為實例的掛載點。定義掛載點的時候,我們用到了css選擇器的id來定義。實例化的名字也可以自己來定義,以便之后調用。

利用v-model進行雙向數據綁定

我們可以用v-model對input輸入框進行綁定,從而我們可以使用動態的獲取數據對象的值。你可以認為v-model是一個指定的屬性,就像html元素的屬性。這里的雙向數據綁定可以用在很多表單元素上,比如input、textarea、select。
Vue利用v-model這個指令綁定了一個數據,而這個數據是我們希望能夠通過用戶輸入操作而更新的數據。
比如我們下面這個例子,我們要在input標簽上綁定數據name,我們需要在Vue實例中的data對象中實現聲明。

<div id="vueInstance">   輸入您的姓名: <input type="text" v-model="name"></div>
<script src="http://cdn.jsdelivr.net/vue/1.0.16/vue.js"></script>//之后這行會省略<script>   var V = new Vue({      el : '#vueInstance',      data : {         name : '_Appian'      }   });</script>

無論用戶輸入多少次,這個name都會被自動更新。并且,如果name的值被改變了,其他有映射name的地方的值也會被修改。
這種input框和映射的同步修改的原因,就是利用v-model這個指令,讓數據通過底層的數據流進行綁定后直接修改。這就是數據的雙向綁定的概念。

為了證明這個概念,我們可以利用$data打印出數據的映射來看看。

<div id="vueInstance">   輸入您的姓名: <input type="text" v-model="name">   <p>{{ $data | json }}</p> //#1   <p>{{ name }}</p>     //#2</div>
<script>   var V = new Vue({      el : '#vueInstance',      data : {         name : '_Appian'      }   });</script>

其1:
$data是Vue實例觀察的數據對象,本質類型是一個對象,所以可以轉成JSON。可以用一個新的對象替換。實例代理了它的數據對象的屬性。
{{}},利用兩個花括號進行插值。這里插入的值是$data實時變化的值。
| json,只是一個更直觀的能讓數據展示出來的方法。也可以看做是一個過濾器,就像JSON.stringify()的效果一樣。

其2:
{{ name }},就是直接在插值表達式,兩個花括號中間插入數據變量,直接映射name的值。

Vue就是這么簡單的進行數據的雙向綁定,只需要一個v-model指令就可以,而不需要利用js或者jq來控制數據。相信你能從上面的例子中理清邏輯。

利用v-on進行事件綁定

Vue是利用v-on指令進行事件監聽和事件分發的。你可以在Vue的實例中創建一個方法來綁定監聽事件,可以創建一個方法來分派一個點擊事件。

下面的例子中,我們將創建一個say方法,這個方法綁定在一個button上。點擊產生的效果就是彈出一個帶有用戶name的歡迎框。為了將這個方法指派給button,我們需要用v-on:click來進行事件綁定。

<div id="vueInstance">   輸入您的姓名: <input type="text" v-model="name">   <button v-on:click="say">歡迎點擊</button> //#1   <button @click="say">歡迎點擊</button>   //#2</div>
<script>   var V = new Vue({      el : '#vueInstance',      data : {         name : '_Appian'      },      methods : {         say : function(){            alert('歡迎' + this.name);         }      }   });</script>

當然了,不僅是可以綁定click點擊事件,還可以綁定其他鼠標事件,鍵盤輸入事件等一些js的事件類型。比如v-on:mouseover,v-on:keydown, v-on:submit, v-on:keypress,v-on:keyup.13等等,或者是一些其他的自定義事件。

在開發過程中,你可能會頻繁的用到事件綁定,v-on寫起來有點麻煩,所以上例中提供了兩種寫法,#2就是對#1寫法的縮寫。利用@代替v-on,這里不多說。

利用v-if或者v-show進行條件判定

如果我們希望用戶在登錄之后才能看到歡迎彈窗,而如果沒有登錄則給它一個登錄界面。Vue會提供給我們v-if指令和v-show指令用來控制不同登錄狀態下的顯示內容。

利用先前的例子,我們可以用loginStatus的值來控制是否登錄,如果是true則顯示輸入框和按鈕讓他能夠看到歡迎彈窗,但如果是false(即未登錄),則只能看到輸入賬號、密碼的輸入框和提交按鈕(暫時不進行身份驗證,只改變登錄狀態)。

<div id="vueInstance">   //loginStatus為true時會顯示的section   <section v-if="loginStatus">     輸入您的姓名: <input type="text" v-model="name">     <button v-on:click="say">歡迎點擊</button>     <button @click="switchLoginStatus">退出登錄</button>   </section>   //loginStatus為false時會顯示的section   <section v-if="!loginStatus">      登錄用戶: <input type="text">      登錄密碼: <input type="password">      <button @click="switchLoginStatus">登錄</button>   </section></div>
<script>   var V = new Vue({      el : '#vueInstance',      data : {         name : '_Appian',         loginStatus : false      },      methods : {         say : function(){            alert('歡迎' + this.name);         },          switchLoginStatus : function(){            this.loginStatus = !this.loginStatus;          }      }   });</script>

this的執行就是實例V。this的指向是一個需要自己去搞懂的問題,這里不多說。
在上述例子中,只要把V-if換成v-show,一樣可以獲得等同的效果。同時v-if和v-show他們都支持v-else,但是綁定v-else命令的標簽的前一兄弟元素必須有 v-if 或 v-show。

在上面的例子中,只要點擊“登錄”或者“退出登錄”按鈕都會觸發switchLoginStatus方法,只要觸發了這個方法就會導致loginStatus的狀態變化(在true和false中進行切換),從而改變了html中的v-if的判斷條件結果的變化,基于當前的loginStatus的布爾值的狀態,使得顯示的section是不同狀態下的section。

v-show和v-if之間有什么區別呢?
在切換 v-if 塊時,Vue有一個局部編譯/卸載過程,因為 v-if 之中的模板也可能包括數據綁定或子組件。v-if 是真實的條件渲染,因為它會確保條件塊在切換當中合適地銷毀與重建條件塊內的事件監聽器和子組件。
v-if 也是惰性的:如果在初始渲染時條件為假,則什么也不做――在條件第一次變為真時才開始局部編譯(編譯會被緩存起來)。
相比之下,v-show 簡單得多――元素始終被編譯并保留,只是簡單地基于 CSS 切換。
一般來說,v-if 有更高的切換消耗而 v-show 有更高的初始渲染消耗。因此,如果需要頻繁切換 v-show 較好,如果在運行時條件不大可能改變 v-if 較好。

這個差別也許對你目前的開發來說并不重要,但是你還是要注意和留心,因為當你的項目開發變大的時候,這點會變得重要起來。

利用v-for輸出列表

如果你是經營一個電商平臺的商人的話,你一定有很多頁面都需要渲染商品列表的輸出。v-for指令允許循環我們的數組對象,用 “element in arrayObj” 的方式,念作“循環arrayObj這個數據對象里的每一個element”。

下面的例子中,我們將會利用v-for指令循環輸出一個商品列表。每一個商品都會在一個li中,li中輸出商品的名稱、價格和商品類型。

<div id="vueInstance">   <ul>     <li v-for="el in products">      {{ el.name }} - ¥ {{ el. price }} - {{ el. category }}     </li>   </ul></div>
<script>   var V = new Vue({      el : '#vueInstance',      data : {          products : [             {name: 'microphone', price: 25, category: 'electronics'},             {name: 'laptop case', price: 15, category: 'accessories'},             {name: 'screen cleaner', price: 17, category: 'accessories'},             {name: 'laptop charger', price: 70, category: 'electronics'},             {name: 'mouse', price: 40, category: 'electronics'},             {name: 'earphones', price: 20, category: 'electronics'},             {name: 'monitor', price: 120, category: 'electronics'}          ]      }   });</script>

當然了,data中的數組對象,可以不用像上面這樣定義也可以,我們可以從數據庫導入,或者是利用ajax請求得到。這里只是為了演示v-for。

有時候我們可能會需要拿到商品在數組對象里的對應下標。我們可以用$index來獲得。

//#1<li v-for="el in products">  {{ $index }} - {{ el.name }} - ¥ {{ el. price }} - {{ el. category }}</li>//#2<li v-for="(index,el) in products">  {{ index }} - {{ el.name }} - ¥ {{ el. price }} - {{ el. category }}</li>

計算屬性Computed

計算屬性的應用場景,一般是在有一個變量的值需要其他變量計算得到的時候,會用到。

比如,例如用戶在輸入框輸入一個數 x,則自動返回給用戶這個數的平方 x²。你需要對輸入框進行數據綁定,然后當數據修改的時候,就馬上計算它的平方。

<div id="vueInstance">     輸入一個數字: <input type="text" v-model="value">     <p>計算結果:{{ square }}</p></div>
<script>   var V = new Vue({      el : '#vueInstance',      data : {         value : 1      },      computed : {         square : function(){            return this.value * this.value;         }      }   });</script>

計算屬性定義數值是通過定義一系列的function,就像我們先前定義methods對象的時候是一樣的。比如square方法是用來計算變量“square”的,其方法的返回值是兩個this.value的乘積。

接下來可以用computed做一個復雜一點例子。系統會隨機取一個1~10以內的數字,用戶可以在輸入框隨機輸入一個1~10之內的數字,如果剛好用戶的輸入和系統的隨機數剛好匹配,則游戲成功,反之失敗。

<div id="vueInstance">     輸入1~10內的數字: <input type="text" v-model="value">     <p>計算結果:{{ resultMsg }}</p></div>
<script>   var V = new Vue({      el : '#vueInstance',      data : {         value : null,         randNum : 5//第一次隨機數為5      },      methods : {         getRandNum: function(min, max){           return Math.floor(Math.random() * (max - min + 1)) + min;         }      },      computed : {         resultMsg : function(){            if (this.value == this.randNum) {              this.randNum = this.getRandNum(1, 10);              return '你猜對了!';            } else {              this.randNum = this.getRandNum(1, 10);              return '猜錯了,再來!';            }         }      }   });</script>

后記

到此為止,你就已經能夠掌握了Vue的基本使用,世界上最簡潔最漂亮的框架之一,它的構建有著自己完整的設計思想,而且越來越流行。這個框架足夠小而輕,在你的開發中會給你帶來更加流暢的用戶體驗,并有效提高開發效率。上文中舉了一系列例子,都掌握了嗎?

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 普宁市| 密山市| 大港区| 岱山县| 梓潼县| 揭东县| 田阳县| 共和县| 龙州县| 罗定市| 霞浦县| 故城县| 营口市| 乐平市| 修武县| 嘉义县| 洞口县| 万安县| 文登市| 乐平市| 大同县| 陇西县| 昭苏县| 万载县| 仁怀市| 江源县| 卓资县| 柯坪县| 财经| 开封市| 赣州市| 丽江市| 凉山| 富蕴县| 故城县| 玉田县| 邵阳县| 邳州市| 确山县| 鸡西市| 定日县|