Vue的使用總結(2)
1、Vue 中 class 和 style 的綁定
在 Vue 中,可以通過數據綁定來操作元素的 class 列表和內聯樣式,操作 class 和 style 是用 v-bind 來綁定的。在將 v-bind 用于 class 和 style 時,Vue.js 做了專門的增強,表達式結果的類型除了字符串之外,還可以是對象或數組。
v-bind: class 指令可以與普通的 class 屬性共存,并不會沖突或者覆蓋。
當在一個自定義組件上使用 class 屬性時,這些 class 將被添加到該組件的根元素上面,這個元素上已經存在的 class 不會被覆蓋。
1.1、綁定 class
1.1.1、字符串語法
字符串語法也就是直接在 v-bind:class 后面直接寫表達式。
<div v-bind:class="'red_class'"> div3 </div> .red_class { background: red; }
1.1.2、對象語法
對象語法就是在 v-bind:class 的表達式語法里寫入一個對象。該對象的屬性名是類名,屬性值的 true 或者 false 決定該屬性名是否添加進類名中。
<div v-bind:class="{ red_class : false" > div1 </div> <div v-bind:class="{ 'red_class' : classBol, 'green_class': true > <!--屬性名可以寫成字符串--> div2 </div> <div v-bind:class="classObj"> <!--也可以直接寫對象變量--> div3 </div> data: { classBol: true, classObj: { red_class: true } }
判斷該對象的屬性值是 true 或者 false 的依據跟 JS 一般情況下判斷數據的布爾值一樣,比如:0為false,1為true,null 為false。
1.1.3、數組語法
可以把一個數組傳給 v-bind:class,以應用一個 class 列表。數組語法和對象語法不同,在數組語法中,數組項是變量名,類名取決于該變量名的值,值是什么,類名就是什么。
<div v-bind:class="[redClass, greenClass]"></div> data: { redClass: 'red_class', greenClass: 'green_class' } <!-- 最終渲染 --> <div class="red_class green_class"></div>
在數組中也可以使用三元表達式,并且數組項也可以是對象
<div v-bind:class="[true? redClass : '', greenClass]"></div> <!-- 三元表達式,不過數組項仍是變量 --> <div v-bind:class="[{ red_class: false }, greenClass]"></div> <!-- 數組項中使用對象 --> data: { redClass: 'red_class', greenClass: 'green_class' }
1.2、綁定 style
當 v-bind:style 使用需要添加瀏覽器引擎前綴的 CSS 屬性時,如 transform,Vue會自動偵測并添加相應的前綴。
1.2.1、對象語法
<div v-bind:style="{ color: colorVal, fontSize: sizeVal + 'px' }"></div> <div v-bind:style="styleObject"></div> <!--直接綁定一個對象變量--> data: { colorVal: 'red', sizeVal: 30, styleObject: { color: 'red', fontSize: '13px' } }
1.2.2、數組語法
綁定 style 的數組語法的數組項是對象,其實就是可以將多個樣式對象綁定到元素上。
<div v-bind:style="[baseObj, otherObj]"></div> data: { baseObj: { color: 'red' }, otherObj: { fontSize: '13px' } }
2、組件
2.1、全局注冊組件
全局注冊組件:
// 定義一個名為 button-counter 的新組件 Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">You clicked me {{ count }} times.</button>' })
組件是可復用的 Vue 實例,且帶有一個名字,上面的例子中是 <button-counter>。
我們可以在一個通過 new Vue 創建的 Vue 根實例中,把這個組件作為自定義元素來使用:
<div id="components-demo"> <button-counter></button-counter> </div>
組件是可復用的 Vue 實例,它們與 new Vue 接收相同的選項,例如 data、computed、watch、methods 以及生命周期鉤子等。僅有的例外是像 el 這樣根實例特有的選項。每用一次組件,就會有一個它的新實例被創建。
組件的 data 必須是一個函數。每個組件只能有一個根元素。組件中的data寫成一個函數,數據以函數返回值形式定義,這樣每復用一次組件,就會返回一份新的data。如果data值為對象,將導致多個實例共享一個對象,其中一個組件改變data屬性值,其它實例也會受到影響。
上面的組件是通過全局注冊的,全局注冊的組件可以用在其被注冊之后的任何 (通過 new Vue) 新創建的 Vue 根實例,也包括其組件樹中的所有子組件的模板中。注意:全局注冊的行為必須在根 Vue 實例 (通過 new Vue) 創建之前發生。
2.2、局部注冊組件
全局注冊往往是不夠理想的。比如,如果你使用一個像 webpack 這樣的構建系統,全局注冊所有的組件意味著即便你已經不再使用一個組件了,它仍然會被包含在你最終的構建結果中。這造成了用戶下載的 JavaScript 的無謂的增加。
局部注冊組件:
<body> <div id="app"> {{parentMsg}} <component-a></component-a> </div> <script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script> <script> //組件 var componentA = { name: "componentA", data: function() { return { msg: '子組件A' } }, template: ` <div>{{msg}}</div> ` } //根實例使用組件 var app = new Vue({ el: '#app', components: { 'component-a': componentA }, data: { parentMsg: '父組件' } }) </script> </body>
頁面渲染效果:

2.3、父子組件通過prop傳值
Prop 是你可以在組件上注冊的一些自定義 attribute。當一個值傳遞給一個 prop attribute 的時候,它就變成了那個組件實例的一個 property。
定義組件的 prop:
Vue.component('blog-post', { props: ['title'], template: '<h3>{{ title }}</h3>' })
給組件傳值:
<blog-post title="My journey with Vue"></blog-post> <blog-post title="Blogging with Vue"></blog-post> <blog-post title="Why Vue is so fun"></blog-post>
一個組件默認可以擁有任意數量的 prop,任何值都可以傳遞給任何 prop。在組件內可以訪問 prop 的值,就像訪問 data 中的值一樣。
prop 可以傳遞靜態值,也可以使用 v-bind 來傳遞動態的值:
<!-- 動態賦予一個變量的值 --> <blog-post v-bind:title="post.title"></blog-post>
2.3.1、prop的類型
在定義組件時,我們可以指定組件的每個 prop 希望接收到的值類型:
Vue.component('my-component', {
...
props: {
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object,
callback: Function,
contactsPromise: Promise // or any other constructor
}
})
指定 prop 的類型之后,如果給組件傳遞的 prop 不是指定的類型將會報錯。
prop 可以接收任何類型的值:
<!-- 傳遞數字 --> <!-- 即便 `42` 是靜態的,我們仍然需要 `v-bind` 來告訴 Vue 是一個 JavaScript 表達式而不是一個字符串。 --> <blog-post v-bind:likes="42"></blog-post> <!-- 布爾值 --> <!-- 包含該 prop 沒有值的情況在內,都意味著 `true`。--> <blog-post is-published></blog-post> <blog-post v-bind:is-published="false"></blog-post> <!-- 數組 --> <blog-post v-bind:comment-ids="[234, 266, 273]"></blog-post> <!-- 對象 --> <blog-post v-bind:author="{ name: 'Veronica', company: 'Veridian Dynamics' }" ></blog-post> <!-- 一次性傳入對象的所有屬性 --> post: { id: 1, title: 'My Journey with Vue' } <blog-post v-bind="post"></blog-post> <!-- 等價于 --> <blog-post v-bind:id="post.id" v-bind:title="post.title" ></blog-post>
注意,在 JavaScript 中對象和數組是通過引用傳入的,所以對于一個數組或對象類型的 prop 來說,在子組件中改變變更這個對象或數組本身將會影響到父組件的狀態。
2.3.2、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
}
}
}
})
當 prop 驗證失敗的時候,(開發環境構建版本的) Vue 將會產生一個控制臺的警告。
組件的 prop 會在該組件的實例創建之前進行驗證,所以實例的 property (如 data、computed 等) 在 default 或 validator 函數中是不可用的。
2.3.3、非prop的屬性
一個非 prop 的 attribute 是指傳向一個組件,但是該組件并沒有相應 prop 定義的 attribute。組件可以接受任意的 attribute,而這些非 prop 的屬性會直接被添加到這個組件的根元素上。
<body>
<div id="app">
{{parentMsg}}
<component-a notProp="aabb"></component-a>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
//組件
var componentA = {
name: "componentA",
data: function() {
return {
msg: '子組件A'
}
},
template: `
<div id="comA">{{msg}}</div>
`
}
//根實例使用組件
var app = new Vue({
el: '#app',
components: {
'component-a': componentA
},
data: {
parentMsg: '父組件'
}
})
</script>
</body>
上面可以看到,notProp屬性在子組件中并未定義,所以是非 prop 屬性,此時這些屬性會直接被添加到組件的根元素上。
最終效果:


如果該屬性在子組件的根元素中也有并且有值,此時該屬性會自動合并,也就是該屬性的值是父元素中傳入的值也子組件中的值的并集。
2.4、父子組件通過事件傳值
父組件在使用子組件時,可以監聽子組件的某個自定義事件,子組件可以通過 $emit() 方法來觸發自定義事件。
//父組件使用子組件時,監聽一個自定義事件 <blog-post ... v-on:enlarge-text="onEnlargeText" ></blog-post> onEnlargeText: function (enlargeAmount) { this.postFontSize += enlargeAmount } //子組件觸發自定義事件 <button v-on:click="$emit('enlarge-text', 0.1)"> Enlarge text </button>
2.5、父子組件通過 v-model 通信
官方文檔:https://cn.vuejs.org/v2/guide/components.html#在組件上使用-v-model

即 v-model 只是一個語法糖,v-model 真正的靠的還是 v-bind 綁定數據,觸發 input 傳遞數據,這不管是在組件還是表單元素中都是一樣的。
組件之間通過 v-model 進行通信的代碼示例:
//父組件代碼 import TodoItem from './components/TodoItem.vue' data(){ return { modelMsg: 'v-model信息' } } <todo-item v-model="modelMsg"></todo-item> //上面的代碼相當于: <todo-item v-bind:value="modelMsg" v-on:input="modelMsg = arguments[0]"></todo-item>
上面其實就是給子組件傳遞了一個 key 為 'value' 的屬性值,并且監聽了子組件的 input 方法, input 的回調方法的方法體為 變量名=arguments[0],也就是會自動將子組件傳遞回來的方法的第一個參數設為屬性的新值。
子組件代碼:
//子組件中使用父組件綁定的值 <input type="text" v-model="modelMsg2" @input="changeMsg($event)"> //上面其實不一定要綁定在表單元素上,傳過來的value其實就是一個普通的 props 屬性值,可以任意使用 <div class="hello"> <h1>父組件的值:{{ value }}</h1> <button @click="changeMsg">點擊</button> </div> data () { return { //這里將value賦值給modelMsg,不然直接修改value時會報錯 modelMsg2: this.value } } props: { //接受父組件傳遞過來的值。注意,這里的key一定是叫做 'value' value: { type: String } } methods: { //需要修改父組件綁定的值時,通過input事件觸發 handleInput(e) { this.$emit('input',e.target.value) }, //需要修改父組件綁定的值時,通過input事件觸發 changeMsg() { this.$emit('input', 'new value值') } }
可以看到,實際上就是給子組件傳遞了一個 'value' 作為 prop,并且給子組件綁定了 input 事件。子組件可以接收到 'value' 的值,并且在 value 發生改變時可以以 input 事件傳遞給父組件,父組件會自動接收到最新的 ‘value’ 的值。
由上面代碼可以得知,需要手動設置一個函數,當子組件的props屬性 value 值發生改變時,通過 $emit 傳遞給父組件,父組件中的 v-model 已經自動監聽了 input 事件,并且會自動同步父組件的數據,由此父子組件之間的數據雙向綁定得以實現。
參考:http://www.rzrgm.cn/rachelch/p/8944367.html
2.6、組件的template通過script定義
組件定義時使用的 template 模板可以通過 script 來定義:
<script type="text/x-template" id="anchored-heading-template">
<h1 v-if="level === 1">
<slot></slot>
</h1>
</script>
//注冊組件
Vue.component('anchored-heading', {
template: '#anchored-heading-template', //引用script來定義template
props: {
level: {
type: Number,
required: true
}
}
})
//使用組件
<anchored-heading :level="1">
Hello world!
</anchored-heading>
3、vue 中的函數參數
3、原生事件的傳遞
3.1、沒有括號時默認會傳原生事件
vue 中調用事件,如果不傳參,默認會將原生 DOM 事件作為參數傳過去
<button @click="a">事件嘗試</button>
methods: {
a (e) {
console.log(e); //輸出原生事件 MouseEvent {isTrusted: true, screenX: 427, screenY: 491, clientX: 388, clientY: 362, …}
}
}
3.1.2、加上括號默認不會傳原生事件
如果加上了括號以后,不管你是否在后面添加參數,都不會自動將原生事件傳過去
<button @click="a()">事件嘗試</button>
methods: {
a (e) {
console.log(e); //輸出 undefined
}
}
<button @click="a('aaa')">事件嘗試</button>
methods: {
a (e) {
console.log(e); //輸出 aaa
}
}
3.1.3、如何手動傳原生事件
有時候可能我們也需要訪問原始的 DOM 事件,這時可以用特殊變量 $event 把它傳入方法。($event 參數不一定要在最后傳遞)
<button @click="a('aaa','bbb',$event)">事件嘗試</button>
methods: {
a (a,b,event) {
console.log(a,b,event); //輸出 aaa bbb MouseEvent {isTrusted: true, screenX: 425, screenY: 507, clientX: 386, clientY: 376, …}
}
}
3.2、父組件如何接收子組件的參數
3.2.1、父組件只接收子組件的參數,不傳遞額外的參數
如果在父組件中只接收子組件的參數,并不傳遞額外的參數,此時父組件的接收函數可以不寫參數,組件默認會將子組件傳過來的參數作為參數傳遞。
/*** 子組件只傳遞一個參數的情況: ***/
//子組件 觸發父組件的事件
this.$emit('childBtnClick','hahahaha')
//父組件
<child @childBtnClick="childClick"></child>
childClick (msg) {
console.log(msg); //輸出 'hahahaha'
}
/*** 子組件傳遞多個參數的情況: ***/
//子組件 觸發父組件的事件
this.$emit('childBtnClick', 'hahahaha', '2222')
//父組件
<child @childBtnClick="childClick"></child>
childClick (msg, msg2) {
console.log(msg, msg2); //輸出 'hahahaha' '2222'
}
3.2.2、父組件接收子組件參數并且傳遞額外的參數
當父組件接收子組件參數,并且自身也往函數中傳遞額外的參數時,可以在函數中使用一些關鍵字來接收子組件傳遞的參數。
當子組件只傳遞一個參數時,可以使用 $event 來接收子組件傳遞的參數。當子組件傳遞多個參數時,可以使用 arguments 來接收多個參數,該關鍵字接收到的是一個數組,子組件傳遞的參數都在里面。
/*** 子組件只傳遞一個參數的情況: ***/
//子組件 觸發父組件的事件
this.$emit('childBtnClick', 'hahahaha')
//父組件
<child @childBtnClick="childClick($event, 'aaa')"></child>
childClick (e, msg) {
console.log(e, msg); //輸出 'hahahaha' 'aaa'
}
/*** 子組件傳遞多個參數的情況: ***/
//子組件 觸發父組件的事件
this.$emit('childBtnClick', 'hahahaha', 'haha2222')
//父組件
<child @childBtnClick="childClick(arguments, 'aaa')"></child>
childClick (arr, msg) {
console.log(arr, arr[0], arr[1], msg); //輸出 Arguments(2)["hahahaha", "haha222", callee: (...), Symbol(Symbol.iterator): ?] "hahahaha" "haha222" "aaa"
}
可參考:http://www.rzrgm.cn/lalalagq/p/9901139.html、https://github.com/vuejs/vue/issues/5735
4、插槽
子組件可以通過 <slot></slot> 來定義插槽,通過插槽可以讓父組件往子組件指定的內容區里面插入想要的元素。
//子組件定義插槽 <a v-bind:href="url" class="nav-link" > <slot></slot> </a> //父組件直接往子組件里面插入內容,該內容將會自動添加至插槽處 <navigation-link url="/profile"> <span class="fa fa-user"></span> Your Profile </navigation-link>
如果子組件中沒有定義插槽元素 <slot>,則父組件往子組件里面插入的內容將會全部被拋棄。
父組件在往子組件里面插入內容時,可以使用父組件的數據,但不能訪問子組件作用域的內容。
//假設myurl在父組件中有定義,而userObj沒有定義。則myurl可以正常顯示,但userObj將報錯 <navigation-link :url="myurl"> Logged in as {{ userObj.name }} {{myurl}} </navigation-link>
父級模板里的所有內容都是在父級作用域中編譯的;子模板里的所有內容都是在子作用域中編譯的。上面實例中,父組件中插槽跟模板的其它地方一樣可以訪問相同的實例 property (也就是相同的“作用域”),而不能訪問 <navigation-link> 的作用域
4.1、默認插槽內容
有時我們可能希望給插槽一些默認內容,當父組件沒有傳入插槽內容時,插槽的默認內容將起作用。
<button type="submit"> <slot>Submit</slot> </button>
如果父組件提供了插槽內容,則默認插槽里面的內容將被取代。
4.2、具名插槽
有時我們需要定義多個插槽,這時可以通過定義插槽的 name 屬性來區別各個插槽。
<div class="container"> <header> <slot name="header"></slot> </header>
<main> <slot></slot> </main>
<footer> <slot name="footer"></slot> </footer> </div>
不帶 name 屬性的插槽即是默認插槽,該插槽會帶有隱含的名字“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>
現在 <template> 元素中的所有內容都將會被傳入相應的插槽。任何沒有被包裹在帶有 v-slot 的 <template> 中的內容都會被視為默認插槽的內容。
在往默認插槽插入內容時,也可以通過 default 來指定插入默認插槽:
<base-layout> <template v-slot:header> <h1>Here might be a page title</h1> </template> <template v-slot:default> <p>A paragraph for the main content.</p> <p>And another one.</p> </template> <template v-slot:footer> <p>Here's some contact info</p> </template> </base-layout>
注意,v-slot 只能添加在 <template> 上 ,除非當被提供的內容只有默認插槽時,組件的標簽才可以被當作插槽的模板來使用,此時 v-slot 可以直接用在組件標簽上。
4.3、作用域插槽
默認情況下,父組件在往子組件里面插入內容時,只可以使用父組件的數據,不能訪問子組件作用域的內容。比如:
//假設myurl在父組件中有定義,而userObj沒有定義。則myurl可以正常顯示,但userObj將報錯 <navigation-link :url="myurl"> Logged in as {{ userObj.name }} {{myurl}} </navigation-link>
要想在父組件中也能訪問子組件的一些數據,此時我們可以使用作用域插槽。
在子組件里定義插槽時,可以將希望傳遞的值作為 slot 元素的屬性傳遞給父組件,父組件就能通過 v-slot 來拿到子組件傳遞的值。我們將子組件綁定在 <slot> 元素上的屬性稱為插槽 prop。
//子組件代碼 <span> <slot v-bind:user="user"> {{ user.lastName }} </slot> </span> //父組件代碼。下面父組件將包含所有插槽 prop 的對象命名為 slotProps,通過該變量就能拿到所有子組件傳遞的值 <current-user> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> </current-user>
當子組件的插槽只有默認插槽時,父組件在使用子組件時,可以將子組件的標簽作為插槽的模板來使用,可以把 v-slot 直接用在組件標簽上:
<current-user v-slot:default="slotProps"> {{ slotProps.user.firstName }} </current-user> //可以省略 default <current-user v-slot="slotProps"> {{ slotProps.user.firstName }} </current-user>
注意默認插槽的縮寫語法不能和具名插槽混用,因為它會導致作用域不明確:
<!-- 無效,會導致警告 --> <current-user v-slot="slotProps"> {{ slotProps.user.firstName }} <template v-slot:other="otherSlotProps"> slotProps is NOT available here </template> </current-user>
<!-- 只要出現多個插槽,請始終為所有的插槽使用完整的基于 <template> 的語法 --> <current-user> <template v-slot:default="slotProps"> {{ slotProps.user.firstName }} </template> <template v-slot:other="otherSlotProps"> ... </template> </current-user>
4.4、廢棄的語法
關于插槽的一些舊語法:slot 和 slot-scope,這些語法在 vue2.6 起被 v-slot 取代,雖然在 vue2.x 版本仍被支持,但 vue3 版本將會廢棄掉不再支持。
具名插槽 slot:
<base-layout> <template 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 slot="footer"> <p>Here's some contact info</p> </template> </base-layout>
作用域插槽:
<slot-example> <template slot="default" slot-scope="slotProps"> {{ slotProps.msg }} </template> </slot-example>
5、過濾器(filter)
Vue.js 允許你自定義過濾器,可被用于一些常見的文本格式化。
你可以在一個組件的選項中定義本地的局部過濾器,也可以在創建 Vue 實例之前全局定義過濾器:
//在vue選項中局部定義過濾器 filters: { capitalize: function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) } } //全局定義過濾 Vue.filter('capitalize', function (value) { if (!value) return '' value = value.toString() return value.charAt(0).toUpperCase() + value.slice(1) })
當全局過濾器和局部過濾器重名時,會采用局部過濾器。
過濾器可以用在兩個地方:雙花括號插值和 v-bind 表達式 (后者從 2.1.0+ 開始支持)。過濾器應該被添加在 JavaScript 表達式的尾部,由“管道”符號指示:
<!-- 在雙花括號中 --> {{ message | capitalize }} <!-- 在 `v-bind` 中 --> <div v-bind:id="rawId | formatId"></div>
過濾器函數總接收表達式的值 (之前的操作鏈的結果) 作為第一個參數。在上述例子中,capitalize 過濾器函數將會收到 message 的值作為第一個參數。
過濾器可以串聯:
{{ message | filterA | filterB }}
上面例子中,filterA 被定義為接收單個參數的過濾器函數,表達式 message 的值將作為參數傳入到函數中。然后繼續調用同樣被定義為接收單個參數的過濾器函數 filterB,將 filterA 的結果傳遞到 filterB 中。
過濾器是 JavaScript 函數,因此可以接收參數:
{{ message | filterA('arg1', arg2) }}
這里,filterA 被定義為接收三個參數的過濾器函數。其中 message 的值作為第一個參數,普通字符串 'arg1' 作為第二個參數,表達式 arg2 的值作為第三個參數。
6、命名問題
6.1、自定義事件命名(使用分隔符命名)
vue 中的自定義事件在被觸發時(子組件觸發父組件的自定義事件),駝峰法和橫線法不會進行自動轉換即不會自動匹配,所以事件名需要完全一致。并且在DOM中的事件名都會被轉換為小寫,所以如果你在 JS 代碼中如果使用了駝峰法,而 DOM 中也使用了駝峰法,則會匹配不上而報錯。
所以事件命名建議使用分隔符命名(kebab-case)。不要使用駝峰法命名,否則可能有問題。
//使用駝峰法命名的問題: //子組件觸發自定義事件 this.$emit('myEvent') <!-- 父組件監聽自定義事件,此時不管使用分隔符還是駝峰法都無法監聽到子組件觸發的事件 --> <my-component v-on:myEvent="doSomething"></my-component> <my-component v-on:my-event="doSomething"></my-component>
6.2、prop的命名(推薦分隔符命名)
在 DOM 中即父組件使用橫線連接符(kebab-case)命名,在子組件中可以使用橫線或者駝峰法,都能匹配上。所以我們推薦使用分隔符命名。
但是當我們使用 DOM 模板(而不是在字符串模板 template: `` 或單文件組件)時,camelCase (駝峰命名法) 的 prop 名需要使用其等價的 kebab-case (短橫線分隔命名) 來匹配:
//在JS中,使用駝峰法和分隔符都能匹配上 Vue.component('blog-post', { props: ['postTitle'], template: '<h3>{{ postTitle }}</h3>' }) //在DOM中只能使用分隔符,使用駝峰法會因大小寫問題導致無法匹配 <blog-post post-title="hello!"></blog-post>
6.3、組件的命名(推薦分隔符命名)
定義組件時,我們需要給組件命名:
Vue.component('my-component-name', { /* ... */ })
組件的命名可以使用分隔線或者首字母大寫的駝峰法。但是我們推薦使用分隔線命名。
當使用分隔線命名時(比如:my-component-name),使用組件的時候也得使用分隔線;
當使用首字母大寫的駝峰法時(比如:MyComponentName),在使用組件時可以使用分隔線也可以使用首字母大寫駝峰法。但是如果是在 DOM 中使用(而不是在字符串模板 template: `` 或單文件組件)時,此時只能通過分隔線來使用組件(即使組件是使用駝峰法的命名),因為在 HTML 中不區分大小寫,瀏覽器會把所有大寫字符解釋為小寫字符,所以在HTML中使用駝峰法可能會因為匹配不上而報錯。

浙公網安備 33010602011771號