这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助

一.@click和@click.native的区别

vue @click.native 原生点击事件:

1,给vue组件绑定事件时候,必须加上native ,不然不会生效(监听根元素的原生事件,使用 .native 修饰符)

2,等同于在子组件中:

子组件内部处理click事件然后向外发送click事件:$emit("click".fn)

不多说看代码:

直接在封装组件上使用@click,看看有什么效果

封装组件wrap-component.vue

 <template>
   <button>封装组件的点击事件</button>
 </template>
 ​
 <script>
 export default {
   name: 'wrapComponent'
 }
 </script>
 ​
 <style>
 ​
 </style>

使用封装组件HomeView.vue

 <template>
   <div class="home">
     <h2>父组件</h2>
 ​
     <wrap-component @click="handleClick"></wrap-component>
   </div>
 </template>
 ​
 <script>
 import wrapComponent from '@/components/wrap-component.vue'
 ​
 export default {
   name: 'HomeView',
   components: {
     wrapComponent
  },
   methods: {
     handleClick () {
       console.log('点击了封装组件的按钮')
    }
  }
 }
 </script>
 ​

页面效果

点击按钮,控制台并没有打印内容

当我们给封装组件中的按钮添加点击事件

 <template>
   <button @click="handleClick">封装组件的点击事件</button>
 </template>
 ​
 <script>
 export default {
   name: 'wrapComponent',
   methods: {
     handleClick () {
       this.$emit('click')
    }
  }
 }
 </script>
 ​
 <style>
 ​
 </style>

页面效果

发现控制台打印了内容,说明触发了封装组件内部的按钮的点击事件

当我们使用@click.native呢?

封装组件wrap-component.vue

 <template>
   <button>封装组件的点击事件</button>
 </template>
 ​
 <script>
 export default {
   name: 'wrapComponent'
 }
 </script>
 ​
 <style>
 ​
 </style>

使用封装组件HomeView.vue

 <template>
   <div class="home">
     <h2>父组件</h2>
 ​
     <wrap-component @click.native="handleClick"></wrap-component>
   </div>
 </template>
 ​
 <script>
 import wrapComponent from '@/components/wrap-component.vue'
 ​
 export default {
   name: 'HomeView',
   components: {
     wrapComponent
  },
   methods: {
     handleClick () {
       console.log('点击了封装组件的按钮')
    }
  }
 }
 </script>
 ​

页面效果

也打印了内容,说明与上面通过子组件$emit出来一样。

那可以把@click.native当作是上面$emit的简写吗?

当我们给封装组件添加其他内容呢?

封装组件wrap-component.vue

 <template>
   <div>
     <button>封装组件的点击事件</button>
     <ul>
       <li>测试</li>
       <li>测试</li>
       <li>测试</li>
       <li>测试</li>
     </ul>
   </div>
 </template>
 ​
 <script>
 export default {
   name: 'wrapComponent',
   methods: {
  }
 }
 </script>
 ​
 <style>
 ​
 </style>
 ​

页面效果:

点击封装组件的任意一个区域都可以打印内容。

说明@click.native并不是通过$emit方式的简写,在只有单个元素点击事件的情况下可以当作是。

native就是把组件变回原生DOM的一种方式,相当于给组件绑定原生事件

特别说明

针对vue-element-ui中的el-button

 //这个库已经在某些地方把原生的click做了处理了,因为不使用native,照常成功
 <el-button type="primary" @click="handleLogin">Sign in</el-button>

二.其他修饰符

在事件处理器中可以使用event.preventDefault()(阻止原生事件), event.stopPropagation()(阻止事件冒泡)。 vue.js为 v-on 提供两个 事件修饰符:.prevent 与 .stop,让html就可以实现这两个功能,不需要再在js中单独写

 <!-- 阻止单击事件继续传播 -->
 <a v-on:click.stop="doThis"></a>
 ​
 <!-- 提交事件不再重载页面 -->
 <form v-on:submit.prevent="onSubmit"></form>
 ​
 <!-- 修饰符可以串联 -->
 <a v-on:click.stop.prevent="doThat"></a>
 ​
 <!-- 添加事件监听器时使用事件捕获模式 -->
 <!-- 即元素自身触发的事件先在此处理,然后才交由内部元素进行处理 -->
 <div v-on:click.capture="doThis">...</div>
 ​
 <!-- 只当在 event.target 是当前元素自身时触发处理函数 -->
 <!-- 即事件不是从内部元素触发的 -->
 <div v-on:click.self="doThat">...</div>

使用修饰符时,顺序很重要;相应的代码会以同样的顺序产生。因此,

用 v-on:click.prevent.self 会阻止所有的点击,

而 v-on:click.self.prevent 只会阻止对元素自身的点击

 <!-- 点击事件将只会触发一次 -->
 <a v-on:click.once="doThis"></a>
 ​
 <!-- 不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上,该处理函数只会触发一次 -->
 <wrap-component @click.native.once="clickTree"></wrap-component>

不像其它只能对原生的 DOM 事件起作用的修饰符,.once 修饰符还能被用到自定义的组件事件上。

Vue 还对应 addEventListener 中的 passive 选项提供了 .passive 修饰符。

 <!-- 滚动事件的默认行为 (即滚动行为) 将会立即触发 -->
 <!-- 而不会等待 `onScroll` 完成 -->
 <!-- 这其中包含 `event.preventDefault()` 的情况 -->
 <div v-on:scroll.passive="onScroll">...</div>

这个 .passive 修饰符尤其能够提升移动端的性能。

不要把 .passive.prevent 一起使用,因为 .prevent 将会被忽略,同时浏览器可能会向你展示一个警告。请记住,.passive 会告诉浏览器你不想阻止事件的默认行为。

使用@click.native.stop来阻止第三方组件的点击事件

场景

在父组件中有一个点击事件,但是在父组件内部又使用其他三方组件,因为是第三方组件所以不能通过在第三方组件内部通过@click.stop的方式来阻止冒泡。现在希望的情况就是,在点击第三方组件封装的点击事件的时候,不想让其冒泡其父组件,触发父组件的点击事件。

场景代码

父组件HomeView.vue

 <template>
   <div class="home" @click="handleParentClick">
     <h2>父组件</h2>
 ​
     <div>
       <wrap-component></wrap-component>
     </div>
   </div>
 </template>
 ​
 <script>
 import wrapComponent from '@/components/wrap-component.vue'
 ​
 export default {
   name: 'HomeView',
   components: {
     wrapComponent
  },
   methods: {
     handleParentClick () {
       console.log('触发了父组件的点击事件')
    }
  }
 }
 </script>

封装组件wrap-component.vue

 <template>
   <div @click="handleSonClick">
     <button>封装组件的点击事件</button>
     <ul>
       <li>测试</li>
       <li>测试</li>
       <li>测试</li>
       <li>测试</li>
     </ul>
   </div>
 </template>
 ​
 <script>
 export default {
   name: 'wrapComponent',
   methods: {
     handleSonClick () {
       console.log('触发了封装组件的点击事件')
    }
  }
 }
 </script>
 ​
 <style>
 ​
 </style>

页面效果

触发了封装组件的点击事件,也冒泡到了父组件,触发了父组件的点击事件

解决

在第一点的时候,介绍了native的作用,它把组件变回原生DOM的一种方式,相当于给组件绑定原生事件,那我们可以直接在组件上使用@click.native.stop来阻止第三方组件内部点击事件的冒泡吗?

父组件HomeView.vue

 <template>
   <div class="home" @click="handleParentClick">
     <h2>父组件</h2>
 ​
     <div>
       <wrap-component @click.native.stop></wrap-component>
     </div>
   </div>
 </template>
 ​
 <script>
 import wrapComponent from '@/components/wrap-component.vue'
 ​
 export default {
   name: 'HomeView',
   components: {
     wrapComponent
  },
   methods: {
     handleParentClick () {
       console.log('触发了父组件的点击事件')
    }
  }
 }
 </script>
 ​

果然是可以的

扩展

一个组件的话可以通过上面描述的方式来解决,如果父组件有多个第三方组件呢,难道要给每个组件添加@click.native.stop吗?如果不闲麻烦的话,当然是可以的。

也有更加简便的方法

父组件HomeView.vue

 <template>
   <div class="home" @click="handleParentClick">
     <h2>父组件</h2>
 ​
     <div @click.stop>
       <wrap-component></wrap-component>
       <wrap-demo></wrap-demo>
     </div>
   </div>
 </template>
 ​
 <script>
 import wrapComponent from '@/components/wrap-component.vue'
 import wrapDemo from '@/components/wrap-demo.vue'
 ​
 export default {
   name: 'HomeView',
   components: {
     wrapComponent,
     wrapDemo
  },
   methods: {
     handleParentClick () {
       console.log('触发了父组件的点击事件')
    }
  }
 }
 </script>
 ​

把使用第三方组件统一包裹起来,对其div使用@click.stop来阻止冒泡

总结

  1. @click.native就是把组件变回原生DOM的一种方式,相当于给组件绑定原生点击事件。
  2. 可以通过这个机制来阻止第三方组件内部封装的冒泡
  3. 如果是直接绑定在原生的div之类的元素上的话,是不需要使用.native的,通常只需要用其他几个后缀。
  4. .native是用来阻止原生的dom事件,一般想要阻止组件内原生的dom事件就需要用.native搭配其他后缀来实现
  5. @click.stop阻止组件$emit的click事件
  6. @click.native.stop阻止组件内原生的dom的click事件

本文转载于:

https://juejin.cn/post/7274883755478335546

如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。

记录--@click和@click.native有什么区别,如何阻止第三方组件内部的冒泡的更多相关文章

  1. React Native学习-控制横竖屏第三方组件:react-native-orientation

    在项目中,有时候可能会想使不同的页面显示的横竖屏也不一样,比如前一段我做的<广播体操>的项目,在首页面,肯定是想使页面为竖屏显示,但是播放页面要为横屏显示,即使用户的手机可以转屏,我们的播 ...

  2. C#中四步轻松使用log4net记录本地日志(WPF有点小区别)

    在这里,记录我在项目中使用log4net记录本地日志的步骤.在不会之前感觉很难,很神秘,一旦会了之后其实没那么难.其实所有的事情都是一样的,下面我就分享一下我使用log4Net的经验. 第一步:首先从 ...

  3. ES 入门记录之 match和term查询的区别

    ElasticSearch 系列文章 1 ES 入门之一 安装ElasticSearcha 2 ES 记录之如何创建一个索引映射 3 ElasticSearch 学习记录之Text keyword 两 ...

  4. H5与native有啥区别?

    app测试,H5与native有啥区别? native是使用原生系统内核的,相当于直接在系统上操作.是我们传统意义上的软件,更加稳定. 但是H5的APP先得调用系统的浏览器内核,相当于是在网页中进行操 ...

  5. gulp die('click').live('click' composer

    gulp  die('click').live('click' composer packagist.org https://getcomposer.org/ 下载后 php composer.pha ...

  6. react native 第三方组件

    react native 的成功离不开优秀的第三方组件,以下是我见过的一些优秀或者有用的RN第三方组件 按钮 APSL/react-native-button 导航 react-native-simp ...

  7. React Native常用第三方组件汇总--史上最全 之一

    React Native 项目常用第三方组件汇总: react-native-animatable 动画 react-native-carousel 轮播 react-native-countdown ...

  8. React Native常用第三方组件汇总--史上最全[转]

    本文出处: http://blog.csdn.net/chichengjunma/article/details/52920137 React Native 项目常用第三方组件汇总: react-na ...

  9. React Native 项目常用第三方组件汇总

    React Native 项目常用第三方组件汇总 https://www.jianshu.com/p/d9cd9a868764?utm_campaign=maleskine&utm_conte ...

  10. fastclick与zepto的 tap事件关于在手机上click事件的300ms延迟的区别

    之前翻译过一篇关于fastclick的快速点击文章http://www.cnblogs.com/lilyimage/p/3568773.html,fastclick可以解决在手机上点击事件的300ms ...

随机推荐

  1. 一份55页Java性能调优PPT分享

    提起"肖桦"这个人,相信很多小伙伴对他比较陌生.除去现任唯品会资深技术专家头衔外,他更为技术圈所熟知的是他的著名开源项目:SpringSide. SpringSide是以sprin ...

  2. JS Leetcode 852. 山脉数组的峰顶索引图解分析,高高的山峰一起吹山风吧。

    壹 ❀ 引 本题来自LeetCode 852. 山脉数组的峰顶索引,难度依旧是简单,也是一道考二分法的题目,题目描述如下: 符合下列属性的数组 arr 称为 山脉数组 : arr.length > ...

  3. 使用yum 报错 :This system is not registered with RHN

    解决办法:(假定你已安装yum,且网络畅通)更改yum的源, 即更换/etc/yum.repos.d/rhel-debuginfo.repo 这个文件.首先备份,如下所示: [root@localho ...

  4. mysql存储过程实战

    今天科比离去,今天肺炎病毒持续肆虐... 意识到生命的脆弱,今天我继续前行,比以往更加坚定和紧迫,这辈子不活好自己就算白来一趟. 最近需要用到mysql存储过程去处理一些表数据,然后利用java po ...

  5. JS实现提示文本框可输入剩余字数

    最近在设计写博客功能时,涉及到留言框输入字数限制,需要给用户剩余数字提示. 参考文章:https://www.cnblogs.com/crazytrip/p/4968230.html 实现效果: 源码 ...

  6. 构建SatelliteRpc:基于Kestrel的RPC框架(整体设计篇)

    背景 之前在.NET 性能优化群内交流时,我们发现很多朋友对于高性能网络框架有需求,需要创建自己的消息服务器.游戏服务器或者物联网网关.但是大多数小伙伴只知道 DotNetty,虽然 DotNetty ...

  7. 【LeetCode回溯算法#03】电话号码的字母组合(数字映射字母)

    电话号码的字母组合 力扣题目链接(opens new window) 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合. 给出数字到字母的映射如下(与电话按键相同).注意 1 不对应任 ...

  8. Javascript之Object、Array

    Object.keys 对象的键转化为数组 Object.values 对象的属性值转化为数组 Object.assign 对象的合并   Array.from() 伪数组对象的属性值转化为数组.类似 ...

  9. 【Azure 服务总线】如何批量删除Azure Service Bus中的Topics(数量较多,需要过滤后批量删除)

    问题描述 Azure Service Bus 的门户操作页面上,是否可以批量删除其中的Topics呢? 问题解答 Azure Service Bus门户或Service Bus Explorer工具没 ...

  10. 【Azure 应用服务】当在Azure App Service的门户上 Log Stream 日志无输出,需要如何操作让其输出Application Logs呢?

    问题描述 在Azure App Service的门户上 Log Stream 日志无输出,需要如何操作让其输出Application Logs呢? 如下图所示: 问题解答 请注意,上图中提示说:App ...