vue_组件_监听组件事件
1.$emit 的使用
在組件中注冊自定義事件
$emit(事件名, 參數)? ? //該參數會當作第一個參數傳入綁定的函數中
下面用一個菜單欄例子來說明,如下圖所示
組件
Vue.component('menu-cmp', {//注冊propprops: {menu: Object,isActive: Boolean,menuIndex: Number},template: `<div><div class="first-menu"//注冊自定義事件,事件名為handle-second-menu,第二個參數則作為被綁定函數的第一個參數@click="$emit('handle-second-menu', {isActiev:menu.isActive,id:menuIndex})">{{menu.firstMenu}}</div><div v-show="menu.isActive" class="second-menu" v-for="secondMune in menu.secondMenuList">{{ secondMune }}</div></div>` })?
組件引用
<div id="app"><menu-cmp class="menu-list" v-for="(menu,menuIndex) in menuList" :menu='menu' :menu-index='menuIndex'@handle-second-menu="handleSecondMenu"> //給自定義事件綁定函數//注:這里的事件處理為函數handleSecondMenu,如果邏輯量少,無需函數處理,那么$emit的第二個參數可以通過$event訪問</menu-cmp> </div>Vue實例
const vm = new Vue({el: '#app',data: {menuList: [{firstMenu: '一級菜單1',secondMenuList: ['二級菜單1', '二級菜單2', '二級菜單3'],isActive: true,}, {firstMenu: '一級菜單2',secondMenuList: ['二級菜單1', '二級菜單2', '二級菜單3'],isActive: true,}, {firstMenu: '一級菜單3',secondMenuList: ['二級菜單1', '二級菜單2', '二級菜單3'],isActive: true,},]},methods: {handleSecondMenu(res) {//res是$emit()的第二個參數this.menuList[res.id].isActive = !this.menuList[res.id].isActive}} })css
.menu-list {width: 200px;height: 50px;text-align: center;display: inline-block;vertical-align: top;background-color: brown;box-sizing: border-box; } .menu-list:not(:last-of-type) {border-right: 1px solid #eee; } .menu-list .first-menu {width: 100%;height: 50px;line-height: 50px;box-sizing: border-box;border-bottom: 1px solid #eee; } .menu-list .second-menu {width: 100%;height: 50px;line-height: 50px; } .menu-list .second-menu.active {display: block; }2.事件名
不同于組件和prop:
另外,v-on事件監聽器在DOM模板中會被自動轉換為全小寫,所以@handleMenu 將會變為@handlemenu ,導致事件監聽失敗,因此,應當使用短橫線命名法。
3.修飾符.native _ 將原生事件綁定到組件
在組件上監聽事件時,監聽的是組件自動觸發的自定義事件,但是在一些情況下可能想要在一個組件的根元素上直接監聽一個原生事件。這時,可以用 v-on 指令的 .native 修飾符,如:
組件
Vue.component('my-input', {template:`<input type="text">` })組件引用
<div id="app"><my-input @focus.native="onFocus"></my-input> </div>Vue實例
const vm = new Vue({el:"#app",methods:{onFocus(){console.log('focus');}} })【結果】
4.$listeners
當<input>標簽不是組件的根元素,即包裹在其他標簽中時,父級的.native 監聽器將靜默失敗。雖然不會產生報錯,但是 onFocus 處理函數不會被調用。為了解決這個問題,Vue提供了一個 $listeners 屬性,它是一個對象,里面包含了作用在這個組件上所有的監聽器,有了這個 $linteners 屬性,我們可以配合 v-on="$linteners" 將所有的事件監聽器指向這個組件的某個特性的子元素,如:
組件
Vue.component('my-input', {template: `<label>姓名<input type="text" v-on="$listeners"></label>` })組件引用
<my-input @focus="onFocus"></my-input>5.在組件上使用v-model
由于自定義事件的出現,在組件上也可以使用 v-model 指令。
在 input 元素上使用 v-model 指令時,相當于綁定了 value 特性以及監聽了 input 事件
<input v-model="searchText" />等價于
<input:value="searchText"@input="searchText = $event.target.value" >當把 v-model 指令引用在組件上時
<base-input v-model="searchText" />等價于
<base-input:value="searchText"@input="searchText = $event" />同 input 元素一樣,在組件上使用 v-model 指令,也是綁定了 value 特性,監聽了 input 事件。所以 為了讓 v-model 指令正常工作,這個組件內的<input>元素必須滿足
組件
Vue.component('my-input',{props:['value'],template:`<input :value="value" @input="$emit('input',$event.target.value)">` })組件引用
<my-input v-model="searchText"></my-input>Vue實例
const vm = new Vue({el:"#app",data:{searchText:''} })【結果】
綜上所述,一個組件上的 v-model 默認會利用名為 value 的 prop 和名為 input 的事件,但是像單選框、復選框等類型的輸入控件可能會將 value 特性用于不用的目的。遇到這種情況,我們可以利用 model 選項來避免沖突:
組件
Vue.component('my-checkbox', {//model選項model: {prop: 'checked',event: 'change'},props: {checked: Boolean},template: `<input type="checkbox":checked="checked"@change="$emit('change',$event.target.checked)">` })組件引用
<my-checkbox v-model="isChecked"></my-checkbox>Vue實例
const vm = new Vue({el: "#app",data: {isChecked: ''} })【結果】
6. .sync修飾符(語法糖)
除了使用 v-model 指令實現組件與外部數據的雙向綁定外,還可以用 v-bind 指令的修飾符. sync 來實現
組件
Vue.component('my-input1',{props:['value'],template:`<input :value="value"@input="$emit('update:value',$event.target.value)">` })組件引用
<my-input1 :value.sync="searchText"></my-input1>Vue實例
const vm = new Vue({el:"#app",data:{searchText:''} })【注】當用一個對象同時設置多個 prop 時,也可以將 .sync 修飾符和 v-bind 配合使用
<base-input v-bind.sync="obj"></base-input>注意:
7.v-model VS .sync
總結
以上是生活随笔為你收集整理的vue_组件_监听组件事件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue_组件_非prop特性
- 下一篇: vue_组件插槽详述