简体   繁体   English

如何在 Vue 3 @click 事件中访问“this”组件?

[英]How to access "this" component in Vue 3 @click event?

I'm using Vue 3 and in a v-for loop, I'm creating multiple button elements.我正在使用Vue 3并在 v-for 循环中创建多个按钮元素。 The buttons are being made in another component named wb-button .这些按钮是在另一个名为wb-button的组件中制作的。 So I call wb-button in every v-for loop.所以我在每个 v-for 循环中调用wb-button

I add @click event listener to the wb-button that calls a method inside the current component, simple:我将 @click 事件侦听器添加到调用当前组件内部方法的wb-button ,很简单:

<div v-for="(item,key) in items" :key="key">
    <span>{{item.name}}</span>
    <wb-button @click="deleteItem(item)">
        Delete item!
    </wb-button>
</div>

This works how I want, the problem starts when I want to pass the wb-button just like a ref to the deleteItem method.这按我想要的方式工作,当我想将wb-button就像对deleteItem方法的引用一样传递时,问题就开始了。 The purpose is to make changes to another ref inside the wb-button .目的是更改wb-button内的另一个 ref。 So what I basically want to do is this:所以我基本上想做的是:

export default{
    name: 'listComponent',
    methods:{
        async deleteItem(item,wbButtonRef){
            // The next line is what I want to do
            wbButtonRef.$refs.btnElement.putInLoadingStatus()
            // do the delete item action
        }
    }
}

I know I can create a ref on each wb-button and pass an ID or something to the method, but I don't think it is the cleanest way to do it.我知道我可以在每个wb-button上创建一个 ref 并将 ID 或其他东西传递给该方法,但我认为这不是最干净的方法。

If there was something to just pass the wb-button element as the method parameter it would be great.如果有什么东西可以将wb-button元素作为方法参数传递,那就太好了。 Something like this:是这样的:

    <!-- I want to know if there is something I can put in 
the second argument of the 'wb-button' @click event -->

    <wb-button @click="deleteItem(item, /* what to put here?*/)">

    <!-- "this","$this","$event.target" etc ... -->

I have tried $event.target but it returns the root element of wb-button , what I need is the wb-button itself just like a $ref.我试过 $event.target 但它返回wb-button的根元素,我需要的是wb-button本身就像 $ref。

Simply put, you can't.简单地说,你不能。 And since this logic is relevant only for the button component itself, it's best to keep this logic within it.由于此逻辑仅与按钮组件本身相关,因此最好将此逻辑保留在其中。 Adding a prop and render something based on that, like you suggested yourself in the comments, is a good way to go about it.添加一个道具并在此基础上渲染一些东西,就像你在评论中建议的那样,是 go 关于它的好方法。

Considering Other Options考虑其他选择

Although I used @paddotk 's answer, 'the props way' to solve my problem, I'm just adding this answer so anyone who reads this question afterward would have a complete answer.尽管我使用了@paddotk 的答案“道具方式”来解决我的问题,但我只是添加了这个答案,以便以后阅读此问题的任何人都会得到完整的答案。

As far as I have found out, there are two more ways of doing this:据我所知,还有两种方法可以做到这一点:

1- As @MrFabio_25 mentioned in the comments, I can create a custom event on the child component and $emit with 'this' as a parameter, so I can handle that in the parent: 1-正如评论中提到的@MrFabio_25,我可以在子组件上创建一个自定义事件并使用'this'作为参数$emit,这样我就可以在父组件中处理它:

// wbButton.vue file

<inside-wb-component ref="btnElement" @click="handleClick">
     <button>
          <slot></slot>
     </button>
</inside-wb-component>  

//and in the script tag
//...
methods:{
     handleClick(){
          this.$emit('buttonClick',this)
     }
}
//...

And simply in the parent component:并且简单地在父组件中:

<wb-button @buttonClick="handleButtonClick">
     A text here
</wb-button>
// in the script tag
methods:{
     handleButtonClick(elem){
          elem.$refs.btnElement.putInLoadingStatus()
     }
}

2- The second way to do so, without the child component being involved, is to use an array of refs, as explained here: Vue 3 Documentation - refs inside v-for 2-在不涉及子组件的情况下,第二种方法是使用引用数组,如下所述: Vue 3 Documentation - refs inside v-for

<div v-for="(item,key) in items" :key="key">
     <wb-button ref="wbButtonRefs" @click="handleButtonClick(item,key)">
          A text here
     </wb-button>
</div>
// and in scripts tag
//...
methods:{
     handleButtonClick(item,index){
          const buttonRef=this.$refs.wbButtonRefs[index]
          // Now do whatever with buttonRef
          buttonRef.$refs.btnElement.putInLoadingStatus()
     }
}
//...
<template>
   <button @click="test($event)">Test</button>
</template>



methods:{
     test(e){
          const comp = e.target.__vueParentComponent
          const props = comp.props
     }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM