Vue.component('my-component-name', { /* ... */ })這裏的
my-component-name
就是組件名,組件名的取法能夠參考指南
kebab-case寫法(-鏈接單詞) 推薦的寫法
定義:javascript
Vue.component('my-component-name', { /* ... */ })
用法:html
<my-component-name></my-component-name>
PascalCase寫法(單詞首字母大寫)vue
Vue.component('MyComponentName', { /* ... */ })
Vue.component('my-component-name', { /* ... */ })
var ComponentA = { /* ... */ } var ComponentB = { /* ... */ }而後在
components
選項中定義你想要使用的組件: new Vue({ el: '#app', components: { 'component-a': ComponentA, 'component-b': ComponentB } })對於 components 對象中的每一個屬性來講,其屬性名就是自定義元素的名字,其屬性值就是這個組件的選項對象。
var ComponentA = { /* ... */ } var ComponentB = { components: { 'component-a': ComponentA }, // ... }或者若是你經過 Babel 和 webpack 使用 ES2015 模塊,那麼代碼看起來更像:
import ComponentA from './ComponentA.vue' export default { components: { ComponentA }, // ... }
import/require
使用一個模塊系統
import ComponentA from './ComponentA' import ComponentC from './ComponentC' export default { components: { ComponentA, ComponentC }, // ... }
prop大小寫(camelCase vs kebab-case)
HTML 中的特性(屬性)名是大小寫不敏感的,因此瀏覽器會把全部大寫字符解釋爲小寫字符,camelCase (駝峯命名法) 的 prop 名須要使用其等價的 kebab-case (短橫線分隔命名) 命名:java
Vue.component('blog-post', { // 在 JavaScript 中是 camelCase 的 props: ['postTitle'], template: '<h3>{{ postTitle }}</h3>' })
<!-- 在 HTML 中是 kebab-case 的 --> <blog-post post-title="hello!"></blog-post>
所以,強烈建議
用kebab-case
寫法。webpack
prop 類型
一般,以字符串數組形式列出 prop:git
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
可是,一般你但願每一個 prop 都有指定的值類型。這時,你能夠以對象形式列出 prop,這些屬性的名稱和值分別是 prop 各自的名稱和類型:github
props: { title: String, likes: Number, isPublished: Boolean, commentIds: Array, author: Object, callback: Function, contactsPromise: Promise // or any other constructor }
傳遞靜態或動態prop
傳遞靜態值:web
<blog-post title="My journey with Vue"></blog-post>
傳遞動態值數組
<!-- 動態賦予一個變量的值 --> <blog-post v-bind:title="post.title"></blog-post> <!-- 動態賦予一個複雜表達式的值 --> <blog-post v-bind:title="post.title + ' by ' + post.author.name" ></blog-post>
實際上,能傳遞的值包括:字符串、數字、布爾值、數組、對象、對象全部屬性。瀏覽器
單向數據流
全部的 prop 都使得其父子 prop 之間造成了一個單向下行綁定:父級 prop 的更新會向下流動到子組件中,可是反過來則不行。
prop驗證
Vue.component('my-component', { props: { // 基礎的類型檢查 (`null` 和 `undefined` 會經過任何類型驗證) 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 ['success', 'warning', 'danger'].indexOf(value) !== -1 } } } })
上面的type
能夠是原生構造函數的一個:String
,Number
,Boolean
,Array
,Object
,Date
,Function
,Symbol
。
非 Prop 的特性
一個非 prop 特性是指傳向一個組件,可是該組件並無相應 prop 定義的特性。
class
和 style
特性會稍微智能一些,即兩邊的值會被合併起來。inheritAttrs: false
,適合配合實例的 $attrs 屬性使用: Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on:input="$emit('input', $event.target.value)" > </label> ` })
事件名
不一樣於組件和 prop,事件名不存在任何自動化的大小寫轉換。而是觸發的事件名須要徹底匹配
監聽這個事件所用的名稱:
this.$emit('myEvent')
則監聽這個名字的 kebab-case 版本是不會有任何效果的:
<!-- 沒有效果 --> <my-component v-on:my-event="doSomething"></my-component>
推薦始終使用 kebab-case 的事件名
自定義組件的 v-model
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>
將原生事件綁定到組件
使用 v-on 的 .native 修飾符:
<base-input v-on:focus.native="onFocus"></base-input>
Vue 提供了一個 $listeners 屬性,它是一個對象,裏面包含了做用在這個組件上的全部監聽器。能夠配合 v-on="$listeners" 將全部的事件監聽器指向這個組件的某個特定的子元素。
Vue.component('base-input', { inheritAttrs: false, props: ['label', 'value'], computed: { inputListeners: function () { var vm = this // `Object.assign` 將全部的對象合併爲一個新對象 return Object.assign({}, // 咱們從父級添加全部的監聽器 this.$listeners, // 而後咱們添加自定義監聽器, // 或覆寫一些監聽器的行爲 { // 這裏確保組件配合 `v-model` 的工做 input: function (event) { vm.$emit('input', event.target.value) } } ) } }, template: ` <label> {{ label }} <input v-bind="$attrs" v-bind:value="value" v-on="inputListeners" > </label> ` })
.sync 修飾符
以 update:myPropName
的模式觸發事件
this.$emit('update:title', newTitle)
<text-document v-bind:title="doc.title" v-on:update:title="doc.title = $event" ></text-document>
縮寫:
<text-document v-bind:title.sync="doc.title"></text-document>
同時設置多個 prop :
<text-document v-bind.sync="doc"></text-document>
插槽內容
<navigation-link url="/profile"> Your Profile </navigation-link>
<navigation-link>
的模板中:
<a v-bind:href="url" class="nav-link"> <slot></slot> </a>
則Your Profile
會替換<slot></slot>
部分。Your Profile
能夠是HTML代碼或者其餘插件。
編譯做用域
父級模板裏的全部內容都是在父級做用域中編譯的;子模板裏的全部內容都是在子做用域中編譯的。
<navigation-link url="/profile"> Clicking here will send you to: {{ url }} <!-- 這裏的 `url` 會是 undefined,由於 "/profile" 是 _傳遞給_ <navigation-link> 的而不是 在 <navigation-link> 組件內部定義的。 --> </navigation-link>
後備內容(默認值)
<button type="submit"> <slot>Submit</slot> </button>
這裏的Submit
就是默認值。
具名插槽
<slot>
元素有一個特殊的特性:name
。這個特性能夠用來定義額外的插槽:
<div class="container"> <header> <slot name="header"></slot> </header> <main> <slot></slot> </main> <footer> <slot name="footer"></slot> </footer> </div>
一個不帶 name
的 <slot>
出口會帶有隱含的名字「default」。
在一個 <template>
元素上使用 v-slot
指令,並以 v-slot 的參數的形式提供其名稱:
<base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <p>A paragraph for the main content.</p> <p>And another one.</p> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
做用域插槽
綁定在 <slot>
元素上的特性被稱爲插槽 prop
。如今在父級做用域中,咱們能夠給 v-slot 帶一個值來定義咱們提供的插槽 prop
的名字:
<current-user> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> </current-user>
獨佔默認插槽的縮寫語法
<current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user>
解構插槽 Prop
<current-user v-slot="{ user }"> {{ user.firstName }} </current-user>
動態插槽名
<base-layout> <template v-slot:[dynamicSlotName]> ... </template> </base-layout>
具名插槽的縮寫
(v-slot:
) 替換爲字符 #
:
其它示例(略)
在動態組件上使用 keep-alive
曾經在一個多標籤的界面中使用 is
特性來切換不一樣的組件:
<component v-bind:is="currentTabComponent"></component>
能夠用一個 <keep-alive>
元素將其動態組件包裹起來,避免切換的時候從新渲染:
<!-- 失活的組件將會被緩存!--> <keep-alive> <component v-bind:is="currentTabComponent"></component> </keep-alive>
異步組件(略)
這些特殊場景和危險狀況須要留心~
訪問元素 & 組件
$root
屬性$parent
屬性ref
特性provide
和 inject
。程序化的事件偵聽器
$on(eventName, eventHandler)
偵聽一個事件$once(eventName, eventHandler)
一次性偵聽一個事件$off(eventName, eventHandler)
中止偵聽一個事件循環引用
模板定義的替代品
控制更新
$forceUpdate
v-once
建立低開銷的靜態組件