Tienou
Tienou

Reputation: 720

vue.js 2.0 communication best practice

I am currently working on some stuff with vue.js and would like to ask if the following is good practice.

I have a parent and a child component, for instance dropdown and dropdown-item. When a dropdown-item gets selected I change via this.$parent.dropdown.selectedthe selected item. Is this good practice or should I go via events?

Here is the code:

<template lang="html">
  <div class="btn-group">
    <button class="btn btn-secondary dropdown-toggle"  @click="toggle" type="button">
      {{dropdown.selected.text}}
    </button>
    <div class="dropdown-menu" v-show="!isClosed">
      <slot></slot>
    </div>
  </div>
</template>

<script>
import DropdownItem from './dropdown-item.vue'

class Dropdown{
  constructor(name, selected, displayedItems) {
    this.name = name
    this.selected = new DropdownItem.uiClass("",selected)
    this.displayedItems = displayedItems
  }
}

export default {
  uiClass: Dropdown,
  name: "ui-dropdown",
  data() {
    return {
      isClosed: true
    }
  },
  props:{
    dropdown: Dropdown
  },
  methods: {
    toggle() {
      this.isClosed = !this.isClosed
    }
  }
}

<template lang="html">
  <a href="#" class="dropdown-item" @click.stop.prevent="select()"
    v-bind:class="{ 'active': value == $parent.dropdown.selected.value }">
    {{text}}
  </a>
</template>

<script>
class DropdownItem {
  constructor(value,text) {
    this.value = value
    this.text = text
  }
}

export default {
  uiClass: DropdownItem,
  name: "ui-dropdown-item",
  props:{
    value: String,
    text: String
  },
  computed: {
    dropdownItem() {
      return new DropdownItem(this.value, this.text)
    }
  },
  methods: {
    select() {
      this.$parent.dropdown.selected = this.dropdownItem;
      this.$parent.toggle()
    }
  }
}
</script>

Thank you for your response

Upvotes: 2

Views: 2046

Answers (1)

Primoz Rome
Primoz Rome

Reputation: 11051

No. Good practice is to emit the event from child and handle the data in the parent. For example:

Dropdown-item component:

<a 
  class="dropdown-item" 
  @click.stop.prevent="select()">
  {{text}}
</a>

methods: {
    select() {
      this.$emit('selected', this.item)
    }
}

Parent component:

<div class="dropdown-menu" v-show="!isClosed">
  <dropdown-item @selected="selectItem"><dropdown>
</div>

methods: {
    selectItem(item) {
      this.selectedItem = item
    }
}

For more check this in Vue.js docs: https://vuejs.org/guide/components.html#Custom-Events

Upvotes: 1

Related Questions