一、當組件的根元素不具備一些DOM事件,但是根元素內部元素具備相對應的DOM事件,那么可以使用$listeners獲取父組件傳遞進來的所有事件函數,再通過v-on="xxxx"綁定到相對應的內部元素上即可。
注意:使用.native修飾符的事件,不會體現在$listeners屬性上。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="Generator" content="EditPlus®">
<meta name="Author" content="">
<meta name="Keywords" content="">
<meta name="Description" content="">
<title>vue測試</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.22/dist/vue.js"></script>
<style>
</style>
</head>
<body>
<div id="app">
<base-input
v-model="username"
label="基礎輸入組件"
@click.native="handleBaseInputClick"
v-on:focus="handleBaseInputFocus"
placeholder="請輸入您的名字"
class="username-input"/>
</div>
<script>
// 注冊組件
// 因為base-input的外層是一個label元素,所以默認情況下使用v-on:focus是無效的,所以需要配合$listeners使用,該屬性可以把事件的監聽指向組件中某個特定的元素
// 注意:如果父級的事件添加了.native修飾符,在$listeners中不會體現出來的
Vue.component('base-input',{
inheritAttrs: false,
props: ['label','value'],
template: `
<label id="base-label">
{{label}}
<input v-bind:value="value" v-bind="$attrs" v-on="inputListeners"/>
</label>
`,
data: function() {
return {
}
},
computed: { inputListeners () { var vm = this
return Object.assign({},
this.$listeners,
{
input: function () {
vm.$emit('input', event.target.value)
},
focus: function (event) {
vm.$emit('focus', '哈哈哈,onfocus了') } } ) } },
mounted: function(){
console.log(`$attrs:`)
console.log(this.$attrs)
console.log(`$listeners:`)
console.log(this.$listeners) // 父級添加的所有屬性都在這里
},
methods: {
}
})
var vm = new Vue({
el: '#app',
data: {
username: ''
},
created: function(){
},
beforeUpdate: function(){
},
computed: {
},
beforeUpdate: function () {
console.log(this.username)
},
methods: {
handleBaseInputFocus: function(ev){
console.log(ev)
},
handleBaseInputClick: function(ev){
console.log(ev.type)
}
}
})
</script>
</body>
</html>
