将原生事件绑定到组件
在我们的自定义组件中使用原生事件绑定
一般情况下,我们在自定义的组件中绑定原生事件是触发不了的,因为我们自定义的组件它并不是原生html里面的标签,所以直接绑定事件是不好用的。将原生事件绑定到自定义组件一共有三种方式:
- 使用 v-on 的 .native 修饰符
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app">
<my-button @click.native="btnClick"></my-button>
</div>
<script>
Vue.component("my-button", {
template:`<button>我是按钮</button>`
});
let app = new Vue({
el: "#app",
data: {},
methods: {
btnClick() {
console.log("我执行了么");
},
},
});
</script>
</body>
</html>
如果在父组件里面的点击事件不加.native修饰符,btnClick点击事件是不会触发的,加上.native修饰符就可以触发点击事件。但是这种方法有一定的局限性,那就是.native是在自定义组件的根元素上面加原生的事件,如果自定义组件的根元素不是目标元素,那么就算用.native事件也是无效的。
例如下面的例子:
<!DOCTYPE html>
<html lang="en">
<body>
<div id="app">
<my-input @focus.native="btnFocus"></my-input>
</div>
<script>
Vue.component("my-input", {
template: `
<label>
<input type="text" />
</label>
`,
});
let app = new Vue({
el: "#app",
data: {},
methods: {
btnFocus() {
console.log("我执行了么");
},
},
});
</script>
</body>
</html>
为什么当input输入框聚焦的时候btnFocus不会执行呢? 以上代码我们可以看到自定义子组件的template里面的根标签是label,上面我们说.native是把元素加到自定义组件的根元素上面,我们这样相当于给label标签加上focus事件,但是此标签并没有聚焦事件,所以无效。
- 第二种方法就是我们常用的子组件发射事件$emit
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.jsdelivr.net/npm/vue@2"></script>
<title>Document</title>
</head>
<body>
<div id="app">
<my-input @my-input="inputText"></my-input>
</div>
<script>
Vue.component("my-input", {
template: `
<label>
<input type="text" @focus='$emit("my-input","我是参数")' />
</label>
`,
});
let app = new Vue({
el: "#app",
data: {},
methods: {
inputText(value){
console.log('我的参数是'+value);
}
},
});
</script>
</body>
</html>
这事我们常用的父子组件通信的方式,在emit发放事件的时候一定要注意,自定义事件名的规则!!!
规则:v-on 事件监听器在 DOM 模板中会被自动转换为全小写 (因为 HTML 是大小写不敏感的),所以 v-on:myEvent 将会变成 v-on:myevent——导致 myEvent 不可能被监听到。因此,我们推荐你始终使用 kebab-case 的事件名,就是中间用横线隔开。这个一定要注意!!!!!
参考文章: