Desenvolvimento Web II

Notas de aula do prof. Eduardo da disciplina de Desenvolvimento Web II (curso técnico)

View on GitHub

Resolução do exercício 2

Para resolver o exercício 2, vamos criar um componente chamado ProductList que exibe uma lista de produtos. Cada produto deve conter um id, nome e preco. O componente ProductList deve exibir a listagem dos produtos e permitir a remoção de um produto. Para isso, vamos criar o componente src/component/ProductList.vue com o seguinte conteúdo:

<script setup>
  const props = defineProps(['produtos']);
</script>

<template>
  <table>
    <thead>
      <tr>
        <th>Nome</th>
        <th>Preço</th>
        <th>Ações</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="produto in props.produtos" :key="produto.id">
        
        <td>{{ produto.nome }}</td>
        <td>{{ produto.preco }}</td>
        <td>
          <i class="mdi mdi-delete" @click="$emit('remove', produto.id)" />
        </td>
        
      </tr>
    </tbody>
  </table>
</template>

<style scoped>
  table {
    width: 50%;
    border-collapse: collapse;
  }

  th,
  td {
    border: 1px solid gray;
    padding: 10px;
  }

  th {
    background-color: lightgray;
  }

  tr {
    text-align: center;
  }

  tr i {
    cursor: pointer;
    font-size: larger;
  }
</style>

Agora, vamos editar o componente ProductsView para exibir a lista de produtos. Edite o arquivo src/views/ProductsView.vue e substitua o conteúdo pelo seguinte:

<script setup>
  import { ref } from 'vue';
  import ProductList from '../components/ProductList.vue';

  const produtos = ref([
    { id: 1, nome: 'Produto 1', preco: 19.99 },
    { id: 2, nome: 'Produto 2', preco: 29.99 },
    { id: 3, nome: 'Produto 3', preco: 39.99 },
  ]);

  function removerItem(id) {
    const index = produtos.value.findIndex((produto) => produto.id === id);
    produtos.value.splice(index, 1);
  }
</script>

<template>
  <product-list :produtos="produtos" @remove="removerItem" />
</template>

Note que esses códigos são os mesmos do conteúdo visto nas aulas de components. O componente ProductList exibe uma tabela com os produtos, e o componente ProductsView exibe o componente ProductList passando a lista de produtos e o método removerItem para remover um produto da lista. A principal diferença é que agora estamos fazendo a listagem a partir de um componente de rota e não mais diretamente no App.vue.

Com essas alterações, a listagem de produtos deve funcionar corretamente na página de produtos.

Criando uma página para mostrar os detalhes de um produto (Rotas dinâmicas)

Para criar uma página que exibe os detalhes de um produto, vamos criar um novo componente chamado ProductDetailsView. Esse componente deve receber um id de produto como parâmetro e exibir os detalhes desse produto. Vamos criar o componente src/views/ProductDetailsView.vue com o seguinte conteúdo:

<script setup>
  import { ref, onMounted } from 'vue';
  const props = defineProps({
    id: String,
  });

  const produtos = ref([
    { id: 1, nome: 'Produto 1', preco: 19.99 },
    { id: 2, nome: 'Produto 2', preco: 29.99 },
    { id: 3, nome: 'Produto 3', preco: 39.99 },
  ]);

  const produto = ref(null);

  onMounted(() => {
    produto.value = produtos.value.find((produto) => produto.id == props.id);
  });
</script>

<template>
  
  <div v-if="produto">
    <h1>{{ produto.nome }}</h1>
    <p>Preço: R$ {{ produto.preco }}</p>
  </div>
  <div v-else>
    <p>Produto não encontrado</p>
  </div>
  
</template>

Veja que o componente ProductDetailsView recebe um id de produto como propriedade e exibe os detalhes desse produto. O componente ProductDetailsView busca o produto com o id informado na lista de produtos e exibe o nome e o preço do produto. Caso o produto não seja encontrado, é exibida a mensagem “Produto não encontrado”.

Vamos agora configurar a rota para a página de detalhes do produto. Edite o arquivo src/router/index.js e adicione a seguinte rota:

import { createRouter, createWebHistory } from 'vue-router';
import HomeView from '../views/HomeView.vue';
import ContactView from '../views/ContactView.vue';
import ProductView from '../views/ProjectView.vue';

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView,
    },
    {
      path: '/about',
      name: 'about',
      component: () => import('../views/AboutView.vue'),
    },
    {
      path: '/contact',
      name: 'contact',
      component: ContactView,
    },
    {
      path: '/products',
      name: 'products',
      component: ProjectView,
    },
    {
      path: '/products/:id',
      name: 'productDetails',
      component: () => import('../views/ProductDetailsView.vue'),
      props: true,
    },
  ],
});

export default router;

No exemplo acima, adicionamos uma nova rota para a página de detalhes do produto. A rota /products/:id recebe um parâmetro id que será passado para o componente ProductDetailsView como propriedade. Dessa forma, ao acessar a URL /products/1, o componente ProductDetailsView exibirá os detalhes do produto com o id 1.

Veja que o Array de produtos está sendo importado diretamente no componente. Além disso, essas informações são repetidas em vários componentes, o que não é uma boa prática. Em um cenário real, esses dados seriam centralizados em um serviço ou store para serem compartilhados entre os componentes.

Alterando a listagem de produtos para exibir os detalhes

Para alterar a listagem de produtos para exibir os detalhes de um produto, vamos adicionar um link para a página de detalhes do produto. Edite o componente ProductList e adicione um link para a página de detalhes do produto. O componente ProductList deve ficar da seguinte forma:

<template>
  <table>
    <thead>
      <tr>
        <th>Nome</th>
        <th>Preço</th>
        <th>Ações</th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="produto in props.produtos" :key="produto.id">
        
        <td>{{ produto.nome }}</td>
        <td>{{ produto.preco }}</td>
        <td>
          <router-link
            :to="{ name: 'productDetails', params: { id: produto.id } }"
          >
            <i class="mdi mdi-eye" />
          </router-link>
          <i class="mdi mdi-delete" @click="$emit('remove', produto.id)" />
        </td>
        
      </tr>
    </tbody>
  </table>
</template>

< Exercícios de fixação Navegação Programática >