vue鼠标事件mouseenter 一直执行 mouseleave执行异常

<template>
  <div class="box_wrap">
    <table ref="box">
      <tr>
        <th>我是标题</th>
        <th>我是标题1</th>
        <th>我是标题2</th>
        <th>我是标题3</th>
      </tr>
      <tr v-for="(data, index) in tableData" :key="index + Math.random() * 32">
        <td
          v-for="(item, key) in data"
          :key='key + Math.random() * 32'
          style="cursor: pointer"
          @mouseenter="handleEnter"
          @mousemove="handleMove"
          @mouseleave="handleLeave">{{item}}</td>
      </tr>
    </table>
    <div class="box_follow" v-show="show" :style="{left: position.x, top: position.y}">hahah</div>
  </div>
</template>

<script>

export default {
  components: {
  
  },
  data() {
    return {
      show: false,
      tableData: [
        {
          name: 1,
          value: 12121,
          dd: 121,
          tt: 233
        },
        {
          name: 2,
          value: 456541,
          dd: 121,
          tt: 233
        },
        {
          name: 3,
          value: 789985,
          dd: 121,
          tt: 233
        },
        {
          name: 4,
          value: 4564561,
          dd: 121,
          tt: 233
        }
      ],
      position: {
        x: 0,
        y: 0
      }
    }
  },
  mounted() {
    
  },
  methods: {
    handleEnter(e) {
      this.show = true
      this.setPosition(e)
      console.log('I am enter hahhhh')
    },
    handleMove(e) {
      this.setPosition(e)
      console.log('I am move xixxxxx')
    },
    handleLeave(e) {
      this.show = false
      this.setPosition(e)
      console.log('I am leave geggggg')
    },
    setPosition(e) {
      const position = this.$refs['box'].getBoundingClientRect()
      const x = e.clientX - position.left - 25 + 'px'
      const y = e.clientY - position.top + 50 + 'px'

      Object.assign(this.position, { x, y })
    }
  }
}
</script>

<style>
.box_wrap {
  position: relative;
}

.box {
  width: 100px;
  height: 100px;
  background: green;
}

.box_follow {
  position: absolute;
  width: 50px;
  height: 50px;
  background: red;
}
</style>

以上的代码,mouseenter一直在执行,mouseleave又可能不执行,但是如果你不进行双向绑定(把this.show和this.setPosition注释掉)就正常执行,找了很久Bug,还没想出来为啥,请大佬救火。。。

阅读 6.8k
2 个回答

原因在于你tr和td的动态key
每次页面重绘的时候, 这两个key都会重新随机而发生变化, vue就会强制重新绑定事件
所以key不要用随机数

先确认下box_follow的显示隐藏是否遮挡或是影响事件触发td的位置?
mouseleave是在你鼠标指针从dom上移出触发,你要是被出现的其他元素遮挡,或因为代码原因导致该dom移动到不在鼠标范围的位置,是不触发这个事件的
一劳永逸的解决方案也简单,直接监听documentmousemove判定target是不是组件内的td进行相应处理即可

推荐问题