vue笔记整理与总结
Vue
一、 簡介:(為什么使用vue)
1、 與angular相比優點:
a) api簡單,快速上手,學習成本低;
b) Angular 使用雙向綁定,Vue 也支持雙向綁定,不過為單向數據流,數據從父組件單向傳給子組件;
c) Vue.js 中指令和組件分得更清晰。指令只封裝 DOM 操作,而組件代表一個自給自足的獨立單元 —— 有自己的視圖和數據邏輯。在 Angular 中兩者有不少相混的地方
d) Angular的臟檢查機制,造成了如果項目龐大之后性能降低問題;每一次更新數據,都導致所有的數據綁定,進行一次遍歷;
Vue的數據變化更新是根據依賴追蹤的觀察系統并且異步列隊去更新,數據變化都是獨立的觸發隊列中相應的事件;
e) 渲染層創建了虛擬dom(輕量級,2.0),減少了內存開銷和加快了渲染速度;
f) 組件式開發,每個組件都具有生命周期,便于自己狀態的維護;實現了代碼的高復用性;
2、 與react相比:
λ 共同點:
a) 使用 Virtual DOM
b) 提供了響應式(Reactive)和組件化(Composable)的視圖組件
c) 將注意力集中保持在核心庫,而將其他功能如路由和全局狀態管理交給相關的庫
λ 優勢:
″ 性能:
a) vue的更新渲染過程是自動追蹤的,而react如果想要提高更新的性能需要通過shouldComponentUpdate鉤子函數對數據進行對比;
b) 對于組件的語法,在vue中既可以支持jsx語法,將css和html都寫入js文件中,又可以使用template模板進行編譯,在vue中推薦使用template模板進行編譯,減少學習成本,更加符合前端開發語法;而react僅僅支持jsx語法,jsx的優點:一、開發工具對jsx的支持比其他的vue模板更先進;
c) 對于css的支持:
vue中可以直接在style中寫css語法,可以支持媒體查詢,等等一切css屬性,并且可以通過scoped進行組件作用域的封閉;
react的組件中如果進行css樣式的隔離,只能寫入js文件中,比較簡單的樣式可以進行支持,但是如果比較復雜的則無法支持;
″ 規模:
共同點:
都提供了路由和狀態管理機制;
都有自己的自動化構建工具;
不同點:
react的學習成本比較高,需要掌握jsx語法和es2015;雖然支持前端babel進行編譯,但是不適合生產環境;
vue向下擴展可以像jq那樣使用在前端項目中,向上擴展可以像react一樣進行前端的自動化構建;
″ 本地渲染:(跨平臺)
reactNative
weex
3、 總結vue:
優點:
a) MVVM的開發模式,從dom中解脫出來,雙向數據綁定;
b) 數據更新采用異步事件機制;
c) 采用單向數據流;
d) 組件式開發;
e) 采用虛擬dom
f) 支持模板和jsx兩種開發模式;
g) 可以進行服務端渲染;
h) 擴展性強,既可以向上又可以向下擴展
缺點:
a) 不兼容IE8以下版本
b) 生態圈不繁榮,開源社區不活躍;
二、 安裝與使用:
1、 直接使用CDN引入:
<script src="https://unpkg.com/vue"></script>
2、 下載到本地:
https://vuejs.org/js/vue.js3、 自動化構建工具:
Vue.js 有一款官方的腳手架生成工具 vue-cli:
λ 全局安裝
npm install –g vue-cli
λ 創建項目
vue init webpack myproject
λ 安裝依賴包
npm install
λ 目錄如下:
build: 用于存放 webpack 相關配置和腳本。
config: 主要存放配置文件,用于區分開發環境、測試環境、線上環境的不同。
src: 項目源碼及需要引用的資源文件。
static: 不需要 webpack 處理的靜態資源。
test: 用于存放測試文件;
λ 啟動服務:
正常開發時,就會運行命令npm run dev,啟動一個小型的express 服務。在這個 express 服務中,會使用webpack-dev-middleware 和 webpack-hot-middleware 這兩個 中間件,來進行項目的熱部署,即每次修改 src 中的文件后,不需要再按瀏覽器的刷新來更新 代碼,啟動的 server 服務會自動監聽文件的變化并編譯,通知瀏覽器自動刷新。
λ 分析packjson文件:
dev:為本地開發的啟動項;
start:和dev一樣;
build:打包線上部署代碼
e2e:這個代表端對端測試,確切的來說就是前端的一個自動化測試;這里使用的是java的nightwatch自動化測試工具,使用測試需要進行java的全局安裝
三、 實例:
1、一個 Vue 實例其實正是一個 MVVM 模式中所描述的 ViewModel - 因此在文檔中經常會使用 vm 這個變量名。
2、在實例化 Vue 時,需要傳入一個選項對象,它可以包含數據、模板、掛載元素、方法、生命周期鉤子等選項 ;
(1)模板:
(2)數據:
可以對外部數據進行代理,外部傳入的數據如果為對象,對此數據進行的淺拷貝,此時我們成為數據的響應式;對于初始化后,進行的數據添加無效,要想對于初始后添加的數據生效,需要使用$set(),不過不推薦這么,盡量在數據初始化時,就對所有需要的數據進行添加,可以用undefined和null進行占位;$watch方法對于實例對象的數據進行監聽,并在回掉中接受舊數據和新數據;(3)方法:
Methods對象來定義方法,并且使用v-on指令來監聽DOM事件;自定義事件:$emit、$on、($broadcast、$dispatch在2.0中已經刪除)(4)生命周期:
在vue實例創建時一系列的初始化步驟:beforeCreate、created、beforeMount、mounted、beforeDestroy、destroyed 、beforeUpdate、updated、activated、deactivated (5)數據綁定:傳統的web項目,往往是通過后端模板引擎來進行數據和視圖的渲染,例如:php的smarty、java的velocity、node的express、也就是傳統的服務端渲染,導致前后端語言混雜在一起,造成渲染后期進行視圖更改是,只能通過dom;a、文本插值使用{{}}大括號,單次賦值:{{*}} (2.0中使用v-once=””) b、 屬性插值{{}} (2.0 v-bind:id=””)c、表達式{{}} (6)指令:a、參數:v-bind:src=”attr”,給屬性綁定值;
或者可以這樣寫:src=”{{attr}}”
或者可以這樣寫 :src=“attr”
四、 計算屬性:
####三種對于數據變化監聽機制:
1、 computed:一個屬性依賴于多個屬性時,推薦使用
2、 watch():多個屬性依賴一個屬性是,推薦使用
3、 Set、get:set對一個屬性設置值時,會自動的調用相應的回掉函數,get的回調函數會根據,函數內部依賴的屬性的改變而自動改變
五、 條件渲染:
1、 v-if
2、 template v-if
如果在一個判斷中要對多個元素進行渲染,則需要配合template標簽;
3、 v-else
4、 v-else-if
多次進行鏈式的使用
5、 key管理可復用的元素:
Vue 會盡可能高效地渲染元素,通常會復用已有元素而不是從頭開始渲染
在這里用key進行元素的唯一標識賦值,降低元素的復用性;
6、 v-if與v-show
v-if 是“真正的”條件渲染,因為它會確保在切換過程中條件塊內的事件監聽器和子組件適當地被銷毀和重建
v-if 有更高的切換開銷,而 v-show 有更高的初始渲染開銷
7、 v-if與v-for一起使用
當 v-if 與 v-for 一起使用時,v-for 具有比 v-if 更高的優先級;如果想讓v-if優先級更高,則需要在外套一層標簽;進行v-if的渲染
六、 列表渲染:
A、數組:
1、 常用寫法:
v-for=”item in items”
v-for=”(item,index) in items”
2、 結合template使用:
帶有 v-for 的 <template> 標簽來渲染多個元素塊
B、對象:
1、 常用寫法:
v-for="value in object"
v-for="(value, key) in object"
v-for="(value, key, index) in object"
C、整數迭代:
1、 常用寫法:
v-for="n in 10"
D、組件:
1、 常用寫法:
<my-component v-for="item in items" :key="item.id"></my-component>
E、key:
當 Vue.js 用 v-for 正在更新已渲染過的元素列表時,它默認用 “就地復用” 策略,默認的模式是高效的,但是只適用于不依賴子組件狀態或臨時 DOM 狀態。為了給 Vue 一個提示,以便它能跟蹤每個節點的身份,從而重用和重新排序現有元素,你需要為每項提供一個唯一 key 屬性。
注:如果加key值,列表重新渲染的元素,是從key變化的第一個元素起到key值變化的最后一個元素結束,中間所有的元素都是重新渲染,不管中間元素的key值變化與否;
F、變異方法,觸發視圖更新:
Push、pop、shift、unshift、splice、sort、reverseG、重塑數組、顯示過濾/排序結果
對于非變異的數組方法,在操作數組時,一般是采用重新賦值的方式,操作做完原數組,再將結果賦給原屬性;如:filter、concat、slice
evenNumbers: function () {return this.numbers.filter(function (number) {return number % 2 === 0}) }七、 方法與事件:
1、 方法處理器:
v-on 指令監聽 DOM 事件
2、 內聯語句處理器:
方法的調用方式,可以直接出入參數,或$event當前事件傳入
3、 事件修飾符:
.stop:等同于調用event.stopPropagetion()
.prevent:等同于調用event.preventDefault()
.capture:使用capture模式添加事件監聽器,使用事件捕獲模式
.self:只當事件是從監聽元素本身時才會觸發回調;
.once:事件將只會觸發一次;
4、 按鍵修飾符:
KeyCode: (鍵值)
<input v-on:keyup.13="submit">
按鍵別名:
enter、tab、delete、esc、space、up、down、left、right
八、 表單控件綁定:
1、 v-model 會忽略所有表單元素的 value、checked、selected 特性的初始值。
2、 text、textarea
3、 復選框:
單選:(值為true/false)
<input type="checkbox" id="checkbox" v-model="checked">
多選:(值為數組格式,數組中每一項為input的value值)
<input type="checkbox" id="jack" value="Jack" v-model="checkedNames">
<input type="checkbox" id="john" value="John" v-model="checkedNames">
4、 單選按鈕
值為字符串,當前選中元素的value值;
<input type="radio" id="one" value="One" v-model="picked">
<input type="radio" id="two" value="Two" v-model="picked">
5、 選擇列表
單選列表:(值為字符串)
<select v-model="selected">
</select>
注:如果 v-model 表達初始的值不匹配任何的選項,<select> 元素就會以”未選中”的狀態渲染。在 iOS 中,這會使用戶無法選擇第一個選項,因為這樣的情況下,iOS 不會引發 change 事件。因此,像以上提供 disabled 選項是建議的做法
多選列表:
a) 值為一個數組格式
b) 多選時,需要ctrl配合
c) 無實際意義
d) 比單選列表多一個multiple屬性
<select v-model="selected" multiple style="width: 50px">
</select>
6、 綁定value:
(當單選或復選框選中時,此時的model值一般為boolen值,但是根據業務需求,有時我們需要動態綁定值,用法如下)
a) 復選框:
<input type="checkbox" v-model="toggle" v-bind:true-value="a" v-bind:false-value="b">
// 當選中時
vm.toggle === vm.a
// 當沒有選中時
vm.toggle === vm.b
b) 單選框:
<input type="radio" v-model="pick" v-bind:value="a">
// 當選中時
vm.pick === vm.a
7、 修飾符
lazy:在 change 事件中同步
number:自動將用戶的輸入值轉為 Number 類型
trim:自動過濾用戶輸入的首尾空格
九、 過渡:
通過 Vue.js 的過渡系統,可以在元素從 DOM 中插入或移除時自動應用過渡效果。Vue.js 會在適當的時機為你觸發 CSS 過渡或動畫,你也可以提供相應JavaScript 鉤子函數在過渡過程中執行自定義的 DOM 操作。
1、 經常使用工具:
在 CSS 過渡和動畫中自動應用 class
可以配合使用第三方 CSS 動畫庫,如 Animate.css
在過渡鉤子函數中使用 JavaScript 直接操作 DOM
可以配合使用第三方 JavaScript 動畫庫,如 Velocity.js
2、 Vue 提供了 transition 的封裝組件,與下面情況一起使用:
v-if
v-show
動態組件 (介紹見組件)
在組件的根節點上,并且被 Vue 實例 DOM 方法(如 vm.$appendTo(el))觸發。
3、 vue對transition組件的處理方式:
a) 自動嗅探目標元素是否應用了 CSS 過渡或動畫,如果是,在恰當的時機添加/刪除 CSS 類名。
b) 如果過渡組件提供了 JavaScript 鉤子函數,這些鉤子函數將在恰當的時機被調用
c) 如果沒有找到 JavaScript 鉤子并且也沒有檢測到 CSS 過渡/動畫,DOM 操作(插入/刪除)在下一幀中立即執行。
4、 類名的添加和切換取決于 transition 特性的值。比如 <transition name="fade">,會有六個 CSS 類名:
A. 當dom插入時:
1) fade-enter: 定義進入過渡的開始狀態。在元素被插入時生效,在下一個幀移除
2) fade-enter-active: 定義過渡的狀態。在元素整個過渡過程中作用,在元素被插入時生效,在 transition/animation 完成之后移除。 這個類可以被用來定義過渡的過程時間,延遲和曲線函數。
3) fade-enter-to: 2.1.8版及以上 定義進入過渡的結束狀態。在元素被插入一幀后生效(于此同時 v-enter 被刪除),在 transition/animation 完成之后移除。
B. 當dom移除時:
1) fade-leave: 定義離開過渡的開始狀態。在離開過渡被觸發時生效,在下一個幀移除。
2) fade-leave-active: 定義過渡的狀態。在元素整個過渡過程中作用,在離開過渡被觸發后立即生效,在 transition/animation 完成之后移除。 這個類可以被用來定義過渡的過程時間,延遲和曲線函數。
3) fade-leave-to: 2.1.8版及以上 定義離開過渡的結束狀態。在離開過渡被觸發一幀后生效(于此同時 v-leave 被刪除),在 transition/animation 完成之后移除。
注:如果一個動畫在dom插入和刪除時執行的效果正好相反,則只需要將v-enter和v-leave-to的樣式設置成一樣就可以;不需要對v-enter-to和v-leave進行設置,對于v-enter-active和v-leave-active可以進行相應的過渡時間和過渡曲線的設置;
5、 通過css的animation屬性來實現過渡的效果:
CSS 動畫用法同 CSS 過渡,區別是在動畫中 v-enter 類名在節點插入 DOM 后不會立即刪除,而是在 animationend 事件觸發時刪除;
注:對于animation的使用,可以直接在定義一個動畫,然后再v-enter-active和v-leave-active中用animation屬性定義動畫的曲線和時間即可;
6、 自定義過渡類名結合第三方動畫庫如Animate.css:
http://cdn.bootcss.com/animat...
自定義的類名屬性有:
enter-class
enter-active-class
enter-to-class (2.1.8+)
leave-class
leave-active-class
leave-to-class (2.1.8+)
注:他們的優先級高于普通的類名;
使用方法:
將上述屬性添加到transition元素上,屬性值為第三方庫的動畫名,可以不書寫name屬性定義的過渡名稱,一般只使用enter-active-class和leave-active-class就可以滿足需求書寫方式:
注:屬性值中一定要加入animated屬性值,否則不生效;
如:
enter-active-class="animated bounce"
7、 css樣式中與第三方動畫庫的結合:
將動畫定義到v-enter-active和v-leave-active類名上:
如:
8、 同時使用transitions和animations時顯示的聲明過渡類型
Vue 為了知道過渡的完成,dom要顯示原有的樣式,必須設置相應的事件監聽器,它可以是 transitionend 或 animationend ,這取決于給元素應用的 CSS 規則。如果你使用其中任何一種,Vue 能自動識別類型并設置監聽。
有時候同時使用transition 和animation ,而執行完畢的時間不統一,會造成后者無法將動畫執行完畢,此時可以用type屬性在transition元素上進行相應的設置需要 Vue 監聽的類型,屬性值為transition 或animation
9、 顯示定義過渡效果的持續時間
應用場景:
Vue 會等待其在過渡效果的根元素第一個 transitionend 或 animationend 事件觸發后,結束過渡效果;一些嵌套的內部元素相比于過渡效果的根元素有延遲的或更長的過渡效果。
使用方式:
<transition :duration="1000">...</transition>
<transition :duration="{ enter: 500, leave: 800 }">...</transition>
10、 js中的鉤子函數
beforeEnter、enter、afterEnter、enterCancelled、beforeLeave、leave、afterLeave、leaveCancelled
結合第三方js動畫庫:<script src="https://cdnjs.cloudflare.com/...;></script>
動畫的書寫格式:
Velocity的參數:第一個為動畫掛載的元素,第二個為定義的動畫css樣式,第三個參數為動畫的時間或者回調函數
如:
Velocity(el,{fontSize:’1.5em’},{duration:300,complete:done})
常用鉤子函數為:beforeEnter 、enter、beforeLeave 、leave分別定義,元素進入時的動畫和元素離開時的動畫;
beforeEnter:定義元素進入時的初始樣式;
enter:定義元素進入過程的動畫樣式(一般第三方庫的動畫使用在此鉤子中)
beforeLeave:定義元素離開是的初始樣式;
leave:定義元素離開過程的動畫樣式(一般第三方庫的動畫使用在此鉤子中)
注:一定注意在enter、leave鉤子中一定使用done的方法的調用,否則動畫將無效;
11、 初始渲染的過渡;
通過appear屬性的添加實現初始渲染的過渡
12、 在一個transition元素中對多個標簽動畫的實現:
需要給每一個元素添加一個key標簽,防止元素的復用(不產生任何動畫)
過渡模式:
場景:在兩個元素的切換過程中,進入元素和離開元素的過渡同時進行,將會導致效果偏差;
解決:
可以在過渡的標簽上添加過渡模式:(mode)
in-out: 新元素先進行過渡,完成之后當前元素過渡離開。(一般不用)
out-in: 當前元素先進行過渡,完成之后新元素過渡進入。
13、 多個組件的過渡
一般使用動態組件的方式實現不同組件間的切換,然后在切換過程中實現過渡效果;
注:動態組件的切換不存在標簽的復用問題
14、 列表過渡:
1) 列表的進入和離開過渡
使用transition-group組件,不同于transition組件,會以一個真實元素呈現,默認為span元素,也可以通過tag特性更換為其他元素;
內部元素必須提供唯一的key值
2) 列表的位移過渡
v-move特性可以在元素的改變定位的過程中應用,可以通過name屬性自定義前綴,也可以通過move-class手動設置
十、 組件
組件 (Component) 是 Vue.js 最強大的功能之一。組件可以擴展 HTML 元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js 的編譯器為它添加特殊功能。
(一) 組件注冊:
組件構造器:Vue.extend({ }),2.0中可以不使用構造器進行構造,直接寫入對象;
規則:對于自定義標簽名,Vue.js 不強制要求遵循 W3C 規則 (小寫,并且包含一個短杠),盡管遵循這個規則比較好
1、 全局注冊:
全局注冊需要在根實例初始化前注冊,這樣才能使組件在任意實例中被使用,方式:Vue.component(“組件名”,組件)
2、 局部注冊:
組件只能在被注冊的組件中使用,而無法在其他組件中使用.
3、 注冊語法糖:
全局注冊和局部注冊(使用components屬性,值為對象,組件名和組件定義對象是鍵值對的關系);
(二) 組件選項:
1、 template:注意分析模板,is使用;
2、 el和data兩個屬性,不可以直接賦值,比如data如果直接賦值,組件使用多次的時候,多個組件將公用一個對象;如果一個改變,則所有都會改變;所以使用function方式,每次return出一個新的對象;el類似;由于el很少直接在組件中掛載,所以可以忽略;
3、 props:
組件間的作用域是孤立的,這里跟angular的指令作用域有所不同,angular指令的默認作用域是公用的,不管是在子指令還是父指令中定義的;在vue中,props起到了父組件向下與子組件間的橋梁作用;子組件給父組件發送消息,需要events;
ν 駝峰命名:html的屬性不區分大小寫;
ν 動態props:
通過v-bind進行綁定;
如果要進行數值的傳遞,必須通過動態綁定,否則直接傳遞過去的是個字符串;
ν props的接受:
在子組件中使用props屬性進行接受,props的值可以為數組(不可做校驗),可以為對象(可以做校驗)
ν props數據的處理:
不應該在子組件中進行prop值的改變,因為prop的值是隨父組件進行更變,如果在組件中直接對prop進行改變,vue則會拋出警告
正確的處理方式:
a) 定義一個局部變量,并用 prop 的值初始化它:(只會在初始化時,進行一次賦值,后期不會動態改變)
props: ['initialCounter'],
b) 定義一個計算屬性,處理prop的值并返回:(進行屬性值的動態跟蹤)
props: ['size'],
ν 綁定類型:
1) 默認時一直跟隨父組件值得變化而變化,
2) .sync:雙向綁定(取消);在2.3.0以后,再次以事件監聽實現雙向數據流;如:
父組件:
<comp :foo="bar" @updata="val => bar = val"></comp>
子組件:
this.$emit('update:foo', newValue)
3) .once:單次綁定,子組件接受一次父組件傳遞的數據后,單獨對這份數據進行維護;(2.0版本后取消此修飾符)
注:如果prop傳遞的是一個引用類型的數據,如對象或數組,即使單向綁定,子組件也會影響父組件;(傳遞為單向傳遞)
ν Props驗證:
1) 基礎類型檢測:prop:Number,接受的參數為原生的構造器:String、Number、Boolen、Function、Object、Aarry、Symbol、Null(意味著任何類型都行)
2) 可以為多種類型:props:[Number,String]
3) 參數必須:props:{type:Number,required:true} 對象的寫法
4) 參數默認:props {type:Number,default:0} 對象的寫法
5) 綁定類型:props:{twoWay:true} 校驗數據綁定類型,如果非雙向綁定會拋出一條警告;(這個不用了)
6) 自定義驗證函數:props:{validator:function(val){ return val>1},這樣就可以驗證一個數值是否大于1;
(三) 非Prop屬性:
1、 在組件上使用自定義屬性,如果不在子組件中使用props進行接受,則此屬性會被默認添加到組件的根元素上;
2、 在組件上使用html元素已有的屬性,如class、style等,則組件上的屬性值,會和組件的根節點的相應屬性值進行合并等特性;如type等屬性值,會進行覆蓋或替換;如:組件中的input的type為number,使用組件時傳入的type值為text,則組件內部的input的type值將被替換為text;
(四) 組件間通信:
1、 直接訪問:
1)?父組件實例children:包含所有子組件實例
3)?:組件所在的根實例;這三個屬性都掛載在組件的上,不推薦這樣做,會造成父子組件間的強耦合;、自定義事件監聽:組件實例化時,在組件的標簽上使用進行事件的監聽;、自定義事件觸發機制:emit:在實例本身上觸發事件在子組件的鉤子函數中去觸發事件;
4、 子組件索引:
通過ref指令,綁定一個子組件,可以在父組件中使用this.$refs.屬性名 的方式獲取子組件;
5、 非父子通信:
思想:建立一個空的vue實例作為中央事件總線,即全局的vue實例;
代碼如下:
(五) 內容分發:
1、 基礎用法:
提供一種混合父組件內容與子組件自己模板的方式叫做內容分發;
Slot標簽;
2、 使用需求:
當子組件中的dom結構以及展示的內容由父組件決定時
3、 編譯作用域:
如果在子組件的模板中使用{{}}解析數據,則模板會解析自己作用域中的數據,而不是解析父組件作用中的數據;
4、 默認slot:
<slot>標簽允許有一個匿名slot,不需要name值,作為找不到匹配的內容片段的回退插槽,如果沒有默認的slot,這些找不到匹配的內容片段將被忽略;
5、 作用域插槽:
在父組件的slot模板中使用子組件中數據;如:
在父級中,具有特殊屬性 scope 的 <template> 元素必須存在,表示它是作用域插槽的模板。scope 的值對應一個臨時變量名,此變量接收從子組件中傳遞的 props 對象;
在slot中可以動態綁定屬性值,綁定的屬性需要在父組件的scope中進行顯示聲明;
(六) 動態組件:
1、基礎用法:
component 標簽上 is 屬性決定了當前采用的子組件,:is 是 v-bind:is 的縮寫,綁定了父 組件中 data 的 currentView 屬性。頂部的 ul 則起到導航的作用,點擊即可修改 currentView 值,也就修改 component 標簽中使用的子組件類型,需要注意的事,currentView 的值需要 和父組件實例中的 components 屬性的 key 相對應。(起到路由的作用)
2、keep-alive
在component 標簽外層包裹一個 keep-alive 標簽,可以將切換出去的組件保留在內存中,避免重新 渲染。
(七) 雜項:
1、 異步組件:
局部定義組件寫法:
2、 當注冊組件 (或者 props) 時,可以使用 kebab-case,camelCase,或 PascalCase。但是使用組件時只能用kebab-case這種寫法;html不識別大小寫;
3、 當組件中包含大量靜態內容時,可以考慮使用 v-once 將渲染結果緩存起來
4、 X-Templates
另一種定義模版的方式是在 JavaScript 標簽里使用 text/x-template 類型
<script type="text/x-template" id="hello-world-template">
<p>Hello hello hello</p>
</script>
十一、 指令
1、 內置指令:
1) V-bind
2) V-model
3) V-if/ v-else-if/v-else/v-show
4) V-for
5) V-on
6) V-text
7) V-html
8) v-pre 指令相對簡單,就是跳過編譯這個元素和子元素,顯示原始的 {{}}Mustache 標 簽,用來減少編譯時間。
9) v-cloak 指令相當于在元素上添加了一個 [v-cloak] 的屬性,直到關聯的實例結束編譯。 官方推薦可以和 css 規則 [v-cloak]{ display :none } 一起使用,可以隱藏未編譯的 Mustache 標簽直到實例準備完畢
10) v-once 指令是 Vue.js 2.0 中新增的內置指令,用于標明元素或組件只渲染一次,即使隨 后發生綁定數據的變化或更新,該元素或組件及包含的子元素都不會再次被編譯和渲染。
2、 自定義指令基礎:
1) 注冊:通過 Vue.directive(id, definition) 方法注冊一個全局自定義指令,接收參數 id 和定義對象。id 是指令的唯一標識,定義對象則是指令的相關屬性及鉤子函數。
也可以通過在組件的 directives 選項注冊一個局部的自定 義指令
2) 指令的定義對象:
主要包含鉤子函數:
bind: 只被調用一次,在指令第一次綁定到元素上時調用。用這個鉤子函數可以定義一個在綁定時執行一次的初始化動作。
inserted: 被綁定元素插入父節點時調用(父節點存在即可調用,不必存在于 document 中)。
update : 所在組件的 VNode 更新時調用,但是可能發生在其孩子的 VNode 更新之前。指令的值可能發生了改變也可能沒有。但是你可以通過比較更新前后的值來忽略不必要的模板更新
componentUpdated: 所在組件的 VNode 及其孩子的 VNode 全部更新時調用。
unbind :指令從元素上解綁時調用,只調用一次。
注:如果我們只需要使用 update 函數時,可以直接傳入一個函數代替定義對象;
指令綁定的值:
a) data 中的屬性,使用<div v-my-directive="constant string"/></div>
b) 綁定字符串需要加單引號,<div v-my-direcitve="'constant string'"></div>
c) 利用字面修飾符后無需使用單引號
d) 受對象字面量或任意合法的 JavaScript 表達式:
<div v-my-directive="{ title : 'Vue.js', author : 'You'}" ></div> <div v-my-directive="isExist ? 'yes' : 'no'" ></div>3) 指令的實例屬性:
a) el: 指令所綁定的元素,可以用來直接操作 DOM 。
b) binding: 一個對象,包含以下屬性:
name: 指令名,不包括 v- 前綴。
value: 指令的綁定值, 例如: v-my-directive="1 + 1", value 的值是 2。
oldValue: 指令綁定的前一個值,僅在 update 和 componentUpdated 鉤子中可用。無論值是否改變都可用。
expression: 綁定值的表達式形式。 例如 v-my-directive="1 + 1" , expression 的值是 "1 + 1"。
arg: 傳給指令的參數。例如 v-my-directive:foo, arg 的值是 "foo"。
modifiers: 一個包含修飾符的對象。 例如: v-my-directive.foo.bar, 修飾符對象 modifiers 的值是 { foo: true, bar: true }。
c) vnode: Vue 編譯生成的虛擬節點,查閱 VNode API 了解更多詳情。
d) oldVnode: 上一個虛擬節點,僅在 update 和 componentUpdated 鉤子中可用。
3、 指令與組件的區別:
組件一般是指一個獨立實體,組件之間的關系通常都是樹狀。
指令是一種Decorator模式,用以改寫某個組件的默認行為,或者增強使其獲得額外功能,一般來說可以在同一個組件上疊加若干個指令,使其獲得多種功能。
十二、 vue-route
(一) 基本用法:
1、 router-link:
a) <router-link> 組件支持用戶在具有路由功能的應用中(點擊)導航。 通過 to 屬性指定目標地址,默認渲染成帶有正確鏈接的?標簽,可以通過配置 tag 屬性生成別的標簽,<router-link> 比起寫死的?會好一些;
b) props:路由參數:
to:格式為字符串或者是對象;
寫法:
append: 在當前(相對)路徑前添加基路徑。例如,我們從 /a 導航到一個相對路徑 b,如果沒有配置 append,則路徑為 /b,如果配了,則為 /a/b
注:另一個路徑不允許加/;
tag:將touter-link轉換為另外一種標簽;
active-class:設置 鏈接激活時使用的 CSS 類名。默認值可以通過路由的構造選項 linkActiveClass 來全局配置。
2、 router-view
渲染對應的路由配置中 components 下的相應組件;可以和<transition> 、 <keep-alive>等配合使用,兩個結合一起用,要確保在內層使用 <keep-alive>:
<transition>
<keep-alive>
</keep-alive>
</transition>
3、 路由信息對象:
路由信息對象表示當前激活的路由的狀態信息,是不可變得,每次成功的導航都會產生一個新的對象;
出現的地方:
λ 組件內部的鉤子函數中;
λ 導航的鉤子函數中
λ watch監聽的$route對象中的(to,from)參數:
例:
scrollBehavior 方法的參數
路由信息對象的屬性:
$route.path:字符串,對應當前路由的路徑,總是解析為絕對路徑,如 "/foo/bar"。
:包含了動態片段和全匹配片段,如果沒有路由參數,就是一個空對象。route.query:一個 key/value 對象,表示 URL 查詢參數。例如,對于路徑 /foo?user=1,則有?,如果沒有查詢參數,則是個空對象。route.matched:一個數組,包含當前路由的所有嵌套路徑片段的 路由記錄 。路由記錄就是 routes 配置數組中的對象副本(還有在 children 數組)
$route.name:當前路由的名稱
4、 router構造配置
mode: 配置路由模式:hash | history | abstract
base:應用的基路徑。例如,如果整個單頁應用服務在 /app/ 下,然后 base 就應該設為 "/app/"。(這里有坑)
linkActiveClass: 全局配置 <router-link> 的默認『激活 class 類名
5、 router實例:
屬性:
router.app: 配置了 router 的 Vue 根實例。
router.mode: 路由使用的 模式。
router.currentRoute:當前路由信息對象;
方法:
router.push(location) :進行路由的跳轉,并且保存到瀏覽器的history中
router.replace(location):進行路由的替換,不會將上次的路由保存到history中
router.go(n):執行瀏覽器的前進動作,n代表前進的步數,負數代表后退
router.back(): 執行瀏覽器的后退動作
router.forward()
router.addRoutes(routes): 動態添加更多的路由規則。參數必須是一個符合 routes 選項要求的數組
6、 動態路由匹配:
書寫方式:
{ path: '/user/:id', component: User } { path: '/user/:username/post/:post_id', component: User }上述的動態值通過?去接受路由參數的變化:使用路由參數時,例如從導航到,原來的組件實例會被復用。因為兩個路由都渲染同個組件,比起銷毀再創建,復用則顯得更加高效。不過,這也意味著組件的生命周期鉤子不會再被調用;解決辦法:(監測變化)route 對象:
7、 嵌套路由:
在 VueRouter 的參數中使用 children 配置,屬性值為路由對象數組;
注意:在子路由的path屬性中設置路由地址時,不可以加“/”,否則將會以根路由進行添加;
8、 多視圖多組件渲染:
多視圖對應多組件,使用的路由對象屬性為:components;
例:
html:
<router-view class="view one"></router-view>
<router-view class="view two" name="a"></router-view>
<router-view class="view three" name="b"></router-view>
js:
9、 重定向:
屬性為redirect,屬性值可以為{name:“foo”}或“foo”或者為一個方法的返回值
例:
{ path: '/a', redirect: { name: 'foo' }}
10、 別名:
例:{ path: '/a', component: A, alias: '/b' }
當用戶訪問/b時,路由顯示的是/b,其實規則為/a
11、 路由的鉤子函數:
1) 全局鉤子:(一般不使用)
使用router的實例對象進行注冊;當一個導航觸發時,全局的 beforeEach鉤子按照創建順序調用。鉤子是異步解析執行,此時導航在所有鉤子 resolve 完之前一直處于 等待中
三個參數:
next(): 進行管道中的下一個鉤子
next(false): 中斷當前的導航。重置到 from 路由對應的地址
next('/') 或next({ path: '/' }):當前導航被中斷,重定向到另一個新的導航:
例:
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {})
2) 路由的獨享鉤子:
在路由的配置項中定義:beforeEnter屬性;
3) 組件內的路由鉤子:
beforeRouteEnter:路由跳轉之前執行,不能獲取this,組件實例還沒有創建;
beforeRouteUpdate:路由重新跳轉之前,該方法在組件復用時調用,該鉤子函數中可以訪問組件的實例this
beforeRouteLeave:離開該組件的對應路由時調用,可以訪問實例this,一般在用戶未保存信息時,不允許跳轉相應的路由,next(false)阻止;
關于beforeRouteEnter鉤子不能訪問this,可以通過一個回調給next來訪問組件實例,例:
beforeRouteEnter (to, from, next) {next(vm => {// 通過 `vm` 訪問組件實例}) }12、 數據的獲取
1) 導航完成之后獲取:先完成導航,然后在接下來的組件生命周期鉤子中獲取數據。在數據獲取期間顯示『加載中』之類的指示。
2) 導航完成之前獲取:導航完成前,在路由的 enter 鉤子中獲取數據,在數據獲取成功后執行導航。
注:
導航完成之后獲取需要借助組件的watch屬性,在動態路由中組件復用時,進行數據的重新請求;
導航完成之前獲取借助beforeRouteUpdate, 在動態路由中組件復用時,進行數據的重新請求;
13、 組件的懶加載
1、 vue的異步組件和webpack的require.ensure()相結合,例:
var index = resolve => require.ensure(['@/components/index'], () => resolve(require('@/components/index')))2、 采用amd風格的require,例:
var?Hello =?resolve?=>?require(['@/components/Hello'], resolve)3、 把組件按組分塊:
提供 require.ensure 第三個參數作為 chunk 的名稱,Webpack 將相同 chunk 下的所有異步模塊打包到一個異步塊里面 —— 這也意味著我們無須明確列出 require.ensure 的依賴(傳空數組就行)
例:
十三、 狀態管理:(vuex)
1、 簡介:
a) 在一些大型應用中,有時我們會遇到單頁面中包含著大量的組件及復雜的數據結構,而 且可能各組件還會互相影響各自的狀態,在這種情況下組件樹中的事件流會很快變得非常復 雜,也使調試變得異常困難。為了解決這種情況,我們往往會引入狀態管理這種設計模式,來 降低這種情況下事件的復雜程度并且使調試變得可以追蹤。
b) 每個組件都會擁有自己的狀態,也可以理解成自身實例中的 data 對 象。用戶在操作的過程中,會通過一些交互行為,例如點擊、輸入、拖動等修改組件的 狀態,而此時往往需要將用戶引起的狀態變化通知到其他相關組件,讓他們也進行對應 的修改。由于 Vue.js 本身的事件流是依賴于 DOM 結構的,組件修改狀態后需要經過 一系列冒泡才能達到頂部的組件,而且如果需要修改兄弟組件的狀態還需要共同的父組 件再進行一次廣播。這種方式無疑是低效而且不易維護的,我們也很難去追蹤事件流的 走向。
c) vuex 和 redux 間的差異表示關注,redux 是 React 生態環境中最流行的 Flux 實現。Redux 事實上無法感知視圖層,所以它能夠輕松的通過一些簡單綁定和Vue一起使用。vuex區別在于它是一個專門為 vue 應用所設計。這使得它能夠更好地和vue進行整合,同時提供簡潔的API和改善過的開發體驗。
2、 配置使用:
安裝vuex,在main.js中引入vuex進行使用;
import vuex from “vuex”, Vue.use(vuex)實例化Vuex:
const store = new Vuex.Store({state: {count: 0},mutations: {increment (state) {state.count++}} })將vuex掛載到Vue實例中:
const app = new Vue({el: '#app',// 把 store 對象提供給 “store” 選項,這可以把 store 的實例注入所有的子組件store,components: { Counter },template: `<div class="app"><counter></counter></div>` })現在,你可以通過 store.state 來獲取狀態對象,以及通過 store.commit 方法觸發狀態變更,我們通過提交 mutation 的方式,而非直接改變 this.$store.state.count,是因為我們想要更明確地追蹤到狀態的變化
3、 核心概念:
a) state:
ν 數據的定義以及存放數據的屬性,類似于組件內部的data屬性;所有在vuex使用的數據都必須在此屬性中進行定義與聲明;不建議將應用所有的數據都放入state,交互性低,比較單一使用的數據,建議放在組件內部定義;
ν mapState輔助函數
寫法:
對象寫法:
數組寫法:
當映射的計算屬性的名稱與 state 的子節點名稱相同時
ν 對象展開運算符:
注意運用此方法時,因為對象擴展運算符是在es提案的stage-3階段,由于babel進行轉碼時,在webpack中默認配置的是es-2015,所以需要借助babel-plugin-transform-object-rest-spread插件進行編譯;
在babel的配置文件中如下配置:
"plugins": ["transform-runtime", "transform-object-rest-spread"],
在computed屬性中的寫法如下:
...mapState({
})
上面的mapState的參數可以是對象,也可以是數組,跟mapState輔助函數中的配置一樣
b) Getters:
應用場景:
有時候,我們需要對state數據進行一些操作后再在組件中進行使用,如果多個組件都需要操作后的這個數據,我們可能會在多個組件computed中都對state進行操作一次;
解決辦法:
使用getters:
組件中使用,跟state的使用一樣,可以使用輔助函數,或者對象展開運算符
c) Mutations:
更改 Vuex 的 store 中的狀態的唯一方法是提交 mutation。Vuex 中的 mutations 非常類似于事件:每個 mutation 都有一個字符串的 事件類型 (type) 和 一個 回調函數 (handler)。這個回調函數就是我們實際進行狀態更改的地方,并且它會接受 state 作為第一個參數;
定義的方式跟getters一樣,例:
回調函數的第一個參數為state,第二個參數可以動態傳入值,值的類型,可以為基本類型或對象;
提交載荷:
可以使用store.commit(‘increment’,10)
或store.commit({type:’increment’,amount:10})
遵循vue的數據相應規則:
在對象上添加新屬性時,使用 Vue.set(obj, 'newProp', 123)或者
state.obj = { ...state.obj, newProp: 123 }
mutation必須是同步函數:
如果為異步,則無法跟蹤數據
在組件中直接提交(不推薦)
d) actions:
action提交的是mutation,而不是直接更變狀態。
action可以包含任意異步操作。
注冊:
i. 在actions的內部可以獲取以一個context參數。這個參數相當于一個store實例,但不是當前應用的store實例本身,因為如果采用modules方式進行數據的管理時,store實例是一個數組;
ii. 可以通過context參數獲取state或者getters等等,一般可以通過此參數來提交commit;
分發action:
應用場景:當一次action對應的數據的更改,必須依賴另外一個action中的數據更改時,必須在本此action中先去觸發另外一個action操作;另外一個action可能為同步,也可能為異步,如果為異步需要借助promise或者async函數;
// 以載荷形式分發
在組件中分發action:
methods: {...mapActions(['increment' // 映射 this.increment() 為 this.$store.dispatch('increment')]),...mapActions({add: 'increment' // 映射 this.add() 為 this.$store.dispatch('increment')})}通過dispatch觸發異步action:
使用promise:
使用async函數:
getData、getOtherData返回的是promise,或者是axiso的數據請求函數
e) modules:
應用場景:
定義:
將 store 分割成模塊(module)。每個模塊擁有自己的 state、mutation、action、getter、甚至是嵌套子模塊——從上至下進行同樣方式的分割
如:
模塊的局部狀態:
對于模塊內部的 mutation 和 getter,接收的第一個參數是模塊的局部狀態對象
對于模塊內部的 action,局部狀態通過 context.state 暴露出來, 根節點狀態則為 context.rootState
在getter中根節點狀態會作為第三個參數暴露出來
總結
以上是生活随笔為你收集整理的vue笔记整理与总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 黑猫315十大行业乱象发布:背后真假套路
- 下一篇: 5分钟了解vue-router的基本使用