首先簡單回顧下組件事件及組件的復用
demo1:按鈕事件
<div class="button_area"> <button-area></button-area> <button-area></button-area> <button-area></button-area> </div> <script type="text/javascript"> // 1、注冊組件 Vue.component('button-area',{ data:function(){ return { count:0 } }, template:`<button v-on:click="count++">您點擊了{{count}}次</button>` }) // 2、實例化,構建組件模板 new Vue({ el:".button_area" }) </script>
demo2:監聽子組件事件
在開發 <event-area>
組件時,它的一些功能可能要求我們和父級組件進行溝通。例如我們可能會引入一個可訪問性的功能來放大博文的字號,同時讓頁面的其它部分保持默認的字號。在其父組件中,可以通過添加一個 blogFontSize數據屬性來支持這個功能:
new Vue({ el:".event_area", data:{ blogs:[ {id:1,title:"文章標題1",content:"文章內容1..."}, {id:2,title:"文章標題2",content:"文章內容2..."}, {id:3,title:"文章標題3",content:"文章內容3..."}, ], blogFontSize:1 } })
它可以在模板中用來控制所有博文的字號:
v-bind:style="{fontSize:blogFontSize+'em'}"
接下來添加按鈕,點擊放大字體。當點擊這個按鈕時,需要告訴父級組件放大所有博文的文本。Vue 實例提供了一個自定義事件的系統來解決這個問題。父級組件可以像處理 native DOM (本地DOM)事件一樣通過 v-on
監聽子組件實例的任意事件:
v-on:add-size="blogFontSize+=0.1"
子組件可以通過調用內建的 $emit
方法 並傳入事件名稱來觸發這個事件
Vue.component('event-area',{ props:['blog'], template:`<div class="blog_show_area"> <p>標題:{{blog.title}}</p> <p>內容:{{blog.content}}</p> <button v-on:click="$emit('add-size')">放大字體</button> </div>` });
有了這個 v-on:add-size="blogFontSize += 0.1"
監聽器,父級組件就會接收該事件並更新 blogFontSize
的值。完整代碼
<div class="event_area"> <event-area v-for="blog in blogs" v-bind:key="blog.id" v-bind:blog="blog" v-bind:style="{fontSize:blogFontSize+'em'}" v-on:add-size="blogFontSize+=0.1" ></event-area> </div> <style type="text/css"> .blog_show_area{ padding: 20px; background-color: rgba(0,0,0,.3); border: 1px solid red; margin: 10px; } </style> Vue.component('event-area',{ props:['blog'], template:`<div class="blog_show_area"> <p>標題:{{blog.title}}</p> <p>內容:{{blog.content}}</p> <button v-on:click="$emit('add-size')">放大字體</button> </div>` }); new Vue({ el:".event_area", data:{ blogs:[ {id:1,title:"文章標題1",content:"文章內容1..."}, {id:2,title:"文章標題2",content:"文章內容2..."}, {id:3,title:"文章標題3",content:"文章內容3..."}, ], blogFontSize:1 } })
(1)事件名
不同於組件和 prop,事件名不存在任何自動化的大小寫轉換。而是觸發的事件名需要完全匹配監聽這個事件所用的名稱。舉個例子,如果觸發一個 addSize名字的事件:
組件template里: <button v-on:click="$emit('addSize')">放大字體</button>
則監聽這個名字的 kebab-case (短橫線隔開式)版本是不會有任何效果。
<event-area v-for="blog in blogs" v-bind:key="blog.id" v-bind:blog="blog" v-bind:style="{fontSize:blogFontSize+'em'}" v-on:add-size="blogFontSize+=0.1" ></event-area>
<!--沒有效果-->
不同於組件和 prop,事件名不會被用作一個 JavaScript 變量名或屬性名,所以就沒有理由使用 camelCase 或 PascalCase 了。並且 v-on
事件監聽器在 DOM 模板中會被自動轉換為全小寫 (因為 HTML 是大小寫不敏感的),所以 v-on:myEvent
將會變成 v-on:myevent
——導致 myEvent
不可能被監聽到。因此,推薦始終使用 kebab-case 的事件名。
測試:這里使用PascalCase (小駝峰式)版本命名調用
父級組件: v-on:addSize="blogFontSize+=0.1" 子級模板中: <button v-on:click="$emit('addSize')">放大字體</button>
此時,控制台輸出警告
翻譯:
請注意,HTML屬性不區分大小寫,並且在使用in-DOM模板時不能使用v-on來偵聽camelCase事件。 您應該使用“add-size”而不是“addSize”。
(2)自定義組件的v-model(待驗證)
(3)將原生事件綁定到組件(待驗證)
(4).sync修飾符(待驗證)
.