防止 Mouseenter 在 Vue 3 中无序的链接列表中冒泡

Prevent Mouseenter bubbling in an unorderest list of links in Vue 3

提问人:Lowtrux 提问时间:1/16/2023 最后编辑:Nikola PavicevicLowtrux 更新时间:1/16/2023 访问量:109

问:

我尝试了很多不同的东西,试图阻止事件在mousenter事件上冒泡,但仍然有问题,当我将鼠标悬停在链接上时,事件会触发所有链接,就像所有链接同时悬停一样。是链接的无序列表,当我将鼠标悬停在链接上时,我正在使用计算值动态更改内联样式:

我的组件是这样的:

      <section class="categoryList">
        <ul>
          <li v-for="category in categories" :key="category.id">
            <a
              @mouseenter.stop="mouseOver()"
              @mouseleave.stop="mouseOver()"
              class="category"
              :style="getStyle"
              href="#"
              @click.prevent="getCategory(category.name)"
              >{{ category.name }}</a
            >
          </li>
        </ul>
      </section>

这是计算值:

const getStyle = computed(() => {
  if (props.primaryColor != undefined && props.primaryColor != "") {
    if (!hover.value) {
      return `background-color:${props.primaryColor};color:${props.secondaryColor}`;
    } else {
      return `background-color:${props.secondaryColor};color:${props.primaryColor}`;
    }
  } else {
    if (!hover.value) {
      return `background-color:#614EFB;color:white`;
    } else {
      return `background-color:#523dfa;color:white`;
    }
  }
});

然后是一个标准函数来动态控制悬停状态:

function mouseOver() {
  hover.value = !hover.value;
}
javascript vue.js vuejs3 事件冒泡

评论

0赞 Dimitar 1/16/2023
问题不在这里冒泡,问题是您的状态保持 true/false,并且您的所有标签都从用于确定提供的样式的函数中获取它们的样式,因此所有标签将同时更改。因此,解决方案是为每个标签添加一个,并具有更复杂的状态 - 。例如:。然后在 getStyle 函数中,传递标记。或者干脆按照尼古拉在他的回答中解释的那样去做。hoveranchorgetStylehoveranchorindexa{ [idx] : value }{ 1: false, 2: true, 3: false }idxa
0赞 Lowtrux 1/16/2023
非常感谢@Dimitar请阅读我对尼古拉答案的评论,也许不是正确的方法?

答:

2赞 Nikola Pavicevic 1/16/2023 #1

如果我理解正确,请尝试将悬停设置为 id 而不是布尔值:

const { ref, computed } = Vue
const app = Vue.createApp({
  setup()  {
    const props = ref({primaryColor: null, secondaryColor: null})
    const categories = ref([{id: 1, name: 'aaa'}, {id: 2, name: 'bbb'}, {id: 3, name: 'ccc'}])
    const hover = ref(null)
    function mouseOver(id) { hover.value = id; }
    function mouseExit() { hover.value = null }
    getCategory = () => {}
    const getStyle = (id) => {
      if (props.primaryColor != undefined && props.primaryColor != "") {
        if (id !== hover.value) {
          return `background-color:${props.primaryColor};color:${props.secondaryColor}`;
        } else {
          return id === hover.value && `background-color:${props.secondaryColor};color:${props.primaryColor}`;
        }
      } else {
        if (id !== hover.value) {
          return `background-color:#614EFB;color:white`;
        } else {
          return `background-color:red;color:white`;
        }
      }
    };
    return { props, categories, mouseOver, getStyle, getCategory, hover, mouseExit }
  }
})
app.mount('#demo')
<script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>
<div id="demo">
  <section class="categoryList">
  <ul>
    <li v-for="category in categories" :key="category.id">
      <a
        @mouseenter="mouseOver(category.id)"
        @mouseleave="mouseExit()"
        class="category"
        :style="getStyle(category.id)"
        href="#"
        @click.prevent="getCategory(category.name)"
        >{{ category.name }}</a
      >
    </li>
  </ul>
  {{hover}}
</section>
</div>

评论

0赞 Lowtrux 1/16/2023
非常感谢@Nikola,您的方法的问题在于,当 <a> 元素不悬停时,我会丢失它们的原始样式。我假设是因为在绑定 :style 时,其中一个条件是悬停状态,因此在计算的 getStyle 上评估的原始状态在未悬停时不会影响元素。
0赞 Nikola Pavicevic 1/16/2023
@Lowtrux嘿伙计,那么你可以使用函数代替计算属性并传递 id。请再次查看片段,我更新了我的答案。
0赞 Lowtrux 1/16/2023
是的,没错,我正在弄清楚这一点。在代码中,只有一件事:当您移动鼠标时,当元素悬停时,它始终保持原样,即使它没有悬停。我想在某个时候,当鼠标离开链接元素时,悬停状态必须再次更改为 null ?
0赞 Nikola Pavicevic 1/16/2023
你是对的,再看一遍,你可以使用事件:)mouseleave