最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

如何輕松學(xué)會(huì)Vue基礎(chǔ)語(yǔ)法

2020-06-23 15:33 作者:自學(xué)Python的小姐姐呀  | 我要投稿

主要內(nèi)容Vue組件自定義事件、插槽、動(dòng)態(tài)組件和異步組件、邊界處理情況、組件生命周期、過(guò)渡&動(dòng)畫(huà)、組件復(fù)用性、自定義指令、過(guò)濾器、渲染函數(shù)&JSX、Vue漸進(jìn)式和Element UI組件庫(kù)。

學(xué)習(xí)目標(biāo)

第一節(jié) Vue組件基礎(chǔ)

Vue組件自定義事件

不同于組件和 prop,事件名不存在任何自動(dòng)化的大小寫(xiě)轉(zhuǎn)換。而是觸發(fā)的事件名需要完全匹配監(jiān)聽(tīng)這個(gè)事件所用的名稱(chēng)。舉個(gè)例子,如果觸發(fā)一個(gè) camelCase 名字的事件

this.$emit('myEvent')

不同于組件和 prop,事件名不會(huì)被用作一個(gè) JavaScript 變量名或?qū)傩悦?,所以就沒(méi)有理由使用 camelCase 或 PascalCase 了。并且 v-on 事件監(jiān)聽(tīng)器在 DOM 模板中會(huì)被自動(dòng)轉(zhuǎn)換為全小寫(xiě) (因?yàn)?HTML 是大小寫(xiě)不敏感的),所以 v-on:myEvent 將會(huì)變成 v-on:myevent——導(dǎo)致 myEvent 不可能被監(jiān)聽(tīng)到。

因此,我們推薦你始終使用 kebab-case 的事件名

.sync 修飾符

在有些情況下,我們可能需要對(duì)一個(gè) prop 進(jìn)行“雙向綁定”。不幸的是,真正的雙向綁定會(huì)帶來(lái)維護(hù)上的問(wèn)題,因?yàn)樽咏M件可以修改父組件,且在父組件和子組件都沒(méi)有明顯的改動(dòng)來(lái)源。

這也是為什么我們推薦以 update:myPropName 的模式觸發(fā)事件取而代之。舉個(gè)例子,在一個(gè)包含 title prop 的假設(shè)的組件中,我們可以用以下方法表達(dá)對(duì)其賦新值的意圖:

this.$emit('update:title', newTitle)

然后父組件可以監(jiān)聽(tīng)那個(gè)事件并根據(jù)需要更新一個(gè)本地的數(shù)據(jù)屬性。例如:

<text-document ?v-bind:title="doc.title" ?v-on:update:title="doc.title = $event"></text-document>

為了方便起見(jiàn),我們?yōu)檫@種模式提供一個(gè)縮寫(xiě),即 .sync 修飾符:

<text-document v-bind:title.sync="doc.title"></text-document>

插槽

插槽內(nèi)容

Vue 實(shí)現(xiàn)了一套內(nèi)容分發(fā)的 API,這套 API 的設(shè)計(jì)靈感源自 Web Components 規(guī)范草案,將 <slot> 元素作為承載分發(fā)內(nèi)容的出口。

它允許你像這樣合成組件:

<navigation-link url="/profile"> ?Your Profile</navigation-link>

然后你在 <navigation-link> 的模板中可能會(huì)寫(xiě)為:

<a ?v-bind:href="url" ?class="nav-link"> ?<slot></slot></a>

當(dāng)組件渲染的時(shí)候,<slot></slot> 將會(huì)被替換為“Your Profile”。插槽內(nèi)可以包含任何模板代碼,包括 HTML:

<navigation-link url="/profile"> ?<!-- 添加一個(gè) Font Awesome 圖標(biāo) --> ?<span class="fa fa-user"></span> ?Your Profile</navigation-link>

甚至其它的組件:

<navigation-link url="/profile"> ?<!-- 添加一個(gè)圖標(biāo)的組件 --> ?<font-awesome-icon name="user"></font-awesome-icon> ?Your Profile</navigation-link>

如果 <navigation-link> 沒(méi)有包含一個(gè) <slot> 元素,則該組件起始標(biāo)簽和結(jié)束標(biāo)簽之間的任何內(nèi)容都會(huì)被拋棄。

編譯作用域

當(dāng)你想在一個(gè)插槽中使用數(shù)據(jù)時(shí),例如:

<navigation-link url="/profile"> ?Logged in as {{ user.name }}</navigation-link>

該插槽跟模板的其它地方一樣可以訪(fǎng)問(wèn)相同的實(shí)例屬性 (也就是相同的“作用域”),而不能訪(fǎng)問(wèn) <navigation-link> 的作用域。例如 url 是訪(fǎng)問(wèn)不到的:

作為一條規(guī)則,請(qǐng)記住:

父級(jí)模板里的所有內(nèi)容都是在父級(jí)作用域中編譯的;子模板里的所有內(nèi)容都是在子作用域中編譯的。

后備內(nèi)容

有時(shí)為一個(gè)插槽設(shè)置具體的后備 (也就是默認(rèn)的) 內(nèi)容是很有用的,它只會(huì)在沒(méi)有提供內(nèi)容的時(shí)候被渲染。例如在一個(gè) <submit-button> 組件中:

<button type="submit"> ?<slot></slot></button>

我們可能希望這個(gè) <button> 內(nèi)絕大多數(shù)情況下都渲染文本“Submit”。為了將“Submit”作為后備內(nèi)容,我們可以將它放在 <slot> 標(biāo)簽內(nèi):

<button type="submit"> ?<slot>Submit</slot></button>

現(xiàn)在當(dāng)我在一個(gè)父級(jí)組件中使用 <submit-button> 并且不提供任何插槽內(nèi)容時(shí):

<submit-button></submit-button>

后備內(nèi)容“Submit”將會(huì)被渲染:

<button type="submit"> ?Submit</button>

但是如果我們提供內(nèi)容:

<submit-button> ?Save</submit-button>

則這個(gè)提供的內(nèi)容將會(huì)被渲染從而取代后備內(nèi)容:

<button type="submit"> ?Save</button>

具名插槽

有時(shí)我們需要多個(gè)插槽。例如對(duì)于一個(gè)帶有如下模板的 <base-layout> 組件:

對(duì)于這樣的情況,<slot> 元素有一個(gè)特殊的特性:name。這個(gè)特性可以用來(lái)定義額外的插槽:

一個(gè)不帶 name 的 <slot> 出口會(huì)帶有隱含的名字“default”。

在向具名插槽提供內(nèi)容的時(shí)候,我們可以在一個(gè) <template> 元素上使用 v-slot 指令,并以 v-slot 的參數(shù)的形式提供其名稱(chēng):

現(xiàn)在 <template> 元素中的所有內(nèi)容都將會(huì)被傳入相應(yīng)的插槽。任何沒(méi)有被包裹在帶有 v-slot 的 <template> 中的內(nèi)容都會(huì)被視為默認(rèn)插槽的內(nèi)容。

然而,如果你希望更明確一些,仍然可以在一個(gè) <template> 中包裹默認(rèn)插槽的內(nèi)容:

任何一種寫(xiě)法都會(huì)渲染出:

注意 v-slot 只能添加在一個(gè) <template> 上 (只有一種例外情況),這一點(diǎn)和已經(jīng)廢棄的 slot 特性不同。

作用域插槽

有時(shí)讓插槽內(nèi)容能夠訪(fǎng)問(wèn)子組件中才有的數(shù)據(jù)是很有用的。例如,設(shè)想一個(gè)帶有如下模板的 <current-user> 組件:

<span> ?<slot>{{ user.lastName }}</slot></span>

我們想讓它的后備內(nèi)容顯示用戶(hù)的名,以取代正常情況下用戶(hù)的姓,如下:

<current-user> ?{{ user.firstName }}</current-user>

然而上述代碼不會(huì)正常工作,因?yàn)橹挥?<current-user> 組件可以訪(fǎng)問(wèn)到 user 而我們提供的內(nèi)容是在父級(jí)渲染的。

為了讓 user 在父級(jí)的插槽內(nèi)容中可用,我們可以將 user 作為 <slot> 元素的一個(gè)特性綁定上去:

<span> ?<slot v-bind:user="user"> ? ?{{ user.lastName }} ?</slot></span>

綁定在 <slot> 元素上的特性被稱(chēng)為插槽 prop?,F(xiàn)在在父級(jí)作用域中,我們可以給 v-slot 帶一個(gè)值來(lái)定義我們提供的插槽 prop 的名字:

<current-user> ?<template v-slot:default="slotProps"> ? ?{{ slotProps.user.firstName }} ?</template></current-user>

在這個(gè)例子中,我們選擇將包含所有插槽 prop 的對(duì)象命名為 slotProps,但你也可以使用任意你喜歡的名字。

具名插槽的縮寫(xiě)

跟 v-on 和 v-bind 一樣,v-slot 也有縮寫(xiě),即把參數(shù)之前的所有內(nèi)容 (v-slot:) 替換為字符 #。例如 v-slot:header 可以被重寫(xiě)為 #header:

然而,和其它指令一樣,該縮寫(xiě)只在其有參數(shù)的時(shí)候才可用。這意味著以下語(yǔ)法是無(wú)效的:

<!-- 這樣會(huì)觸發(fā)一個(gè)警告 --><current-user #="{ user }"> ?{{ user.firstName }}</current-user>

如果你希望使用縮寫(xiě)的話(huà),你必須始終以明確插槽名取而代之:

<current-user #default="{ user }"> ?{{ user.firstName }}</current-user>

動(dòng)態(tài)組件 & 異步組件

在動(dòng)態(tài)組件上使用 keep-alive

我們之前曾經(jīng)在一個(gè)多標(biāo)簽的界面中使用 is 特性來(lái)切換不同的組件:

<component v-bind:is="currentTabComponent"></component>

當(dāng)在這些組件之間切換的時(shí)候,你有時(shí)會(huì)想保持這些組件的狀態(tài),以避免反復(fù)重渲染導(dǎo)致的性能問(wèn)題。

重新創(chuàng)建動(dòng)態(tài)組件的行為通常是非常有用的,但是在這個(gè)案例中,我們更希望那些標(biāo)簽的組件實(shí)例能夠被在它們第一次被創(chuàng)建的時(shí)候緩存下來(lái)。為了解決這個(gè)問(wèn)題,我們可以用一個(gè) <keep-alive> 元素將其動(dòng)態(tài)組件包裹起來(lái)。

<!-- 失活的組件將會(huì)被緩存!--><keep-alive> ?<component v-bind:is="currentTabComponent"></component></keep-alive>

修改后的結(jié)果,組件的狀態(tài)可以被緩存

異步組件

在大型應(yīng)用中,我們可能需要將應(yīng)用分割成小一些的代碼塊,并且只在需要的時(shí)候才從服務(wù)器加載一個(gè)模塊。為了簡(jiǎn)化,Vue 允許你以一個(gè)工廠(chǎng)函數(shù)的方式定義你的組件,這個(gè)工廠(chǎng)函數(shù)會(huì)異步解析你的組件定義。Vue 只有在這個(gè)組件需要被渲染的時(shí)候才會(huì)觸發(fā)該工廠(chǎng)函數(shù),且會(huì)把結(jié)果緩存起來(lái)供未來(lái)重渲染。例如:

Vue.component('async-example', function (resolve, reject) { ?setTimeout(function () { ? ?// 向 `resolve` 回調(diào)傳遞組件定義 ? ?resolve({ ? ? ?template: '<div>I am async!</div>' ? ?}) ?}, 1000) })

如你所見(jiàn),這個(gè)工廠(chǎng)函數(shù)會(huì)收到一個(gè) resolve 回調(diào),這個(gè)回調(diào)函數(shù)會(huì)在你從服務(wù)器得到組件定義的時(shí)候被調(diào)用。你也可以調(diào)用 reject(reason) 來(lái)表示加載失敗。這里的 setTimeout 是為了演示用的,如何獲取組件取決于你自己。一個(gè)推薦的做法是將異步組件和 webpack 的 code-splitting 功能一起配合使用:

Vue.component('async-webpack-example', function (resolve) { ?// 這個(gè)特殊的 `require` 語(yǔ)法將會(huì)告訴 webpack ?// 自動(dòng)將你的構(gòu)建代碼切割成多個(gè)包,這些包 ?// 會(huì)通過(guò) Ajax 請(qǐng)求加載 ?require(['./my-async-component'], resolve) })

你也可以在工廠(chǎng)函數(shù)中返回一個(gè) Promise,所以把 webpack 2 和 ES2015 語(yǔ)法加在一起,我們可以寫(xiě)成這樣:

Vue.component( ?'async-webpack-example', ?// 這個(gè) `import` 函數(shù)會(huì)返回一個(gè) `Promise` 對(duì)象。 ?() => import('./my-async-component') )

當(dāng)使用局部注冊(cè)的時(shí)候,你也可以直接提供一個(gè)返回 Promise 的函數(shù):

new Vue({ ?// ... ?components: { ? ?'my-component': () => import('./my-async-component') ?} })

處理加載狀態(tài)

這里的異步組件工廠(chǎng)函數(shù)也可以返回一個(gè)如下格式的對(duì)象:

第二節(jié) 組件基礎(chǔ)與生命周期

處理邊界情況

訪(fǎng)問(wèn)元素 & 組件

在絕大多數(shù)情況下,我們最好不要觸達(dá)另一個(gè)組件實(shí)例內(nèi)部或手動(dòng)操作 DOM 元素。不過(guò)也確實(shí)在一些情況下做這些事情是合適的。

訪(fǎng)問(wèn)根實(shí)例

在每個(gè) new Vue 實(shí)例的子組件中,其根實(shí)例可以通過(guò) $root 屬性進(jìn)行訪(fǎng)問(wèn)。例如,在這個(gè)根實(shí)例中:

所有的子組件都可以將這個(gè)實(shí)例作為一個(gè)全局 store 來(lái)訪(fǎng)問(wèn)或使用。

訪(fǎng)問(wèn)父級(jí)組件實(shí)例

和 $root 類(lèi)似,$parent 屬性可以用來(lái)從一個(gè)子組件訪(fǎng)問(wèn)父組件的實(shí)例。它提供了一種機(jī)會(huì),可以在后期隨時(shí)觸達(dá)父級(jí)組件,以替代將數(shù)據(jù)以 prop 的方式傳入子組件的方式。

另外在一些可能適當(dāng)?shù)臅r(shí)候,你需要特別地共享一些組件庫(kù)。舉個(gè)例子,在和 JavaScript API 進(jìn)行交互而不渲染 HTML 的抽象組件內(nèi),諸如這些假設(shè)性的 Google 地圖組件一樣:

<google-map> ?<google-map-markers v-bind:places="iceCreamShops"></google-map-markers></google-map>

這個(gè) <google-map> 組件可以定義一個(gè) map 屬性,所有的子組件都需要訪(fǎng)問(wèn)它。在這種情況下 <google-map-markers> 可能想要通過(guò)類(lèi)似 this.$parent.getMap 的方式訪(fǎng)問(wèn)那個(gè)地圖,以便為其添加一組標(biāo)記。你可以在這里查閱這種模式。

請(qǐng)留意,盡管如此,通過(guò)這種模式構(gòu)建出來(lái)的那個(gè)組件的內(nèi)部仍然是容易出現(xiàn)問(wèn)題的。比如,設(shè)想一下我們添加一個(gè)新的 <google-map-region> 組件,當(dāng) <google-map-markers> 在其內(nèi)部出現(xiàn)的時(shí)候,只會(huì)渲染那個(gè)區(qū)域內(nèi)的標(biāo)記:

<google-map> ?<google-map-region v-bind:shape="cityBoundaries"> ? ?<google-map-markers v-bind:places="iceCreamShops"></google-map-markers> ?</google-map-region></google-map>

那么在 <google-map-markers> 內(nèi)部你可能發(fā)現(xiàn)自己需要一些類(lèi)似這樣的 hack:

var map = this.$parent.map || this.$parent.$parent.map

很快它就會(huì)失控。這也是我們針對(duì)需要向任意更深層級(jí)的組件提供上下文信息時(shí)推薦依賴(lài)注入的原因。

訪(fǎng)問(wèn)子組件實(shí)例或子元素

盡管存在 prop 和事件,有的時(shí)候你仍可能需要在 JavaScript 里直接訪(fǎng)問(wèn)一個(gè)子組件。為了達(dá)到這個(gè)目的,你可以通過(guò) ref 特性為這個(gè)子組件賦予一個(gè) ID 引用。例如:

<base-input ref="usernameInput"></base-input>

現(xiàn)在在你已經(jīng)定義了這個(gè) ref 的組件里,你可以使用:

this.$refs.usernameInput

來(lái)訪(fǎng)問(wèn)這個(gè) <base-input> 實(shí)例,以便不時(shí)之需。比如程序化地從一個(gè)父級(jí)組件聚焦這個(gè)輸入框。在剛才那個(gè)例子中,該 <base-input> 組件也可以使用一個(gè)類(lèi)似的 ref 提供對(duì)內(nèi)部這個(gè)指定元素的訪(fǎng)問(wèn),例如:

<input ref="input">

甚至可以通過(guò)其父級(jí)組件定義方法:

methods: { ?// 用來(lái)從父級(jí)組件聚焦輸入框 ?focus: function () { ? ?this.$refs.input.focus() ?} }

這樣就允許父級(jí)組件通過(guò)下面的代碼聚焦 <base-input> 里的輸入框:

this.$refs.usernameInput.focus()

當(dāng) ref 和 v-for 一起使用的時(shí)候,你得到的引用將會(huì)是一個(gè)包含了對(duì)應(yīng)數(shù)據(jù)源的這些子組件的數(shù)組。

組件生命周期

每個(gè) Vue 實(shí)例在被創(chuàng)建時(shí)都要經(jīng)過(guò)一系列的初始化過(guò)程——例如,需要設(shè)置數(shù)據(jù)監(jiān)聽(tīng)、編譯模板、將實(shí)例掛載到 DOM 并在數(shù)據(jù)變化時(shí)更新 DOM 等。同時(shí)在這個(gè)過(guò)程中也會(huì)運(yùn)行一些叫做生命周期鉤子的函數(shù),這給了用戶(hù)在不同階段添加自己的代碼的機(jī)會(huì)。

比如 created 鉤子可以用來(lái)在一個(gè)實(shí)例被創(chuàng)建之后執(zhí)行代碼:

也有一些其它的鉤子,在實(shí)例生命周期的不同階段被調(diào)用,如 mounted、updated 和 destroyed。生命周期鉤子的 this 上下文指向調(diào)用它的 Vue 實(shí)例。

生命周期圖示

下圖展示了實(shí)例的生命周期。你不需要立馬弄明白所有的東西,不過(guò)隨著你的不斷學(xué)習(xí)和使用,它的參考價(jià)值會(huì)越來(lái)越高



組件復(fù)用性

這里我們又回到data函數(shù)狀態(tài)下,data必須是一個(gè)純函數(shù)。

當(dāng)我們定義這個(gè) <button-counter> 組件時(shí),你可能會(huì)發(fā)現(xiàn)它的 data 并不是像這樣直接提供一個(gè)對(duì)象:

data: { ?count: 0 }

取而代之的是,一個(gè)組件的 data 選項(xiàng)必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立的拷貝:

data: function () { ?return { ? ?count: 0 ?} }

如果 Vue 沒(méi)有這條規(guī)則,點(diǎn)擊一個(gè)按鈕就可能會(huì)像如下代碼一樣影響到其它所有實(shí)例:

這里可以增加列表性實(shí)例的引用。

第三節(jié) Vue API

過(guò)渡&動(dòng)畫(huà)

Vue 在插入、更新或者移除 DOM 時(shí),提供多種不同方式的應(yīng)用過(guò)渡效果。

包括以下工具:

  • 在 CSS 過(guò)渡和動(dòng)畫(huà)中自動(dòng)應(yīng)用 class

  • 可以配合使用第三方 CSS 動(dòng)畫(huà)庫(kù),如 Animate.css

  • 在過(guò)渡鉤子函數(shù)中使用 JavaScript 直接操作 DOM

  • 可以配合使用第三方 JavaScript 動(dòng)畫(huà)庫(kù),如 Velocity.js

單元素/組件的過(guò)渡

Vue 提供了 transition 的封裝組件,在下列情形中,可以給任何元素和組件添加進(jìn)入/離開(kāi)過(guò)渡

  • 條件渲染 (使用 v-if)

  • 條件展示 (使用 v-show)

  • 動(dòng)態(tài)組件

  • 組件根節(jié)點(diǎn)

這里是一個(gè)典型的例子:

當(dāng)插入或刪除包含在 transition 組件中的元素時(shí),Vue 將會(huì)做以下處理:

  1. 自動(dòng)嗅探目標(biāo)元素是否應(yīng)用了 CSS 過(guò)渡或動(dòng)畫(huà),如果是,在恰當(dāng)?shù)臅r(shí)機(jī)添加/刪除 CSS 類(lèi)名。

  2. 如果過(guò)渡組件提供了 JavaScript 鉤子函數(shù),這些鉤子函數(shù)將在恰當(dāng)?shù)臅r(shí)機(jī)被調(diào)用。

  3. 如果沒(méi)有找到 JavaScript 鉤子并且也沒(méi)有檢測(cè)到 CSS 過(guò)渡/動(dòng)畫(huà),DOM 操作 (插入/刪除) 在下一幀中立即執(zhí)行。(注意:此指瀏覽器逐幀動(dòng)畫(huà)機(jī)制,和 Vue 的 nextTick 概念不同)

過(guò)渡類(lèi)名

在進(jìn)入/離開(kāi)的過(guò)渡中,會(huì)有 6 個(gè) class 切換。

  1. v-enter:定義進(jìn)入過(guò)渡的開(kāi)始狀態(tài)。在元素被插入之前生效,在元素被插入之后的下一幀移除。

  2. v-enter-active:定義進(jìn)入過(guò)渡生效時(shí)的狀態(tài)。在整個(gè)進(jìn)入過(guò)渡的階段中應(yīng)用,在元素被插入之前生效,在過(guò)渡/動(dòng)畫(huà)完成之后移除。這個(gè)類(lèi)可以被用來(lái)定義進(jìn)入過(guò)渡的過(guò)程時(shí)間,延遲和曲線(xiàn)函數(shù)。

  3. v-enter-to: 2.1.8版及以上 定義進(jìn)入過(guò)渡的結(jié)束狀態(tài)。在元素被插入之后下一幀生效 (與此同時(shí) v-enter 被移除),在過(guò)渡/動(dòng)畫(huà)完成之后移除。

  4. v-leave: 定義離開(kāi)過(guò)渡的開(kāi)始狀態(tài)。在離開(kāi)過(guò)渡被觸發(fā)時(shí)立刻生效,下一幀被移除。

  5. v-leave-active:定義離開(kāi)過(guò)渡生效時(shí)的狀態(tài)。在整個(gè)離開(kāi)過(guò)渡的階段中應(yīng)用,在離開(kāi)過(guò)渡被觸發(fā)時(shí)立刻生效,在過(guò)渡/動(dòng)畫(huà)完成之后移除。這個(gè)類(lèi)可以被用來(lái)定義離開(kāi)過(guò)渡的過(guò)程時(shí)間,延遲和曲線(xiàn)函數(shù)。

  6. v-leave-to: 2.1.8版及以上 定義離開(kāi)過(guò)渡的結(jié)束狀態(tài)。在離開(kāi)過(guò)渡被觸發(fā)之后下一幀生效 (與此同時(shí) v-leave 被刪除),在過(guò)渡/動(dòng)畫(huà)完成之后移除。


對(duì)于這些在過(guò)渡中切換的類(lèi)名來(lái)說(shuō),如果你使用一個(gè)沒(méi)有名字的 <transition>,則 v- 是這些類(lèi)名的默認(rèn)前綴。如果你使用了 <transition name="my-transition">,那么 v-enter 會(huì)替換為 my-transition-enter。


v-enter-active 和 v-leave-active 可以控制進(jìn)入/離開(kāi)過(guò)渡的不同的緩和曲線(xiàn),在下面章節(jié)會(huì)有個(gè)示例說(shuō)明。

CSS 過(guò)渡

常用的過(guò)渡都是使用 CSS 過(guò)渡。

下面是一個(gè)簡(jiǎn)單例子:

CSS 動(dòng)畫(huà)

CSS 動(dòng)畫(huà)用法同 CSS 過(guò)渡,區(qū)別是在動(dòng)畫(huà)中 v-enter 類(lèi)名在節(jié)點(diǎn)插入 DOM 后不會(huì)立即刪除,而是在 animationend 事件觸發(fā)時(shí)刪除。

自定義過(guò)渡的類(lèi)名

我們可以通過(guò)以下特性來(lái)自定義過(guò)渡類(lèi)名:

enter-class

enter-active-class

enter-to-class (2.1.8+)

leave-class

leave-active-class

leave-to-class (2.1.8+)

他們的優(yōu)先級(jí)高于普通的類(lèi)名,這對(duì)于 Vue 的過(guò)渡系統(tǒng)和其他第三方 CSS 動(dòng)畫(huà)庫(kù),如 Animate.css 結(jié)合使用十分有用。

自定義指令

除了核心功能默認(rèn)內(nèi)置的指令 (v-model 和 v-show),Vue 也允許注冊(cè)自定義指令。注意,在 Vue2.0 中,代碼復(fù)用和抽象的主要形式是組件。然而,有的情況下,你仍然需要對(duì)普通 DOM 元素進(jìn)行底層操作,這時(shí)候就會(huì)用到自定義指令。舉個(gè)聚焦輸入框的例子

當(dāng)頁(yè)面加載時(shí),該元素將獲得焦點(diǎn) (注意:autofocus 在移動(dòng)版 Safari 上不工作)。事實(shí)上,只要你在打開(kāi)這個(gè)頁(yè)面后還沒(méi)點(diǎn)擊過(guò)任何內(nèi)容,這個(gè)輸入框就應(yīng)當(dāng)還是處于聚焦?fàn)顟B(tài)?,F(xiàn)在讓我們用指令來(lái)實(shí)現(xiàn)這個(gè)功能:

// 注冊(cè)一個(gè)全局自定義指令 `v-focus` Vue.directive('focus', { ?// 當(dāng)被綁定的元素插入到 DOM 中時(shí)…… ?inserted: function (el) { ? ?// 聚焦元素 ? ?el.focus() ?} })

如果想注冊(cè)局部指令,組件中也接受一個(gè) directives 的選項(xiàng):

directives: { ?focus: { ? ?// 指令的定義 ? ?inserted: function (el) { ? ? ?el.focus() ? ?} ?} }

然后你可以在模板中任何元素上使用新的 v-focus 屬性,如下:

<input v-focus>

鉤子函數(shù)

一個(gè)指令定義對(duì)象可以提供如下幾個(gè)鉤子函數(shù) (均為可選):

  • bind:只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用。在這里可以進(jìn)行一次性的初始化設(shè)置。

  • inserted:被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用 (僅保證父節(jié)點(diǎn)存在,但不一定已被插入文檔中)。

  • update:所在組件的 VNode 更新時(shí)調(diào)用,但是可能發(fā)生在其子 VNode 更新之前。指令的值可能發(fā)生了改變,也可能沒(méi)有。但是你可以通過(guò)比較更新前后的值來(lái)忽略不必要的模板更新 (詳細(xì)的鉤子函數(shù)參數(shù)見(jiàn)下)。

  • componentUpdated:指令所在組件的 VNode 及其子 VNode 全部更新后調(diào)用。

  • unbind:只調(diào)用一次,指令與元素解綁時(shí)調(diào)用。

接下來(lái)我們來(lái)看一下鉤子函數(shù)的參數(shù) (即 el、binding、vnode 和 oldVnode)。

鉤子函數(shù)參數(shù)

指令鉤子函數(shù)會(huì)被傳入以下參數(shù):

el:指令所綁定的元素,可以用來(lái)直接操作 DOM 。

binding:一個(gè)對(duì)象,包含以下屬性:

name:指令名,不包括 v- 前綴。

value:指令的綁定值,例如:v-my-directive="1 + 1" 中,綁定值為 2。

oldValue:指令綁定的前一個(gè)值,僅在 update 和 componentUpdated 鉤子中可用。無(wú)論值是否改變都可用。

expression:字符串形式的指令表達(dá)式。例如 v-my-directive="1 + 1" 中,表達(dá)式為 "1 + 1"。

arg:傳給指令的參數(shù),可選。例如 v-my-directive:foo 中,參數(shù)為 "foo"。

modifiers:一個(gè)包含修飾符的對(duì)象。例如:v-my-directive.foo.bar 中,修飾符對(duì)象為 { foo: true, bar: true }。

vnode:Vue 編譯生成的虛擬節(jié)點(diǎn)。移步 VNode API 來(lái)了解更多詳情。

oldVnode:上一個(gè)虛擬節(jié)點(diǎn),僅在 update 和 componentUpdated 鉤子中可用。

過(guò)濾器

Vue.js 允許你自定義過(guò)濾器,可被用于一些常見(jiàn)的文本格式化。過(guò)濾器可以用在兩個(gè)地方:雙花括號(hào)插值和 v-bind 表達(dá)式 (后者從 2.1.0+ 開(kāi)始支持)。過(guò)濾器應(yīng)該被添加在 JavaScript 表達(dá)式的尾部,由“管道”符號(hào)指示:

<!-- 在雙花括號(hào)中 -->{{ message | capitalize }}<!-- 在 `v-bind` 中 --><div v-bind:id="rawId | formatId"></div>

你可以在一個(gè)組件的選項(xiàng)中定義本地的過(guò)濾器:

filters: { ?capitalize: function (value) { ? ?if (!value) return '' ? ?value = value.toString() ? ?return value.charAt(0).toUpperCase() + value.slice(1) ?} }

或者在創(chuàng)建 Vue 實(shí)例之前全局定義過(guò)濾器:

當(dāng)全局過(guò)濾器和局部過(guò)濾器重名時(shí),會(huì)采用局部過(guò)濾器。

過(guò)濾器函數(shù)總接收表達(dá)式的值 (之前的操作鏈的結(jié)果) 作為第一個(gè)參數(shù)。在上述例子中,capitalize 過(guò)濾器函數(shù)將會(huì)收到 message 的值作為第一個(gè)參數(shù)。

過(guò)濾器可以串聯(lián):

{{ message | filterA | filterB }}

在這個(gè)例子中,filterA 被定義為接收單個(gè)參數(shù)的過(guò)濾器函數(shù),表達(dá)式 message 的值將作為參數(shù)傳入到函數(shù)中。然后繼續(xù)調(diào)用同樣被定義為接收單個(gè)參數(shù)的過(guò)濾器函數(shù) filterB,將 filterA 的結(jié)果傳遞到 filterB 中。

過(guò)濾器是 JavaScript 函數(shù),因此可以接收參數(shù):

{{ message | filterA('arg1', arg2) }}

這里,filterA 被定義為接收三個(gè)參數(shù)的過(guò)濾器函數(shù)。其中 message 的值作為第一個(gè)參數(shù),普通字符串 'arg1' 作為第二個(gè)參數(shù),表達(dá)式 arg2 的值作為第三個(gè)參數(shù)。

渲染函數(shù)&JSX

Vue 推薦在絕大多數(shù)情況下使用模板來(lái)創(chuàng)建你的 HTML。然而在一些場(chǎng)景中,你真的需要 JavaScript 的完全編程的能力。這時(shí)你可以用渲染函數(shù),它比模板更接近編譯器。

這里參考React,不再贅述


如何輕松學(xué)會(huì)Vue基礎(chǔ)語(yǔ)法的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
南召县| 观塘区| 肃宁县| 葫芦岛市| 隆昌县| 商水县| 姜堰市| 东兰县| 清流县| 安西县| 苍山县| 桓台县| 黄龙县| 庆元县| 武威市| 宁德市| 洛南县| 太仓市| 屏山县| 外汇| 含山县| 桐梓县| 三原县| 绥化市| 洪湖市| 大荔县| 武邑县| 乐清市| 西华县| 建昌县| 曲阜市| 凤山县| 任丘市| 泰兴市| 茂名市| 浪卡子县| 晋州市| 神池县| 建昌县| 肥城市| 梓潼县|