Sebi
Sebi

Reputation: 4522

Multiple events attached to the same prop (vue)

The documentation:

https://v2.vuejs.org/v2/guide/components-custom-events.html#Customizing-Component-v-model

is not clear (at least to me) about how to attach multiple events to the same component:

In:

https://codesandbox.io/s/dawn-dust-2tno0?file=/src/components/EditCategory.vue

is this the right way of emitting multiple events (edit/delete category) bound to the same prop:

  <div
    class="modal-body"
    v-bind:taskItem="taskItem"
    @click="$emit('edit-category', $event.target.taskItem)"
  >
    <slot name="name"> Edit Name </slot>
  </div>

  <div
    class="modal-body"
    v-bind:taskItem="taskItem"
    @click="$emit('delete-category', $event.target.taskItem)"
  >
    <slot name="delete"> Delete Category </slot>
  </div>

?

Model defined as:

  model: {
    prop: "taskItem",
    event: "edit-category",
  },
  props: {
    taskItem: {
      required: true,
      type: Object,
      default() {
        return {};
      },
    },
  },

The sample in the docs:

Vue.component('base-checkbox', {
  model: {
    prop: 'checked',
    event: 'change'
  },
  props: {
    checked: Boolean
  },
  template: `
    <input
      type="checkbox"
      v-bind:checked="checked"
      v-on:change="$emit('change', $event.target.checked)"
    >
  `
})

does not explicitly state how to bind more than one event per prop; e.g. something like:

  model: {
    prop: 'checked',
    event: 'event-a',
    event: 'event-b',
  },

?

Upvotes: 0

Views: 493

Answers (1)

Decade Moon
Decade Moon

Reputation: 34286

This isn't a situation where v-model makes sense.

v-model is just an abstraction for a particular prop and which event will be emitted by the component when that prop value should be updated with a new value. This makes sense for something like an input field which has a value prop (a string) and it emits an input event with a new value when that binding should be updated.

It doesn't seem like your taskItem example fits this structure. taskItem is an object. There are two distinct actions that can happen: its category/name can be edited or deleted. You're not replacing the entire taskItem object in either of those actions, so this isn't a good fit for v-model.

A couple of other things:

  • You can't use v-bind:taskItem on a <div>. <div> is not a component and hence does not have a taskItem prop to bind to. (Vue would probably attempt to set the taskItem attribute on the div to the stringified value of the taskItem prop which is not the behavior you want.)
  • Your click handler for the <div> accesses $event.target.taskItem which does not exist (I suppose you thought the v-bind:taskItem would make it accessible like that?). taskItem is already in scope as a prop on the component so you can just use it as-is.

Upvotes: 1

Related Questions