vue總結系列--數據驅動和相應式

在公司里幫項目組裡開闢背景體系的前端項目也有一段時間了。 vue這類數據驅動,組件化的框架和react很像,
從一最先的疾速上手基本的開闢,到厥後最先自定義組件,對element UI的組件二次封裝以滿足項目需求,時期也是踩了不少坑。
由於未來很長一段時間能夠再也不會打仗前端了,趁着如今對vue還很闇練的時刻,趕忙將這時期的收成紀錄下來。

根據我的明白,vue的特徵在於,高條理的籠統模子,組件化,數據驅動與響應式。
<!–more–>

注重:本文中一切涉及到{ {的,現實上不包括中心的空格,由於hexo會無腦把這個語法當做hexo的一種迥殊語法

vue是什麼及特徵

vue是什麼

簡樸的來講,vue是一套用於前端開闢的框架。
進修一門手藝起首應當對該手藝有着一個清楚準確的熟悉和思緒,不然如同浮沙之上建高樓。下面就來談談我對vue這個框架的明白。

vue它的冷艷的處所在於,對上,它供應了一套異常優異的與傳統前端判然差別的前端開闢模子,對下,它屏障了傳統前端開闢的種種貌寢的手藝。
在完成龐雜的頁面需求時,vue幫你從傳統前端的種種HACK般的奇淫技能擺脫出來,vue供應的籠統開闢模子具有壯大的 表達能力,能夠如絲順滑般的完成種種龐雜的需求。

總而言之,vue之於傳統前端,相似C言語之於彙編言語,就像C言語供應了一個壯大的表達能力強的言語模子一樣,vue一樣供應了一個刁悍的表達前端的框架模子,這是籠統的威力。
因而,進修vue的80%的重心,都在進修這個刁悍的vue模子上。

vue的特徵

從我個人對vue的明白,它的幾個主要特徵有:

  1. 籠統的組件。這是vue框架模子中的一個基本,vue的一切都是基於vue組件的。你在vue組件上能夠運用vue供應的種種特徵,vue會將其轉換成瀏覽器能夠辨認的結果經由過程瀏覽器襯着出來。
  2. 數據驅動。這是vue的理念之一,數據才是項目的中心,也是狀況的終究保留者。而視圖,只不過是一種能夠由數據耽誤盤算出來的終究結果罷了,它自身不存儲狀況。
  3. 響應式。既然襯着結果只是數據的衍生產品,那末當數據轉變時,襯着結果自然則然的也要轉變。這類機制就是響應式。
  4. 組件化。vue自身供應的 籠統特徵 。從我個人的明白來看,自定義組件在vue中的職位,相似於函數在C,java之類的言語當中的職位。

它另有幾個別的的的特徵:

  1. 易用和功用統籌。在我傳統的思想里,易用的東西平常會捐軀一部份功用,而功用壯大的東西會須要很大的本錢進修,魚和熊掌不可兼得。
    然則vue用現實行動狠狠給了我一耳光,只需模子設想的正交圓滿,完全能夠統籌易用性和功用性。
  2. 與傳統前端的優越兼容。
    我如今所做的項目中,由於需求的龐雜化項目須要從easy UI迭代到vue,底本我做好了雷厲風行大規模重構的預備,不過,經由查閱文檔和幾個小demo試驗我發明,這玩意竟然能夠和傳統前端並存!
    結果是異常使人高興的,我逐漸的,逐步的將項目從easy UI迭代到vue版本,一個頁面一個頁面的替換,對項目的影響下降到了最小。

組件定義

下面的例子定義了一個簡樸的組件,x-my-component。
由因而須要兼容easy UI的背景體系,該項目並不能運用到webpack + babel + es6等手藝,因而我在vue上的履歷大都是運用原生的js編寫的,

<div id="x-my-component">
    <div>
      { { message }}
    </div>
</div>

<script>
Vue.component('x-my-component', {
  template: '#x-my-component',
  data: function () {
      return {
        message: 'Hello Vue!'
      };
  }
});
</script>
  1. 能夠瞥見一個組件分為兩部份:視圖部份,和數據部份。
  2. 視圖部份運用html定義,然則vue會對一些迥殊的語法給予vue本身的意義。如 { { message }} 示意將數據message綁定到視圖的這個處所來。
  3. 這裡是運用原生js編寫的,因而數據部份和視圖部份經由過程id選擇器關聯起來,定義了一個x-my-component全局組件。
  4. 從這裏就可以夠開端感受到數據驅動。組件的狀況都是寄存的數據中的,而視圖只擔任襯着,自身不保留狀況。
    當數據穩定時,襯着結果肯定穩定;當數據轉變時,襯着結果就要發作轉變。

由於vue是組件化的,組件能夠層層嵌套。不過,終究的根節點得是app節點,如許才襯着出結果。它的定義體式格局不太雷同:

<div id="app">
    <x-my-component></x-my-component>
</div>
<script>
var app = new Vue({
  el: '#app',
});
</script>
  1. 從這裡能夠看出,自定義的全局組件在vue的別的組件中能夠直接運用,就像運用一個已存在的html標籤一樣。

 數據綁定

從數據驅動的看法,我們很輕易分析出數據流向:
數據源 –> vue對象 –> DOM

文本綁定,html綁定及xss進擊

<div id="x-my-component">
  <span v-bind:title="message">
  { { message }}
  { { message.split('').reverse().join('') }}
  </span>
  <span :title="message"> </span>
  <div v-html="rawHtml"></div>
</div>
<script>
Vue.component('x-my-component', {
  template: '#x-my-component',
  data: function () {
      return {
        message: 'Hello Vue!',
        rawHtml: '<s>deleted!</s>'
      };
  }
});
</script>
  1. 將數據綁定到平常的內容上,用簡樸的 { {}} 的語法就可以夠了。
  2. 將數據綁定到屬性上,須要用迥殊的 v-bind 語法。上面將 message 數據綁定到了title屬性上。
    由於這個語法太經常使用了, v-bind:title 可直接縮寫為 :title
  3. -v-html 語法,綁定原始的html數據。
  4. 能綁定的不僅僅是屬性鍵值,還能夠是 單個表達式 。注重 只能 是單個表達式。
    這些表達式只能接見全局變量的一個白名單,如Math和Date, 不能接見用戶自定義的全局變量

在傳統的前端編程中,須要細緻防備的一點是xss進擊。xss進擊的道理是:

  1. 用戶輸入的數據直接被插進去到了DOM中。
  2. 用戶輸入的數據中含有html或js代碼,那末它會直接作為DOM的一部份,被襯着或被實行出來。
  3. 應用這一點,就可以夠製造一個指向進擊者頁面的一張圖片或許鏈接,從而偷取用戶的cookies或sid,或許引誘用戶點擊垂綸網址。

因而,為防備xss,任何用戶給定的數據展現到頁面上都須要細緻的處置懲罰。然則假如運用vue,就沒必要太費心這個題目。
由於,vue供應了一個更高條理的前端模子,一切的營業代碼都須要經由過程vue處置懲罰。我們只須要看vue對xss的處置懲罰狀況就可以夠了。
從上面我們能夠看到,數據到視圖襯着中必需運用vue的插值語法:

  1. 一般的文本插值。vue會過濾xss進擊,因而能夠平安運用。
  2. 運用v-html語法將html插進去襯着后的DOM中。這當然會形成xss進擊,因而,運用v-html語法時要異常的警惕。

前提與輪迴

<div id="x-my-component">
  <p v-if="seen">如今你看到我了</p>
  <ol>
    <li v-for="todo in todos">
      { { todo.text }}
    </li>
  </ol>
</div>
<script>
Vue.component('x-my-component', {
  template: '#x-my-component',
  data: function () {
      return {
        seen: true,
        todos: ["A", "B", "C"]
      };
  }
});
</script>
  • v-if 綁定的數據,掌握此元素是不是顯現。
  • v-for 綁定的迥殊語法,用於掌握輪迴, v-for 的元素會被反覆。如上所示,todos是一個數組。

響應式

上面的例子中能夠數據綁定的語法,現實上,將數據綁定到視圖上的操縱並不少見,這些操縱,和後端手藝經常使用的樣子容貌引擎相似,如python的Jinja2, java的freemarker。
然則,vue的數據綁定的另有一大差別點點是 響應式
由於視圖襯着是從數據盤算出來的產品,相似一個傳入數據傳出襯着結果的純函數,因而,當數據轉變時,襯着結果也會轉變,所獲得的結果是頁面展現的界面也會發送轉變。

數據綁定還不能完全走通一個vue組件的數據流程,從上面的數據綁定我們能夠發明一個現實:
數據由vue對象流向視圖進而襯着出來。

那末,反過來呢?假如讓數據從頁面流向vue對象?這就是下面要說到的事宜處置懲罰。

事宜處置懲罰

事宜處置懲罰的數據流向是如許的:
用戶操縱頁面發生數據 –> 頁面 –> vue對象

<div id="x-my-component">
  <p>{ { message }}</p>
  <button v-on:click="reverseMessage">逆轉音訊</button>
  <button @click="reverseMessage">逆轉音訊</button>
  <input v-model="message">
</div>
<script>
Vue.component('x-my-component', {
  template: '#x-my-component',
  data: function () {
      return {
        message: 'Hello Vue.js!'
      };
  },
  methods: {
    reverseMessage: function () {
      this.message = this.message.split('').reverse().join('');
    }
  }
});
</script>
  1. 經由過程 v-on 語法,綁定事宜。按鈕的數據傳入到vue對象中。
    這個語法太經常使用了,所以 v-on:click 可縮寫成 @click
  2. 經由過程 v-model 語法,將表單的數據傳入到vue對象中。v-model的數據活動是雙向的,相當於:value數據綁定和@input事宜綁定的語法糖。

能夠與用戶交互的組件都能夠發生數據。當用戶操縱組件時,組件的響應事宜被觸發,進而實行綁定到事宜的響應函數。
在函數內部你能夠做任何處置懲罰邏輯,比如說轉變vue對象紀錄的狀況,也就是數據。

那末,如許,一個完全的數據流程就跑通了:

  1. 用戶操縱vue組件。
  2. 響應的事宜被觸發,從而致使綁定事宜的函數被觸發。
  3. 函數實行營業代碼,轉變vue組件的狀況,也就是前面說到的數據綁定中的數據。
  4. 數據被轉變,綁定了該數據的視圖也會發送轉變,視圖被重新襯着。
  5. 頁面發作響應轉變,用戶視察到了本身操縱的反應結果。

再談響應式

virtual DOM

我們曉得,數據被綁定到視圖上,視圖自身不存儲狀況,當數據穩定時,襯着結果穩定;當數據轉變時,視圖也須要重新襯着。

好了,如今思想里能夠會有一個簡樸的思緒了:

  1. 當數據轉變時,觸發數據的setter,setter除了更改數據更改外,還須要實行數據更新邏輯。
  2. 重新實行襯着函數,重新的數據中盤算出新的襯着結果。
  3. 將襯着結果插進去瀏覽器DOM樹中。

然則,我們細緻考核下第三步。瀏覽器的DOM樹轉變后,瀏覽器才會真正的重新襯着這個DOM,盤算種種css,種種計劃,層層挪用種種畫圖函數重新繪製GUI等等。。。
總而言之,這個步驟是異常異常耗時的。

那末,一個優化的手腕是,盡能夠讓真正的DOM轉變的起碼,如許瀏覽器只須要襯着起碼的結果就可以到達結果,提拔機能。
因而,vurtual DOM就湧現了。以下:

  1. 當數據轉變時,觸發數據的setter,setter除了更改數據更改外,還須要實行數據更新邏輯。
  2. 重新實行襯着函數,重新的數據中盤算出新的襯着結果。
  3. 襯着結果被放在virtual DOM中,vue將新的DOM和就的DOM舉行diff。
  4. 將diff后的差別結果更新到真正的瀏覽器DOM樹中。

能夠看到,全部流程中的一大重點是diff算法。關於DOM的diff算法,我沒有打仗過。。。。。。。
之前研討過文本diff算法是基於LCS算法的動態計劃優化,以後有興緻能夠研討下DOM的diff算法。

數據更新檢測的坑

從上面我們曉得,當直接設置一個vue屬性的值時,會觸發getter函數。
現實上,getter函數是js的一個機制。在修正數組或對象時,也有相似的機制保證vue能檢測到數據的更新以觸發襯着。

然則,有幾種狀況,由於js的限定沒法檢測到,現實編程中要迥殊注重,不然就會覺得碰到了一個玄學bug。。。

  1. 數組。

    1. 應用索引來直接設置數組元素。如 this.todos[index] = "B"。解決計劃是:Vue.set(this.todos, index, "B"),經由過程vue的函數設置。
    2. 直接修正數組的長度。如 this.todos.length = 10。替換計劃發起運用不可變數據結構。
  2. 對象。vue沒法檢測到對象屬性的增加或刪除。增加的話,能夠運用Vue.set,刪除的話,能夠運用不可變數據結構。

末了

此篇博文梳理了vue的基本特徵,然則關於vue最重量級的功用—-組件化,沒有涉及到。關於組件化的相干梳理留到下篇博文梳理。

注:該文於2018-04-09撰寫於我的github靜態頁博客,現同步到我的segmentfault來。

    原文作者:frapples
    原文地址: https://segmentfault.com/a/1190000015452018
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞