Vue.js – 起手式

MR_LP發表於2019-03-02

請各位讀者新增一下作者的微信公眾號,以後有新的文章,將在微信公眾號直接推送給各位,非常感謝。

Vue.js – 起手式

0x00:前言


這次前言不想扯太多。

本文主要是記錄一下自己的學習歷程,順帶做一個總結。

其中有參考 Vue.js 的中文文件,也有去檢視其它大大們給出的總結。

最後也是一個期盼,希望能夠幫助到其他有需要的小夥伴。

補充:
第一次自學的話,推薦直接去檢視以下內容。

0x01:Vue 基礎介紹


以下部分內容參考於官方文件。

Vue.js 是什麼
Vue.js(讀音 /vjuː/, 類似於 view) 是一套構建使用者介面的 漸進式框架。與其他重量級框架不同的是,Vue 採用自底向上增量開發的設計。Vue 的核心庫只關注檢視層,並且非常容易學習,非常容易與其它庫或已有專案整合。另一方面,Vue 完全有能力驅動採用單檔案元件和 Vue 生態系統支援的庫開發的複雜單頁應用。
Vue.js 的目標是通過儘可能簡單的 API 實現響應的資料繫結和組合的檢視元件。

至於很多小夥伴,對於是否要選擇 Vue 可能存在一些顧慮,或者說可能會覺得 Vue 不值得去學習。

在這裡,筆者和大家分享一句我以前打遊戲時很喜歡說的話。

沒有垃圾的英雄,只有菜比的玩家

每一個框架的存在都是有其特定意義的,只是在不同的使用場景,才會有適不適合之分。

此外再去補充一下關於 SegmentFault 在 2016 年 8 月給出的 Vue 的增長趨勢。

Vue.js – 起手式

由此也能看出來,Vue 的未來前景如何。

說了這麼多,也該書歸正文,一起來看一下,如果我們要學習 Vue,該做哪些準備?

0x02:Vue 和其他 MVVM 框架的對比

首先在開始學習 Vue 之前,我們首先需要了解一下,Vue 和其他框架有什麼不同?

這裡請允許我直接引用一下懶得安分大神的話術。

關於MVVM,原來在介紹knockout.js的時候有過講解,目前市面上比較火的MVVM框架也是一抓一大把,比如常見的有Knockout.js、Vue.js、AvalonJSAngularjs等,每一款都有它們自己的優勢。

  • Knockout:微軟出品,可以說是MVVM的模型領域內的先驅,使用函式偷龍轉鳳,最短編輯長度演算法實現DOM的同步,相容IE6,實現高超,但原始碼極其難讀,最近幾年發展緩慢。
  • Vue:是最近幾年出來的一個開源Javascript框架,語法精簡,實現精緻,但對瀏覽器的支援受限,最低只能支援IE9。
  • AvalonJS:是一個簡單易用迷你的MVVM框架,由大神司徒正美研發。使用簡單,實現明快。
  • React:React並不屬於MVVM架構,但是它帶來virtual dom的革命性概念,受限於檢視的規模。
  • Angularjs:Google出品,已經被用於Google的多款產品當中。AngularJS有著諸多特性,最為核心的是:MVC、模組化、自動化雙向資料繫結、語義化標籤、依賴注入等等。入門容易上手難,大量避不開的概念也是很頭疼的。

除此之外,在 Vue 的官網上也提供了和其他框架的對比。

Vue : 對比其他框架

0x03:什麼是 MVVM?

MVVM是Model-View-ViewModel的簡寫。
MVVM(Model-View-ViewModel)框架的由來便是MVP(Model-View-Presenter)模式與WPF結合的應用方式時發展演變過來的一種新型架構框架。它立足於原有MVP框架並且把WPF的新特性糅合進去,以應對客戶日益複雜的需求變化。

—-《百度百科》

除此以外,我們還可以通過這張圖來看一下 MVVM。

Vue.js – 起手式

這張圖足以說明MVVM的核心功能,在這三者裡面,ViewModel無疑起著重要的橋樑作用。

一方面,通過ViewModel將Model的資料繫結到View的Dom元素上面,當Model裡面的資料發生變化的時候,通過ViewModel裡面資料繫結的機制,觸發View裡面Dom元素的變化;

另一方面,又通過ViewModel來監聽View裡面的Dom元素的資料變化,當頁面上面的Dom元素髮生變化的時候,ViewModel通過Dom樹的監聽機制,觸發對應的Model的資料變化。

當然在Vue.js裡面ViewModel也是核心部件,它就是一個Vue例項。這個例項作用於單個或者多個html元素,從而實現Dom樹監聽和資料繫結的雙向更新操作。

0x04:Vue 的引入

關於 Vue 的引入,首先要明確一點。

Vue.js 不支援 IE8 及其以下版本,因為 Vue.js 使用了 IE8 不能模擬的 ECMAScript 5 特性。 Vue.js 支援所有相容 ECMAScript 5 的瀏覽器

除此之外,我們當然也可以去下載 Vue 的原始碼。

最後,我們在選擇安裝方式的時候,要注意vue-cli,對 Node.js 不夠熟悉的同學不推薦使用。

這裡附錄一下,關於 vue-cli 的路徑說明。

.
|-- build                            // 專案構建(webpack)相關程式碼
|   |-- build.js                     // 生產環境構建程式碼
|   |-- check-version.js             // 檢查node、npm等版本
|   |-- dev-client.js                // 熱過載相關
|   |-- dev-server.js                // 構建本地伺服器
|   |-- utils.js                     // 構建工具相關
|   |-- webpack.base.conf.js         // webpack基礎配置
|   |-- webpack.dev.conf.js          // webpack開發環境配置
|   |-- webpack.prod.conf.js         // webpack生產環境配置
|-- config                           // 專案開發環境配置
|   |-- dev.env.js                   // 開發環境變數
|   |-- index.js                     // 專案一些配置變數
|   |-- prod.env.js                  // 生產環境變數
|   |-- test.env.js                  // 測試環境變數
|-- src                              // 原始碼目錄
|   |-- components                   // vue公共元件
|   |-- store                        // vuex的狀態管理
|   |-- App.vue                      // 頁面入口檔案
|   |-- main.js                      // 程式入口檔案,載入各種公共元件
|-- static                           // 靜態檔案,比如一些圖片,json資料等
|   |-- data                         // 群聊分析得到的資料用於資料視覺化
|-- .babelrc                         // ES6語法編譯配置
|-- .editorconfig                    // 定義程式碼格式
|-- .gitignore                       // git上傳需要忽略的檔案格式
|-- README.md                        // 專案說明
|-- favicon.ico 
|-- index.html                       // 入口頁面
|-- package.json                     // 專案基本資訊複製程式碼

這裡我們們直接去使用一下官方推薦的基礎引入方法。

<script src="https://unpkg.com/vue/dist/vue.js"></script>複製程式碼

0x05:Vue 的宣告式渲染

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <!--引入 Vue-->
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="div">
        {{message}}
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    var app = new Vue({
            //注意這裡,需要填寫的是對應的選擇器
            el:"#div",
            data: {
                message:"hello vue!"
            }
    })
</script>
</html>複製程式碼

其中使用到了兩個需要注意的內容。

  • el :
    • 提供一個在頁面上已存在的 DOM 元素作為 Vue 例項的掛載目標。
    • 其實說白了就是需要繫結的 DOM 元素。
  • data :
    • Vue 例項的資料物件。
    • 大概來說,data 應該只能是資料 – 不推薦觀察擁有狀態行為的物件。

這是官方給出的基本案例,我們在這個案例之上,去從新書寫一個新的案例。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <!--引入 Vue-->
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>姓名:{{ Name }}</h1>
        <h1>年齡:{{ Age }}</h1>
        <h1>性別:{{ Sex }}</h1>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
     //Model
    var data = {
        Name: `李先生`,
        Age: 18,
        Sex:`男人`,
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

用 MVVM 的角度,來從新看待這個問題,我們會發現。

  • Model就是data變數
  • ViewModel就是這裡的new Vue()得到的物件

需要注意,我們在上方所使用的 {{message}} 是 Vue 中資料繫結最常見的形式。

也就是去使用 “Mustache” 語法(雙大括號)來在文字中插入值。

Mustache 標籤將會被替代為對應資料物件上 msg 屬性的值。無論何時,繫結的資料物件上 msg 屬性發生了改變,插值處的內容都會更新。

但是請注意,它所說的是繫結的資料物件的屬性發生改變才會更新。

Vue.js – 起手式

0x06:處理使用者輸入

Vue 提供了 v-model 指令,它使得在表單輸入和應用狀態中做雙向資料繫結變得非常輕巧。

你可以用 v-model 指令在表單控制元件元素上建立雙向資料繫結。
它會根據控制元件型別自動選取正確的方法來更新元素。
儘管有些神奇,但 v-model 本質上不過是語法糖,它負責監聽使用者的輸入事件以更新資料,並特別處理一些極端的例子。

首先來看一個例子。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
      <input v-model="message" placeholder="edit me">
      <p>{{ message }}</p>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    var app = new Vue({
      el: `#app`,
      data: {
        message: `測試文字`
      }
    })
</script>
</html>複製程式碼

我們會發現,一旦我們輸入某些內容,我們對應標籤頁會實時更新,這種方式我們一般稱之為雙向繫結。

除此之外,我們還可以針對像 textarea 等內容進行資料的繫結。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <span>Multiline message is:</span>
        <p style="white-space: pre">{{ message }}</p>
        <br>
        <textarea v-model="message" placeholder="add multiple lines" style="resize: none;"></textarea>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    var app = new Vue({
      el: `#app`,
      data: {
        message: ` `
      }
    })
</script>
</html>複製程式碼

同時需要注意,在文字區域插值<textarea></textarea>並不會生效,應用 v-model 來代替。

更多內容請參照,表單資料繫結

0x07:Vue 常用指令

以下內容,我就直接轉載 懶得安分大神的文章,並對其內容作了更改。

Vue裡面為我們提供的常用指令主要有以下一些。

每一個指令都可以連結到相關文件,博主覺得文件裡面每種指令的語法寫得非常詳細,在此就沒必要重複做說明了,下面博主打算將一些常用的指令以分組的形式分別結合demo來進行解釋說明。

0x08:v-text、v-html指令

v-text、v-html這兩者分為一組很好理解,一個用於繫結文字,一個用於繫結html。

上文使用到的 {{ Name }}這種寫法就是v-text的的縮寫形式。這個很簡單,沒什麼好糾結的,看一個Demo就能明白。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>姓名:<label v-text="Name"></label></h1>
        <h1>姓名:{{ Name }}</h1>
        <div style="font-size:30px;font-weight:bold;" v-html="Age">年齡:</div>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //Model
    var data = {
        Name: `李先生`,
        Age: "<label>20</label>",
        School:`大連某校`,
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

Vue.js – 起手式

程式碼說明:

  • {{Name}}這種寫法和v-text的作用是相同的,用於繫結標籤的text屬性。注意如果標籤沒有text屬性,該繫結會失效,比如你在一個文字框上面使用v-text是沒有效果的
  • 由得到的效果可以看出,v-html繫結後會覆蓋原來標籤裡面的內容(比如上面的“年齡:”),記住此處是覆蓋而非append。
  • 對於v-html應用的時候要慎重,在網站上動態渲染任意 HTML 有一定的危險存在,因為容易導致 XSS 跨站指令碼攻擊。所以最好是在信任的網址上面使用。
  • 注意v-text和v-html繫結都是單向的,只能從Model到View的繫結,不能實現View到Model的更新。

0x09:v-model指令

v-model上面有介紹它的雙向繫結功能,對於v-model指令,vue限定只能對錶單控制元件進行繫結,常見的有<input><select><textarea>等。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h2>編輯姓名:<input type="text" v-model="Name" /></h2>
        <h2>姓名:{{Name}}</h2>
        <hr />
        <h2>編輯備註:<textarea v-model="Remark"></textarea></h2>
        <h2>備註:{{Remark}}</h2>
        <hr />

        <input type="checkbox" id="basketball" value="籃球" v-model="Hobby">
        <label for="basketball">籃球</label>
        <input type="checkbox" id="football" value="足球" v-model="Hobby">
        <label for="football">足球</label>
        <input type="checkbox" id="running" value="跑步" v-model="Hobby">
        <label for="running">跑步</label>
        <br>
        <h2>學生愛好: {{ Hobby }}</h2>

        <hr />
        <h2>戶籍:{{ Huji }}</h2>
        <select style="width:100px;" class="form-control" v-model="Huji">
            <option>湖南</option>
            <option>廣東</option>
            <option>北京</option>
        </select>
</body>
<script type="text/javascript" charset="utf-8">
     //Model
    var data = {
        Name: `李先生`,
        Age: 18,
        School: `光明小學`,
        Hobby: [],
        Remark: `三好學生`,
        Huji:""
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

Vue.js – 起手式

關於selece的資料來源的動態繫結,我們留在v-for指令的時候介紹。

0x10:v-if、v-else指令

v-if和v-else是一對離不開的好兄弟,使用條件運算子判斷時常用。需要說明的是,v-if可以單獨使用,但是v-else的前面必須要有一個v-if的條件或者v-show指令(後面介紹),這個和我們程式設計的原理是一樣一樣的。

它們作為條件渲染指令,他們的基礎語法如下:

v-if="expression",v-else;複製程式碼

注意這裡的v-else可以不寫,expression表示式是一個返回bool型別的屬性或者表示式。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
     <div id="app">
        <h1>姓名:<label v-text="Name"></label></h1>
        <h1>是否已婚:<span v-if="IsMarry"></span></h1>
        <h1>大人or小孩:<span v-if="Age>18">大人</span><span v-else>小屁孩</span></h1>
        <h1>學校:{{ School }}</h1>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //Model
    var data = {
        Name: `李先生`,
        IsMarry: true,
        Age: 20,
        School:`大連某校`,
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

Vue.js – 起手式

#0x11:v-show指令

v-show指令表示根據表示式之bool值,覺得是否顯示該元素。需要說明的是,如果bool值false,對應的Dom標籤還是會渲染到頁面上面,只是將該標籤的css屬性display設為none而已。而如果你用v-if值,bool值為false的時候整個dom樹都不被渲染到頁面上面。從這點上來說看,如果你的需求是需要經常切換元素的顯示和隱藏,使用v-show效率更高,而如果你只做一次條件判斷,使用v-if更加合適。

v-show還常和v-else一起使用,表示如果v-show條件滿足,則顯示當前標籤,否則顯示v-else標籤。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
     <div id="app">
        <h1>姓名:<label v-text="Name"></label></h1>
        <h1>是否已婚:<span v-show="IsMarry"></span></h1>
        <h1>學校:{{ School }}</h1>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //Model
    var data = {
        Name: `李先生`,
        IsMarry: false,
        Age: 20,
        School:`大連某校`,
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

Vue.js – 起手式

0x12:v-for指令

v-for 指令需要以 item in items 形式的特殊語法。常用來繫結資料物件。

最簡單的例子:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
      <div id="app">
        <ul>
            <li v-for="value in nums">{{value}}</li>
        </ul>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: {
            nums: [1, 2, 3, 4, 5, 6, 7, 8, 9]
        }
    });
</script>
</html>複製程式碼

Vue.js – 起手式

除了基礎資料之外,還支援Json陣列的繫結。比如:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <ul>
            <li v-for="value in values">姓名:{{value.Name}},年齡:{{value.Age}}</li>
        </ul>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: {
            values: [{ Name: "李先生", Age: 20 }, { Name: "小剛", Age: 18 }, { Name: "小紅", Age: 16 }]
        }
    });
</script>
</html>複製程式碼

Vue.js – 起手式

0x13:v-once指令

v-once表示只渲染元素和元件一次。隨後的重新渲染,元素/元件及其所有的子節點將被視為靜態內容並跳過。什麼意思呢?還是來看demo說話:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>姓名:<label v-once v-text="Name"></label></h1>
        <h1 v-once>年齡:{{ Age }}</h1>
        <h1>學校:{{ School }}</h1>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //Model
    var data = {
        Name: `李先生`,
        Age: 18,
        School:`光明小學`,
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

Vue.js – 起手式

可以看出,只要使用v-once指令的,View和Model之間除了初次渲染同步,之後便不再同步,而同一次繫結裡面沒使用v-once指令的還是會繼續同步。

#0x14:v-bind指令

對於html標籤的text、value等屬性,Vue裡面提供了v-text、v-model去繫結。但是對於除此之外的其他屬性呢,這就要用到接下來要講的v-bind指令了。博主的理解是v-bind的作用是繫結除了text、value之外的其他html標籤屬性,常見的比如class、style、自定義標籤的自定義屬性等。它的語法如下:

v-bind:property="expression"複製程式碼

先來看幾個簡單的例子。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>姓名:<label v-text="Name"></label></h1>
        <h1>是否紅領巾:<span class="class1" v-bind:class="{backred:IsBack}"><label v-if="IsBack"></label></span></h1>
        <h1>學校星級:<span v-bind:style="{color:SchoolLevel}">aa</span></h1>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //Model
    var data = {
        Name: `李先生`,
        Age: 18,
        School: `光明小學`,
        SchoolLevel: `red`,
        IsBack:true
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

需要說明的是同一個標籤裡面的同一個屬性,可以既有繫結的寫法,也有靜態的寫法,元件會自動幫你合併,比如上文中的class屬性。

得到效果如下:

Vue.js – 起手式

0x15:v-on指令

屬性jquery的朋友應該很熟悉這個“on”,對於時間的監聽和繫結,jquery裡面最常用的就是on了。同樣,在Vue裡面,v-on指令用來繫結標籤的事件,其語法和v-bind基本類似。

v-on:event="expression";複製程式碼

這裡的event可以是Javascript裡面的常用事件,也可以是自定義事件。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>姓名:<label v-text="Name"></label></h1>
        <h1>年齡:{{ Age }}</h1>

        <button class="btn btn-primary" v-on:click="Age++;if(Name==`李先生`)Name=`吉姆格林`;else Name=`李先生`;">
                年齡遞增
        </button>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //Model
    var data = {
        Name: `李先生`,
        Age: 18,
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
    });
</script>
</html>複製程式碼

這段程式碼是一個最簡單的應用,直接在click事件裡面執行邏輯,改變變數的值。效果如下:

Vue.js – 起手式

除了直接在標籤內寫處理邏輯,還可以定義方法事件處理器。

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <script src="https://unpkg.com/vue/dist/vue.js"></script>
</head>
<body>
    <div id="app">
        <h1>姓名:<label v-text="Name"></label></h1>
        <h1>年齡:{{ Age }}</h1>

        <button class="btn btn-primary" v-on:click="Hello">Hello</button>
    </div>
</body>
<script type="text/javascript" charset="utf-8">
    //Model
    var data = {
        Name: `李先生`,
        Age: 18,
    }

    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
        methods: {
            Hello: function (event) {
                // `this` 在方法裡指當前 Vue 例項
                alert(`Hello ` + this.Name + `!`);
                this.Age++;
            }
        }
    });
</script>
</html>複製程式碼

Vue.js – 起手式

0x16:例項一:30分鐘搞定增刪改查

在編寫這個例項之前,首先先說明一下當前文件中需要引入的庫。

實現效果:

Vue.js – 起手式

案例原始碼:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <link href="bootstrap/css/bootstrap.css" rel="stylesheet" />
    <style type="text/css">
        table thead tr th {
            text-align:center;
        }
    </style>
</head>
<body>
    <div style="padding:20px;" id="app">
        <div class="panel panel-primary">
            <div class="panel-heading">使用者管理</div>
            <table class="table table-bordered table-striped text-center">
                <thead>
                    <tr>
                        <th>使用者名稱</th>
                        <th>年齡</th>
                        <th>畢業學校</th>
                        <th>備註</th>
                        <th>操作</th>
                    </tr>
                </thead>
                <tbody>
                    <template v-for="row in rows ">
                        <tr><td>{{row.Name}}</td><td>{{row.Age}}</td><td>{{row.School}}</td><td>{{row.Remark}}</td>
                        <td><a href="#" @click="Edit(row)">編輯</a>  <a href="#" @click="Delete(row.Id)">刪除</a></td>
                        </tr>
                    </template>
                    <tr>
                        <td><input type="text" class="form-control" v-model="rowtemplate.Name" /></td>
                        <td><input type="text" class="form-control" v-model="rowtemplate.Age" /></td>
                        <td><select class="form-control" v-model="rowtemplate.School">
                    <option>中山小學</option>
                    <option>復興中學</option>
                    <option>光明小學</option>
                </select></td>
                        <td><input type="text" class="form-control" v-model="rowtemplate.Remark" /></td>
                        <td><button type="button" class="btn btn-primary" v-on:click="Save">儲存</button></td>
                    </tr>
                </tbody>
            </table>
        </div>
    </div>
</body>
<script src="JQuery/jquery-3.1.1.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript" charset="utf-8">
    //Model
        var data = {
            rows: [
            { Id: 1, Name: `李先生`, Age: 18, School: `光明小學`, Remark: `三好學生` },
            { Id: 2, Name: `小剛`, Age: 20, School: `復興中學`, Remark: `優秀班幹部` },
            { Id: 3, Name: `吉姆格林`, Age: 19, School: `光明小學`, Remark: `吉姆做了汽車公司經理` },
            { Id: 4, Name: `李雷`, Age: 25, School: `復興中學`, Remark: `不老實的傢伙` },
            { Id: 5, Name: `韓梅梅`, Age: 22, School: `光明小學`, Remark: `在一起` },
            ],
            rowtemplate: { Id: 0, Name: ``, Age: ``, School: ``, Remark: `` }
        };
    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
        methods: {
            Save: function (event) {
                if (this.rowtemplate.Id == 0) {
                    //設定當前新增行的Id
                    this.rowtemplate.Id = this.rows.length + 1;
                    this.rows.push(this.rowtemplate);
                }

                //還原模板
                this.rowtemplate = { Id: 0, Name: ``, Age: ``, School: ``, Remark: `` }
            },
            Delete: function (id) {
                //實際專案中引數操作肯定會涉及到id去後臺刪除,這裡只是展示,先這麼處理。
                for (var i=0;i<this.rows.length;i++){
                    if (this.rows[i].Id == id) {
                        this.rows.splice(i, 1);
                        break;
                    }
                }
            },
            Edit: function (row) {
                this.rowtemplate = row;
            }
        }
    });
</script>
</html>複製程式碼

#0x17:例項二:帶分頁的表格

上面的例子用最簡單的方式實現了一個增刪改查,為了進一步體驗我們Vue的神奇,博主更進了一步,用Vue去做了一個客戶端分頁的表格功能。其實程式碼量並不大。

實現效果:

Vue.js – 起手式

這裡做出一下修改,參照於原帖中某位讀者的留言,給出一種更優的解決方案。

案例程式碼:

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <link href="bootstrap/css/bootstrap.css" rel="stylesheet" />
    <style type="text/css">
        table thead tr th {
            text-align:center;
        }
    </style>
</head>
<body>
    <<div style="padding:20px;" id="app">
        <div class="panel panel-primary">
            <div class="panel-heading">使用者管理</div>
            <table class="table table-bordered table-striped text-center">
                <thead>
                    <tr>
                        <th>使用者名稱</th>
                        <th>年齡</th>
                        <th>畢業學校</th>
                        <th>備註</th>
                    </tr>
                </thead>
                <tbody>
                    <template v-for="(row, index) in rows ">
                        <tr v-if="index>=(curpage-1)*pagesize&&index<curpage*pagesize">
                            <td>{{row.Name}}</td>
                            <td>{{row.Age}}</td>
                            <td>{{row.School}}</td>
                            <td>{{row.Remark}}</td>
                        </tr>
                    </template>
                </tbody>
            </table>
        </div>
        <nav style="float:right;">
            <ul class="pagination pagination-lg">
                <li v-if="curpage==1" class="disabled"><a href="#">上一頁</a></li>
                <li v-else v-on:click="PrePage()" ><a href="#">上一頁</a></li>
                <template v-for="page in pageCount">
                    <li v-if="page==curpage" class="active" v-on:click="NumPage(page, $event)"><a href="#">{{page}}</a></li>
                    <li v-else v-on:click="NumPage(page, $event)"><a href="#">{{page}}</a></li>
                </template>
                <li v-if="curpage==pageCount" class="disabled"><a href="#">下一頁</a></li>
                <li v-else v-on:click="NextPage()" ><a href="#">下一頁</a></li>
            </ul>
        </nav>
    </div>
</body>
<script src="JQuery/jquery-3.1.1.min.js" type="text/javascript" charset="utf-8"></script>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script type="text/javascript" charset="utf-8">
    //Model
        var data = {
            rows: [
            { Id: 1, Name: `李先生`, Age: 18, School: `光明小學`, Remark: `三好學生` },
            { Id: 2, Name: `小剛`, Age: 20, School: `復興中學`, Remark: `優秀班幹部` },
            { Id: 3, Name: `吉姆格林`, Age: 19, School: `光明小學`, Remark: `吉姆做了汽車公司經理` },
            { Id: 4, Name: `李雷`, Age: 25, School: `復興中學`, Remark: `不老實的傢伙` },
            { Id: 5, Name: `韓梅梅`, Age: 22, School: `光明小學`, Remark: `在一起` },
            { Id: 1, Name: `李先生`, Age: 18, School: `光明小學`, Remark: `三好學生` },
            { Id: 2, Name: `小剛`, Age: 20, School: `復興中學`, Remark: `優秀班幹部` },
            { Id: 3, Name: `吉姆格林`, Age: 19, School: `光明小學`, Remark: `吉姆做了汽車公司經理` },
            { Id: 4, Name: `李雷`, Age: 25, School: `復興中學`, Remark: `不老實的傢伙` },
            { Id: 5, Name: `韓梅梅`, Age: 22, School: `光明小學`, Remark: `在一起` },
            { Id: 1, Name: `李先生`, Age: 18, School: `光明小學`, Remark: `三好學生` },
            { Id: 2, Name: `小剛`, Age: 20, School: `復興中學`, Remark: `優秀班幹部` },
            { Id: 3, Name: `吉姆格林`, Age: 19, School: `光明小學`, Remark: `吉姆做了汽車公司經理` },
            { Id: 4, Name: `李雷`, Age: 25, School: `復興中學`, Remark: `不老實的傢伙` },
            { Id: 5, Name: `韓梅梅`, Age: 22, School: `光明小學`, Remark: `在一起` },
            { Id: 1, Name: `李先生`, Age: 18, School: `光明小學`, Remark: `三好學生` },
            { Id: 2, Name: `小剛`, Age: 20, School: `復興中學`, Remark: `優秀班幹部` },
            { Id: 3, Name: `吉姆格林`, Age: 19, School: `光明小學`, Remark: `吉姆做了汽車公司經理` },
            { Id: 4, Name: `李雷`, Age: 25, School: `復興中學`, Remark: `不老實的傢伙` },
            { Id: 5, Name: `韓梅梅`, Age: 22, School: `光明小學`, Remark: `在一起` },
            ],
            pagesize: 6,
            curpage:1,//當前頁的頁碼
        };
    //ViewModel
    var vue = new Vue({
        el: `#app`,
        data: data,
        created:function(){
            this.pageCount = Math.ceil(this.rows.length/this.pagesize);
        },
        methods: {
            //上一頁方法
            PrePage: function (event) {
                if (this.curpage>1) {
                    this.curpage = this.curpage-1;
                }
            },
            //下一頁方法
            NextPage: function (event) {
                if (this.curpage < this.pageCount) {
                    this.curpage = this.curpage+1;
                }
            },
            //點選頁碼的方法
            NumPage: function (num, event) {
                if (this.curpage == num) {
                    return;
                }
                this.curpage = num;
            }
        }
    });
</script>
</html>複製程式碼

#0x18:後記

本文主體參考於 懶得安分 大神 的 文章。
JS元件系列——又一款MVVM元件:Vue(一:30分鐘搞定前端增刪改查)

除此之外,還有部分內容是摘抄於 Vue 的官網。

本文僅做個人學習記錄之用,請勿隨意轉載。

若需轉載請私信,並在文章開始位置放上作者和原文連結。

謝謝。

李鵬
2017年02月16日11:32:21

相關文章