【问题标题】:Pass events onto an element of component VueJS将事件传递到组件 VueJS 的元素上
【发布时间】:2019-11-16 05:26:49
【问题描述】:

我有一些包含输入的组件:

<div class="some-component">
    <input type="text" />
</div>

我这样称呼它:

<some-component v-on:click="dostuff" ref="thatcomponent"></some-component>

然后:

methods: {
    dostuff(){
        this.$refs.thatcomponent.$el.focus();
    }
}

哪个专注于 div,我真的希望专注于输入。这个例子是我的第一个用例,但总的来说我想将组件上调用的所有事件传递给该组件中的特定元素。我不想在组件中四处寻找来自父组件的元素。

这有 Vue 模式吗?

【问题讨论】:

  • 如果您想从组件外部(即父级)控制特定元素,最好的选择可能是简单地使用(作用域)插槽。
  • @TommyF 通常我会同意。在这种情况下,组件比此处的示例要复杂得多。此外,实际上只是希望将针对组件调用的事件传递给元素而不是完全控制。
  • 你可以在那个组件中创建一个方法来聚焦你的输入,然后像这样调用它。$refs.thatcomponent.focusTheInput()
  • @AlvaroCcatamayo 单个事件的好解决方案,对于“所有事件”场景来说有点棘手。也许我只是想多了
  • 另一种选择是创建一个Vue事件总线并在父组件上注册事件并在子组件上监听它们。但是您仍然必须在 EventBus 上手动注册和触发每个事件,这有点颠倒了父子 vue 组件的期望关系。但它可能对你有用,

标签: vue.js vuejs2


【解决方案1】:

我不知道对此有 Vue 特定的解决方案。但是,您可以通过在目标元素上调度新事件来手动将事件从一个元素重定向到另一个元素。
但是,您将需要对目标元素的引用以及手动处理所有事件类型(没有像 foo.addEventListener("*", ...) 这样的通配符事件侦听器

clicked(e) {
  var target = document.querySelector("#target");
  target.dispatchEvent(new event.constructor(e.type, e));
}

基本示例:
https://codesandbox.io/s/vue-template-76svb

虽然这是一种非常不寻常的模式,但应该仔细评估这是否是问题的正确解决方案。

【讨论】:

    【解决方案2】:

    更好的方法是在子组件中添加焦点方法

    子组件

    <div class="child-component">
        <input type="text" ref="theInput" />
    </div>
    
    // child-component
    methods: {
        focus(){
            this.$refs.theInput.focus();
        }
    }
    

    父组件

    <child-component v-on:click="dostuff" ref="childComponent"></child-component>
    
    // parent-component
    methods: {
        dostuff(){
            this.$refs.childComponent.focus();
        }
    }
    

    在任何情况下,如果您想从父组件与子组件的输入元素进行交互(如果您无法控制子组件,则很有用

    // parent-component
    methods: {
        dostuff(){
            this.$refs.childComponent.$el.querySelector('input').focus();
        }
    }
    

    【讨论】:

      【解决方案3】:

      我猜你最好的选择是使用 ref 属性和 $refs 对象。 Vuejs Docs 中的 section 可能有用。

      子组件

      在模板中:

      <div class="some-component">
        <input ref="input" type="text" />
      </div>
      

      在脚本中:

      methods: {
        ...
        focus() {
          this.$refs.input.focus();
        },
        ...
      },
      

      父组件

      在模板中:

      您需要在这里使用.native 修饰符来直接监听根元素上的原生事件。

      <some-component v-on:click.native="dostuff" ref="thatcomponent"></some-component>
      

      在脚本中:

      methods: {
        ...
        dostuff() {
          this.$refs.thatcomponent.focus();
        },
        ...
      }
      

      Vuejs 文档

      $refs 仅在组件被渲染后才被填充,并且它们不是响应式的。它仅作为直接子操作的逃生舱口 - 您应该避免从模板或计算属性中访问 $refs。

      这里是CodeSandBox 示例

      希望对您有所帮助。

      【讨论】:

      • 我需要的正好相反。我需要召集听众,而不是捆绑他们。
      • 我想,你需要澄清更多你想要的东西(可能是更新帖子)。那会很有帮助:)
      猜你喜欢
      • 2022-09-30
      • 1970-01-01
      • 2020-11-08
      • 1970-01-01
      • 1970-01-01
      • 2018-12-12
      • 2020-08-13
      • 1970-01-01
      • 2017-10-03
      相关资源
      最近更新 更多