Vue 淺談前端js框架vue

Vue

Vue近幾年來特別的受關注,三年前的時候angularJS霸佔前端JS框架市場很長時間,接着react框架橫空出世,由於它有一個特性是虛擬DOM,從性能上碾軋angularJS,這個時候,vue1.0悄悄javascript

的問世了,它的優雅,輕便也吸引了一部分用戶,開始收到關注,16年中旬,VUE2.0問世,這個時候vue無論從性能上,仍是從成本上都隱隱超過了react,火的一塌糊塗,這個時候,angularcss

開發團隊也開發了angular2.0版本,而且改名爲angular,吸取了react、vue的優勢,加上angular自己的特色,也吸引到不少用戶,目前已經迭代到5.0了。html

學習vue是如今前端開發者必須的一個技能。前端

前端js框架到底在幹嗎,爲何要用

js框架幫助開發者寫js邏輯代碼,在開發應用的時候js的功能劃分爲以下幾點:vue

  1. 渲染數據java

  2. 操做dom(寫一些效果)react

  3. 操做cookie等存儲機制apiwebpack

在前端開發中,如何高效的操做dom、渲染數據是一個前端工程師須要考慮的問題,並且當數據量大,流向較亂的時候,如何正確使用數據,操做數據也是一個問題angularjs

而js框架對上述的幾個問題都有本身趨於完美的解決方案,開發成本下降。高性能高效率。惟一的缺點就是須要使用必定的成原本學習。web

Vue官網介紹

vue是漸進式JavaScript框架

「漸進式框架」和「自底向上增量開發的設計」是Vue開發的兩個概念

Vue能夠在任意其餘類型的項目中使用,使用成本較低,更靈活,主張較弱,在Vue的項目中也能夠輕鬆融匯其餘的技術來開發,而且由於Vue的生態系統特別龐大,能夠找到基本全部類型的工

具在vue項目中使用

特色:易用(使用成本低),靈活(生態系統完善,適用於任何規模的項目),高效(體積小,優化好,性能好)

Vue是一個MVVM的js框架,可是,Vue 的核心庫只關注視圖層,開發者關注的只是m-v的映射關係

與AngularJS的對比

Vue的不少api、特性都與angularJS類似,實際上是由於Vue在開發的時候借鑑了不少AngularJS中的特色,而AngularJS中固有的缺點,在Vue中已經解決,也就是青出於藍而勝於藍,Vue的學習

成本比AngularJS低不少,由於複雜性就低

AngularJS是強主張的,而Vue更靈活

Vue的數據流是單向的,數據流行更清晰

Angular裏指令能夠是操做dom的,也能夠封裝一段結構邏輯代碼,例如:廣告展現模塊

Vue中的指令只是操做dom的,用組件來分離結構邏輯

AngularJS的性能比不上Vue

Vue的使用

Vue不支持IE8,由於使用了ES5的不少特性

能夠直接經過script標籤來引入vue.js,有開發版本和生產版本,開發版本通常咱們在開發項目的時候引入,當最後開發完成上線的時候引入生產版本,開發版本沒有壓縮的,而且有不少提

示,而生產版本所有刪掉了

在Vue中提供了一個腳手架(命令行工具)能夠幫咱們快速的搭建基於webpack的開發環境...

Vue的實例

每個應用都有一個根實例,在根實例裏咱們經過組件嵌套來實現大型的應用

也就是說組件不必定是必須的,可是實例是必需要有的

在實例化實例的時候咱們能夠傳入一個;配置項,在配置項中設置不少屬性方法能夠實現複雜的功能

在配置中能夠設置el的屬性,el屬性表明的是此實例的做用範圍

在配置中同過設置data屬性來爲實例綁定數據

mvc/mvvm

摘自阮一峯博客

mvc 分爲三層,其實M層是數據模型層,它是真正的後端數據在前端js中的一個映射模型,他們的關係是:數據模型層和視圖層有映射關係,model改變,view展現也會更改,當view產生用戶

操做或會反饋給controller,controller更改model,這個時候view又會進行新的數據渲染

MVC

這是純純的MVC的模式,可是不少框架都會有一些更改

前端mvc框架,如angularjs,backbone:

前端MVC

會發現,用戶能夠直接操做controller(例如用戶更改hash值,conrtoller直接監聽hash值變化後執行邏輯代碼,而後通知model更改)

控制器能夠直接操做view,若是,讓某一個標籤得到進入頁面得到焦點,不須要model來控制,因此通常會直接操做(angularJS,指令)

view能夠直接操做model (數據雙向綁定)

MVP:

mvp

view和model不能直接通訊,全部的交互都由presenter來作,其餘部分的通訊都是雙向的

view較薄 ,presenter較爲厚重

MVVM:

mvvm

MVVM和MVP及其類似,只是view和viewmodel的通訊是雙向綁定,view的操做會自動的像viewmodel經過

v-for

在vue中能夠經過v-for來循環數據的通知循環dom,語法是item in/of items,接收第二個參數是索引 (item,index) of items,還能夠循環鍵值對,第一個參數是value,第二個是key,第三

個依然是索引

v-on

在vue中還有v-on來爲dom綁定事件,在v-on:後面加上要綁定的事件類型,值裏能夠執行一些簡單javascript表達式:++ -- = ...

能夠將一些方法設置在methods裏,這樣就能夠在v-on:click的值裏直接寫方法名字能夠,默認會在方法中傳入事件對象,當寫方法的時候加了()就能夠傳參,這個時候若是須要事件對象,那

就主動傳入$event

v-on綁定的事件能夠是任意事件,v-on:能夠縮寫爲@

爲何在 HTML 中監聽事件?

你可能注意到這種事件監聽的方式違背了關注點分離 (separation of concern) 這個長期以來的優良傳統。但沒必要擔憂,由於全部的 Vue.js 事件處理方法和表達式都嚴格綁定在當前視圖的

ViewModel 上,它不會致使任何維護上的困難。實際上,使用 v-on 有幾個好處:

  1. 掃一眼 HTML 模板便能輕鬆定位在 JavaScript 代碼裏對應的方法。
  2. 由於你無須在 JavaScript 裏手動綁定事件,你的 ViewModel 代碼能夠是很是純粹的邏輯,和 DOM 徹底解耦,更易於測試。
  3. 當一個 ViewModel 被銷燬時,全部的事件處理器都會自動被刪除。你無須擔憂如何本身清理它們。
模板語法

在vue中,咱們使用mustache插值({{}})來將數據渲染在模板中

使用v-once指令能夠控制只能插入一次值,當數據變化的時候,模板對應的視圖不更新

使用v-html指令能夠解析html格式的數據

在html標籤屬性裏不能使用mustache插值,這個時候給元素添加動態屬性的時候使用v-bind來綁定屬性,能夠縮寫成:

在使用v-bind綁定class和內聯樣式的時候,vue作了一些優化,可使用對象語法和數組的語法來控制

防止表達式閃爍:

  1. v-cloak

    給模板內的元素添加v-cloak屬性後,元素在vue沒有加載完的時候就有這個屬性,當vue加載完成後這個屬性就消失了,因此咱們能夠給這個屬性設置css樣式爲隱藏

    <style>
     [v-cloak]{
         visibility: hidden;
     }
     </style>
  2. v-text/v-html

    v-text會指定將模板內元素的textContent屬性替換爲指令值所表明的數據,也能夠用於防止閃爍
    v-html能夠解析標籤,更改元素的innerHTML,性能比v-text較差

  3. v-pre

    跳過元素和其子元素的編譯過程,能夠用來顯示mustache

vue-resource

這是一款vue的插件,能夠用來進行數據交互,支持的請求方式:GET/POST/JSONP/OPTIONS...

這個插件官方宣佈不在更新維護,也就是說盡可能不要使用

計算屬性、監聽
有的時候咱們須要在模板中使用數據a,這個時候就須要用到表達式,可是有的地方咱們須要對a數據進行一些簡單的處理後才能使用,那麼咱們就會在表達式中寫一些js邏輯運算

```
<div id="example">
{{ message.split('').reverse().join('') }}
</div>
```
這樣咱們的維護就會很是困難,也不便於閱讀


那め咱們就能夠在methods裏設置一個方法,在模板的表達式中使用這個方法

```
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在組件中
methods: {
reversedMessage: function () {
    return this.message.split('').reverse().join('')
}
}
```

可是這個時候,只要vm中有數據變化,這個變化的數據可能和咱們關注的數據無關,可是vm都會從新渲染模板,這個時候表達式中的方法就會從新執行,大大的影響性能


這個時候其實咱們可使用監聽器裏完成:

在vm實例中設置watch屬性,在裏面經過鍵值對來設置一些監聽,鍵名爲數據名,值能夠是一個函數,這個函數在數據改變以後纔會執行,兩個參數分別是性格前的值和更改後的值
a: function (val, oldVal) {
        console.log('new: %s, old: %s', val, oldVal)
    }
值還能夠是一個方法名字,當數據改變的時候這個方法會執行

當數據爲object的時候,object的鍵值對改變不會被監聽到(數組的push等方法能夠),這個時候須要設置深度監聽:
c: {
        deep:true,
        handler:function (val, oldVal) {
            console.log('new: %s, old: %s', val, oldVal)
        }
    },
監聽的handler函數前面的這幾種寫法都是在數據變化的時候纔會執行,初始化的時候不會執行,可是若是設置immediate爲true就能夠了
num:{
        immediate:true,
        handler:function(val){
            this.nums = val*2
        }
    }
咱們在回到上面的問題,用監聽器加上immediate屬性就能夠作到該效果,可是你們能夠看到的是邏輯稍稍有點複雜

watch還能夠經過實例對象直接使用:vm.$watch,返回一個取消監聽的函數,這個函數執行以後會取消監聽


咱們通常都會用到一個叫計算屬性的東西來解決:

計算屬性就是在實例配置項中經過computed來爲vm設置一個新的數據,而這個新數據會擁有一個依賴(一條已經存在的數據),當依賴發送變化的時候,新數據也會發送變化

與方法的方式相比,它性能更高,計算屬性是基於它們的依賴進行緩存的。計算屬性只有在它的相關依賴發生改變時纔會從新求值。相比之下,每當觸發從新渲染時,調用方法將總會再

次執行函數。

與watch相比,寫起來簡單,邏輯性更清晰,watch通常多用於,根據數據的變化而執行某些動做,而至於這些動做是在幹什麼其實無所謂,而計算屬性更有針對性,根據數據變化而更改

另外一個數據

計算屬性也擁有getter和setter,默認寫的是getter,設置setter執行能夠當此計算屬性數據更改的時候去作其餘的一些事情,至關於watch這個計算屬性
xm:{
        get:function(){//getter 當依賴改變後設置值的時候
            return this.xing+'丶'+this.ming
        },
        set:function(val){//setter 當自身改變後執行
            this.xing = val.split('丶')[0]
            this.ming = val.split('丶')[1]
        }
    }
過濾器

vue中能夠設置filter(過濾器)來實現數據格式化,雙花括號插值和 v-bind 表達式中使用

vue1.0的有默認的過濾器,可是在2.0的時候所有給去掉了

因此在vue中若是想要使用過濾器就須要自定義

自定義的方法有兩種:全局定義和局部定義,全局定義的過濾器在任意的實例、組件中均可以使用,局部定義就是在實例、組件中定義,只能在這個實例或組件中使用

  1. 全局定義

    Vue.filter(name,handler)

    name是過濾器的名字,handler是數據格式化處理函數,接收的第一個參數就是要處理的數據,返回什麼數據,格式化的結果就是什麼

    在模板中經過 | (管道符) 來使用,在過濾器名字後面加()來傳參,參數會在handler函數中第二個及後面的形參來接收

<p>{{msg | firstUpper(3,2)}}</p>

    Vue.filter('firstUpper',function (value,num=1,num2) {
        console.log(num2)
        return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase()
    })
  1. 局部定義

    在實例、組件的配置項中設置 filters,鍵名爲過濾器名,值爲handler

    filters:{
         firstUpper:function (value,num=1,num2) {
         console.log(num2)
         return value.substr(0,num).toUpperCase()+value.substr(num).toLowerCase()
         }
     }

注意:

過濾器只能在mustache插值、v-bind裏使用,其餘的指令等地方都不能用
條件渲染

在Vue中可使用v-if來控制模板裏元素的顯示和隱藏,值爲true就顯示,爲false就隱藏

v-if控制的是是否渲染這個節點

當咱們須要控制一組元素顯示隱藏的時候,能夠用template標籤將其包裹,將指令設置在template上,等等vm渲染這一組元素的時候,不會渲染template

當有else分支邏輯的時候,能夠給該元素加上v-else指令來控制,v-else會根據上面的那個v-if來控制,效果與v-if相反,注意,必定要緊挨着

還有v-else-if指令能夠實現多分支邏輯

<input type="text" v-model="mode">  
      <template  v-if="mode=='A'">
        <h1>1.title</h1>
        <p>個人第一個P標籤</p>  
      </template>
     <template  v-else-if="mode=='B'">
        <h1>2.title</h1>
        <p>個人第二個P標籤</p>
     </template>
     <template  v-else-if="mode=='C'">
        <h1>3.title</h1>
        <p>個人第三個P標籤</p>
     </template>
     <template  v-else>
       
        <p>很差意思,輸入有誤</p>
     </template>

須要注意的另外一個地方是:Vue 會盡量高效地渲染元素,一般會複用已有元素而不是從頭開始渲染。這樣確實能使Vue變得更快,性能更高,可是有的時候咱們須要讓實例去更新dom而不是

複用,就須要給dom加上不一樣的key屬性,由於vue在判斷到底渲染什麼的時候,包括哪些dom能夠複用,都會參考key值,若是dom表現基本一致,符合複用的條件,可是key值不一樣,依然不會復

Vue還提供了v-show指令,用法和v-if基本同樣,控制的是元素的css中display屬性,從而控制元素的顯示和隱藏 , 不能和v-else配合使用,且不能使用在template標籤上,由於template不

會渲染,再更改它的css屬性也不會渲染,不會生效

v-if vs v-show

v-if 是「真正」的條件渲染,由於它會確保在切換過程當中條件塊內的事件監聽器和子組件適當地被銷燬和重建。
v-if 也是惰性的:若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。
相比之下,v-show 就簡單得多——無論初始條件是什麼,元素老是會被渲染,而且只是簡單地基於 CSS 進行切換。
通常來講,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。所以,若是須要很是頻繁地切換,則使用 v-show 較好;若是在運行時條件不多改變,則使用 v-if 較好。

mixin

在Vue中,咱們能夠經過定義多個mixin來實現代碼抽離複用,便於維護,提高頁面的邏輯性

要注意的是:data屬性不要使用mixin,由於從邏輯上來講,每個實例、組件的數據都應該是獨立的

一個mixin其實就是一個純粹的對象,上面掛載着抽離出來的配置,在某一個實例中,經過mixins選項(數組)導入後,此實例就擁有導入的mixin的配置

且導入的配置不會覆蓋原有的,而是合併到一塊兒

虛擬dom

頻繁且複雜的dom操做一般是前端性能瓶頸的產生點,Vue提供了虛擬dom的解決辦法

虛擬的DOM的核心思想是:對複雜的文檔DOM結構,提供一種方便的工具,進行最小化地DOM操做。這句話,也許過於抽象,卻基本概況了虛擬DOM的設計思想

(1) 提供一種方便的工具,使得開發效率獲得保證

(2) 保證最小化的DOM操做,使得執行效率獲得保證

也就是說,虛擬dom的框架/工具都是這麼作的:

  1. 根據現有的真實dom來生成一個完整的虛擬dom樹結構
  2. 當數據變化,或者說是頁面須要從新渲染的時候,會從新生成一個新的完整的虛擬dom
  3. 拿新的虛擬dom來和舊的虛擬dom作對比(使用diff算法),。獲得須要更新的地方以後,更新內容

這樣的話,就能大量減小真實dom的操做,提升性能

組件化

模塊化就是將系統功能分離成獨立的功能部分的方法,通常指的是單個的某一種東西,例如js、css

而組件化針對的是頁面中的整個完整的功能模塊劃分,組件是一個html、css、js、image等外鏈資源,這些部分組成的一個聚合體

優勢:代碼複用,便於維護

劃分組件的原則:具備大量的佈局結構的,或者是獨立的邏輯的,都應該分紅組件

組件應該擁有的特性:可組合,可重用,可測試,可維護

組件

在vue中,咱們經過Vue.extend來建立Vue的子類,這個東西其實就是組件

也就是說Vue實例和組件的實例有差異可是差異不帶,由於畢竟一個是父類一個是子類

通常的應用,會擁有一個根實例,在根實例裏面都是一個一個的組件

由於組件是要嵌入到實例或者父組件裏的,也就是說,組件能夠互相嵌套,並且,全部的組件最外層必須有一個根實例,因此組件分爲:全局組件和局部組件

全局組件在任意的實例、父級組件中都能使用,局部組件只能在建立本身的父級組件或者實例中使用

組件經過不一樣的註冊方法成爲全局、局部組件

建立組件:

Vue.extend(options)

全局註冊:

var App = Vue.extend({
        template:"<h1>hello world</h1>"
    })
    Vue.component('my-app',App)

組件經過template來肯定本身的模板,template裏的模板必須有根節點,標籤必須閉合

組件的屬性掛載經過:data方法來返回一個對象做爲組件的屬性,這樣作的目的是爲了每個組件實例都擁有獨立的data屬性

響應式原理

由於vue是mvvm的框架,因此當數據變化的時候,視圖會當即更新,視圖層產生操做後會自動通知vm來更改model,因此咱們能夠實現雙向數據綁定,而其中的原理就是實例會將設置的data逐

個遍歷利用Object.defineProperty給數據生成getter和setter,當數據變化地方時候setter會監聽到而且通知對應的watcher工具進行邏輯運算會更新視圖

聲明式渲染

在vue中,咱們能夠先在vue實例中聲明數據,而後經過{{}}等方式渲染在dom中

相關文章
相關標籤/搜索