複習Vue中的方法,計算和偵聽者

歡迎關注富途web開發團隊,缺人從衆css

最近一直在Vue和angualr.js 1.x之間切換。大腦都快切換不過來了。html

趁着週末,仍是把Vue的基本知識複習一下。vue

查看原文 連接react

正文

工做中我喜歡用Vue的緣由之一就是由於方法,計算屬性和偵聽者很是有用,而且他們以前差別的可讀性很好。在理解這三者以前,我很難充分的利用Vue的所有功能。儘管如此,大多數人對這個框架感到困惑的也多集中在這三者之間的差別,因此讓咱們一塊兒來深刻研究下。git

若是你想獲得一個直接結論,或者你沒有時間閱讀整篇文章,這裏給一些略長的小總結:程序員

  • Methods(方法):顧名思義,就是方法的意思。這些方法是能操做對象的函數-一般是Vue實例自己或者Vue組件。github

  • Computed(計算):這些計算屬性可能乍看起來就像方法同樣使用,但其實不是的。在Vue中,咱們須要用data去響應咱們想要的一個特定屬性的變化。計算屬性不只能夠定義一個與data使用方式相同的屬性,而且能夠有一些基於其依賴關係進行緩存的自定義邏輯。你能夠將計算屬性視爲數據的另外一個視圖。web

  • Watchers(偵聽者):偵聽者能夠窺視數據變化。咱們提供了一些鉤子函數來監視Vue存儲的一些屬性。若是你想在數據變化時添加一些功能,或者對一些特定的更改作出響應,咱們能夠偵聽這個屬性並應用一些邏輯。這意味着偵聽者的名字必需要與咱們偵聽的內容相匹配。正則表達式

若是這麼說讓你聽起來有些困惑,不要擔憂!咱們將在下面進行更多的探討但願能解答你的困惑。若是你已經熟悉vanilla Javascript,那麼除了一兩個注意事項外,方法對你來講是比較重要的。這可能會讓你跳過ComoutedWatchers這兩個部分。api

Methods(方法)

方法多是你在使用Vue時常常用到的。其實它就是咱們把一些函數方法掛到一個對象上,因此它實質上就是這樣被命名的。它對於將功能鏈接到事件指令很是有用,甚至只要建立一小段邏輯就能夠像其餘函數同樣複用。例如,你能夠在另外一個方法中調用方法。你也能夠在生命週期鉤子函數中調用這個方法。這是很是靈活的。

這裏有一個簡單的演示:點擊連接

//HTML
<code class="language-css"><div id="app">
  <button @click="tryme">Try Me</button>
  <p>{{ message }}</p>
</div>
複製代碼
//JS
new Vue({
  el: '#app',
  data() {
    return {
      message: null
    }
  },
  methods: {
    tryme() {
      this.message = Date()
    }
  }
})
複製代碼

咱們也能夠直接在指令自己中執行這個邏輯,如<button @click="message = Date()">Try Me</button> 這在小示例中是很是有效的。可是,隨着應用程序愈來愈複雜,對於上面這種常見的方法是將其分解出來更加清晰。Vue容許你在指令中表達邏輯也是有限制的-例如,表達式能夠,但語句不行。

你可能會注意到,咱們能夠在該組件或Vue實例中訪問這個方法,而且能夠調用任何一條數據,在本例中就是this.message.你不須要用像在指令中調用函數的方法。例如:不須要這樣@click=」methodName()」,除非你要傳一個參數,像這樣@click=」methodName(param)」

使用指令調用方法也挺好的,由於咱們有一些事件修飾符。其中一個經常使用的例子就是.prevent,它將在提交事件中阻止頁面從新加載。

//HTML
<form v-on:submit.prevent="onSubmit"></form>
複製代碼

還有更多能夠學習下

Computed (計算屬性)

計算屬性對於處理已存在的數據很是有價值。不管什麼時候,當你須要對大量數據進行排序而且不想在每次按鍵時從新進行運算,請考慮使用計算屬性。

一些經常使用的場景例如:

  • 在用戶輸入時更新大量的信息,例如過濾列表。
  • 從Vuex商店中收集信息
  • 表單驗證
  • 數據可視化須要依賴於用戶查看的內容而變化

計算屬性是理解學習Vue的一個重要部分。它們是基於依賴關係進行緩存的計算,而且在依賴關係變化時進行更新。若是使用得當會很是高效。有不少大型的組件庫都是爲了處理這種邏輯,然而如今只須要幾行代碼就能解決。

計算屬性並不想方法那樣使用,儘管起初它們長的差很少-你在函數中聲明一些邏輯並返回-可是這個函數的名字變成了一個屬性,而後你將在程序中應用它,如data

若是咱們須要根據用戶輸入的內容來篩選這些人的名單,那麼咱們將如何作到這一點。爲了看起來簡單些,你能夠減小一些基本概念。首先,列表數據將會把存儲在數據中的名稱在模板中輸出:

//JS
new Vue({
  el: '#app',
  data() {
    return {
      names: [
        'Evan You',
        'John Lindquist',
        'Jen Looper',
        'Miriam Suzanne',
        ...
      ]
    }
  }
})
複製代碼
//HTML
<div id="app">
  <h1>Heroes</h1>
  <ul>
    <li v-for="name in names">
      {{ name }}
    </li>
  </ul>
</div>
複製代碼

效果見 連接

如今讓咱們爲這些名稱建立一個過濾器。咱們先建立一個有v-model的input,該輸入起初回事個空字符串,可是咱們將使用它來匹配和過濾咱們的列表。咱們將調用findName這個屬性,你能夠在輸入和data中看到這個引用。

//HTML
<label for="filtername">Find your hero:</label>
<input v-model="findName" id="filtername" type="text" />
複製代碼
//JS
data() {
  return {
    findName: '',
    names: [
      'Evan You',
      'John Lindquist',
      ...
    ]
  }
}
複製代碼

如今咱們能夠建立計算屬性,根據用戶輸入的內容來過濾名稱,所以咱們的findName屬性中的任何內容都會被使用。你會注意這裏我用了正則表達式來確保用戶輸入大小寫都不要緊,由於用戶輸入時一般不會大寫。

//JS
computed: {
  filteredNames() {
    let filter = new RegExp(this.findName, 'i')
    return this.names.filter(el => el.match(filter))
  }
}
複製代碼

如今咱們將更新模板中使用的內容輸出:

//HTML
<ul>
  <li v-for="name in names">
    {{ name }}
  </li>
</ul>
複製代碼

變成這樣

//HTML
<ul>
  <li v-for="name in filteredNames">
    {{ name }}
  </li>
</ul>
複製代碼

這將會在每次按鍵時爲咱們進行過濾,咱們只須要添加幾行代碼就能達到這個效果,而沒必要加載任何其餘的庫。

效果以下 連接

我在使用它時,不知道節省了多少時間,若是你在用Vue可是尚未探索過這個功能,那麼趕忙去使用吧,你會感謝個人。

Watchers(偵聽者)

Vue具備很好的抽象性,任何一個曾經作過程序員的都會告訴你,抽象是一種痛,由於最終你會遇到一個他們沒法解決的用例。然而,這種狀況是能夠解釋的,由於Vue可以更深刻的訪問反應系統,咱們能夠利用它來偵聽正在改變的事物。這個多是頗有用的,由於做爲應用程序開發人員,咱們負責的大部分事情都是變化的。

Watchers還容許咱們編寫更多的聲明性代碼。你不用再去追蹤一切。Vue已經在作這件事了,因此你能夠訪問它所追蹤的任何屬性的變化,例如:data,computed或者props

當一個屬性發生變化時,偵聽者很是適合執行適用於別的東西的邏輯(我第一次聽到這個是從Chris Fritz那裏,他說他也是從別人那裏聽到的☺️)這不是一個硬性的原則-你徹底可使用偵聽者來引用屬性自己的邏輯,可是這是區別偵聽者和計算屬性不一樣的一個很好的方式,當咱們將要用到的引用屬性改變時。

咱們來看看最簡單的例子,就能瞭解這其中發生了啥。

視頻連接

//JS
new Vue({
  el: '#app', 
  data() {
    return {
      counter: 0
    }
  },
  watch: {
    counter() {
      console.log('The counter has changed!')
    }
  }
})
複製代碼

正如上面代碼中看到的那樣,咱們將counter存儲在data中,而且使用該屬性名稱做爲函數名稱,咱們就能夠偵聽它了,當咱們在watche中引用counter時,就能夠觀察到這個屬性的變化了。

Watchers的過分狀態

若是狀態足夠類似,你甚至能夠簡單的將狀態轉換爲偵聽者。這裏看下我用Vue畫的一個表格。當數據發生變化時,觀察者將更新它而且能在二者之間簡單的轉換。

SVG對於這樣的場景也使用,由於它也是用數學創建的。

效果連接

//JS
watch: {
  selected: function(newValue, oldValue) {

    var tweenedData = {}

    var update = function () {
      let obj = Object.values(tweenedData);
      obj.pop();
      this.targetVal = obj;
    }

    var tweenSourceData = { onUpdate: update, onUpdateScope: this }

    for (let i = 0; i < oldValue.length; i++) {
      let key = i.toString()
      tweenedData[key] = oldValue[i]
      tweenSourceData[key] = newValue[i]
    }

    TweenMax.to(tweenedData, 1, tweenSourceData)
  }
}
複製代碼

這裏發生了什麼呢?

  • 首先咱們建立了一個虛擬對象,它將跟隨動畫庫變化更新。

  • 而後咱們有一個更新的函數,在tween step中調用這個函數。咱們用這個來推進數據。

  • 而後咱們建立一個對象來保存元數據和更新事件的函數

  • 咱們建立一個for循環,而後將當前索引變成一個字符串。

  • 而後咱們能夠在目標虛擬對象上進行tween ,可是咱們只會對特定的關鍵點執行這個操做。

咱們也能夠在觀察者中使用動畫來建立相似於這個時間差的錶盤。我旅行了一段時間,我全部的同事都在不一樣的地方,因此我想要用一種方式來追蹤咱們當地的時間,以及白天時間/晚上時間變化的意義。

效果連接

在這裏,咱們正在偵聽checked屬性,而且咱們將使用包含時間線動畫的不一樣方法來改變色調和飽和度以及基於與當前時間的相對關聯的一些其餘元素。正如前面提到的那樣 - 變化發生在下拉菜單上,但咱們正在執行的是在其餘地方應用的邏輯。

//JS
watch: {
  checked() {
    let period = this.timeVal.slice(-2),
      hr = this.timeVal.slice(0, this.timeVal.indexOf(':'));

    const dayhr = 12,
      rpos = 115,
      rneg = -118;

    if ((period === 'AM' && hr != 12) || (period === 'PM' && hr == 12)) {
      this.spin(`${rneg - (rneg / dayhr) * hr}`)
      this.animTime(1 - hr / dayhr, period)
    } else {
      this.spin(`${(rpos / dayhr) * hr}`)
      this.animTime(hr / dayhr, period)
    }

  }
},
複製代碼

關於watchers還有一些其餘有趣的事情,例如:咱們能夠將屬性的新版本和舊版本做爲參數進行訪問,若是咱們想偵聽嵌套對象,咱們能夠指定deep。更多詳情看指引,本指南中提供了許多有用的信息

您能夠看到偵聽者對於實時更新的任何內容-不管是表單輸入,異步更新仍是動畫均可以發揮很是有用的做用。若是你很好奇Vue是如何作到的,那麼這部分指南是很是有用的。若是你想了解更多的響應,推薦我喜歡的Andre Staltz的博文和Mike Bostock的更好的編碼方式

總結

我但願這是一個關於如何使用的指引,而且能提升你使用Vue進行應用程序開發的效率。有一個數據統計,咱們用70%的時間去閱讀代碼,而只用了30%的時間來寫。我的而言,做爲一個維護者我喜歡這一點,我能夠看以前沒有見過的代碼庫,而且可以經過methods,computedwatchers的區別用法來了解做者的意圖。

原文:Methods, Computed, and Watchers in Vue.js

做者:SARAH DRASNER

譯者:Diandian

相關文章
相關標籤/搜索