Skip to content

Regras Prioridade D: Use com Cautela

Algumas funcionalidades do Vue existem para acomodar casos extremos raros ou suavizar migrações de uma base de código legado. Entretanto, ao serem utilizadas excessivamente, elas podem tornar o seu código mais difícil de manter ou até mesmo se tornarem uma fonte de bugs. Estas regras demonstram funcionalidades possivelmente arriscadas, descrevendo quando e porquê elas devem ser evitadas.

Seletores de elemento com scoped

Seletores de elemento devem ser evitados com scoped.

Prefira seletores de classe em vez de seletores de elemento nos estilos scoped, porque um grande número de seletores de elemento diminuem a velocidade.

Explicação Detalhada

Para definir estilos em escopo, o Vue adiciona um atributo único aos elementos componentes, algo como data-v-f3f3eg9. Então os seletores são modificados para que apenas elementos correspondentes com este atributo sejam selecionados (e.g. button[data-v-f3f3eg9]).

O problema é que um grande número de seletores elemento-atributo (e.g. button[data-v-f3f3eg9]) serão consideravelmente mais lentos do que seletores classe-atributo (e.g. .btn-close[data-v-f3f3eg9]), então seletores de classe devem ser escolhidos sempre quando possível.

Ruim

template
<template>
  <button>×</button>
</template>

<style scoped>
button {
  background-color: red;
}
</style>

Bom

template
<template>
  <button class="btn btn-close">×</button>
</template>

<style scoped>
.btn-close {
  background-color: red;
}
</style>

Comunicação pai-filho implícita

Props e eventos devem ser preferíveis para a comunicação entre componentes pai-filho, ao invés de this.$parent ou de realizar mutações em props.

Uma aplicação Vue ideal segue props para baixo, eventos para cima. Manter-se a esta convenção tornará os seus componentes mais fáceis de se entender. Entretanto, existem casos extremos em que a mutação de props ou this.$parent pode simplificar dois componentes já profudamente acoplados.

O problema é, há muitos outros casos simples onde esses padrões podem ser convenientes. Cuidado: não fique tentando a trocar simplicidade (estar apto a entender o fluxo do seu estado) por conveniência a curto-prazo (escrever menos código).

Ruim

js
app.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },

  template: '<input v-model="todo.text">'
})
js
app.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },

  methods: {
    removeTodo() {
      this.$parent.todos = this.$parent.todos.filter(
        (todo) => todo.id !== vm.todo.id
      )
    }
  },

  template: `
    <span>
      {{ todo.text }}
      <button @click="removeTodo">
        ×
      </button>
    </span>
  `
})

Bom

js
app.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },

  emits: ['input'],

  template: `
    <input
      :value="todo.text"
      @input="$emit('input', $event.target.value)"
    >
  `
})
js
app.component('TodoItem', {
  props: {
    todo: {
      type: Object,
      required: true
    }
  },

  emits: ['delete'],

  template: `
    <span>
      {{ todo.text }}
      <button @click="$emit('delete')">
        ×
      </button>
    </span>
  `
})
Regras Prioridade D: Use com Cautela has loaded