模版語(yǔ)法
不管是使用v-指令綁定attribute還是Mustache語(yǔ)法禽车,后面可以跟值或者js表達(dá)式婆排,如果是事件監(jiān)聽(tīng)后面可以跟函數(shù)或js語(yǔ)句巍糯,例如:
<button v-bind:disabled="isButtonDisabled">Button</button>
<a v-bind:href="isButtonDisabled ? url : ''">...</a>
{{ message.split('').reverse().join('') }}
<el-checkbox @change="getPort"></el-checkbox>
<el-checkbox @change="(val, $event) => getPort(val, event, 'check')"></el-checkbox>
動(dòng)態(tài)屬性
上面說(shuō)的是值是動(dòng)態(tài)的,從2.6.0開(kāi)始,新增屬性動(dòng)態(tài)
<a v-bind:[attributeName]="url"> ... </a>
<a :[attributeName]="url"> ... </a>
<a @[event]="doSomething"> ... </a>
Class和Style綁定
Class對(duì)象語(yǔ)法
<div v-bind:class="{ active: isActive }"></div>
<div class="static" v-bind:class="{ active: isActive, 'text-danger': hasError }"></div>
<div v-bind:class="classObject"></div>
data: {
classObject: {
active: true,
'text-danger': false
}
}
<div v-bind:class="classObject"></div>
computed: {
classObject: function () {
return {
active: this.isActive && !this.error,
'text-danger': this.error && this.error.type === 'fatal'
}
}
}
// 用于自定義組件
<my-component v-bind:class="{ active: isActive }"></my-component>
Class數(shù)組語(yǔ)法
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
<div v-bind:class="[isActive ? activeClass : '', errorClass]"></div>
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
通過(guò)以上例子我們總結(jié)出如果是對(duì)象饶套,那么變量必須是布爾值,如果是數(shù)組垒探,那么變量必須是值或js表達(dá)式妓蛮。
Style對(duì)象語(yǔ)法
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
<div v-bind:style="styleObject"></div>
data: {
styleObject: {
color: 'red',
fontSize: '13px'
}
}
Style數(shù)組語(yǔ)法
<div v-bind:style="[baseStyles, overridingStyles]"></div>
data () {
return {
baseStyles: {
color: 'red'
},
overridingStyles: {
fontSize: '70px'
}
}
}
從上面我們可以看到如果是對(duì)象,變量就是值或js表達(dá)式圾叼,如果是數(shù)組內(nèi)部對(duì)象的變量同樣是值或js表達(dá)式蛤克。
列表渲染
<ul id="example-2">
<li v-for="(item, index) in items" :key="item.message">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
<ul id="example-2">
<li v-for="(item, index) of items" :key="item.message">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
data: {
parentMessage: 'Parent',
items: [
{ message: 'Foo' },
{ message: 'Bar' }
]
}
<div v-for="(value, name, index) in object" :key="name">
{{ index }}. {{ name }}: {{ value }}
</div>
data: {
object: {
title: 'How to do lists in Vue',
author: 'Jane Doe',
publishedAt: '2016-04-10'
}
}
從上面例子中我們可以看出v-for可以遍歷數(shù)組也可以遍歷對(duì)象,遍歷數(shù)組最多兩個(gè)參數(shù)夷蚊,遍歷對(duì)象可以有三個(gè)參數(shù)构挤,in和of遍歷效果一樣,只不過(guò)of更接近js迭代器語(yǔ)法惕鼓。v-for的變量只能是值或js表達(dá)式筋现,比如從計(jì)算屬性、方法里面返回的值箱歧,也可以是整數(shù)例如v-for="n in 10"
在<template>上使用v-for
類(lèi)似于v-if矾飞,也可以利用帶有v-for的<template>來(lái)循環(huán)渲染一段包含多個(gè)元素的內(nèi)容。
比如:
<ul>
<template v-for="item in items">
<li>{{ item.msg }}</li>
<li class="divider" role="presentation"></li>
</template>
</ul>
v-for和v-if不能在同一個(gè)層級(jí)使用呀邢,但是可以跟v-show一起使用
事件處理
監(jiān)聽(tīng)事件
v-on指令監(jiān)聽(tīng)DOM事件洒沦,并在觸發(fā)時(shí)運(yùn)行一些js語(yǔ)句或函數(shù),直接把 JavaScript 代碼寫(xiě)在 v-on 指令中是不可行的
下面的例子是一個(gè)特例:
<input onKeypress='javascript:if(event.keyCode==32)event.returnValue=false' />
可以寫(xiě)成下面這樣
<button v-on:click="counter += 1">Add 1</button>
$event變量
有時(shí)候需要在內(nèi)聯(lián)語(yǔ)句處理器中訪問(wèn)原始的DOM事件驼鹅,可以使用特殊變量$event把它傳入方法:
Vue模版
<div @click="submit">Submit1</div>
<div @click="submitFile('file', $event)">Submit2</div>
methods: {
submit(event) {
event.preventDefault()
},
submitFile(type, event) {
// 現(xiàn)在我們可以訪問(wèn)原生事件對(duì)象
if (event) {
console.log(event)
event.preventDefault()
}
}
}
// 正確寫(xiě)法
<div @change="(val, $event) => getPort(val, event, 'check')"></div>
<el-checkbox @change="(val, $event) => getPort(val, event, 'check')"></el-checkbox>
// 錯(cuò)誤寫(xiě)法
<div @change="function(val, $event) {getPort(val, event, 'check')}"></div>
methods: {
getPort (val, event, type) {
console.log(val, event, type)
}
}
我們可以看到觸發(fā)方法如果沒(méi)有傳參微谓,那么調(diào)用方法第一個(gè)參數(shù)默認(rèn)是原生DOM對(duì)象森篷,也可以將原生DOM對(duì)象以參數(shù)的形式傳遞,
事件修飾符
<div @click="clickEvent">
<a @click="test" >百度</a> // 觸發(fā)test豺型、clickEvent仲智、自身事件
<a @click.stop="test" >百度</a> // 阻止事件冒泡,觸發(fā)test姻氨、自身事件
<a @click.prevent="test" >百度</a> // 阻止a標(biāo)簽?zāi)J(rèn)行為钓辆,觸發(fā)test、clickEvent
<a @click.capture="test" >百度</a> // 事件在捕獲階段觸發(fā)肴焊,觸發(fā)test前联、clickEvent、自身事件
<a @click.self="test" >百度</a> // 事件在目標(biāo)階段觸發(fā)娶眷,觸發(fā)test似嗤、clickEvent、自身事件
<a @click.once="test" >百度</a> // 點(diǎn)擊事件只會(huì)觸發(fā)一次届宠,觸發(fā)test烁落、clickEvent、自身事件豌注,test事件只會(huì)觸發(fā)一次伤塌,其他不影響,不像其它只能對(duì)原生的 DOM 事件起作用的修飾符轧铁,`.once` 修飾符還能被用到自定義組件事件上每聪,例如<base-checkbox v-model.once="lovingVue"></base-checkbox>
</div>
<div v-on:scroll.passive="onScroll">頁(yè)面滾動(dòng)</div> .passive 會(huì)告訴瀏覽器你不想阻止事件的默認(rèn)行為,.passive 修飾符尤其能夠提升移動(dòng)端的性能齿风。不要把 .passive 和 .prevent 一起使用药薯,因?yàn)?.prevent 將會(huì)被忽略,同時(shí)瀏覽器可能會(huì)向你展示一個(gè)警告聂宾。
methods: {
clickEvent () {
alert('點(diǎn)擊')
},
test () {
alert('測(cè)試')
}
}
組件基礎(chǔ)
data必須是一個(gè)函數(shù)
data不是直接提供一個(gè)對(duì)象果善,而必須是一個(gè)函數(shù),因此每個(gè)實(shí)例可以維護(hù)一份被返回對(duì)象的獨(dú)立拷貝系谐。
在組件上使用v-model
v-model是vue的語(yǔ)法糖
<input v-model="searchText">
// 等價(jià)于
<input v-bind:value="searchText" v-on:input="searchText = $event.target.value">
當(dāng)用在組件上時(shí),v-model 則會(huì)這樣:
<custom-input v-bind:value="searchText" v-on:input="searchText = $event"></custom-input>
// 等價(jià)于
<custom-input v-model="searchText"></custom-input>
為了讓它正常工作讨跟,這個(gè)組件內(nèi)的 <input> 必須:
- 將其 value attribute 綁定到一個(gè)名叫 value 的 prop 上
- 在其 input 事件被觸發(fā)時(shí)纪他,將新的值通過(guò)自定義的 input 事件拋出
寫(xiě)成代碼之后是這樣的:
Vue.component('custom-input', {
props: ['value'],
template: `
<input
v-bind:value="value"
v-on:input="$emit('input', $event.target.value)">
`
})
Prop
Prop類(lèi)型
以字符串?dāng)?shù)組形式列出的 prop:
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
prop 指定的值類(lèi)型
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor }
傳遞靜態(tài)或動(dòng)態(tài)Prop
// 包含該 prop 沒(méi)有值的情況在內(nèi),都意味著 `true`
<blog-post is-published></blog-post>
// 如果你想要將一個(gè)對(duì)象的所有 property 都作為 prop 傳入晾匠,你可以使用不帶參數(shù)的 v-bind
<blog-post v-bind="post"></blog-post>
// 等價(jià)于
<blog-post
v-bind:id="post.id"
v-bind:title="post.title">
</blog-post>
單向數(shù)據(jù)流
所有的 prop 都使得其父子 prop 之間形成了一個(gè)單向下行綁定:父級(jí) prop 的更新會(huì)向下流動(dòng)到子組件中茶袒,如果傳遞的是基本數(shù)據(jù)類(lèi)型,改變子組件的prop會(huì)報(bào)錯(cuò)凉馆,如果傳遞的是對(duì)象或數(shù)組 薪寓,改變子組件的prop父組件的值也會(huì)被改變亡资。
有兩種常見(jiàn)的試圖變更一個(gè)prop的情形:
1.這個(gè)prop用來(lái)傳遞一個(gè)初始值,這個(gè)子組件接下來(lái)希望將其作為一個(gè)本地的prop數(shù)據(jù)來(lái)使用向叉∽赌澹可以在data中將這個(gè)prop用作初始值:
props: ['initialCounter'],
data: function () {
return {
counter: this.initialCounter
}
}
2.這個(gè)prop以一種原始的值傳入且需要進(jìn)行轉(zhuǎn)換。這時(shí)候最好使用計(jì)算屬性:
props: ['size'],
computed: {
normalizedSize: function () {
return this.size.trim().toLowerCase()
}
}
Prop驗(yàn)證
我們可以為組件的prop指定驗(yàn)證要求母谎,如果需求沒(méi)有滿(mǎn)足則Vue會(huì)在瀏覽器中報(bào)錯(cuò)瘦黑。
Vue.component('my-component', {
props: {
// 基礎(chǔ)的類(lèi)型檢查 (`null` 和 `undefined` 會(huì)通過(guò)任何類(lèi)型驗(yàn)證)
propA: Number,
// 多個(gè)可能的類(lèi)型
propB: [String, Number],
// 必填的字符串
propC: {
type: String,
required: true
},
// 帶有默認(rèn)值的數(shù)字
propD: {
type: Number,
default: 100
},
// 帶有默認(rèn)值的對(duì)象
propE: {
type: Object,
// 對(duì)象或數(shù)組默認(rèn)值必須從一個(gè)工廠函數(shù)獲取
default: function () {
return { message: 'hello' }
}
},
// 自定義驗(yàn)證函數(shù)
propF: {
validator: function (value) {
// 這個(gè)值必須匹配下列字符串中的一個(gè)
return ['success', 'warning', 'danger'].indexOf(value) !== -1
}
}
}
})
注意那些 prop 會(huì)在一個(gè)組件實(shí)例創(chuàng)建之前進(jìn)行驗(yàn)證,所以實(shí)例的 property (如 data奇唤、computed 等) 在 default 或 validator 函數(shù)中是不可用的幸斥。
非Prop的Attribute
一個(gè)非prop的attribute是指?jìng)飨蛞粋€(gè)組件,但是改組件并沒(méi)有相應(yīng)prop定義的attribute咬扇。
<bootstrap-date-input data-date-picker="activated"></bootstrap-date-input>
然后這個(gè) data-date-picker="activated" attribute 就會(huì)自動(dòng)添加到 <bootstrap-date-input> 的根元素上甲葬。
替換/合并已有的Attribute
想象一下 <bootstrap-date-input> 的模板是這樣的:
<input type="date" class="form-control">
為了給我們的日期選擇器插件定制一個(gè)主題,我們可能需要像這樣添加一個(gè)特別的類(lèi)名:
<bootstrap-date-input
type="text"
data-date-picker="activated"
class="date-picker-theme-dark">
</bootstrap-date-input>
最終結(jié)果
<input type="text" class="form-control date-picker-theme-dark" data-date-picker="activated">
我們看到內(nèi)部模版的type被替換成外部傳入的懈贺,class被合并经窖。class和style會(huì)合并內(nèi)外的值,其他的屬性都會(huì)被替換成外部傳入的值隅居。
禁用Attribute繼承
inheritAttrs:默認(rèn)值為true钠至,默認(rèn)情況下父作用域不被子組件認(rèn)作props特性的屬性將會(huì)作為子組件根元素的屬性,inheritAttrs就是去掉這一默認(rèn)行為胎源,class和style除外棉钧。
$attrs
:包含了父作用域中不作為prop被識(shí)別的屬性(class和style除外)。
inheritAttrs和$attrs可以實(shí)現(xiàn)跨組件通信涕蚤。
<template>
<div>
<p>我是父組件</p>
<test name="tom" :age="12" :id="12345" class="child" style="color: red" />
</div>
</template>
<script>
export default {
components: {
test: {
template: `
<div>
<p>我是子組件</p>
<test2 v-bind="$attrs" s1="sss" s2="sss" />
</div>`,
inheritAttrs: false,
props: ["name"],
created() {
console.log(this.$attrs); // {age: 12, id: 12345}
},
components: {
test2: {
template: `<p>我是孫子組件</p>`,
inheritAttrs: false,
props: ["age", "s1"],
created() {
console.log(this.$attrs); // {s2: "sss", id: 12345}
}
}
}
}
}
};
</script>
自定義組件的v-model
一個(gè)組件上的v-model默認(rèn)會(huì)利用名為value的prop和名為input的事件宪卿,但是像單選框、復(fù)選框等類(lèi)型的輸入控件可能會(huì)將value的attribute用于不用的目的万栅。model就是用來(lái)改變v-model默認(rèn)屬性和方法
Vue.component('base-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean
},
template: `
<input
type="checkbox"
v-bind:checked="checked"
v-on:change="$emit('change', $event.target.checked)">
`
})
父組件
<base-checkbox v-model="lovingVue"></base-checkbox>
.sync修飾符
在有些情況下佑钾,我們可能需要對(duì)某些數(shù)據(jù)雙向綁定,父子組件數(shù)據(jù)同步烦粒,prop是單向數(shù)據(jù)流休溶,不建議直接改變prop,以往的做法是將數(shù)據(jù)傳遞給子組件扰她,子組件使用$emit觸發(fā)父組件的監(jiān)聽(tīng)方法重新賦值兽掰,現(xiàn)在這個(gè)方法有個(gè)語(yǔ)法糖.sync
<text-document v-bind:title="doc.title" v-on:update:title="doc.title = $event"></text-document>
// .sync簡(jiǎn)寫(xiě)
<text-document :title.sync="doc.title"></text-document>
子組件
<template>
<button @click="changeTitle"></button>
</template>
export default {
props: {
title: String
},
methods: {
changeTitle () {
this.$emit('update:title', newTitle)
}
}
}
v-model和.sync
共同點(diǎn)
- 只能跟變量,都不能跟表達(dá)式一起使用
- 都可以實(shí)現(xiàn)數(shù)據(jù)的雙向綁定
不同點(diǎn)
- v-model一個(gè)組件只能使用一個(gè)徒役,.sync一個(gè)組件可以使用多個(gè)
<text-document :title.sync="doc.title" :name.sync="doc.name"></text-document>
// 可以簡(jiǎn)寫(xiě)
<text-document :title.sync="doc"></text-document>
具體可參考:http://www.reibang.com/p/f0673a9eba3f
$listeners
包含了父作用域(不含.native修飾符)v-on事件監(jiān)聽(tīng)器孽尽。它可以通過(guò)v-on="$listeners"傳入內(nèi)部組件。它是一個(gè)對(duì)象忧勿,里面包含了作用在這個(gè)組件上的所有事件監(jiān)聽(tīng)器杉女,相當(dāng)于子組件繼承了父組件的事件瞻讽,可以實(shí)現(xiàn)跨組件傳遞方法。
father.vue組件
<template>
<child :name="name" :age="age" :infoObj="infoObj" @updateInfo="updateInfo" @delInfo="delInfo" />
</template>
child.vue組件
<template>
<grand-son @addInfo="addInfo" v-bind="$attrs" v-on="$listeners" />
// 通過(guò) $listeners 將父作用域中的事件熏挎,傳入 grandSon 組件速勇,使其可以獲取到 father 中的事件
</template>
<script>
import GrandSon from '../components/grandSon.vue'
export default {
components: { GrandSon },
created() {
console.log(this.$listeners); // updateInfo: f, delInfo: f
}
}
</script>
grandSon.vue組件
<template>
<div>
{{ $attrs }} --- {{ $listeners }}
<div>
</template>
<script>
export default {
created() {
console.log(this.$listeners) // updateInfo: f, delInfo: f, addInfo: f
this.$emit('updateInfo') // 可以觸發(fā) father 組件中的updateInfo函數(shù)
}
}
</script>
處理邊界情況
provide和inject
父子組件可以使用prop、$emit實(shí)現(xiàn)數(shù)據(jù)或方法傳遞婆瓜,但是針對(duì)嵌套多層組件這種情況快集,除了使用vuex還可以使用依賴(lài)注入,我們可以將依賴(lài)注入理解成大范圍有效的prop廉白,不過(guò)依賴(lài)注入不是響應(yīng)式的个初。
// 祖先元素
export default {
name: "grandfather",
provide(){
return{
foo:'halo'
}
},
}
//后代組件 注入foo
export default {
inject:['foo'],
}
改成響應(yīng)式的,只需要傳遞的是對(duì)象即可
provide(){
return{
test:this.activeData
}
},
data() {
return {
activeData:{name:'halo'},
}
}
mounted(){
setTimeout(()=>{
this.activeData.name = 'world';
},3000)
}
插槽
父級(jí)模版里的所有內(nèi)容都是在父級(jí)作用域中編譯的猴蹂;子模版里的所有內(nèi)容都是在子作用域中編譯的院溺。如果讓父組件中的插槽內(nèi)容訪問(wèn)子組件中數(shù)據(jù),就需要用到作用域插槽磅轻。綁定在slot元素上的attribute被稱(chēng)為插槽prop珍逸,在這個(gè)例子中,我們將所有插槽prop的對(duì)象命名為slotProps聋溜,也可以命名為其他名字谆膳。
父組件
<current-user>
<template v-slot:default="slotProps">
{{slotProps.user.firstName}}
</template>
</current-user>
// 解構(gòu)插槽prop,跟js解構(gòu)賦值寫(xiě)法一樣
<current-user>
<template v-slot:default="{{user}}">
{{user.firstName}}
</template>
</current-user>
子組件
<template>
<section>
<slot v-bind:user="user">{{user.lastName}}</slot>
</section>
</template>
<slot></slot>這個(gè)是插槽撮躁,v-slot是對(duì)應(yīng)插槽的內(nèi)容漱病,但是必須添加在template標(biāo)簽上,只有一種情況除外把曼,就是被提供的內(nèi)容只有默認(rèn)插槽的時(shí)候杨帽,組件的標(biāo)簽才可以被當(dāng)作插槽的模版來(lái)使用,這一點(diǎn)和已經(jīng)廢棄的slot attribute不同嗤军。
<current-user v-slot:default="slotProps">
{{slotProps.user.firstName}}
</current-user>
動(dòng)態(tài)插槽名
<base-layout>
<template v-slot:[dynamicSlotName]>
...
</template>
</base-layout>
具名插槽的縮寫(xiě)
跟v-on和v-bind一樣注盈,v-slot也有縮寫(xiě),v-slot替換為字符#叙赚,例如v-slot:header可以被重寫(xiě)為#header
<base-layout>
<template #header>
<h1>Here might be a page title</h1>
</template>
<template #footer>
<p>Here's some contact info</p>
</template>
</base-layout>
使用場(chǎng)景
- 通過(guò)插槽可以讓用戶(hù)可以拓展組件老客,去更好地復(fù)用組件和對(duì)其做定制化處理
- 如果父組件在使用到一個(gè)復(fù)用組件的時(shí)候,獲取這個(gè)組件在不同的地方有少量的更改震叮,如果去重寫(xiě)組件是一件不明智的事情
- 通過(guò)slot插槽向組件內(nèi)部指定位置傳遞內(nèi)容沿量,完成這個(gè)復(fù)用組件在不同場(chǎng)景的應(yīng)用,比如布局組件冤荆、表格列、下拉選擇权纤、彈框顯示內(nèi)容等
自定義指令
除了核心功能默認(rèn)內(nèi)置的指令(v-model和v-show)钓简,Vue也允許注冊(cè)自定義指令乌妒。
一個(gè)指令定義對(duì)象可以提供如下幾個(gè)鉤子函數(shù)(均為可選):
- bind:只調(diào)用一次,指令第一次綁定到元素時(shí)調(diào)用外邓。在這里可以進(jìn)行一次性初始化設(shè)置撤蚊。
- inserted:被綁定元素插入父節(jié)點(diǎn)時(shí)調(diào)用
- update:所在組件的VNode更新時(shí)調(diào)用,也可能在其子VNode更新之前調(diào)用
- componentUpdated:指令所在組件VNode及其子VNode全部更新后調(diào)用
- unbind:只調(diào)用一次损话,指令與元素解綁時(shí)調(diào)用
鉤子函數(shù)參數(shù)
- el:指令所綁定的元素侦啸,可以用來(lái)直接操作DOM
- binding:一個(gè)對(duì)象,包含以下property:
1.name:指令名丧枪,不包括v-前綴
2.value:指令的綁定值光涂,例如v-my-directive=“1+1”,綁定值為2
3.oldValue:指令綁定的前一個(gè)值
4.expression:字符串形式的指令表達(dá)式拧烦。例如v-my-directive=“1+1”忘闻,表達(dá)式為‘1+1’
5.arg:傳給指令的參數(shù)。例如v-my-directive=“foo”中恋博,參數(shù)為‘foo’
6.modifiers:一個(gè)包含修飾符的對(duì)象齐佳。例如:v-my-directive.foo.bar中,修飾符對(duì)象為{foo:true, bar: true} - vnode:Vue編譯生成的 虛擬節(jié)點(diǎn)
- oldVnode:上一個(gè)虛擬節(jié)點(diǎn)
除了el之外债沮,其他參數(shù)都應(yīng)該是只讀的炼吴,切勿進(jìn)行修改。如果需要在鉤子之間共享數(shù)據(jù)疫衩,建議通過(guò)元素的dataset來(lái)進(jìn)行硅蹦。
這是一個(gè)自定義鉤子樣例:
<div id="hook-arguments-example" v-demo:foo.a.b="message"></div>
Vue.directive('demo', {
bind: function (el, binding, vnode) {
var s = JSON.stringify
el.innerHTML =
'name: ' + s(binding.name) + '<br>' +
'value: ' + s(binding.value) + '<br>' +
'expression: ' + s(binding.expression) + '<br>' +
'argument: ' + s(binding.arg) + '<br>' +
'modifiers: ' + s(binding.modifiers) + '<br>' +
'vnode keys: ' + Object.keys(vnode).join(', ')
}
})
new Vue({
el: '#hook-arguments-example',
data: {
message: 'hello!'
}
})
動(dòng)態(tài)指令參數(shù)
指令的參數(shù)可以是動(dòng)態(tài)的。例如隧土,在 v-mydirective:[argument]="value" 中提针,argument 參數(shù)可以根據(jù)組件實(shí)例數(shù)據(jù)進(jìn)行更新!這使得自定義指令可以在應(yīng)用中被靈活使用曹傀。
例如你想要?jiǎng)?chuàng)建一個(gè)自定義指令辐脖,用來(lái)通過(guò)固定布局將元素固定在頁(yè)面上。我們可以像這樣創(chuàng)建一個(gè)通過(guò)指令值來(lái)更新豎直位置像素值的自定義指令:
<div id="baseexample">
<p>Scroll down the page</p>
<p v-pin="200">Stick me 200px from the top of the page</p>
</div>
Vue.directive('pin', {
bind: function (el, binding, vnode) {
el.style.position = 'fixed'
el.style.top = binding.value + 'px'
}
})
new Vue({
el: '#baseexample'
})
這會(huì)把該元素固定在距離頁(yè)面頂部 200 像素的位置皆愉。但如果場(chǎng)景是我們需要把元素固定在左側(cè)而不是頂部又該怎么辦呢嗜价?這時(shí)使用動(dòng)態(tài)參數(shù)就可以非常方便地根據(jù)每個(gè)組件實(shí)例來(lái)進(jìn)行更新。
<div id="dynamicexample">
<h3>Scroll down inside this section ↓</h3>
<p v-pin:[direction]="200">I am pinned onto the page at 200px to the left.</p>
</div>
Vue.directive('pin', {
bind: function (el, binding, vnode) {
el.style.position = 'fixed'
var s = (binding.arg == 'left' ? 'left' : 'top')
el.style[s] = binding.value + 'px'
}
})
new Vue({
el: '#dynamicexample',
data: function () {
return {
direction: 'left'
}
}
})
函數(shù)簡(jiǎn)寫(xiě)
在很多時(shí)候幕庐,你可能想在 bind 和 update 時(shí)觸發(fā)相同行為久锥,而不關(guān)心其它的鉤子。比如這樣寫(xiě):
Vue.directive('color-swatch', function (el, binding) {
el.style.backgroundColor = binding.value
})
對(duì)象字面量
如果指令需要多個(gè)值异剥,可以傳入一個(gè) JavaScript 對(duì)象字面量瑟由。記住,指令函數(shù)能夠接受所有合法的 JavaScript 表達(dá)式冤寿。
<div v-demo="{ color: 'white', text: 'hello!' }"></div>
Vue.directive('demo', function (el, binding) {
console.log(binding.value.color) // => "white"
console.log(binding.value.text) // => "hello!"
})