淺入淺出Vue

zimo發表於2017-11-27

前言

vue,在2017已經不是什麼新鮮詞了!作為一個前端學習者,今天寫下學習總結。

本篇主要是一些vue的學習總結。開始寫的原因——也是工作中,對於它的使用,逐漸增多了。並且也覺得是時候做一個總結。其實,我也算是三大框架的使用者啦!!!從最早期的angular,中期的react,直至vue。那麼,就此開始做一個總結。如果你喜歡我的文章,歡迎評論,歡迎Star~。歡迎關注我的github部落格

正文

其實,我並不知道從何開始去總結vue,因為vue的官方文件,可謂“中文開發者”的福音,實在是太全了!再次致敬悠大大。那麼,我們廢話不多說,還是從基本的東西說起——物件

相信看了文件的小夥伴,都會意識到Vue具備一個Vue的建構函式。如果使用ES5的語法來書寫vue時,我們往往可以看到以下的例項:

var app = new Vue({
    //....
});複製程式碼

在其中配置各種的引數,例如:

  • el:掛載點,其實就是一個選擇器,可以在瀏覽器解析完之後,將Vue物件掛載到對應的選擇器上
  • data:這個就是內部狀態的資料,之後或許還會涉及到。
  • computed和methods:方法,通常是一些函式
  • 生命週期階段

當然咯,還會有其他的屬性,例如components等等。具體的可以看官方文件。

資料響應

此處,我們引出了物件,那麼我們就從vue的響應式原理講起吧。Vue的思想可以說是從angular1.x開始衍生出來的,元素的基因,讓他具備了一些輕便的指令。當然,從react中,它借鑑了VDOM等思想。那麼,你是否考慮過它的響應式原理。

它同React一樣,屬於資料驅動型框架,它們均有一個正規化:F(data) = view。同時,react可以通過setState這個關鍵方法達到這樣子的效果,那麼,Vue呢?Vue是如何實現的呢?

答案——「資料劫持」。其實,從ES5開始,物件就可以通過一個API來定義屬性,如下:

var obj = {};

Object.defineProperty(obj, 'name', {
  value: 'zimo'
});

console.log(obj.name);複製程式碼

這裡可以看到,我們通過這樣子的方式也可以定義物件的屬性。所以Vue在獲得data中的內容之後,會將其中的資料,通過這樣子的形式定義到Vue物件上面。然後,我們通過set和get方法的監聽,來劫持資料,我們可以通過一個例子來說明:

var obj = {};

Object.defineProperty(obj, 'name', {
  get: function(){
    console.log('get');
    return val;
  },
  set: function(value){
    console.log('set');
    val = value;
  }
});

obj.name = 'zimo';    //'set'
console.log(obj.name);    //'get',  'zimo'複製程式碼

看過例子之後,我們會發現這defineProperty的API中使用set和get方法時,可以對物件資料進行劫持。這種效果,就可以達到setState的效果。

注:vue中,必須保證資料驅動的資料保證在物件建立時設定,即在data中設定。這樣才可以達到資料劫持的效果。

官網原話:值得注意的是只有當例項被建立時 data 中存在的屬性是響應式

但是,你會覺得這種方式是完美的嗎?當然不是,我們可以來看一個例子(該例子通過上面改編的):

var obj = {};

Object.defineProperty(obj, 'name', {
  get: function(){
    console.log('get');
    return val;
  },
  set: function(value){
    console.log('set');
    console.log(value);
    val = value;
  }
});

obj.name = ['zimo'];
obj.name[0] = 1;
console.log(obj.name); 
// "set"
// ["zimo"]
// "get"
// "get"
// [1]複製程式碼

這個例子中發生了什麼你一定好奇?或者說,你已經看出來了!那麼我們直接說吧!

這裡的obj.name[0]=1表示式並沒有觸發setter的函式。不信的話,你可以親自動手嘗試一下。相信只有親自動手才會使得記憶深刻一些。

陣列通過索引的方式去改變資料,適合並不會觸發setter進行資料劫持。這個問題在早期的vue中的確存在。當然了,這麼嚴重的問題,自然是會被解決的。相信熟悉ES6的人都知道,ES6中具備一個非常好的特性可以解決這個問題——proxy。每次就是資料代理,這種方式,可以在上述方法的基礎上,進一步解決我們之前提到的缺點。

那麼,關於proxy的問題,我在此處並不會做深入分析。

生命週期

上面我們大致搞清楚了vue的資料響應原理,那麼data中的資料一旦發生變化,除了資料劫持發生之外,總該談談生命週期的話題了。

生命週期,就是一個元件,或是一個物件的存在時期。從最初的建立、安裝、更新、解除安裝。我們可以通過官網的圖來實際說明:

生命週期
生命週期

這幅圖中,清晰地講明瞭,vue元件地從建構函式建立到銷燬地全過程。

公用方法定義

既然我們知道了vue是由物件組成的,那麼,我們往往會有些方法,並不僅僅是在一個Vue物件中使用的,舉個例子:

我需要在vue中使用圖表highchart,那麼我可以做如下的操作:

import Highchart from 'highchart';

Vue.prototype.$highchart = Highchart;

const app = new Vue({
    methods: {
        init: function () {
            this.$highchart() //...
        }
    }
})複製程式碼

當然了,我們只是舉了一個通俗的例子,通過這樣子的方式,你就可以在Vue物件中新增許多原型方法,但是,需要記得的是——在方法定義時,請帶上'$'符號,方便進行區分。

vue2.0

vue2.0是一個大版本的更迭,同時它的改變,使得越來越多的人喜歡使用它。它在這個版本中,引入了VDOM的概念。相信接觸過React的小夥伴們,對VDOM這個概念應該一點也不陌生吧。

不得不說地是這樣的改變,使得vue的效能得到了極大的提升。尤其是像diff演算法的優化,react中體現地淋漓盡致。獲取可以看我的另一篇文章——react diff演算法

總結

關於vue的東西,其實還有很多。作為可以與react、angular並駕齊驅的三架馬車。它的優越之處在於總結了angular1.0的失敗之處,綜合了react的優雅之點。同時,它也深深地嵌入了尤大大的個人智慧。同時,為前端程式設計師提供了良好的學習環境。本篇淺入淺出vue.js到此結束。

如果你對我寫的有疑問,可以評論,如我寫的有錯誤,歡迎指正。你喜歡我的部落格,請給我關注Star~呦。大家一起總結一起進步。歡迎關注我的github部落格

相關文章