1、提到框架,先引入框架模式MVC、MVVM、MVP,下面分別介紹了其概念及異同css
MVC是Model-View-Controller的縮寫,特色在於實現關注點分離,即應用程序中的數據模型與業務和展現邏輯解耦。它將應用程序劃分爲三個部分:html
Model: 模型(用於封裝與應用程序的業務邏輯相關的數據以及對數據的處理方法)View: 視圖(渲染頁面)Controller: 控制器(M和V之間的鏈接器,用於控制應用程序的流程,及頁面的業務邏輯)前端
MVC流程一共有兩種:vue
一種是經過 View 接受指令,傳遞給 Controller,而後對模型進行修改或者查找底層數據,最後把改動渲染在視圖上。 另外一種是經過controller接受指令,傳給View。node
MVP是MVC改良模式,和MVC的相同之處在於:Controller/Presenter負責業務邏輯,Model管理數據,View負責顯示只不過是將 Controller 更名爲 Presenter,同時改變了通訊方向。react
M、V、P之間雙向通訊。View 與 Model 不通訊,都經過 Presenter 傳遞。Presenter徹底把Model和View進行了分離。webpack
MVVM是Model-View-ViewModel的簡寫,主要目的是分離視圖(View)和模型(Model)。 git
MVVM特色: 1) 低耦合。視圖(View)能夠獨立於Model變化和修改,一個ViewModel能夠綁定到不一樣的"View"上,當View變化的時候Model能夠不變,當Model變化的時候View也能夠不變。angularjs
2.)可重用性。你能夠把一些視圖邏輯放在一個ViewModel裏面,讓不少view重用這段視圖邏輯。es6
3)獨立開發。開發人員能夠專一於業務邏輯和數據的開發(ViewModel),設計人員能夠專一於頁面設計。
4)可測試。界面素來是比較難於測試的,而如今測試能夠針對ViewModel來寫。
MVP與MVC有着一個重大的區別:在MVP中View並不直接使用Model,它們之間的通訊是經過 Presenter (MVC中的Controller)來進行的,全部的交互都發生在Presenter內部,而在MVC中View會直接從Model中讀取數據而不是經過 Controller。
MVVM 模式將 Presenter 更名爲 ViewModel,基本上與 MVP 模式徹底一致。 惟一的區別是,它採用雙向綁定(data-binding):View的變更,自動反映在 ViewModel,反之亦然。這樣開發者就不用處理接收事件和View更新的工做,框架已經幫你作好了。
2、Vue.js 是什麼
Vue.js是一個輕巧、高性能、可組件化的MVVM庫,同時擁有很是容易上手的API;
Vue.js是一個構建數據驅動的Web界面的庫。
Vue.js是一套構建用戶界面的漸進式框架。與其餘重量級框架不一樣的是,Vue 採用自底向上增量開發的設計。Vue 的核心庫只關注視圖層,而且很是容易學習,很是容易與其它庫或已有項目整合。另外一方面,Vue 徹底有能力驅動採用單文件組件和 Vue 生態系統支持的庫開發的複雜單頁應用。數據驅動+組件化的前端開發。
簡而言之:Vue.js是一個構建數據驅動的 web 界面的漸進式框架。Vue.js 的目標是經過儘量簡單的 API 實現響應的數據綁定和組合的視圖組件。核心是一個響應的數據綁定系統。
什麼是數據驅動
數據驅動是vue.js最大的特色。在vue.js中,所謂的數據驅動就是當數據發生變化的時候,用戶界面發生相應的變化,開發者不須要手動的去修改dom。
vue專一於ViewModel層,view對應DOM,Model對應js對象。vue經過Directives指令操做view,對dom監聽,經過dom listener改變model層變化。最終實現雙向綁定。
那麼vuejs是如何實現這種數據驅動的呢?(雙向綁定)
首先,vuejs在實例化的過程當中,會對實例化對象選項中的data 選項進行遍歷,遍歷其全部屬性並使用 Object.defineProperty 把這些屬性所有轉爲 getter/setter。同時每個實例對象都有一個watcher實例對象,他會在模板編譯的過程當中,用getter去訪問data的屬性,watcher此時就會把用到的data屬性記爲依賴,這樣就創建了視圖與數據之間的聯繫。當以後咱們渲染視圖的數據依賴發生改變(即數據的setter被調用)的時候,watcher會對比先後兩個的數值是否發生變化,而後肯定是否通知視圖進行從新渲染這樣就實現了所謂的數據對於視圖的驅動。
Vue.js的特性以下:
1.輕量級的框架
2.雙向數據綁定
3.指令
4.插件化
漸進式的理解:
Vue的核心的功能,是一個視圖模板引擎,但這不是說Vue就不能成爲一個框架。以下圖所示,這裏包含了Vue的全部部件,在聲明式渲染(視圖模板引擎)的基礎上,咱們能夠經過添加組件系統、客戶端路由、大規模狀態管理來構建一個完整的框架。更重要的是,這些功能相互獨立,你能夠在覈心功能的基礎上任意選用其餘的部件,不必定要所有整合在一塊兒。能夠看到,所說的「漸進式」,其實就是Vue的使用方式,同時也體現了Vue的設計的理念
圖掛了,見https://blog.csdn.net/weixin_41049850/article/details/79431682
好比,Angular,它兩個版本都是強主張的,若是你用它,必須接受如下東西:
因此Angular是帶有比較強的排它性的,若是你的應用不是從頭開始,而是要不斷考慮是否跟其餘東西集成,這些主張會帶來一些困擾。
好比React,它也有必定程度的主張,它的主張主要是函數式編程的理念,好比說,你須要知道什麼是反作用,什麼是純函數,如何隔離反作用。它的侵入性看似沒有Angular那麼強,主要由於它是軟性侵入。
Vue是漸進的,沒有強主張,你能夠在原有大系統的上面,把一兩個組件改用它實現,當jQuery用。
三.Vue.js與其餘框架的區別?
1.與angularjs的區別
相同點:
都支持指令:內置指令和自定義指令。都支持過濾器:內置過濾器和自定義過濾器。都支持雙向數據綁定。都不支持低端瀏覽器。
不一樣點:
(1).AngularJS的學習成本高,好比增長了Dependency Injection特性,而Vue.js自己提供的API都比較簡單、直觀。(2).在性能上,AngularJS依賴對數據作髒檢查,因此Watcher越多越慢。Vue.js使用基於依賴追蹤的觀察而且使用異步隊列更新。全部的數據都是獨立觸發的。對於龐大的應用來講,這個優化差別仍是比較明顯的。
髒檢查:
在 angular中,他沒有辦法判斷你的數據是否作了更改, 因此它設置了一些條件,當你觸發了這些條件以後,它就執行一個檢測來遍歷全部的數據,對比你更改了地方,而後執行變化。這個檢查很不科學。並且效率不高,有不少多餘的地方,因此官方稱爲 髒檢查
2.與React的區別
相同點:
react採用特殊的JSX語法,Vue.js在組件開發中也推崇編寫.vue特殊文件格式,對文件內容都有一些約定,二者都須要編譯後使用。
中心思想相同:一切都是組件,組件實例之間能夠嵌套。都提供合理的鉤子函數,可讓開發者定製化地去處理需求。都不內置列數AJAX,Route等功能到核心包,而是以插件的方式加載。在組件開發中都支持mixins的特性。
不一樣點:
React依賴Virtual DOM,而Vue.js使用的是DOM模板。React採用的Virtual DOM會對渲染出來的結果作髒檢查。Vue.js在模板中提供了指令,過濾器等,能夠很是方便,快捷地操做DOM。
3.吸收兩家之長,借鑑了Angular的指令(v-show,v-hide)和React的組件化(優勢:可維護性,複用性)
4、vue核心內容:
一、vue-cli:
vue是以組件化開發的,最好要搭配webpack構建工具開發,獨立搭建對大部分人較爲困難,vue-cli就能很好解決這一問題。即便你對webpack還不是很瞭解,你也能夠先搭建好項目在慢慢研究。cli已經將須要的東西配置好,只要寫好項目業務,在用命令行就能夠達到調試或打包的功能。
安裝:
首先node版本最好高於4.x.x,穩定。而後執行npm install -g vue-cli,安裝後選擇webpack模板(也可選擇其餘模板)vue init webpack 項目名稱而後按照提示選擇一些選項,以後按照後面提示執行cd 項目名稱,npm install便可。項目可經過npm run dev創建服務器,監聽了8080端口,就能夠經過localhost:8080訪問了。
各文件功能:
項目名稱 ->build ------------------------------------------ webpack配置相關文件 ->config ------------------------------------------ webpack配置相關文件 ->node_modules ------------------------------------------ 依賴代碼庫 ->src ------------------------------------------ 存放源碼 ->static ------------------------------------------ 存放第三方靜態資源 ->.babelrc.JSON ------------------------------------------ babe的配製,用於從es6編譯至es5 ->.editorconfig ------------------------------------------ 編譯器配置 ->.eslintignore ------------------------------------------ 忽略語法檢查的目錄文件 ->.eslintrc.js ------------------------------------------ eslint的配置 ->.gitignore ------------------------------------------ git忽略的目錄或文件 ->index.html ------------------------------------------ 入口文件,項目編譯過程當中會自動插入其中 ->package.json ------------------------------------------ 配置文件,描述一個項目 ->README.md ------------------------------------------ 項目描述文件
2.webpack
找到JS模塊及其它的一些瀏覽器不能直接運行的拓展語言(Scss,TypeScript等),並將其轉換和打包爲合適的格式供瀏覽器使用。
Webpack的工做方式是:把你的項目當作一個總體,經過一個給定的主文件(如:index.js),使用entry 屬性來定義入口。Webpack將從這個文件開始找到你的項目的全部依賴文件,使用loaders處理它們,最後打包爲一個或多個瀏覽器可識別的JavaScript文件。
出口:webpack 的 output 屬性描述瞭如何處理歸攏在一塊兒的代碼。
module.exports: 在咱們本身寫模塊的時候,須要在模塊最後寫好模塊接口,聲明這個模塊對外暴露什麼內容,module.exports 提供了暴露接口的方法
插件在 webpack 的配置信息 plugins 中指定,用於完成一些 loader 不能完成的工做。好比咱們能夠安裝內置的 BannerPlugin 插件,用於在文件頭部輸出一些註釋信息
Babel是一個編譯JSt的平臺,能使用最新的JavaScript代碼(ES6,ES7...),能使用基於JavaScript進行了拓展的語言,好比React的JSX。
Loader:webpack只能處理JS模塊,若是要處理其餘類型的文件,就須要使用 loader 進行轉換。css-loader 和 style-loader,兩者處理的任務不一樣, css-loader使你可以使用相似@import
和 url(...)
的方法實現 require()
的功能,style-loader將全部的計算後的樣式加入頁面中,兩者組合在一塊兒使你可以把樣式表嵌入webpack打包後的JS文件中。
3.v-if和v-show
v-if是動態的向DOM樹內添加或者刪除DOM元素; 適合運營條件不大可能改變;切換有一個局部編譯/卸載的過程,切換過程當中合適地銷燬和重建內部的事件監聽和子組件;
v-show是經過設置DOM元素的display樣式屬性控制顯隱;適合頻繁切換;只是簡單的基於css切換。
v-else元素必須跟在前面二者之一的後面,不然不能被識別。
4.v-bind
用於響應地更新 HTML 特性 形式如:v-bind:href 縮寫爲 :href;
5.v-on
用於監聽DOM事件 形式如:v-on:click 縮寫爲 @click;
Vue.js 爲v-on提供了事件修飾符。在事件處理程序中調用 event.preventDefault()
或 event.stopPropagation()
是很是常見的需求。儘管咱們能夠在方法中輕鬆實現這點,但更好的方式是:方法只有純粹的數據邏輯,而不是去處理 DOM 事件細節。
<!-- 阻止單擊事件繼續傳播 --> <a v-on:click.stop="doThis"></a> <!-- 提交事件再也不重載頁面 --> <form v-on:submit.prevent="onSubmit"></form> <!-- 修飾符能夠串聯 --> <a v-on:click.stop.prevent="doThat"></a> <!-- 只有修飾符 --> <form v-on:submit.prevent></form> <!-- 添加事件監聽器時使用事件捕獲模式 --> <!-- 即元素自身觸發的事件先在此到處理,而後才交由內部元素進行處理 --> <div v-on:click.capture="doThis">...</div> <!-- 只當在 event.target 是當前元素自身時觸發處理函數 --> <!-- 即事件不是從內部元素觸發的 --> <div v-on:click.self="doThat">...</div> 使用修飾符時,順序很重要;相應的代碼會以一樣的順序產生。所以,用 v-on:click.prevent.self 會阻止全部的點擊,而 v-on:click.self.prevent 只會阻止對元素自身的點擊。
6.Vuex
Vuex 是一個專爲 Vue.js 應用程序開發的狀態管理模式,也就是 Vuex 就是處理數據的。
store是Vuex應用的核心,基本上就是一個容器,它包含着你的應用中大部分的狀態(state)。
Vuex如何管理數據:
state:惟一數據源 打個比方:state中定義一個x值,在整個應用中任意地方均可以取到。
getters: 就是計算屬性。
mutations: 更改state的惟一方法(只能同步,異步處理放在action中)。每一個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler) ,事件類型 = 方法名,回調函數 = 方法
actions: 處理mutations不能作的異步操做。其中 分發 就是 觸發
modules: 將前面四個分紅modules = { state: { ... }, mutations: { ... }, actions: { ... }, getters: { ... } }
七、一些重要的全局API
Vue.extend():建立一個子類,參數是一個包含組件選項的對象。而後使用$mount掛載到元素上.
注:extend和component做用基本相同,區別僅在於當咱們不須要組件名稱時,使用extend更簡便些; 而當咱們須要使用新的標籤時,那麼請使用component去建立組件
var author = Vue.extend({ template: "<p><a :href='url'>{{author}}</a></p>", data : function() { return { author : 'vamous', url : 'http://blog.csdn.net/Dear_Mr/article/details/72614370' } } }); 對應的HTML:<author></author> 擴展實例構造器須要掛載:new author().$mount('author');
Vue.nextTick([callback,context]):修改數據後馬上使用這個方法,獲取更新後的DOM
// 修改數據 vm.msg = 'Hello' // DOM 尚未更新 Vue.nextTick(function () { // DOM 更新了 })
Vue.set(object,key,value):設置對象的屬性。若是對象是響應式的,確保屬性被建立後也是響應式的,同時觸發視圖更新。這個方法用於避開Vue不能檢測屬性被添加的限制。
Vue.delete(object,key):刪除對象的屬性。若是對象是響應式的,確保刪除能觸發更新視圖。這個方法主要用於避開 Vue 不能檢測到屬性被刪除的限制,可是你應該不多會使用它。
Vue.directive(id,function(){}):註冊指令,指令跟組件同樣須要註冊才能使用。提供了五個鉤子函數來供咱們使用,分別表明了一個組件的各個生命週期。
>bind: 只調用一次,指令第一次綁定到元素時調用,用這個鉤子函數能夠定義一個在綁定時執行一次的初始化動做。
>inserted: 被綁定元素插入父節點時調用(父節點存在便可調用,沒必要存在於 document 中)。
>update: 被綁定元素所在的模板更新時調用,而不論綁定值是否變化。經過比較更新先後的綁定值,能夠忽略沒必要要的模板更新(詳細的鉤子函數參數見下)。
>componentUpdated: 被綁定元素所在模板完成一次更新週期時調用。
>unbind: 只調用一次, 指令與元素解綁時調用。
實例,刷新頁面input自動獲取焦點
<div id="app"> <input type="text" v-focus/> </div> <script> // 註冊一個全局自定義指令 v-focus Vue.directive('focus', { // 當綁定元素插入到 DOM 中。 inserted: function (el,binding) { // 聚焦元素 el.focus(); } }); new Vue({ el:'#app' }); </script>
Vue.filter( id, [definition] ):註冊或獲取全局過濾器.
// 註冊 Vue.filter('my-filter', function (value) { // 返回處理後的值 }) // getter,返回已註冊的過濾器 var myFilter = Vue.filter('my-filter')
Vue.component(id, [definition]):註冊或獲取全局組件。註冊還會自動使用給定的id
設置組件的名稱
// 註冊組件,傳入一個擴展過的構造器 Vue.component('my-component', Vue.extend({ /* ... */ })) // 註冊組件,傳入一個選項對象(自動調用 Vue.extend) Vue.component('my-component', { /* ... */ }) // 獲取註冊的組件(始終返回構造器) var MyComponent = Vue.component('my-component')
Vue.mixin:混入 (mixins) 是一種分發 Vue 組件中可複用功能的很是靈活的方式。混入對象能夠包含任意組件選項。當組件使用混入對象時,全部混入對象的選項將被混入該組件自己的選項。
通俗一點的說,就是定義一部分公共的方法或者計算屬性,而後混入到各個組件中使用,方便管理與統一修改。
// 定義一個混入對象 var myMixin = { created: function () { this.hello() }, methods: { hello: function () { console.log('hello from mixin!') } } } // 定義一個使用混入對象的組件 var Component = Vue.extend({ mixins: [myMixin] }) var component = new Component() // => "hello from mixin!"
八、props:能夠是數組或對象,用於接收來自父組件的數據。
九、watch:鍵是須要觀察的表達式,值是對應回調函數。Vue實例將會在實例化時調用之,遍歷watch對象的每個屬性。
十、render:字符串模板的代替方案,容許你發揮 JavaScript 最大的編程能力。
十一、生命週期鉤子
beforecreated:el 和 data 並未初始化 ,能夠在這加個loading事件
created:完成了 data 數據的初始化,el沒有,在這結束loading,還作一些初始化,實現函數自執行
beforeMount:完成了 el 和 data 初始化
mounted:完成掛載, 在這發起後端請求,拿回數據,配合路由鉤子作一些事情
beforeDestory:銷燬,執行了destroy操做,後續就再也不受vue控制了。應用:你確認刪除XX嗎? destroyed :當前組件已被刪除,清空相關內容。
注意:不要在選項屬性或回調上使用箭頭函數,好比 created: () => console.log(this.a)
或 vm.$watch('a', newValue => this.myMethod())
。由於箭頭函數是和父級上下文綁定在一塊兒的,this
不會是如你所預期的 Vue 實例,常常致使 Uncaught TypeError: Cannot read property of undefined
或 Uncaught TypeError: this.myMethod is not a function
之類的錯誤。
十二、model(2.2.0新增)
容許一個自定義組件在使用 v-model
時定製 prop 和 event。默認狀況下,一個組件上的 v-model
會把 value
用做 prop 且把 input
用做 event,可是一些輸入類型好比單選框和複選框按鈕可能想使用 value
prop 來達到不一樣的目的。使用 model
選項能夠迴避這些狀況產生的衝突。
Vue.component('my-checkbox', { model: { prop: 'checked', event: 'change' }, props: { // this allows using the `value` prop for a different purpose value: String, // use `checked` as the prop which take the place of `value` checked: { type: Number, default: 0 } }, // ... }) <my-checkbox v-model="foo" value="some value"></my-checkbox>
1三、組件
每用一次組件,就會有一個它的新實例被建立。
一個組件的 data
選項必須是一個函數。
能夠調用內建的$emit方法,並傳入事件的名字,來向父級組件觸發一個事件。
全局註冊和局部註冊:
全局註冊: Vue.component('my-component-name', { // ... 選項 ... }) 它們在註冊以後能夠用在任何新建立的 Vue 根實例 (new Vue) 的模板中 Vue.component('component-a', { /* ... */ }) Vue.component('component-b', { /* ... */ }) Vue.component('component-c', { /* ... */ }) new Vue({ el: '#app' }) html <div id="app"> <component-a></component-a> <component-b></component-b> <component-c></component-c> </div>
全局註冊的弊端在於:若是你使用webpack這樣的構建系統,全局註冊意味着即使你再也不使用一個組件,它仍然會被包含在你最終的構建結果中。這形成了用戶下載的 JavaScript 的無謂的增長。
局部註冊: var ComponentA = { /* ... */ } var ComponentB = { /* ... */ } var ComponentC = { /* ... */ } 而後 new Vue({ el: '#app' components: { 'component-a': ComponentA, 'component-b': ComponentB } })
注意局部註冊的組件在其子組件中不可用。例如,若是你但願 ComponentA
在 ComponentB
中可用,則你須要這樣寫:
var ComponentA = { /* ... */ } var ComponentB = { components: { 'component-a': ComponentA }, // ... }
1四、slot
概述:簡單來講,假如父組件須要在子組件內放一些DOM,那麼這些DOM是顯示、不顯示、在哪一個地方顯示、如何顯示,就是slot分發負責的活。
默認狀況下,父組件在子組件內套的內容是不顯示的:
<div id="app"> <children> <span>12345</span> <!--上面這行不會顯示--> </children> </div> <script> var vm = new Vue({ el: '#app', components: { children: { template: "<button>爲了明確做用範圍,因此使用button標籤</button>" } } }); </script> 顯示內容是一個button按鈕,不包含span標籤裏面的內容;
使用slot標籤的話,能夠將父組件放在子組件的內容,放到想讓他顯示的地方。父組件放在子組件裏的內容,插到了子組件的<slot></slot>位置;即便有多個標籤,會一塊兒被插入,至關於用父組件放在子組件裏的標籤,替換了<slot></slot>這個標籤。
<div id="app"> <children> <span>12345</span> <!--上面這行不會顯示--> </children> </div> <script> var vm = new Vue({ el: '#app', components: { children: { //這個無返回值,不會繼續派發 template: "<button><slot></slot>爲了明確做用範圍,因此使用button標籤</button>" } } }); </script> 結果是: <button><span>12345</span>爲了明確做用範圍,因此使用button標籤</button>
假如父組件沒有在子組件中放置有標籤,或者是父組件在子組件中放置標籤,但有slot屬性,而子組件中沒有該slot屬性的標籤。那麼,子組件的slot標籤,將不會起到任何做用。
1五、provide和inject:
全部後代都須要訪問同一個方法時,使用$parent沒法很好擴展到更深層記得嵌套組件,可以使用上述方法。例如:
<google-map> <google-map-region v-bind:shape="cityBoundaries"> <google-map-markers v-bind:places="iceCreamShops"></google-map-markers> </google-map-region> </google-map>
全部的<google-map>後代都須要getMap方法,provide容許制定提供給後代組件的數據/方法:
provide: function () { return { getMap: this.getMap } }
而後再相應組件裏使用inject接受屬性。
inject: ['getMap']
1六、過渡(transition)
整個階段有6個class過程:
v-enter:進入過渡的開始狀態,元素被插入前生效,被插入後的下一幀移除;
v-enter-active:進入過渡生效時的狀態。在整個進入過渡的階段中應用,在元素被插入以前生效,在過渡/動畫完成以後移除。這個類能夠被用來定義進入過渡的過程時間,延遲和曲線函數;
v-enter-to:進入過渡的結束狀態。在元素被插入以後下一幀生效 ,在過渡/動畫完成以後移除;
v-leave:離開過渡的開始狀態。在離開過渡被觸發時馬上生效,下一幀被移除;
v-leave-active:離開過渡生效時的狀態。在整個離開過渡的階段中應用,在離開過渡被觸發時馬上生效,在過渡/動畫完成以後移除。這個類能夠被用來定義離開過渡的過程時間,延遲和曲線函數。
v-leave-to:離開過渡的結束狀態。在離開過渡被觸發以後下一幀生效,在過渡/動畫完成以後移除。
注:若是你使用一個沒有名字的 <transition>
,則 v-
是這些類名的默認前綴。若是你使用了 <transition name="my-transition">
,那麼 v-enter
會替換爲 my-transition-enter
動畫animationend,同過渡,區別是在動畫中v-enter在節點插入DOM後不回當即刪除,而在animationend觸發時刪除。
1七、自定義指令:
使用directive建立,以下所示。
// 註冊一個全局自定義指令 `v-focus` Vue.directive('focus', { // 當被綁定的元素插入到 DOM 中時…… inserted: function (el) { // 聚焦元素 el.focus() } }) //局部指令 directives: { focus: { // 指令的定義 inserted: function (el) { el.focus() } } }
1八、過濾器:
只能在雙花括號內和v-bind表達式使用。定義經過filters:{}實現(或者全局的vue.filter())。