自定义 vue 组件的模糊事件

Posted

技术标签:

【中文标题】自定义 vue 组件的模糊事件【英文标题】:Blur event for custom vue component 【发布时间】:2020-12-06 09:50:08 【问题描述】:

我有什么 上面带有过滤器文本输入的自定义下拉菜单。 DropDown 可以独立于过滤器文本输入打开。

我想要什么 预期的行为是,当过滤器输入失去焦点以及当我在 DropDown 外部用鼠标单击时,下拉菜单关闭,从而使 DropDown 失去焦点。

我尝试了什么

绑定到控件中我的根 div 元素上的 blur 事件,该事件根本不会触发。 我也找不到任何可以覆盖的内部组件方法。

代码

  <div @blur="onRootLostFocus">
    ...
  </div>

  ...
  ...
  ...

  onRootLostFocus() 
    console.log('LostFocus');
    this.deactivateSearchPanel();
    this.deactivateSelectionPanel();
  

解决方案

我错过了,div 需要 tabindex="0" 才能获得焦点,这解决了我的问题

【问题讨论】:

您能提供一些代码示例吗? @vchan 相应地更新了我的问题 【参考方案1】:

这样的?

答案:你需要设置tabindex="0" 使其具有焦点。

这里有一个自定义下拉列表,您可以如何做到这一点:

Vue.component("dropdown", 
   props: ["value"],
   data()
      return 
         open: false,
         options: ["BMW", "Fiat", "Citroen", "Audi", "Tesla"]
      
   ,
   methods: 
      toggleDropdown() 
         this.open = !this.open;
      ,
      closeDropdown()
         this.open = false;
      ,
      selectOption(option) 
         this.$emit("input", option);
      
   ,
   template: `<div class="dropdown">
   <div @blur="closeDropdown" tabindex="0" ref="dropdown" @click="toggleDropdown" class="select">
    value 
   </div>
   <div class="options" :style="'max-height': open ? '300px' : '0px'">
      <div v-for="option in options" @mousedown="selectOption(option)" class="option">
          option 
      </div>
   </div>
</div>`
)

new Vue(
   el: "#app",
   data: 
      selectedCar: "BMW"
   
)
.dropdown 
   width: 200px;
   position: relative;


.select 
   height: 40px;
   position: absolute;
   left: 0;
   width: 100%;
   background: green;
   display: flex;
   justify-content: center;
   align-items: center;
   color: white;
   cursor: pointer;

.option 
   width: 100%;
   height: 40px;
   background: darkgreen;
   color: white;
   display: flex;
   justify-content: center;
   align-items: center;
   cursor: pointer;

.option:hover 
   background: green;

.options 
   overflow: hidden;
   transition: max-height 200ms;
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app"> <p>
    selectedCar </p>
   <dropdown v-model="selectedCar" />
  
</div>

【讨论】:

你那里没有组件 @TheFool 是这样的吗?带有自定义 v-model 的组件 我想,他想传播模糊,所以我不明白为什么需要 v-model。看看我对他的问题的尝试,但没有奏效。我想 $emit blur 并在父母身上听。 codesandbox.io/s/purple-dew-v87py?file=/src/App.vue 这就是我想要的,但我不明白,为什么我的模糊事件没有在 div 上触发,而你的却被触发了。 @TheFool 我明白了。 div 需要 tabindex="0" 才能获得焦点。我在顶部的回答中也说过【参考方案2】:

请注意,还有 tabindex="-1" 以使其无法通过顺序键盘导航访问。

考虑到可访问性问题,还可以考虑使用&lt;button&gt;

见https://developer.mozilla.org/en-US/docs/Web/html/Global_attributes/tabindex

【讨论】:

以上是关于自定义 vue 组件的模糊事件的主要内容,如果未能解决你的问题,请参考以下文章

vue创建自定义组件并监听原生事件

2019-07-10 在vue UI组件事件中 基于已有参数 灵活自定义传参

自定义vue点击事件传递数据

Vue:从自定义组件派生的自定义组件中的 v-model 和输入事件

Vue自定义事件

Vue自定义事件