vue 學習筆記(一)

對於 vue 官網給的教程由淺及深,很是容易上手。我以前有過 react 項目開發經驗,對 webpack 打包,腳手架這一類的東西並不陌生。因此也是我上手比較快的緣由吧。簡單將我在學習 vue 中碰見的問題和我以爲比較重要的東西記錄一下,增長記憶。先說好,我這是我的筆記,不是教程,不喜勿噴。javascript

哦,有個特別尷尬,特別嚴肅的問題。
我想說一聲
讀 : /vjuː/,相似於 view
別在讀 v u e 了,各位大佬。
官網學習地址:https://cn.vuejs.org/v2/guidehtml

簡單介紹

一套用於構建用戶界面的漸進式框架。與其它大型框架不一樣的是,Vue 被設計爲能夠自底向上逐層應用。Vue 的核心庫只關注視圖層,不只易於上手,還便於與第三方庫或既有項目整合。另外一方面,當與現代化的工具鏈以及各類支持類庫結合使用時,Vue 也徹底可以爲複雜的單頁應用提供驅動。vue

安裝方式

npm i -g vue vue-cli

官網上說對於新手不推薦使用 vue-cli,注意學習一下打包工具 webpack, gulp 之類的,瞭解一下 node 構建流程,而後再回頭用 vue-cli,絕壁會醍醐灌頂,如夢初醒,恍然大悟,豁然開朗,茅塞頓開... 沒得詞語了,書讀少了。差很少就是這個意思,站在了一個更高的層面的來學 vue-cli 了。java

而後,新建一個文件夾 vue 用來存放項目的。在 vue 文件夾下打開命令行,用 vue-cli 初始化一個項目。ok, just sonode

vue init webpack 項目名稱

而後一路回車就行了。回車前能夠大概看一下,各個選項都是什麼意思。react

Project name (項目名稱): 項目名稱
Project description (A Vue.js project): 項目描述,能夠爲空。
Author:做者姓名
Runtime + Compiler: recommended for most users: 運行加編譯
Runtime-only: about 6KB lighter min+gzip, but templates (or any Vue-specificHTML) are ONLY allowed in .vue files - render functions are required elsewhere:回車就行了
Install vue-router? (Y/n): 是否安裝vue-router,通常都要安裝
Use ESLint to lint your code? (Y/n):  是否使用ESLint管理代碼,看我的習慣,條條框框太多,我的不肯使用。
接下來也是選擇題Pick an ESLint preset (Use arrow keys): 選擇一個ESLint預設,編寫vue項目時的代碼風格
Setup unit tests with Karma + Mocha? (Y/n): 是否安裝單元測試
Setup e2e tests with Nightwatch?(Y/n): 是否安裝e2e測試

數據與方法

當一個 Vue 實例被建立時,它向 Vue 的響應式系統中加入了其 data 對象中能找到的全部的屬性。當這些屬性的值發生改變時,視圖將會產生「響應」,即匹配更新爲新的值。webpack

1. 只有當實例被建立時 data 中存在的屬性纔是響應式的。
2. 惟一的例外是使用 Object.freeze(),這會阻止修改現有屬性,系統將沒法追蹤變化。
3. 除了數據屬性,vue實例還會暴露一些有用的實例屬性和方法。一般都前綴$,以便與用戶定義的屬性區分開來。如 $watch, $el, $data ...ios

var data = {
    a: 1
}
var vm = new Vue({
    el: "#example",
    data: data
})

console.log(
    "vm.$data === data  ", vm.$data === data, "\n", // true
    "vm.$el === document.getElementById('example'): ",  vm.$el === document.getElementById('example') // true
)
vm.$watch('a', function(newValue, oldValue) {
    // 當修改 a 的值時,會執行該方法
    console.log("newValue === oldValue: ", newValue === oldValue)
})

再舉個栗子:web

具體能夠查看 API瞭解更多vue-router

生命週期

要說,生命週期是最基礎,最必需要理解的。和 react 同樣,每一個實例在被建立時,都會經歷幾個階段。beforeCreate,created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed

模板語法

# 插值

數據綁定最多見的形式就是使用「Mustache」語法(雙大括號) ==> 通常用於插入文本
v-html: Mustache 會將數據解析成普通文本,而非 html 代碼。

<p>Using mustaches: {{rawHtml}}</p>
<p>Using v-html directive: <span v-html="rawHtml"></span></p>

span 的內容會被替換成 rawHtml 的值,這種會忽略解析 rawHtml 值中的數據綁定。不能使用 v-html 來複合局部模板,由於 vue 不是基於字符串的模板引擎。

Mustache 語法不能做用在 html 特性上,遇到這種狀況應該使用 v-bind 指令;在布爾特性的狀況下,v-bind 工做起來略有不一樣。eg:

<button v-bind:disabled="isButtonDisabled">Button</button>

若是 isButtonDisabled 的值是 null, undefined 或是 false,則 disabled 特性甚至不會被包含在渲染出來的 button 元素中。

對於全部的數據綁定,Vue.js 都提供了徹底的 JavaScript 表達式支持。流控制,語句,語句塊都是不會生效的。

PS: 模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如 Math 和 Date 。你不該該在模板表達式中試圖訪問用戶定義的全局變量。

# 指令

指令 (Directives) 是帶有 v- 前綴的特殊特性。指令特性的值預期是單個 JavaScript 表達式 (v-for 是例外狀況,稍後咱們再討論)。指令的職責是,當表達式的值改變時,將其產生的連帶影響,響應式地做用於 DOM。

一些指令可以接收一個「參數」,在指令名稱以後以冒號表示。eg: v-bind, v-on

<a v-bind:href="url">aaa</a>
<a v-on:click="doSomething">bbb</a>

在這裏 href 是參數,告知 v-bind 指令將該元素的 href 特性與表達式 url 的值綁定;v-on 用於監聽 dom 事件。

對 v-bind 和 v-on 的簡寫爲: :, 和 @; eg:

<a v-bind:href="url">aaa</a>
<a :href="url">aaa</a>

<a v-on:click="do">bbb</a>
<a @click="do">bbb</a>

# 計算屬性和偵聽器

PS: 對於任何複雜邏輯,都應當使用計算屬性(computed);

計算屬性 vs 方法
計算屬性只有在它的相關依賴發生改變時纔會從新求值。這就意味着只要 message 尚未發生改變,屢次訪問 reversedMessage 計算屬性會當即返回以前的計算結果,而沒必要再次執行函數。使用方法,就不會有緩存。

計算屬性 vs 偵聽屬性
Vue 提供了一種更通用的方式來觀察和響應 Vue 實例上的數據變更:偵聽屬性。當你有一些數據須要隨着其它數據變更而變更時,你很容易濫用 watch。
計算屬性默認只有 getter,在須要的時也能夠提供一個 setter;

computed: {
  fullName: {
    // getter
    get: function () {
      return this.firstName + ' ' + this.lastName
    },
    // setter
    set: function (newValue) {
      var names = newValue.split(' ')
      this.firstName = names[0]
      this.lastName = names[names.length - 1]
    }
  }
}

偵聽器(有時間,再瞭解一下)

雖然計算屬性在大多數狀況下更合適,但有時也須要一個自定義的偵聽器。這就是爲何 Vue 經過 watch 選項提供了一個更通用的方法,來響應數據的變化。當須要在數據變化時執行異步或開銷較大的操做時,這個方式是最有用的。

在這兒須要學習一下 axios, lodash。
axios: 異步請求封裝
lodash: 限制操做頻率

有個問題值得注意一下:

Vue.component('my-component', {
  template: '<p class="foo bar">Hi</p>'
})

<my-component v-bind:class="{ active: isActive }"></my-component>

當 isActive 爲 truthy 時, html 將會被渲染成:
<p class="foo bar active">Hi</p>

尤爲注意,這裏的 truthy 不是 true 哈。詳情參見MDN

# 條件渲染

v-show

  1. 始終會被渲染並保留在 DOM 中。v-show 只是簡單地切換元素的 CSS 屬性 display。
  2. v-show 不支持 <template > 元素,也不支持 v-else。

v-if vs v-show

  • v-if:
  1. 會確保在切換過程當中條件塊內的事件監聽器和子組件適當地被銷燬和重建。
  2. v-if 也是惰性的;若是在初始渲染時條件爲假,則什麼也不作——直到條件第一次變爲真時,纔會開始渲染條件塊。
  • v-show:
    無論初始條件是什麼,元素老是會被渲染,而且只是簡單地基於 CSS 進行切換。

通常來講,v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷。所以,若是須要很是頻繁地切換,則使用 v-show 較好;若是在運行時條件不多改變,則使用 v-if 較好。

v-ifv-for 一塊兒使用時,v-for 具備比 v-if 個更的優先級。

# 列表渲染
  1. 在 v-for 塊中,咱們擁有對父做用域屬性的徹底訪問權限;
    question: 對祖先級呢?
  2. 能夠用 of 代替 in 做爲分隔符。v-for="item of items"
  3. 能夠用 v-for 遍歷對象。能夠有三個參數 (value, key, index);
  4. 在遍歷對象時,是按 Object.keys() 的結果遍歷,可是不能保證它的結果在不一樣的 JavaScript 引擎下是一致的。

Vue 包含一組觀察數組的變異方法,因此它們也將會觸發視圖更新。以下:

  • push()
  • pop()
  • shift()
  • unshift()
  • splice()
  • sort()
  • reverse()

變異方法 (mutation method),顧名思義,會改變被這些方法調用的原始數組。相比之下,也有非變異 (non-mutating method) 方法,例如:filter(), concat() 和 slice() 。這些不會改變原始數組,但老是返回一個新數組。當使用非變異方法時,能夠用新數組替換舊數組:

example1.items = example1.items.filter(function (item) {
  return item.message.match(/Foo/)
})

你可能認爲這將致使 Vue 丟棄現有 DOM 並從新渲染整個列表。幸運的是,事實並不是如此。Vue 爲了使得 DOM 元素獲得最大範圍的重用而實現了一些智能的、啓發式的方法,因此用一個含有相同元素的數組去替換原來的數組是很是高效的操做。


PS:

① 因爲 JavaScript 的限制,Vue 不能檢測如下變更的數組:

1. 當利用索引直接設置一個項時,例如:vm.items[indexOfItem] =newValue
2. 當修改數組的長度時,例如:vm.items.length = newLength
舉個栗子:

var vm = new Vue({
  data: {
    items: ['a', 'b', 'c']
  }
})
vm.items[1] = 'x' // 不是響應性的
vm.items.length = 2 // 不是響應性的

解決方法

// Vue.set
Vue.set(vm.items, indexOfItem, newValue)

// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)

// 也可使用 vm.$set 實例方法,該方法是全局方法 Vue.set 的一個別名
vm.$set(vm.items, indexOfItem, newValue)

// 解決第二類問題
vm.items.splice(newLength)

② 因爲js的限制,Vue不能檢測對象屬性的添加或刪除:
譬如,

var vm = new Vue({
	data: {
		userProfile: {
			name: "Mobro"
		}
	}
})

// 1
Vue.set(userProfile, "age", 23);

// 2
vm.$set(userProfile, "age", 23);

// 3
vm.userProfile = Object.assign(vm.userProfile, {
	age: 23,
	sex: male
})

③ v-for 也能夠用來取整數


v-for 和 v-if 在同一個節點上的時候, v-for 比 v-if 優先級更高,即 v-if 將分別重複運行於每一個 v-for 循環中。

⭐️ 注意組件上的 is 屬性使用哈。

#事件處理

  1. v-on 監聽 DOM 事件,並在觸發時運行一些 js 代碼。
  2. v-on 能夠接受一個須要調用的方法名稱。
  3. @click="say('the name is: ', $event)" // $event 是當前 dom 元素

事件修飾符:

  • .stop 阻止事件繼續傳播,即捕獲和冒泡
  • .prevent 阻止默認事件,等同於 ev.preventDefault()
  • .capture 添加事件監聽器時使用事件捕獲模式,即在捕獲模式下觸發
  • .self 當前元素是自身時纔會觸發函數,是根據 ev.target 是否是自身來決定是否觸發
  • .once 只觸發一回,也能夠用於用戶自定義組件事件上。
  • .passive 解決瀏覽器卡頓的新特性,尤爲可以提高移動端性能 參考文章

js
不要把 .passive.prevent 一塊兒使用,由於 .prevent 將會被忽略,同時瀏覽器可能會報警告。.passive 會告訴瀏覽器你 不想 阻止事件的默認行爲。

按鍵修飾符

  • .enter
  • .tab
  • .delete (捕獲 「刪除」 和 「退格」 鍵)
  • .esc
  • .space
  • .up
  • .down
  • .left
  • .right

經過全局 config.keyCodes 對象 自定義按鍵修飾符別名:
Vue.config.keyCodes.f1 = 112;

有些按鍵(.esc 以及全部方向鍵)在 IE9 中有不一樣的 key 值,若想支持 IE9, 它們的內置別名應該是首選。

系統修飾符
能夠用以下修飾符來實現僅在按下相應按鍵時才觸發鼠標或鍵盤事件的監聽器。

  • .ctrl
  • .alt
  • .shift
  • .meta 在 mac 上,對應 command 鍵。在 windows 對應 win 鍵。
  • .exact 修飾符容許你控制由精確的系統修飾符組合觸發的事件。

eg:

<!-- 即便 Alt 或 Shift 被一同按下時也會觸發 -->
<button @click.ctrl="onClick">A</button>

<!-- 有且只有 Ctrl 被按下的時候才觸發 -->
<button @click.ctrl.exact="onCtrlClick">A</button>

<!-- 沒有任何系統修飾符被按下的時候才觸發 -->
<button @click.exact="onClick">A</button>

鼠標按鈕修飾符

  • .left
  • .right
  • .middle

這些修飾符會限制處理函數僅相應特定的鼠標按鈕。

Q: 爲何在 html 中監聽事件?

A: 你可能注意到這種事件監聽的方式有點違背了關注點分離這個長期以來的優良傳統。但沒必要擔憂,由於全部的 vue.js 事件處理方式和表達式都嚴格綁定在當前視圖的 viewModel 上,它不會致使任何維護上的困難。實際上,使用 v-on 有幾個好處:

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

當年吹過得牛逼,如已否則,便全不做數。 -- Mobro

相關文章
相關標籤/搜索