返回顶部
首页 > 资讯 > 前端开发 > node.js >vue组件间怎么实现事件传递
  • 815
分享到

vue组件间怎么实现事件传递

2024-04-02 19:04:59 815人浏览 泡泡鱼
摘要

Vue组件间怎么实现事件传递,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。由于新工作需要用vue,所以最近接触最多的也是vue,因为之前一

Vue组件间怎么实现事件传递,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

由于新工作需要用vue,所以最近接触最多的也是vue,因为之前一直在用React,所以对于vue上手还是很快的。

我也尽量找一些他们两个的异同点,除了多了一些辅助用的方法以外,最大的不同应该是对于组件间的通信,不仅有props,还有一种事件监听,也是可以通过组件间传递的。

但是,在vue2.+中,vue引入了diff算法和虚拟dom来提升效率。我们知道这些事为了处理频繁更新dom元素所提出的一种优化方案,可频繁变动更新以及事件监听的初始化之间是否会有矛盾,当组件需要变动时,有没有对注册过的事件进行解绑? 我们来写一些简单的代码印证一下。

我们写两个div做的按钮,一个是写的html代码,一个是通过组件的形式插入,两个按钮完全一样,但我们加一个disabled的属性在外层,并通过if-else来判断disabled从而显示不同的按钮(当然正常场景下我们不会这么去写代码,这里只是通过这种方式模拟一种特殊场景,我们自行考虑在我们的业务中是否存在这种场景)。

<template>
 <div class="test">
 <div class="btn" v-if="disabled" @click="handleClick">可点击</div>
 <div class="btn" v-else >不可点击</div>
 <Button v-if="disabled" @clickTest="handleClick">可点击</Button>
 <Button v-else>不可点击</Button>
 </div>
</template>

<script>
import Button from './Button'
export default {
 data () {
 return {
  disabled: true
 }
 },
 methods: {
 handleClick() {
  alert('可点击')
 }
 },
 components: {
 Button,
 },
 mounted() {
 setTimeout(() => {
  this.disabled = false
 }, 1000)
 }
}
</script>
<style>
.btn{
 margin: 100px auto;
 width: 200px;
 line-height: 50px;
 border: 1px solid #42b983;
 border-radius: 5px;
 color: #42b983;
}
</style>

我们加一点样式,让他尽量好看一点,看着很简单,两个按钮,可点击时为他绑定一个点击事件,不可点击时不为他绑定。不同点是一个是直接写的html代码,一个是组件。组件的代码如下:

<template>
 <div class="btn" @click="handleClick"><slot></slot></div>
</template>
<script>
 export default {
  methods: {
   handleClick() {
    this.$emit('clickTest')
   }
  }
 }
</script>

然后在mounted周期里加一个1秒的settimeout将disabled变为false,然后我们测试一下

vue组件间怎么实现事件传递

vue组件间怎么实现事件传递

当disabled还是true得时候,两个按钮点击都会弹出可点击的alert。但当disebled变为false的时候,上面用html写的不会再弹框,可下面用组件写的就还是会弹窗。

vue组件间怎么实现事件传递

这种问题出现时是非常不好定位的,因为代码上很显然不会去调取这个clicktest事件,而在页面上,我们也能确定按钮已经变为不可点击的那一个了。那为什么这个事件还是会被调取呢?

这先要从diff算法说起,传统的diff tree算法的算法复杂度是O(n^3),而react在引入diff算法时,抛除了跨级移动的情况,即只比对同一级的节点异同,让算法复杂度降低到了O(n),让我们可以肆无忌惮(当然也要适可而止)的频繁刷新整个页面。

(呵呵,没图)

diff有一条策略是拥有相同类的两个组件将会生成相似的树形结构,拥有不同类的两个组件将会生成不同的树形结构。所以它的比对顺序就是

1)tree diff

2)component diff

3)element diff

回到我们的代码上,我们在进行component diff时,认为他们是相同的组件,然后进行element diff,即进行新增 删除和移动所以问题就是发生在了这里,在实例化组件的时候我们初始化了事件监听,但在替换相同组件里的dom时,vue并没有对已添加到组件上的事件监听做删除。

我们看一下vue的代码,

Vue.prototype.$emit = function (event: string): Component {
 const vm: Component = this
 if (process.env.node_ENV !== 'production') {
  const lowerCaseEvent = event.toLowerCase()
  if (lowerCaseEvent !== event && vm._events[lowerCaseEvent]) {
  tip(
   `Event "${lowerCaseEvent}" is emitted in component ` +
   `${fORMatComponentName(vm)} but the handler is reGIStered for "${event}". ` +
   `Note that HTML attributes are case-insensitive and you cannot use ` +
   `v-on to listen to camelCase events when using in-DOM templates. ` +
   `You should probably use "${hyphenate(event)}" instead of "${event}".`
  )
  }
 }
 let cbs = vm._events[event]
 if (cbs) {
  cbs = cbs.length > 1 ? toArray(cbs) : cbs
  const args = toArray(arguments, 1)
  for (let i = 0, l = cbs.length; i < l; i++) {
  try {
   cbs[i].apply(vm, args)
  } catch (e) {
   handleError(e, vm, `event handler for "${event}"`)
  }
  }
 }
 return vm
 }

vue是通过vdom里的_events属性下确定是否有绑定事件的。我们看一下不可点击的按钮的_events

:
clickTest
:
Array(1)
0
:
ƒ invoker()
length
:

发现clicktest还在。这就是问题所在了。

那么我们该如何去回避这样的问题呢,还是应从diff的比对方式来解决问题,还是看代码。

function sameVnode (a, b) {
 return (
 a.key === b.key && (
  (
  a.tag === b.tag &&
  a.isComment === b.isComment &&
  isDef(a.data) === isDef(b.data) &&
  sameInputType(a, b)
  ) || (
  isTrue(a.isAsyncPlaceholder) &&
  a.asyncFactory === b.asyncFactory &&
  isUndef(b.asyncFactory.error)
  )
 )
 )
}

也就是对diff来说,所谓相同的第一判定原则是key。

key也是react引入diff时添加的一个属性,用来判断前后vdom树上是否为统一元素(注意是同级关系上),所以我们只需要在代码上加key,就可以避免这个问题

<Button key="1" v-if="disabled" @clickTest="handleClick">可点击</Button>
<Button key="2" v-else>不可点击</Button>

这样,我们在点击按钮时,就不会再出弹框了。

key的作用很广泛,当我们在遍历数组生成dom时,添加一个可确定的唯一id(注意不应该用数组索引),会优化我们的比对效率以及更少的操作dom。我们也会在某个div上添加key以确保他不会因为兄弟元素的变动而被重新渲染(这类div一般会被绑定react或vue以外的事件或动作,如在这个div中生成了一个canvas等)。

那么除了在组件上加这种不必要key值以外,还有别的方法解决吗?

有的,这里有一种很反vue但是类react的方式,就是把回调事件通过props的方式传递,向下面着这样,

<Button v-if="disabled" :clickTest="handleClick">可点击</Button>
<Button v-else>不可点击</Button>
  props: {
   'clickTest': {
    type: Function
   }
  },
  methods: {
   handleClick() {
    //this.$emit('clickTest')
    this.clickTest && this.clickTest()
   }
  }

虽然vue给了我们更方便的事件传递的方式,但props里是允许我们去传递任何类型的,我的期望是在真实的dom上或者在公共组件的入口处以外的地方,都是通过props的方式来传递结果的。虽然这种方式很不vue,而且也享受不到v-on给我们带来的遍历,但是这样确实可以减少不必要的麻烦。

当然既然用了vue,更好的利用vue给我们带来的便利也很重要,所以对于这种很少会出现的麻烦,我们有一个预期,并可以快速定位并修复问题,就可以了。

关于vue组件间怎么实现事件传递问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注编程网node.js频道了解更多相关知识。

--结束END--

本文标题: vue组件间怎么实现事件传递

本文链接: https://lsjlt.com/news/72294.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • vue组件间怎么实现事件传递
    vue组件间怎么实现事件传递,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。由于新工作需要用vue,所以最近接触最多的也是vue,因为之前一...
    99+
    2024-04-02
  • vue中怎么实现组件间参数传递
    vue中怎么实现组件间参数传递,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。举例说明例如:element-ui组件库中使用switch开关...
    99+
    2024-04-02
  • 如何用vue实现组件间参数传递
    这篇文章主要介绍“如何用vue实现组件间参数传递”,在日常操作中,相信很多人在如何用vue实现组件间参数传递问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何用vue实现组件间参数传递”的疑惑有所帮助!接下来...
    99+
    2023-07-04
  • vue中怎么实现子组件传递数据给父组件
    本篇文章为大家展示了vue中怎么实现子组件传递数据给父组件,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。发送者:modifyName:是接受者的键,也就是发送和接收...
    99+
    2024-04-02
  • vue组件间数据传递实现的方法是什么
    本篇内容主要讲解“vue组件间数据传递实现的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue组件间数据传递实现的方法是什么”吧!(1)props属性:在父组件中,可以通过子组件标签...
    99+
    2023-07-04
  • vue如何实现属性事件传递
    这篇文章给大家分享的是有关vue如何实现属性事件传递的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。属性事件传递写过高阶组件的童鞋可能都会碰到过将加工过的属性向下传递的情况,如果碰...
    99+
    2024-04-02
  • vue中怎么实现父组件向子组件传递多个数据
    本篇文章为大家展示了vue中怎么实现父组件向子组件传递多个数据,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。第一种:静态数据传递:传递一个 字符串第二种:动态数据传...
    99+
    2024-04-02
  • Vue父子组件之间事件通信怎么实现
    这篇“Vue父子组件之间事件通信怎么实现”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Vue父子组件之间事件通信怎么实现”文...
    99+
    2023-07-05
  • vue中怎么实现父子组件间传值
    今天就跟大家聊聊有关vue中怎么实现父子组件间传值,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。先定义一个子组件,在组件中注册props<te...
    99+
    2024-04-02
  • vue组件中如何实现数据传递
    这篇文章给大家分享的是有关vue组件中如何实现数据传递的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。具体如下:1、props:父组件 -->传值到子组件app.vue是父组...
    99+
    2024-04-02
  • vue子组件中怎么通过自定义事件向父组件传递数据
    这篇文章将为大家详细讲解有关vue子组件中怎么通过自定义事件向父组件传递数据,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。使用v-on绑定自定义事件可以让子...
    99+
    2024-04-02
  • vue中怎么使用eventbus实现组件间传值
    这期内容当中小编将会给大家带来有关vue中怎么使用eventbus实现组件间传值,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。当然,使用存储也是可以得,但是并非一定要缓存...
    99+
    2024-04-02
  • python文件间传递参数怎么实现
    在Python中,可以使用命令行参数、环境变量、文件等方式在不同的Python文件之间传递参数。1. 命令行参数:可以使用`sys....
    99+
    2023-09-27
    python
  • Vue组件间传值的实现解析
    目录1. 父组件向子组件传值1.1 描述1.2 props接收数据2. 子组件向父组件传值3. 兄弟组件间传值4. 事件总线5. Ref6. root/parent/children...
    99+
    2024-04-02
  • Vue父组件和子组件之间数据传递和方法怎么调用
    本篇内容主要讲解“Vue父组件和子组件之间数据传递和方法怎么调用”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Vue父组件和子组件之间数据传递和方法怎么调用”吧!vue组件在通信中,无论是子组件...
    99+
    2023-07-04
  • React中怎么实现父子组件传递
    React中怎么实现父子组件传递,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。React的组件生命周期react主要思想是构建可复用组件来构建...
    99+
    2024-04-02
  • vue中怎么实现组件传值
    这篇文章给大家分享的是有关vue中怎么实现组件传值的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。vue是什么Vue是一套用于构建用户界面的渐进式JavaScript框架,Vue与其它大型框架的区别是,使用Vue可...
    99+
    2023-06-14
  • android点击事件传递机制怎么实现
    Android的点击事件传递机制是通过View的dispatchTouchEvent方法和onTouchEvent方法实现的。首先,...
    99+
    2023-10-20
    android
  • vue 实现上传组件
    目录1.介绍2.思路文件上传的两种实现方式3.生命周期4.代码草稿5.具体实现1.介绍 效果如下图   2.思路 文件上传的两种实现方式 1.From形式 <...
    99+
    2024-04-02
  • vue如何实现兄弟组件的数据传递
    本篇内容介绍了“vue如何实现兄弟组件的数据传递”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在main.js里面设置data{eventH...
    99+
    2023-07-04
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作