You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue子组件emit传值父组件收到PointerEvent对象问题排查

问题根因

  1. 事件监听对象错误:父组件没有监听子Button抛出的自定义click事件,反而在自身根DOM节点上绑定了原生click事件,点击子组件时事件冒泡触发该原生事件,接收到的参数自然是原生PointerEvent对象,而非子组件传递的宽度数据
  2. 子组件模板语法错误:<div class="button @click="click" ref="button"> 中class属性缺少闭合引号,会导致模板解析异常
  3. 自定义事件命名歧义:自定义事件使用原生DOM事件名click,容易和原生事件混淆引发逻辑异常
  4. 父组件模板语法错误:插槽未用<slot/>标签声明,slider节点未闭合

修复方案

第一步:修改子组件(Button)

<template>
  <!-- 补全class属性闭合引号 -->
  <div class="button" @click="handleClick" ref="button"> 
    <slot />
  </div>
</template>

<script>
import { ref } from 'vue'
export default {
  name: 'Button',
  // 自定义事件名改为非原生事件名避免歧义,同时传递滑块需要的left和width两个参数
  emits: ['tab-click'],
  data () {
    return {
      width: '',
      left: ''
    }
  },
  setup() {
    const button = ref(null)
    return {
      button
    }
  },
  mounted () {
    this.$nextTick(() => {
      this.left = Math.ceil(this.button.getBoundingClientRect().left)
      this.width = Math.ceil(this.button.getBoundingClientRect().width)
    })
  },
  methods: {
    handleClick () {
      this.$emit('tab-click', { width: this.width, left: this.left })
      console.log(`${this.width} has been emitted to the tabs component`)
    }
  }
}
</script>

第二步:修改父组件(Tabs)

<template>
  <div class="tabs">
    <!-- 正确声明插槽 -->
    <slot/>
  </div>
  <!-- 补全slider闭合标签,style绑定接收完整的样式对象 -->
  <div class="slider" :style="sliderStyle"></div>
</template>

<script>
import Button from './Button.vue'

export default {
  name: 'Tabs',
  components: {
   Button
  },
  data () {
    return {
      // 调整为样式对象,支持同时设置宽度和偏移量
      sliderStyle: {
        width: '0px',
        left: '0px'
      }
    }
  },
  methods: {
    updateSlider ({ width, left }) {
      // 拼接合法的CSS样式值
      this.sliderStyle = {
        width: `${width}px`,
        left: `${left}px`
      }
      console.log(`${width} has been received and assigned by parent`)
    }
  }
}
</script>

第三步:调用时绑定自定义事件

在使用Tabs组件的页面,给每个插入的Button绑定tab-click事件即可:

<Tabs>
  <Button @tab-click="updateSlider">标签1</Button>
  <Button @tab-click="updateSlider">标签2</Button>
  <Button @tab-click="updateSlider">标签3</Button>
</Tabs>

内容的提问来源于stack exchange,提问作者Chelsey Machin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 06:06:02