Vue.js 學習筆記 一



 

本文的Demo和源代碼已放到GitHub,如果您覺得本篇內容不錯,請點個贊,或在GitHub上加個星星!

https://github.com/zwl-jasmine95/Vue_test

 以下所有知識都是基於vue.js 2.0版本


 

一、簡介

Vue.js(讀音 /vjuː/,類似於 view) 是一套構建用戶界面的漸進式框架。與其他重量級框架不同的是,Vue 采用自底向上增量開發的設計Vue 的核心庫只關注視圖層,它不僅易於上手,還便於與第三方庫或既有項目整合。

另一方面,當與單文件組件和 Vue 生態系統支持的庫結合使用時,Vue 也完全能夠為復雜的單頁應用程序提供驅動。

 

Vue.js是當下很火的一個JavaScript MVVM庫,它是以數據驅動和組件化的思想構建的。相比於Angular.js,Vue.js提供了更加簡潔、更易於理解的API,使得我們能夠快速地上手並使用Vue.js。

MVVM:

 DOM Listeners和Data Bindings兩個工具,它們是實現雙向綁定的關鍵。
從View側看,ViewModel中的DOM Listeners工具會幫我們監測頁面上DOM元素的變化,如果有變化,則更改Model中的數據;
從Model側看,當我們更新Model中的數據時,Data Bindings工具會幫我們更新頁面中的DOM元素。

 


 

二、vue.js基礎指令知識

Vue.js提供了一些常用的內置指令:

  • v-if指令
  • v-show指令
  • v-else指令
  • v-for指令
  • v-bind指令
  • v-on指令

1.聲明式渲染

Vue.js 的核心是一個允許采用簡潔的模板語法來聲明式的將數據渲染進 DOM。  個人感覺實現原理還是和angularJS很像的。

我們試一下寫一個簡單的hello world!:

 1 <body>
 2     <div id="app">
 3         {{message}}
 4     </div>
 5 
 6     <script type="text/javascript" src="lib/js/vue.js"></script>
 7     <script type="text/javascript">
 8         /**
 9          * 采用簡潔的模板語法來聲明式的將數據渲染進 DOM
10          */
11         var app = new Vue({
12             el:'#app',
13             data:{
14                 message:'Hello World!'
15             }
16         });
17     </script>
18 </body>

可以通過app.message來查看數據值。但是在寫代碼的過程中需要注意很重要的兩點:

1)我們編寫的js代碼一定要放在body標簽的最下面,不然會報錯‘沒有找到#app’,因為js代碼放在head標簽里時頁面DOM結果還沒加載完。

2){{message}}這里其實相當於一個變量,可以任意命名,只要和js里對應即可。

 

數據和 DOM 已經被綁定在一起,一切都是響應式的。可以通過app.message改變數據值。

______________  除了文本插值,我們還可以采用指令的方式綁定 DOM 元素屬性,指令帶有前綴 v-,以表示它們是 Vue 提供的特殊屬性。

 

v-bind指令可以在其名稱后面帶一個參數,中間放一個冒號隔開,這個參數通常是HTML元素的特性(attribute),例如:v-bind:class

v-bind:argument="expression"
 1 <body>
 2     <div id="app-2">
 3         <span v-bind:title="message">
 4             鼠標懸停幾秒鍾查看此處動態綁定的提示信息!
 5         </span>
 6     </div>
 7 
 8     <script type="text/javascript" src="lib/js/vue.js"></script>
 9     <script type="text/javascript">
10         /**
11          * 采用簡潔的模板語法來聲明式的將數據渲染進 DOM
12          */
13         var app2 = new Vue({
14             el: '#app-2',
15             data: {
16                 message: '頁面加載於 ' + new Date()
17             }
18         })
19     </script>
20 </body>

這里該指令的作用是:“將這個元素節點的 title 屬性和 Vue 實例的 message 屬性保持一致”。

 

 

使用Vue的過程就是定義MVVM各個組成部分的過程的過程。

  1. 定義View
  2. 定義Model
  3. 創建一個Vue實例或"ViewModel",它用於連接View和Model

在創建Vue實例時,需要傳入一個選項對象,選項對象可以包含數據、掛載元素、方法、模生命周期鈎子等等。

在這個示例中,選項對象el屬性指向View,el: '#app'表示該Vue實例將掛載到<div id="app">...</div>這個元素;data屬性指向Model,data: message表示我們的Model是message對象。
Vue.js有多種數據綁定的語法,最基礎的形式是文本插值,使用一對大括號語法,在運行時{{ message }}會被數據對象的message屬性替換,所以頁面上會輸出"Hello World!"。

 

雙大括號以及v-text會將數據解釋為純文本,而非 HTML 。為了輸出真正的 HTML ,需要使用 v-html 指令。

 

 

2、條件與循環

1)v-if

v-if是條件渲染指令,根據條件表達式的值來執行元素的插入或者刪除行為。

v-if="expression"

expression是一個返回bool值的表達式,表達式可以是一個bool屬性,也可以是一個返回bool的運算式。

1 <div class="app">
2     <span v-if="true">你好!vue.js!</span>
3 </div>

 

這一段代碼可以還用js來實現:

<body>
    <div class="app">     <!--這里不一定要用id,class也行的,只要js里的選擇器對應-->
        <span v-if="tag">你好!vue.js!</span>
    </div>

    <script type="text/javascript" src="lib/js/vue.js"></script>
    <script type="text/javascript">
        var app = new Vue({
            el:'.app',    //注意選擇器
            data:{
                tag:true
            }
        });
    </script>
</body>

盡管用了class而不是id,但是在控制台也是可以通過app.tag來查看變量的:

 

 拓展:

v-show也是條件渲染指令,和v-if指令不同的是,使用v-show指令的元素始終會被渲染到HTML,它只是簡單地為元素設置CSS的style屬性。

還可以用v-else指令為v-ifv-show添加一個“else塊”。v-else元素必須立即跟在v-ifv-show元素的后面——否則它不能被識別。

v-else元素是否渲染在HTML中,取決於前面使用的是v-if還是v-show指令。)

 1 <body>
 2     <div id="app">
 3         <p v-if="tag">你好!vue.js!</p>
 4         <p v-else>這里是例外情況</p>
 5     </div>
 6 
 7     <script type="text/javascript" src="lib/js/vue.js"></script>
 8     <script type="text/javascript">
 9         var app = new Vue({
10             el:'#app',    //注意選擇器
11             data:{
12                 tag:true
13             }
14         });
15     </script>
16 </body>

在控制台中改變tag的值:

 

 

 

 

2)v-for

v-for指令基於一個數組渲染一個列表,它和JavaScript的遍歷語法相似:

v-for="item in items"

items是一個數組,item是當前被遍歷的數組元素。

v-for 指令可以綁定數組的數據來渲染一個項目列表:

 1 <body>
 2     <div class="app">
 3         <p>前端學習之路:</p>
 4         <ol>
 5             <li v-for="item in items">{{item.text}}</li>
 6         </ol>
 7     </div>
 8 
 9     <script type="text/javascript" src="lib/js/vue.js"></script>
10     <script type="text/javascript">
11         var app = new Vue({
12             el:'.app',
13             data:{
14                 items:[
15                     {text:'HTML'},
16                     {text:'CSS'},
17                     {text:'JavaScript'},
18                     {text:'jQuery'}
19                 ]
20             }
21         });
22     </script>
23 </body>

 

 

 在控制台里,輸入 app.items.push({ text: '新項目' }),你會發現列表中添加了一個新項:

 

 另外:v-for還有一種特殊寫法可以獲取索引值:

index可以直接用作索引值


 3、處理用戶輸入

1)v-on

v-on指令用於給監聽DOM事件,它的用語法和v-bind是類似的,例如監聽<a>元素的點擊事件:

<a v-on:click="doSomething">

有兩種形式調用方法:綁定一個方法(讓事件指向方法的引用),或者使用內聯語句。

 1 <body>
 2     <div id="app">
 3         <p>{{ message }}</p>
 4         <button v-on:click="reverseMessage">逆轉消息</button>
 5     </div>
 6 
 7     <script type="text/javascript" src="lib/js/vue.js"></script>
 8     <script type="text/javascript">
 9         var app = new Vue({
10             el: '#app',
11             data: {
12                 message: 'Hello Vue.js!'
13             },
14             // 在 `methods` 對象中定義方法
15             methods: {
16                 reverseMessage: function () {
17                     //reverse() 方法用於顛倒數組中元素的順序。
18                     //方法中的this指向app
19                     this.message = this.message.split('').reverse().join('')
20                 }
21             }
22         })
23     </script>
24 </body>

——————>

 

 

Vue.js為最常用的兩個指令v-bindv-on提供了縮寫方式。v-bind指令可以縮寫為一個冒號,v-on指令可以縮寫為@符號。

2)v-model

Vue 提供了 v-model 指令,使表單輸入和應用狀態間的雙向綁定變得輕而易舉。

 1 <body>
 2     <div id="app">
 3         <p>{{ message }}</p>
 4         <input type="text" v-model="message">
 5         <button v-on:click="alertMessage">彈出輸入框內容</button>
 6     </div>
 7 
 8     <script type="text/javascript" src="lib/js/vue.js"></script>
 9     <script type="text/javascript">
10         var app = new Vue({
11             el: '#app',
12             data: {
13                 message: 'Hello Vue.js!'
14             },
15             // 在 `methods` 對象中定義方法
16             methods: {
17                 alertMessage: function () {
18                     
19                     //方法中的this指向app
20                     alert(this.message);
21                 }
22             }
23         })
24     </script>
25 </body>

 

改變輸入框的值,會發現上面的p標簽的值也改變了。然后點擊按鈕,彈框中會顯示改變的輸入框值,這就是雙向數據綁定。(也可以通過控制台來改變輸入框以及p標簽的值)

 

 

 


三、vue.js基礎用法知識

 一開始就學習vue.js的內置指令,估計有些人對vue.js的執行還是有點不理解,下面做簡單的講解。

1、構造器

每個 Vue.js 應用都是通過構造函數 Vue 創建一個 Vue 的根實例 啟動的:

1 var vm = new Vue({
2   // 選項
3 })

雖然沒有完全遵循 MVVM 模式, Vue 的設計無疑受到了它的啟發。因此在文檔中經常會使用 vm (ViewModel 的簡稱) 這個變量名表示 Vue 實例。

在實例化 Vue 時,需要傳入一個選項對象,它可以包含數據、模板、掛載元素、方法、生命周期鈎子等選項。

 

(這是我用思維導圖工具xMind畫的,后面三個就不具體列出來了,更加具體的內容可以在官方API查看。)

 

 

 

new一個vue對象的時候可以設置屬性,其中最重要的包括三個,分別是data、methods、watch

其中data代表vue對象的數據,methods代表vue對象的方法,watch設置了對象監聽的方法。如下:

 

 

 

在第二節的內置指令中已經用到了data和methods。,其他的后面用到了再系統講解。

 

另外可以擴展Vue構造器,從而用預定義選項創建可復用的組件構造器:

1 var MyComponent = Vue.extend({
2   // 擴展選項
3 })
4 // 所有的 `MyComponent` 實例都將以預定義的擴展選項被創建
5 var myComponentInstance = new MyComponent()

所有的 Vue.js 組件其實都是被擴展的 Vue 實例。

 

2、屬性與方法

 每個 Vue 實例都會代理其 data 對象里所有的屬性

 1 var data = { a: 1 }
 2 var vm = new Vue({
 3   data: data
 4 })
 5 vm.a === data.a // -> true
 6 // 設置屬性也會影響到原始數據
 7 vm.a = 2
 8 data.a // -> 2
 9 // ... 反之亦然
10 data.a = 3
11 vm.a // -> 3

注意只有這些被代理的屬性是響應的。如果在實例創建之后添加新的屬性到實例上,它不會觸發視圖更新。

除了 data 屬性, Vue 實例暴露了一些有用的實例屬性與方法。這些屬性與方法都有前綴 $,以便與代理的 data 屬性區分。

 1 var data = { a: 1 }
 2 var vm = new Vue({
 3   el: '#example',
 4   data: data
 5 })
 6 vm.$data === data // -> true
 7 vm.$el === document.getElementById('example') // -> true
 8 // $watch 是一個實例方法
 9 vm.$watch('a', function (newVal, oldVal) {
10   // 這個回調將在 `vm.a`  改變后調用
11 })

 

3、實例生命周期

 每個 Vue 實例在被創建之前都要經過一系列的初始化過程。例如,實例需要配置數據觀測(data observer)、編譯模版、掛載實例到 DOM ,然后在數據變化時更新 DOM 。在這個過程中,實例也會調用一些 生命周期鈎子 ,這就給我們提供了執行自定義邏輯的機會。例如,created 這個鈎子在實例被創建之后被調用:

var vm = new Vue({
  data: {
    a: 1
  },
  created: function () {
    // `this` 指向 vm 實例
    console.log('a is: ' + this.a)
  }
})
// -> "a is: 1"

也有一些其它的鈎子,在實例生命周期的不同階段調用,如 mounted、 updated 、destroyed 。鈎子的 this 指向調用它的 Vue 實例。一些用戶可能會問 Vue.js 是否有“控制器”的概念?答案是,沒有。組件的自定義邏輯可以分布在這些鈎子中。

 

生命周期圖示:

 

 


 

四、實踐案例

 1、表格

 主要是利用v-for來實現的:(源代碼: github上 demo1/table.html)

html:

 1 <table id="myTable"  class="table table-striped">
 2         <thead>
 3             <tr>
 4                 <th>姓名</th>
 5                 <th>性別</th>
 6                 <th>年齡</th>
 7             </tr>
 8         </thead>
 9        <tbody>
10            <tr v-for="item in items">
11                <td>{{item.name}}</td>
12                <td>{{item.sex}}</td>
13                <td>{{item.age}}</td>
14            </tr>
15        </tbody>
16     </table>

 

js:

var vm = new Vue({
            el:'#myTable',
            data:{
                items:[
                    {
                        name:'張姍',
                        sex:'女',
                        age:'42'
                    },
                    {
                        name:'李四',
                        sex:'男',
                        age:'33'
                    },
                    {
                        name:'王五',
                        sex:'男',
                        age:'58'
                    }
                ]
            }
        });

將v-for嵌套在tr標簽中,這樣就可以生成下面的表格了。案例比較簡單。

 

 2、實時表格編輯

(源代碼: github上 demo1/editTable.html)

首先我們先確定一下需要做什么:

我們可以在上面的表單中輸入要添加的表格行的具體內容,然后點擊添加按鈕即可在表格中增加一行。

點擊表格每一行后面的刪除按鈕,即可刪除該表格行。

 

 1)布局

在實現功能之前,現將表單模塊和表格模塊利用HTML實現,這里為了節省時間,直接是使用bootstrap框架。

 

 1 <form class="form-horizontal" role="form">
 2         <div class="form-group">
 3             <label for="name" class="col-sm-2 control-label">姓名</label>
 4             <div class="col-sm-10">
 5                 <input type="text" class="form-control" id="name" placeholder="請輸入名字">
 6             </div>
 7         </div>
 8         <div class="form-group">
 9             <label for="age" class="col-sm-2 control-label">年齡</label>
10             <div class="col-sm-10">
11                 <input type="text" class="form-control" id="age" placeholder="請輸入年齡">
12             </div>
13         </div>
14         <div class="form-group">
15             <label for="sex" class="col-sm-2 control-label">性別</label>
16             <div class="col-sm-10">
17                 <select name="" id="sex" class="form-control">
18                     <option value="男"></option>
19                     <option value="女"></option>
20                 </select>
21             </div>
22         </div>
23         <div class="form-group">
24             <div class="col-sm-offset-2 col-sm-10">
25                 <button type="button" class="btn btn-primary">添加</button>
26             </div>
27         </div>
28     </form>
29 
30     <table id="editTable" class="table table-striped">
31         <thead>
32             <tr>
33                 <th>姓名</th>
34                 <th>年齡</th>
35                 <th>性別</th>
36                 <th>操作</th>
37             </tr>
38         </thead>
39         <tbody>
40             <tr v-for="item in items">
41                 <td>{{item.name}}</td>
42                 <td>{{item.age}}</td>
43                 <td>{{item.sex}}</td>
44                 <td><button type="button" class="btn btn-primary">刪除</button></td>
45             </tr>
46         </tbody>
47     </table>
View Code

 

 2)數據綁定

接下來我們使用v-model將表單輸入框綁定到數據層。

先在data里創建一個新的對象-newItem,用來存放新增的表格行:

然后將數據綁定到輸入框,例如:

 

 3)添加新增按鈕事件

 

定義名為createItem的函數:

1 methods:{
2                 creatItem:function () {
3                     this.items.push(this.newItem);  //this指向data
4                     // 添加完newItem對象后,重置newItem對象
5                     this.newItem = {name: '', age: 0, sex: '女'}
6                 }
7             }

 

 

 4)添加刪除按鈕事件

定義名為deleteItem的函數,並將該表格行的索引作為參數傳入;

 1 //事件處理
 2             methods:{
 3                 /**
 4                  * 根據表格行的索引刪除該表格行
 5                  * @param  {[number]} index [表格行的索引]
 6                  * @return 
 7                  */
 8                 deleteItem:function (index) {
 9                     this.items.splice(index,1);
10                 }
11             }

 

 完整代碼:

https://github.com/zwl-jasmine95/Vue_test/blob/master/demo1/editTable.html

  1 <!DOCTYPE html>
  2 <html lang="en">
  3 <head>
  4     <meta charset="UTF-8">
  5     <title>實時表格編輯</title>
  6     <link rel="stylesheet" href="../lib/css/bootstrap.min.css">
  7     <style>
  8         body{
  9             padding:50px;
 10         }
 11     </style>
 12 </head>
 13 <body>
 14     <div id="editTable">
 15         <form class="form-horizontal" role="form">
 16             <div class="form-group">
 17                 <label for="name" class="col-sm-2 control-label">姓名</label>
 18                 <div class="col-sm-10">
 19                     <input type="text" class="form-control" id="name" placeholder="請輸入名字" v-model="newItem.name">
 20                 </div>
 21             </div>
 22             <div class="form-group">
 23                 <label for="age" class="col-sm-2 control-label">年齡</label>
 24                 <div class="col-sm-10">
 25                     <input type="text" class="form-control" id="age" placeholder="請輸入年齡" v-model="newItem.age">
 26                 </div>
 27             </div>
 28             <div class="form-group">
 29                 <label for="sex" class="col-sm-2 control-label">性別</label>
 30                 <div class="col-sm-10">
 31                     <select name="" id="sex" class="form-control" v-model="newItem.sex">
 32                         <option value="男"></option>
 33                         <option value="女"></option>
 34                     </select>
 35                 </div>
 36             </div>
 37             <div class="form-group">
 38                 <div class="col-sm-offset-2 col-sm-10">
 39                     <button type="button" class="btn btn-primary" v-on:click="creatItem">添加</button>
 40                 </div>
 41             </div>
 42         </form>
 43 
 44         <table class="table table-striped">
 45             <thead>
 46             <tr>
 47                 <th>姓名</th>
 48                 <th>年齡</th>
 49                 <th>性別</th>
 50                 <th>操作</th>
 51             </tr>
 52             </thead>
 53             <tbody>
 54             <tr v-for="(item,index) in items">
 55                 <td>{{item.name}}</td>
 56                 <td>{{item.age}}</td>
 57                 <td>{{item.sex}}</td>
 58                 <td><button type="button" class="btn btn-primary" v-on:click="deleteItem(index)">刪除</button></td>
 59             </tr>
 60             </tbody>
 61         </table>
 62     </div>
 63 
 64     <script type="text/javascript" src="../lib/js/vue.js"></script>
 65     <script type="text/javascript">
 66         var vm = new Vue({
 67             el:'#editTable',
 68             data:{
 69                 newItem:{
 70                     name:'',
 71                     sex:'',
 72                     age:'0'
 73                 },
 74                 items:[
 75                     {
 76                         name:'張姍',
 77                         sex:'',
 78                         age:'42'
 79                     },
 80                     {
 81                         name:'李四',
 82                         sex:'',
 83                         age:'33'
 84                     },
 85                     {
 86                         name:'王五',
 87                         sex:'',
 88                         age:'58'
 89                     }
 90                 ]
 91             },
 92             //事件處理
 93             methods:{
 94                 creatItem:function () {
 95                     this.items.push(this.newItem);  //this指向data
 96                     // 添加完newItem對象后,重置newItem對象
 97                     this.newItem = {name: '', age: 0, sex: ''}
 98                 },
 99 
100                 /**
101                  * 根據表格行的索引刪除該表格行
102                  * @param  {[number]} index [表格行的索引]
103                  * @return
104                  */
105                 deleteItem:function (index) {
106                     this.items.splice(index,1);
107                 }
108             }
109             
110         });
111     </script>
112 </body>
113 </html>
View Code

 


 


免責聲明!

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



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