介紹
原文引自 Vue 官方教程 :https://cn.vuejs.org/v2/guide/
Vue.js 是什么?
Vue.js 是一套構建用戶界面的漸進式框架。采用的是自底向上增量開發的設計(與其他重量級框架不同點)。Vue的核心庫只關注圖層,不僅易於上手,還便於與第三方庫或既有項目整合。
起步
# helloword
- 注意:不能將id = ‘app’寫在body或者html中
<script src = './vue.js'><script>
<div id = 'app>
<p> {{ message }} </p>
</div>
<script>
var app = new Vue({
el: '#app',
message: 'helloword!!!'
})
<script>
- 現在的數據和DOM已經綁定在一起了,所有的元素都是響應式
- 文本插值:從控制台輸入app.message = '新信息' ,可以修改DOM相應的更新
- 元素屬性:通過v-bind綁定 例如v-bind:title="哈哈哈"
條件循環
- v-if (文本到數據) 提供了一個強大的過渡效果系統,可以在Vue插入/刪除/更新時自動應用過渡系統
- v-for (結構到數據)
處理用戶輸入
- v-on 指令綁定一個事件監聽器,通過它調用我們Vue實例中定義的方法
- v-on:click = "Add"
- v-model 實現表單輸入和應用狀態之間的雙向綁定
實例中的參數
- el: 'id' //el就是 vue 程序的解析入口
- data: { 數據 } //data就是ViewModel
- methods: { 函數 } //函數中的this指向該應用中data的數據
- computed: { 聲明一個計算屬性函數 }
- 例子
computed: { // a computed getter reversedMessage: function () { // `this` points to the vm instance return this.message.split('').reverse().join('') } }
- filters: { 過濾器函數 }
組件化應用構建
在Vue里,一個組件本質上是一個擁有預定義選項的一個Vue實例
Vue實例
構造器
- 每個 Vue.js應用都是通過構造函數Vue創建的一個Vue的根實例啟動的
var vm = new Vue({
//選項
})
- 沒有完全遵循MVVM模式
- 可以擴展Vue構造器,從而用預定義選項創建可復用的組件構造器
- 所有的 Vue.js 組件其實都是被擴展的 Vue 實例
屬性和方法
- 每個Vue實例都會代理其data對象里所有的屬性
- 除了data屬性外,Vue實例還會暴露了一些有用的實例屬性和方法,都帶前綴$,以便與代理的data屬性區分
- 不要在實例屬性和回調函數中箭頭函數,因為箭頭函數綁定父上下文,this不會像預想的一樣是Vue實例
實例生命周期
- Vue.js 是否有“控制器”的概念?答案是,沒有。
語法模板
- 在底層的實現上,Vue將模板編譯成虛擬DOM渲染函數。結合響應系統,在應用狀態發生改變時,Vue能夠智能地計算出重新渲染組件的最小代價並應用到DOM操作上。
- 也可以不用模板,直接寫渲染(render)函數,使用可選的JSX語法
插值
# 文本
- 數據綁定最常見的形式就是使用“Mustache”(雙大括號)的文本插值
- 使用 v-once 指令,你也能執行一次性地插值,當數據改變時,插值處的內容不會更新
# 純HTML
- 雙大括號會將數據解析成純文本,而非HTML。為了輸出真正的HTML,需要使用v-html指令
- 注意:你的站點上動態渲染的任意 HTML 可能會非常危險,因為它很容易導致 XSS 攻擊。請只對可信內容使用 HTML 插值,絕不要對用戶提供的內容插值。
# 屬性
- Mustache不能在HTML屬性中使用,應使用v-bind指令
- 對id,布爾值的屬性有效
# 使用Javascript表達式
- 例子
- {{ number + 1 }}
- {{ ok ? 'YES' : 'NO' }}
- {{ message.split('').reverse().join('') }}
- 表達式會在所屬 Vue 實例的數據作用域下作為 JavaScript 被解析。有個限制就是,每個綁定都只能包含單個表達式。
<!-- 這是語句,不是表達式 -->
{{ var a = 1 }}
<!-- 流控制也不會生效,請使用三元表達式 -->
{{ if (ok) { return message } }}
注意:模板表達式都被放在沙盒中,只能訪問全局變量的一個白名單,如 Math 和 Date 。你不應該在模板表達式中試圖訪問用戶定義的全局變量。
指令
- 是帶有v-前綴的特殊屬性
# 參數
- 一個指令能接受一個參數,在指令后面以冒號指明
# 修飾符
- 修飾符(Modifiers)是以半角句號 . 指明的特殊后綴,用於指出一個指令應該以特殊方式綁定。例如,.prevent 修飾符告訴 v-on 指令對於觸發的事件調用 event.preventDefault()
<form v-on:submit.prevent="onSubmit"></form>
過濾器
- Vue.js允許自定義過濾器,可被用作一些常見的文本格式化,用在兩個地方:mustache插值和v-bind表達式
<!-- in mustaches -->
{{ message | capitalize }}
<!-- in v-bind -->
<div v-bind:id="rawId | formatId"></div>
- 過濾器函數
- 可以串聯
- 可以接受參數
# 縮寫
- v-on
<!-- 完整語法 -->
<a v-on:click="doSomething"></a>
<!-- 縮寫 -->
<a @click="doSomething"></a>
- v-bind
<!-- 完整語法 -->
<a v-bind:href="url"></a>
<!-- 縮寫 -->
<a :href="url"></a>
計算屬性
計算屬性
# 基礎例子
# 計算緩存 vs methods
- 計算屬性:是基於它們依賴進行緩存的(因依賴改變而重新求值);Date.now()不是響應式依賴
- methods:只要發生重新渲染, method調用總會調用執行該函數
# Computed屬性 vs Watched 屬性
- Watched 屬性: 觀察和響應Vue實例上的數據變動
- 缺點:命令式和重復式。更多選擇 computed 屬性
# 計算 setter
- 計算屬性默認只有getter,根據需求也可以提供一個setter
觀察 Watchers
Class 與 Style 綁定
綁定 HTML Class
# 對象語法
- v-bind:class={ 鍵:值 };可以與普通的class屬性共存
- 也可以綁定數據里的一個對象 v-bind:class=“classObject”
- 也可以綁定一個計算屬性
# 數組語法
<div v-bind:class="[activeClass, errorClass]">
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
# 用在組件上
綁定內聯樣式
# 對象語法
- v-bind:style 的對象語法十分直觀,看着非常像CSS,本質是一個 JavaScript 對象,屬性名可以用駝峰式或者短橫分隔命名
- 直接綁定到一個樣式對象
# 數組語法
<div v-bind:style="[baseStyles, overridingStyles]">
# Vue會自動判斷並添加前綴
- 當 v-bind:style 使用需要特定前綴的 CSS 屬性時,如 transform ,Vue.js 會自動偵測並添加相應的前綴。
條件渲染
v-if
#
中 v-if 條件組
- v-if 是一個指令,只能添加到一個元素上,如果像切換到多個元素,需要 元素當做包裝元素,並在上面使用 v-if 。
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
# v-else 指令來表示 v-if 的“else塊”
- v-else 元素必須緊跟在 v-if 或者 v-else-if 元素的后面——否則它將不會被識別。
# v-else-if 指令充當 v-if 的“else-if塊”
- 類似於 v-else,,v-else-if 必須緊跟在 v-if 或者 v-else-if 元素之后。
# 用 key 管理可復用的元素
- 高效渲染元素,對復用已有元素不受從頭渲染。
- 還有別的好處,見官網
v-show
- v-show 是簡單地切換元素地 CSS 屬性 display。
- 注意: 不支持 語法,也不支持v-else。
v-if vs v-show
- v-if 是真正地條件渲染(條件塊內的所有適當地被銷毀和重建);同時也是惰性地;更高地切換開銷
- v-show:不管初始條件是什么,元素始終會被渲染;更高地初始渲染開銷
v-if 與 v-for 一起使用
- v-for 具有比 v-if 更高地優先級
列表渲染
v-for
- v-for 還支持一個可選的第二個參數為當前項的索引。
<li v-for="(item, index) in items">
- 可以用 of 替代 in。
- Template v-for
- 對象迭代 v-for
- 通過一個對象地屬性來迭代
<li v-for="value in object">
+ 提供第二個的參數為鍵名
+ 第三個參數為索引
+ 注意:在遍歷對象時,是按 Object.keys() 的結果遍歷,但是不能保證它的結果在不同的 JavaScript 引擎下是一致的。
- 整數迭代 v-for
<span v-for="n in 10">{{ n }}</span>
- 組件和 v-for
+ <my-component v-for="item in items"></my-component>
key
- 重用和重新排序現有元素,每項提供一個唯一的 key 屬性,需要用 v-bind 來綁定動態值。理想的 key 值是每項都有唯一的id。
<div v-for="item in items" :key="item.id">
<!-- 內容 -->
</div>
- 建議盡可能使用 v-for 來提供 key。
- key 並不特別與 v-for 關聯,key 還有其他用途
數組檢查更新
- 變異方法
- push()
- pop()
- shift()
- unshift()
- splice()
- sort()
- reverse()
- 重塑數組(非變異方法)
- filter()
- concat()
- slice()
- 不會改變原始數組,總是返回一個新數組
- 注意事項
- 不能檢測變動的數組
- 當你利用索引直接設置一個項時,例如: vm.items[indexOfItem] = newValue
- 當你修改數組的長度時,例如: vm.items.length = newLength
- 不能檢測變動的數組
顯示過濾/排序結果
- 如果想要顯示一個數組的顧慮或者排序的副本,而不是實際改變或重置原始數據。=>創建返回過濾或排序數組的計算屬性
事件處理器
監聽事件
- v-on
v-on:click="counter += 1"
方法事件處理器
- 在處理比較復雜的邏輯,直接把 Javascript 代碼寫在 v-on 是不可行的,可以用 v-on 接受一個定義的方法來調用
v-on:click="greet"
內聯處理器方法
v-on:click="say('hi')"
事件修飾符
- .stop() 阻止單擊事件冒泡
- .prevent() 提交事件不再重載頁面
- .capture() 添加事件偵聽器時使用事件捕獲模式
- .self() 事件只在該元素本身(而不是子元素)觸發時觸發回調
- .once() 點擊事件將只會觸發一次
按鍵修飾符
- 監聽常見的鍵值
- Vue 為 v-on 在監聽鍵盤事件時添加按鍵修飾符:
<input v-on:keyup.13="submit">
- 按鍵別名
<input v-on:keyup.enter="submit">
- 全部按鍵別名
- .enter
- .tab
- .delete (捕獲“刪除”和“退格”鍵)
- .esc
- .space
- .up
- .down
- .left
- .right
- 通過全局 config.keyCodes 對象 自定義按鍵修飾符別名:
Vue.config.keyCode.f1 = 112
- 2.1.0新增
- .ctrl
- .alt
- .shift
- .meta
為什么在 HTML 中監聽事件?
- 這種事件監聽的方式違背了關注點分離傳統理念。不必擔心,因為所有 Vue.js 事件處理方式和表達式都嚴格綁定在當前視圖的 ViewModel 上,它不會導致任何維護上的困難。v-on 有幾個好處:
- 掃一眼 HTML 模板可以輕松定位到 javascript 代碼中對應的方法
- 因為你無法在Javascript中手動綁定事件,你的ViewModel可以式非常純粹的邏輯,和DOM完全解耦,便於測試
- 當一個ViewModel被銷毀,所有的時間處理器都會自動被刪除,無需擔心自己如何清理它們
表單控件綁定
基礎用法
- v-model 指令在表單控件元素上創建雙向數據綁定。負責監聽用戶的輸入事件以更新數據 ,並處理一些極端的例子。
- 注意:v-model 不關心表單控件初始化所生成的值。因為它會選擇 Vue 實例數據來作為具體的值。
# 文本
- input type=“text”
# 多行文本
- textarea
# 復選框
- input type=checkbox id=“hello”
- label for=“hello”
# 單選按鈕
- input type=“radio” id=“hello”
- label for=“hello”
# 選擇列表
- select
- option
綁定 value
- v-bind:value=“a”
修飾符
# .lazy
- 轉變為在 change 事件中同步
<input v-model.lazy="msg" >
# .number
- 將用戶的輸入值轉為 Number 類型
<input v-model.number="age" type="number">
# .trim
- 自動過濾用戶的首尾空格
<input v-model.trim="msg">
v-model 與組件
組件
什么是組件
- 組件是Vue.js最強大的功能之一。可以拓展 HTML 元素,可以封裝可重用的代碼。
- 在較高層面上,組件是自定義元素,Vue.js 編譯器為它添加特殊功能。在有些情況下,組件也可以是原生 HTML 元素的形式,以 is 特性拓展
使用組件
# 注冊
- 創建一個全局組件
Vue.component('my-component', {
// 選項
})
- 確保初始化之前注冊組件
# 局部注冊
new Vue({
// ...
components: {
// <my-component> 將只在父模板可用
'my-component': Child
}
})
# DOM 模板解析說明
- 限制性元素:
<u l> ,<o l>,<t a b l e> ,<s e l e c t> 限制了能被它包裹的元素, 而一些像 <o p t i o n> 這樣的元素只能出現在某些其它元素內部。解決方案:使用特殊的 is 屬性
<table>
<tr is="my-row"></tr>
</table>
- 這些限制不適用:
+ <script type="text/x-template">
+ JavaScript內聯模版字符串
+ .vue 組件
# data 必須是函數
- 多個組件共享同一個 data,增加一個 counter 會影響所有的組件。解決方案:每個組件返回一個全新的 data 對象:
data: function () {
return {
counter: 0
}
}
# 構成組件
- 父子組件:組件 A 在它的模板中使用了組件 B。它們的關系可以總結為 props down,events up。父組件通過 props 向下傳遞數據給子組件,子組件通過 events 給父組件發送消息。
Prop
# 使用 Prop 傳遞數據
- 組件實例的作用域是孤立的。
- 子組件使用父組件的數據,需要通過子組件的 props 選項
# camelCased(駝峰式) vs. kebab-case(短橫線隔開式)命名
# 動態 Prop
# 字面量語法 vs 動態語法
<!-- 傳遞了一個字符串 "1" -->
<comp some-prop="1"></comp>
<!-- 傳遞實際的 number -->
<comp v-bind:some-prop="1"></comp>
# 單向數據流
- prop 是單向綁定的:父組件的屬性發生變化時,將傳導給子組件,不會反過來。--防止子組件無意修改額父組件的狀態。
- prop 作為初始值傳入后,子組件想把它當作局部數據來用;解決方法:定義一個局部變量,並用 prop 的值初始化它
props: ['initialCounter'],
data: function () {
return { counter: this.initialCounter }
}
- prop 作為初始值傳入,由子組件處理成其它數據輸出,解決方法:定義一個計算屬性,處理 prop 的值並返回。
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
- 注意在 JavaScript 中對象和數組是引用類型,指向同一個內存空間,如果 prop 是一個對象或數組,在子組件內部改變它會影響父組件的狀態。
# Prop 驗證
自定義事件
- 父組件是使用 props 傳遞數據給子組件,但如果子組件要把數據傳遞回去,應該怎樣做?那就是自定義事件!
# 使用 v-on 綁定自定義事件
# 給組件綁定原生事件
- v-on:click.native="doThing"
# 使用自定義事件的表單輸入組件
# 非父子組件通信
- 在簡單的場景夏,可以使用一個空的 Vue 實例作為中央事件總線:
- 在復雜的情況下,我們應該考慮使用專門的狀態管理模式
使用 Slot 分發內容
- 為了讓組件可以組合,我們需要一種方式來混合父組件的內容和子組件自己的模板,這個過程叫做內容分發,使用
元素作為原始內容的插槽。
# 編譯作用域
# 單個 Slot
# 具名 Slot
# 作用域插槽(2.1.0新增)
動態組件
- keep-alive
雜項
# 編寫可復用組件
- 編寫組件時,記住是否要復用組件有好處。一次性組件和其它組件緊密耦合沒關系,但是可復用組件應當定義一個清晰的公開接口。
- Vue 組件的 API 來自三個部分 - props,events 和 slots:
- Props 允許外部環境傳遞數據給組件
- Events 允許組件觸發外部環境的副作用
- Slots 允許外部環境將額外的內容組合在組件中。
# 子組件索引
# 異步組件
# 組件命名約定
# 遞歸組件
# 組件間的循環引用
# 內聯模板
-這在有很多模版或者小的應用中有用,否則應該避免使用,因為它將模版和組件的其他定義隔離了。