4

I'm trying to extract the data-reportid attribute from a parent <tr> when the user clicks on the <td>.

HTML

<tr :data-reportid="modifiedRows[index]['id']" v-for="(row,index) in modifiedRows" :key="index">
  <td v-html="value" v-for="(value, ind) in row" @click="modalRequest(index, ind, value, rowReportID)" :key="ind">
    {{ row[ind] }}    <---- i know i can just use 'value', i was experimenting.
  </td>
</tr>

VueJS - computed

rowReportID() {
  return $(this).parent().data('reportid');
},

When the user clicks, the console reports 'undefined' as the result. The DOM correctly renders the data-reportid attribute and it contains the correct values, so that's not a factor.

What am I missing here? Please be patient. Mostly PHP background.

2
  • Can you suplie reproduction? Commented Mar 8, 2020 at 21:58
  • what's to add? that's it. modal request() simply console.log()'s the parameters. put a number or string into data-reportid and go. Commented Mar 8, 2020 at 22:00

1 Answer 1

2

A computed property can only have a single, cached value per Vue instance. In this case you seem to be trying to calculated a value based on the current element. A computed property doesn't have that context.

In general a computed property shouldn't be trying to access the DOM. The DOM is not reactive and won't trigger property updates. Further, the DOM may not exist at the point the property is first evaluated.

I believe in this case the specific problem is that this will be the Vue instance, not a DOM element, so $(this) won't match anything. You can try adding some console logging inside rowReportID to confirm.

Instead of using a computed property you could use a method. To access the DOM node you'd need to get it from the native browser event object, which Vue exposes as $event:

@click="modalRequest(index, ind, value, rowReportID($event))"

with:

methods: {
  rowReportID(event) {
    return $(event.target).parent().data('reportid');
  }
}

There isn't really any need to use jQuery here, you could do this using native DOM APIs just as easily. jQuery generally isn't required when using Vue.

Further, unless there's a really good reason to grab this attribute from the DOM you should avoid that stage altogether. Instead you can do something like this:

@click="modalRequest(index, ind, value, modifiedRows[index].id)"
Sign up to request clarification or add additional context in comments.

4 Comments

okay. i understand! awesome! BTW, event.targetEL should read just event.target. as for the very last... let me wrap my head around that and get back to you...or edit this as needed. same thing. :)
yep. got my head around it, sort of. i see that it really doesn't work as intended the other way round if my table order gets changed with a sort or filter whereas the latter doesn't have that problem. still unsure why, but at this point, i'll take the win and ponder it later. thank you for being so clear. :)
@WhiteRau Not sure where I dreamt up targetEl but I have updated my answer to the less fictional target. As for the last part, when you use inline code for a listener like this Vue will wrap it in a function that is scoped to that point in the execution of the template. The result is that any local template variables are caught up in the function's closure. This generally avoids any need to store data in attributes. Very rarely it can be useful to use attributes so that all elements can share a single function but usually that isn't worth the extra effort.
ok. I understand. and, yeah, while I can see scenarios where you WOULD share a common function, this isn't it. thanks again for taking the time. very much appreciated! :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.