一、前端MVC概要 1.1、庫與框架的區別 框架是一個軟體的半成品,在全局範圍內給了大的約束。庫是工具,在單點上給我們提供功能。框架是依賴庫的。Vue是框架而jQuery則是庫。 1.2、AMD與CMD 在傳統的非模塊化JavaScript開發中有許多問題:命名衝突、文件依賴、跨環境共用模塊、性能優 ...
一、前端MVC概要
1.1、庫與框架的區別
框架是一個軟體的半成品,在全局範圍內給了大的約束。庫是工具,在單點上給我們提供功能。框架是依賴庫的。Vue是框架而jQuery則是庫。
1.2、AMD與CMD
在傳統的非模塊化JavaScript開發中有許多問題:命名衝突、文件依賴、跨環境共用模塊、性能優化、職責單一、模塊的版本管理、jQuery等前端庫層出不窮,前端代碼日益膨脹
AMD規範及其代表:RequireJS
非同步模塊定義(Asynchronous Module Definition),它是依賴前置 (因為依賴必須一開始就寫好)會先儘早地執行(依賴)模塊 , 相當於所有的require都被提前了
CMD規範及其代表:SeaJS
(Common Module Definition)模塊定義規範
一個模塊就是一個文件;它推崇依賴就近想什麼時候require就什麼時候載入,實現了 懶載入, 延遲執行 (as lazy as possible)
1.2、前端MVC概要
MVC的核心理念是:你應該把管理數據的代碼(Model)、業務邏輯的代碼(Controller)、以及向用戶展示數據的代碼(View)清晰的分離開
- 模型:代表應用當前的狀態
- 視圖:用於展示數據,用於介面
- 控制器:用來管理模型和視圖之間的關係
通過MVC框架又衍生出了許多其它的架構,統稱MV*,最常見的是MVP與MVVM
MVVM(Model-View-ViewModel)框架的由來便是MVP(Model-View-Presenter)模式與WPF結合的應用方式時發展演變過來的一種新型架構框架。
Vue與Angular就是一個MVVM框架,MVVM與MVC最大的區別是模型與視圖實現了雙向綁定。
在Vue中用戶自定義的實例就是vm,功能與Controller類似
1.3、React
React 起源於 Facebook 的內部項目,因為該公司對市場上所有 JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設 Instagram 的網站。做出來以後,發現這套東西很好用,就在2013年5月開源了。由於 React 的設計思想極其獨特,屬於革命性創新,性能出眾,代碼邏輯卻非常簡單。所以,越來越多的人開始關註和使用,認為它可能是將來 Web 開發的主流工具。支持虛擬DOM(Virtual DOM)和組件化的開發。
ReactJS官網地址:
http://facebook.github.io/react/
Github地址:
https://github.com/facebook/react
1.4、AngularJS簡介
AngularJS是一個前端MVVM框架。
angular的英文字面意思是:有角的; 用角測量的
AngularJS是協助搭建單頁面工程(SPA)的開源前端框架。它通過MVC模式使得開發與測試變得更容易。
AngularJS試圖成為WEB應用中的一種端對端的解決方案。它將指導開發整個應用。
AngularJS於2009年發佈第一個版本,由Google進行維護,壓縮版94k。
1.3版後不再支持IE8
1.3版後不支持全局控制器
2.0版 alpha
git倉庫: https://github.com/angular/
官網: https://www.angularjs.org/
http://www.angularjs.cn/中文社區
http://www.apjs.net/ 中文網
a web framework for modern web apps
1.5、Vue.js
Vue.js是一個輕巧、高性能、可組件化的MVVM庫,同時擁有非常容易上手的API,作者是尤雨溪是中國人。
易用
已經會了HTML,CSS,JavaScript?即刻閱讀指南開始構建應用!
靈活
簡單小巧的核心,漸進式技術棧,足以應付任何規模的應用。
性能
17kb min+gzip 運行大小、超快虛擬 DOM 、最省心的優化
當前三大前端MVC框架的對比:
1.5.1、Vue2.JS簡介
Vue (讀音 /vjuː/,類似於 view) 是一套用於構建用戶界面的漸進式框架。與其它大型框架不同的是,Vue 被設計為可以自底向上逐層應用。Vue 的核心庫只關註視圖層,不僅易於上手,還便於與第三方庫或既有項目整合。另一方面,當與 現代化的工具鏈以及各種 支持類庫結合使用時,Vue 也完全能夠為複雜的單頁應用提供驅動。
如果你已經是有經驗的前端開發者,想知道 Vue 與其它庫/框架有哪些區別,請查看 對比其它框架。
不適合SEO、交互頻繁的,如游戲之類交互體驗網站
瀏覽器支持:
Vue.js 不支持 IE8 及其以下版本,因為 Vue.js 使用了 IE8 不能模擬的 ECMAScript 5 特性。Vue.js 支持所有 相容 ECMAScript 5 的瀏覽器。
1.6、vue2入門示例
文章中的許多內容都是來自vue官網,因為沒有其它更加合適的教程。
1.6.1、獲取vue2
如果要開發基於angularJS的項目,則先要添加對angularJS的引用,有如下幾個方法:
1)、去vue2官網或git下載,地址:
https://github.com/vuejs/vue
2)、使用cdn
3)、安裝node.js,使用npm獲取
具體的安裝細節: https://cn.vuejs.org/v2/guide/installation.html
在本文的示例中已經包含了運行環境與幫助文件chm
1.6.2、聲明式渲染
Vue.js 的核心是一個允許採用簡潔的模板語法來聲明式地將數據渲染進 DOM 的系統:
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue2介紹</title> </head> <body> <div id="app1"> {{message}} </div> <div id="app2"> <span v-bind:title="message"> 把滑鼠放到這裡試試 </span> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //vue應用對象 var app1 = new Vue({ el: "#app1", data: { message: "Hello Vue2!" } }); //綁定屬性 var app2 = new Vue({ el: "#app2", data: { message: "頁面載入時間是:" + new Date().toLocaleDateString() } }); </script> </body> </html>
結果:
這裡我們遇到了一點新東西。你看到的 v-bind
特性被稱為指令。指令帶有首碼 v-
,以表示它們是 Vue 提供的特殊特性。可能你已經猜到了,它們會在渲染的 DOM 上應用特殊的響應式行為。在這裡,該指令的意思是:“將這個元素節點的 title
特性和 Vue 實例的 message
屬性保持一致”。
如果你再次打開瀏覽器的 JavaScript 控制台,輸入 app2.message = '新消息'
,就會再一次看到這個綁定了 title
特性的 HTML 已經進行了更新。
我們已經成功創建了第一個 Vue 應用!看起來這跟渲染一個字元串模板非常類似,但是 Vue 在背後做了大量工作。現在數據和 DOM 已經被建立了關聯,所有東西都是響應式的。我們要怎麼確認呢?打開你的瀏覽器的 JavaScript 控制台 (就在這個頁面打開),並修改 app.message
的值,你將看到上例相應地更新。
1.6.3、條件與迴圈
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue2介紹</title> </head> <body> <div id="app3"> <span v-if="isShow"> isShow為true時你可以看到我 </span> </div> <div id="app4"> <span v-if="isShow"> <table border="1" cellspacing="1" cellpadding="1" width="50%"> <tr><th>序號</th><th>名稱</th><th>價格</th></tr> <tr v-for="(obj,index) in fruits"> <td>{{index+1}}</td> <td>{{obj.name}}</td> <td>{{obj.price}}</td> </tr> </table> </span> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //if指令 var app3 = new Vue({ el: "#app3", data: { isShow: true } }); //迴圈指令 var app4 = new Vue({ el: "#app4", data: { isShow:true, fruits: [{ name: "蘋果", price: "6.8" }, { name: "橙子", price: "3.5" }, { name: "香蕉", price: "2.3" }] } }); </script> </body> </html>
結果:
這個例子演示了我們不僅可以把數據綁定到 DOM 文本或特性,還可以綁定到 DOM 結構。此外,Vue 也提供一個強大的過渡效果系統,可以在 Vue 插入/更新/移除元素時自動應用 過渡效果。
1.6.4、事件、處理用戶輸入與計算
為了讓用戶和你的應用進行交互,我們可以用 v-on 指令添加一個事件監聽器,通過它調用在 Vue 實例中定義的方法:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue2介紹</title> </head> <body> <div id="app5"> <button v-on:click="showMe">{{message}}</button> <input v-model="message" /> </div> <p id="app6"> <button v-on:click="n1+=1">+</button><input v-model="n1"/>+ <input v-model="n2"/>= <input v-model="sum"/> </p> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //事件 var app5 = new Vue({ el: "#app5", data: { message:"vue2事件" }, methods:{ showMe:function(){ this.message=this.message.split('').reverse().join(''); } } }); //計算 var app6 = new Vue({ el: "#app6", data: { n1:0, n2:0 }, computed:{ sum:function(){ return parseInt(this.n1)+parseInt(this.n2); } } }); </script> </body> </html>
結果:
註意在 showMe方法中,我們更新了應用的狀態,但沒有觸碰 DOM——所有的 DOM 操作都由 Vue 來處理,你編寫的代碼只需要關註邏輯層面即可。
Vue 還提供了 v-model 指令,它能輕鬆實現表單輸入和應用狀態之間的雙向綁定。
二、組件化應用構建
組件系統是 Vue 的另一個重要概念,因為它是一種抽象,允許我們使用小型、獨立和通常可復用的組件構建大型應用。仔細想想,幾乎任意類型的應用界面都可以抽象為一個組件樹:
2.1、普通組件
在 Vue 里,一個組件本質上是一個擁有預定義選項的一個 Vue 實例。在 Vue 中註冊組件很簡單:
// 定義名為 todo-item 的新組件 Vue.component('todo-item', { template: '<li>這是個待辦項</li>' })
現在你可以用它構建另一個組件模板:
<ol> <!-- 創建一個 todo-item 組件的實例 --> <todo-item></todo-item> </ol>
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue2介紹</title> </head> <body> <div id="app1"> <ol> <todo-item></todo-item> </ol> <ol> <todo-item v-for="item in items"></todo-item> </ol> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //在vue中添加一個名為todo-item組件 Vue.component("todo-item",{ template:"<li>這是一個li單項</li>" }); //構件 var app1 = new Vue({ el: "#app1", data:{ items:[1,3,5,7,9] } }); </script> </body> </html>
結果:
2.2、帶屬性的組件
但是這樣會為每個待辦項渲染同樣的文本,這看起來並不炫酷。我們應該能從父作用域將數據傳到子組件才對。讓我們來修改一下組件的定義,使之能夠接受一個 prop:
Vue.component('todo-item', { // todo-item 組件現在接受一個 // "prop",類似於一個自定義特性。 // 這個 prop 名為 todo。 props: ['todo'], template: '<li>{{ todo.text }}</li>' })
現在,我們可以使用 v-bind
指令將待辦項傳到迴圈輸出的每個組件中:
<div id="app-7"> <ol> <!-- 現在我們為每個 todo-item 提供 todo 對象 todo 對象是變數,即其內容可以是動態的。 我們也需要為每個組件提供一個“key”,稍後再 作詳細解釋。 --> <todo-item v-for="item in groceryList" v-bind:todo="item" v-bind:key="item.id"> </todo-item> </ol> </div>
js:
Vue.component('todo-item', { props: ['todo'], template: '<li>{{ todo.text }}</li>' }) var app7 = new Vue({ el: '#app-7', data: { groceryList: [ { id: 0, text: '蔬菜' }, { id: 1, text: '乳酪' }, { id: 2, text: '隨便其它什麼人吃的東西' } ] } })
結果:
1.蔬菜 2.乳酪 3.隨便其它什麼人吃的東西
示例:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>vue2介紹</title> </head> <body> <div id="app1"> <ol> <todo-item info="Hello Component"></todo-item> </ol> <ol> <student-item v-for="item in students" v-bind:stu="item" v-bind:key="item.name"></student-item> </ol> </div> <script src="../js/vue.js" type="text/javascript" charset="utf-8"></script> <script type="text/javascript"> //在vue中添加一個名為todo-item組件 Vue.component("todo-item",{ props:["info","vtitle"], template:"<li>{{info||'empty'}}</li>" }); Vue.component("student-item",{ props:["stu"], template:"<li>{{stu.name}} - {{stu.age}}</li>" }); //構件 var app1 = new Vue({ el: "#app1", data:{ students:[ {"name":"tom","age":18},{"name":"rose","age":80},{"name":"lucy","age":8} ] } }); </script> </body> </html>
結果:
儘管這隻是一個刻意設計的例子,但是我們已經設法將應用分割成了兩個更小的單元。子單元通過 prop 介面與父單元進行了良好的解耦。我們現在可以進一步改進 <todo-item>
組件,提供更為複雜的模板和邏輯,而不會影響到父單元。
在一個大型應用中,有必要將整個應用程式劃分為組件,以使開發更易管理。
2.3、與自定義元素的關係
你可能已經註意到 Vue 組件非常類似於自定義元素——它是 Web 組件規範的一部分,這是因為 Vue 的組件語法部分參考了該規範。例如 Vue 組件實現了 Slot API 與 is
特性。但是,還是有幾個關鍵差別:
-
Web 組件規範仍然處於草案階段,並且未被所有瀏覽器原生實現。相比之下,Vue 組件不需要任何 polyfill,並且在所有支持的瀏覽器 (IE9 及更高版本) 之下表現一致。必要時,Vue 組件也可以包裝於原生自定義元素之內。
-
Vue 組件提供了純自定義元素所不具備的一些重要功能,最突出的是跨組件數據流、自定義事件通信以及構建工具集成。
三、綜合示例
通過一個綜合示例來快速瞭解Vue2,會使用到模板、過濾器、計算,表達式、組件等等,要求實現一個簡單的購物車,運行時的效果如下:
參考代碼:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>購物車</title> <style type="text/css"> .bg{ background:dodgerblue; color:white; } </style> </head> <body> <div id="app1"> <h2>購物車</h2> <table border="1" cellspacing="0" cellpadding="0" width="100%"> <tr> <th>序號</th> <th>名稱</th> <th>單價</th> <th>數量</th> <th>小計</th> <th>操作</th> </tr> <tr v-for="(pdt,index) in products" v-bind:class="{bg:index%2==0}"> <td>{{index+1}}</td> <td<