Pular para conteúdo

Componentes Vue

O frontend do omegaUp usa Vue.js 2.5.22 com TypeScript para desenvolvimento de componentes.

Estrutura do Componente

Os componentes estão localizados em frontend/www/js/omegaup/components/.

Componente Básico

<template>
  <div class="my-component">
    <h1>{% raw %}{{ title }}{% endraw %}</h1>
    <button @click="handleClick">Click me</button>
  </div>
</template>

<script lang="ts">
import { Vue, Component, Prop } from 'vue-property-decorator';

@Component
export default class MyComponent extends Vue {
  @Prop({ required: true })
  title!: string;

  handleClick(): void {
    this.$emit('clicked');
  }
}
</script>

Diretrizes de componentes

Evite sinalizadores de comportamento

Não crie componentes que alterem significativamente o comportamento com base em sinalizadores. Use slots em vez disso:

<!-- ✅ Good: Using slots -->
<template>
  <div>
    <slot name="header"></slot>
    <slot name="content"></slot>
  </div>
</template>

Internacionalização

Nunca codifique o texto. Sempre use strings de tradução:

// ❌ Bad
<div>Hello World</div>

// ✅ Good
<div>{% raw %}{{ T.helloWorld }}{% endraw %}</div>

Evite concatenação de strings

Use ui.formatString() para strings parametrizadas:

// ❌ Bad
{% raw %}{{ T.greeting }}{% endraw %} {% raw %}{{ userName }}{% endraw %}

// ✅ Good
{% raw %}{{ ui.formatString(T.greeting, { name: userName }) }}{% endraw %}

Cores

Use variáveis CSS, não cores codificadas:

/* ❌ Bad */
color: #ff0000;

/* ✅ Good */
color: var(--color-primary);

Integração com livro de histórias

Usamos o Storybook para documentação e teste de componentes.

Adicionando histórias

Crie histórias para cada componente:

import MyComponent from './MyComponent.vue';

export default {
  title: 'Components/MyComponent',
  component: MyComponent,
};

export const Default = () => ({
  components: { MyComponent },
  template: '<MyComponent title="Hello" />',
});

Livro de histórias em execução

yarn storybook
Abre o livro de histórias em http://localhost:6006

Teste de componentes

Cada componente Vue deve ter testes unitários:

import { mount } from '@vue/test-utils';
import MyComponent from './MyComponent.vue';

describe('MyComponent', () => {
  it('renders title', () => {
    const wrapper = mount(MyComponent, {
      propsData: { title: 'Test' }
    });
    expect(wrapper.text()).toContain('Test');
  });
});

Documentação Relacionada