指令
指令(Directives)是帶有v-
前綴的特別屬性。指令的職責是,當表達式的值轉變時,將其發作的連帶影響,相應式地作用於DOM。
v-if前提推斷
<template v-if="ok">
<h1>Title</h1>
<p>Paragraph 1</p>
<p>Paragraph 2</p>
</template>
<template>
元素看成不可見的包裹元素
<div v-if="type === 'A'">A</div>
<div v-else-if="type === 'B'">B</div> <!-- vue2.1今後才有 v-else-if指令 -->
<div v-else>Not A/B/C</div>
v-if是惰性的:假如在初始襯着時前提為假,則什麼也不做——直到前提第一次變成真時,才會最先襯着前提塊。
v-show顯現推斷
<h1 v-show="ok">Hello!</h1>
與v-if
差別,v-show只是舉行CSS的變更。
v-bind屬性綁定
<a v-bind:href="url">...</a>
綁定url到href,當url有變化可相應dom重襯着,可縮寫成
<a :href="url">...</a>
v-on事宜綁定
<a v-on:click="doSomething">...</a>
綁定doSomething函數到a標籤的點擊事宜,可縮寫成
<a @click="doSomething">...</a>
v-for輪迴
可輪迴襯着動態選項,數組情勢
<select v-model="selected">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
與react差別,react須要運用map要領遍歷返回組件,vue直接把輪迴掛在標籤屬性上。
對象情勢
data: {
options: {
jock: '佐客',
tom: '湯姆',
miko: '咪口'
}
}
<select v-model="selected">
<option v-for="(value, key) in options" v-bind:value="option.key">
{{ option.value }}
</option>
</select>
潤飾符
潤飾符(Modifiers)是以半角句號.
指明的特別後綴,用於指出一個指令應該以特別體式格局綁定。比方,.prevent
潤飾符通知v-on
指令關於觸發的事宜挪用 event.preventDefault()
:
<form v-on:submit.prevent="onSubmit">...</form>
事宜潤飾符
-
.prevent
=>event.preventDefault()
-
.stop
=>event.stopPropagation()
-
.capture
運用事宜捕捉 -
.self
只當在 event.target 是當前元素本身時觸發處置懲罰函數,即事宜不是從內部元素觸發的 -
.once
事宜只觸發一次
按鍵潤飾符
<!-- 只要在 `keyCode` 是 13 時挪用 `vm.submit()` -->
<input v-on:keyup.13="submit">
<!-- 同上 -->
<input v-on:keyup.enter="submit">
<!-- 縮寫語法 -->
<input @keyup.enter="submit">
悉數的按鍵別號:
- .enter
- .tab
- .delete (捕捉“刪除”和“退格”鍵)
- .esc
- .space
- .up
- .down
- .left
- .right
體系潤飾鍵
- .ctrl
- .alt
- .shift
- .meta
在 Mac 體系鍵盤上,meta 對應 command 鍵 (⌘)。在 Windows 體系鍵盤 meta 對應 Windows 徽標鍵 (⊞)。
.exact 潤飾符
.exact 潤飾符許可你掌握由準確的體系潤飾符組合觸發的事宜。
<!-- 縱然 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
這些潤飾符會限定處置懲罰函數僅相應特定的鼠標按鈕。
盤算屬性computed
基本例子以下
<div id="example">
<p>Original message: "{{ message }}"</p>
<p>Computed reversed message: "{{ reversedMessage }}"</p>
</div>
var vm = new Vue({
el: '#example',
data: {
message: 'Hello'
},
computed: {
// 盤算屬性的 getter
reversedMessage: function () {
// `this` 指向 vm 實例
return this.message.split('').reverse().join('')
}
}
})
computed下的reversedMessage
要領依靠data下的變量message,當message發作變量,reversedMessage會從新盤算效果,與mobx中的computed的作用雷同。
以上例子也可經由過程method
屬性完成,以下
<p>Reversed message: "{{ reversedMessage() }}"</p>
// 在組件中
methods: {
reversedMessage: function () {
return this.message.split('').reverse().join('')
}
}
差別的是盤算屬性是基於它們的依靠舉行緩存的。
盤算屬性computed
也可同時設置setter和getter要領庖代直接寫funciton,以下:
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]
}
}
}
偵聽器watch
new Vue({
data: {
watchData: ''
},
watch: {
watchData: function (newData, oldData) {
// doSomething
}
}
})
Class與Style
class的對象情勢,與classnames模塊相似
<div v-bind:class="{ active: isActive }"></div>
class數組情勢
<div v-bind:class="[activeClass, errorClass]"></div>
data: {
activeClass: 'active',
errorClass: 'text-danger'
}
class對象與數組夾雜運用
<div v-bind:class="[{ active: isActive }, errorClass]"></div>
在組件上運用
Vue.component('my-component', {
template: '<p class="foo bar">Hi</p>'
})
<my-component class="baz boo"></my-component>
效果為:
<p class="foo bar baz boo">Hi</p>
style對象情勢
<div v-bind:style="{ color: activeColor, fontSize: fontSize + 'px' }"></div>
data: {
activeColor: 'red',
fontSize: 30
}
style數組情勢
<div v-bind:style="[baseStyles, overridingStyles]"></div>
表單輸入綁定
v-model
指令在表單input
及textarea
元素上建立雙向數據綁定。它會依據控件範例自動拔取準確的要領來更新元素。v-model會疏忽一切表單元素的value、checked、selected特徵的初始值而老是將Vue實例的數據作為數據泉源。你應該經由過程JavaScript在組件的data選項中聲明初始值。
如:
<input v-model="message" placeholder="edit me">
<p>Message is: {{ message }}</p>
多行文本
<span>Multiline message is:</span>
<p style="white-space: pre-line;">{{ message }}</p>
<br>
<textarea v-model="message" placeholder="add multiple lines"></textarea>
.lazy
在默許情況下,v-model 在每次 input 事宜觸發后將輸入框的值與數據舉行同步。你能夠增加 lazy 潤飾符,從而轉變成運用 change 事宜舉行同步:
<!-- 在“change”時而非“input”時更新 -->
<input v-model.lazy="msg" >
.number
假如想自動將用戶的輸入值轉為數值範例,能夠給 v-model 增加 number 潤飾符:
<input v-model.number="age" type="number">
.trim
假如要自動過濾用戶輸入的首尾空缺字符,能夠給 v-model 增加 trim 潤飾符:
<input v-model.trim="msg">
組件
組件 (Component) 是Vue.js最壯大的功用之一。組件能夠擴大HTML元素,封裝可重用的代碼。在較高層面上,組件是自定義元素,Vue.js的編譯器為它增加特別功用。在有些情況下,組件也能夠表現為用is
特徵舉行了擴大的原生 HTML 元素。
請注意,關於自定義標籤的定名Vue.js不強迫遵照W3C劃定規矩 (小寫,而且包括一個短杠),只管這被認為是最好實踐。
全局註冊組件
Vue.component('my-component', {
// 選項
})
部分註冊組件
var Child = {
template: '<div>A custom component!</div>'
}
new Vue({
// ...
components: {
// <my-component> 將只在父組件模板中可用
'my-component': Child
}
})
因為html元素之間不能隨便嵌套,如table、ul、ol,所以在自定義組件中運用這些受限定的元素時會致使一些問題,比方:
<table>
<my-row>...</my-row>
</table>
自定義組件<my-row>會被看成無效的內容,因而會致使毛病的襯着效果。變通的計劃是運用特別的is
特徵:
<table>
<tr is="my-row"></tr>
</table>
然則假如代碼來自以下字符串模板,則沒有這個限定:
- <script type=”text/x-template”>
- JavaScript 內聯模板字符串
- .vue 組件
data
必需是函數
聲明的組件data必需為一個函數並返回相應數據,不然會湧現正告並住手運轉,聲明比方相似以下:
var data = { counter: 0 }
Vue.component('simple-counter', {
template: '<button v-on:click="counter += 1">{{ counter }}</button>',
// 技術上 data 的確是一個函數了,因而 Vue 不會正告,
// 然則我們卻給每一個組件實例返回了同一個對象的援用
data: function () {
return {
counter: 0
}
}
})
new Vue({
el: '#example-2'
})
Prop
與react相似,prop為傳入組件的參數,屬於單向數據流,假如是綁定了父組件的data,變化會引起DOM重襯着,聲明組件時刻須要聲明預期的props,以下:
Vue.component('child', {
// 聲明 props
props: ['message'],
// 就像 data 一樣,prop 也能夠在模板中運用
// 一樣也能夠在 vm 實例中經由過程 this.message 來運用
template: '<span>{{ message }}</span>'
})
因為HTML不辨別大小寫,聲明prop的時刻我們須要聲明為camelCase
駝峰定名情勢,然則傳入的時刻必需寫成kebab-case
短橫線分開式定名。以下:
Vue.component('child', {
// 在 JavaScript 中運用 camelCase
props: ['myMessage'],
template: '<span>{{ myMessage }}</span>'
})
<!-- 在 HTML 中運用 kebab-case -->
<child my-message="hello!"></child>
動態Prop
能夠用 v-bind 來動態地將 prop 綁定到父組件的數據。每當父組件的數據變化時,該變化也會傳導給子組件:
<div id="prop-example-2">
<input v-model="parentMsg">
<br>
<child v-bind:my-message="parentMsg"></child>
</div>
new Vue({
el: '#prop-example-2',
data: {
parentMsg: 'Message from parent'
}
})
prop聲明時能夠指定特定劃定規矩,範例prop的花樣,如:
Vue.component('example', {
props: {
// 基本範例檢測 (`null` 指許可任何範例)
propA: Number,
// 多是多種範例
propB: [String, Number],
// 必傳且是字符串
propC: {
type: String,
required: true
},
// 數值且有默許值
propD: {
type: Number,
default: 100
},
// 數組/對象的默許值應該由一個工場函數返回
propE: {
type: Object,
default: function () {
return { message: 'hello' }
}
},
// 自定義考證函數
propF: {
validator: function (value) {
return value > 10
}
}
}
})
type也能夠是一個自定義組織器函數,運用instanceof
檢測。
動態組件
經由過程運用保存的<component> 元素,並對其is
特徵舉行動態綁定,你能夠在同一個掛載點動態切換多個組件:
var vm = new Vue({
el: '#example',
data: {
currentView: 'home'
},
components: {
home: { /* ... */ },
posts: { /* ... */ },
archive: { /* ... */ }
}
})
<component v-bind:is="currentView">
<!-- 組件在 vm.currentview 變化時轉變! -->
</component>
也能夠直接綁定到組件對象上:
var Home = {
template: '<p>Welcome home!</p>'
}
var vm = new Vue({
el: '#example',
data: {
currentView: Home
}
})
插槽<slot>
<slot>相似於react中的props.children,能夠替代輸出父組件中傳給子組件標籤內的內容,以下:
假定 my-component 組件有以下模板:
<div>
<h2>我是子組件的題目</h2>
<slot>
只要在沒有要分發的內容時才會顯現。
</slot>
</div>
父組件模板:
<div>
<h1>我是父組件的題目</h1>
<my-component>
<p>這是一些初始內容</p>
<p>這是更多的初始內容</p>
</my-component>
</div>
襯着效果:
<div>
<h1>我是父組件的題目</h1>
<div>
<h2>我是子組件的題目</h2>
<p>這是一些初始內容</p>
<p>這是更多的初始內容</p>
</div>
</div>
<slot>元素能夠用一個特別的特徵 name 來進一步設置怎樣分發內容。多個插槽能夠有差別的名字。簽字插槽將婚配內容片斷中有對應slot特徵的元素。
比方,假定我們有一個 app-layout 組件,它的模板為:
<div class="container">
<header>
<slot name="header"></slot>
</header>
<main>
<slot></slot>
</main>
<footer>
<slot name="footer"></slot>
</footer>
</div>
父組件模板:
<app-layout>
<h1 slot="header">這裏多是一個頁面題目</h1>
<p>重要內容的一個段落。</p>
<p>另一個重要段落。</p>
<p slot="footer">這裡有一些聯絡信息</p>
</app-layout>
襯着效果為:
<div class="container">
<header>
<h1>這裏多是一個頁面題目</h1>
</header>
<main>
<p>重要內容的一個段落。</p>
<p>另一個重要段落。</p>
</main>
<footer>
<p>這裡有一些聯絡信息</p>
</footer>
</div>
在設想組合運用的組件時,內容分發 API 黑白常有效的機制。
子組件援用
然則偶然依然須要在JavaScript中直接接見子組件。與react相似,能夠運用ref
為子組件指定一個援用ID。比方:
<div id="parent">
<user-profile ref="profile"></user-profile>
</div>
var parent = new Vue({ el: '#parent' })
// 接見子組件實例
var child = parent.$refs.profile
當ref和v-for一同運用時,獲取到的援用會是一個數組,包括和輪迴數據源對應的子組件。
自定義事宜
運用 v-on 綁定自定義事宜
- 運用 $on(eventName) 監聽事宜
- 運用 $emit(eventName, optionalPayload) 觸發事宜
例子以下:
<div id="message-event-example" class="demo">
<p v-for="msg in messages">{{ msg }}</p>
<button-message v-on:message="handleMessage"></button-message>
</div>
Vue.component('button-message', {
template: `<div>
<input type="text" v-model="message" />
<button v-on:click="handleSendMessage">Send</button>
</div>`,
data: function () {
return {
message: 'test message'
}
},
methods: {
handleSendMessage: function () {
this.$emit('message', { message: this.message })
}
}
})
new Vue({
el: '#message-event-example',
data: {
messages: []
},
methods: {
handleMessage: function (payload) {
this.messages.push(payload.message)
}
}
})
給組件綁定原生事宜
能夠運用v-on的潤飾符.native
。比方:
<my-component v-on:click.native="doTheThing"></my-component>
.sync潤飾符
該潤飾符能夠讓一個prop變成”雙向綁定”,以下
<comp :foo.sync="bar"></comp>
當comp內修正了foo變量時,父組件的foo也會同時被修正,該潤飾符Vue2.0后被移除,在Vue2.3又被引入,只是此次它只是作為一個編譯時的語法糖存在。它會被擴大為一個自動更新父組件屬性的 v-on 監聽器。如上例子會被擴大成:
<comp :foo="bar" @update:foo="val => bar = val"></comp>
當子組件須要更新 foo 的值時,它須要顯式地觸發一個更新事宜:
this.$emit('update:foo', newValue)
自定義組件的v-model
默許情況下,一個組件的 v-model 會運用 value prop 和 input 事宜。然則諸如單選框、複選框之類的輸入範例可能把 value 用作了別的目標。model 選項能夠防止如許的爭執:
Vue.component('my-checkbox', {
model: {
prop: 'checked',
event: 'change'
},
props: {
checked: Boolean,
// 如許就許可拿 `value` 這個 prop 做別的事了
value: String
},
// ...
})
<my-checkbox v-model="foo" value="some value"></my-checkbox>
上述代碼等價於:
<my-checkbox
:checked="foo"
@change="val => { foo = val }"
value="some value">
</my-checkbox>