Cursos / Informática para Internet / Plataformas de aplicações Web / Aula

arrow_back Aula 15 - PetTopStore - Loja on-line - Parte 2

Loja on-line - Carrinho de compras

Antes de falar sobre a implementação do carrinho de compras é importante aprendermos sobre um recurso muito importante do Svelte: stores

Stores

No Svelte, existe um recurso muito útil chamado stores, que são um mecanismo de compartilhar dados entre componentes. No caso do SvelteKit você pode usar stores para compartilhar dados entre componentes de em uma mesma página ou em páginas diferentes.

Uma store pode ser do tipo "writable", "readable" e "derived", e representam dados que são alteráveis, somente leitura ou derivados de outras stores, respectivamente.

Um exemplo de uma store que guarda pro exemplo uma lista de frutas pode ser criado em um projeto qualquer em um arquivo javascript chamado mercado_store.js com o seguinte conteúdo:

import { writable } from 'svelte/store';

// criação e exportação de uma store chamada frutasDisponiveis, com o valor inicial sendo um array vazio
export const frutasDisponiveis = writable([]);

Esse arquivo exporta uma variável (store) chamada frutasDisponiveis que poderá ser importada por qualquer componente, em qualquer página, para acessar ou alterar o seu conteúdo basta acessar a variável importada com um $ na frente assim: $frutasDisponiveis. Se o seu valor alterar em um conponente, todos os outros que a utilizam irão reagir a essa mudança alterando o seu HTML de acordo.

Exemplo de um componente acessando e mudando o valor de frutasDisponiveis:

<script>
    import { frutasDisponiveis } from './mercado_store.js'
    let novaFrutaNome;
</script>

<h1>Frutas disponíveis</h1>
Total: {$frutasDisponiveis.length}<br/>

<ul>
    {#each $frutasDisponiveis as fruta}
    <li>{fruta}</li>
    {/each}
</ul>

<input type="text" bind:value={novaFrutaNome} />

<button on:click={() => {
        $frutasDisponiveis = [...$frutasDisponiveis, novaFrutaNome];
        novaFrutaNome = '';
    }}
>
    Adicionar Fruta
</button>

Resultado:

Repare que no exemplo se adiciona uma nova fruta na store (qua guarda um array como dados) de forma muito similar a alterar o valor de um array normal:

$frutasDisponiveis = [...$frutasDisponiveis, novaFrutaNome];

Só para deixar claro, esse exemplo de stores não faz parte do projeto da PetTopStore e não precisa ser adicionado ao projeto da loja on-line.

Para saber mais sobre sobre stores acesse: https://svelte.dev/docs#svelte_store

Outra fonte interessante para se aprender mais sobre stores é você seguir o tutorial oficial do Svelte no site https://svelte.dev/tutorial até chegar a sessão sobre stores. Recomendo que faça o tutorial todo para um aprendizado melhor guiado.

As stores no Svelte usam a sintaxe com o $ para serem acessadas de forma mais simplificada, como se fossem uma simples variável com os dados. Porém isso é um artefato que pode não ser usado e por debaixo dos panos existem métodos especiais em uma store, como o "subscribe" que é chamado quando o valor dela muda com o método "set". Não vamos entrar em muitos detalhes, e você precisa estudar mais sobre esses métodos caso deseje.

Store do Carrinho de compras

É importante observar que os dados escritos nas stores são compartilhados entre páginas e componentes, mas somente enquanto o usuário não efetua um reload completo no navegador (está navegando somente clicando nos links). Para que os dados fiquem persistidos no navegador é necessário se usar o LocalStorage como já vimos anteriormente. No projeto da loja on-line vamos criar um carrinho de compras como uma store especial que persiste os seus dados no LocalStorage quando o seu valor muda, e tem um valor inicial também resgatado do LocalStorage. Isso faz com que possamos usar o recurso de Stores no SvelteKit, que é muito últil para compartilhamento entre componentes, mas que eles fiquem persistidos no navegador mesmo quando a página é fechada.

Para isso existe um arquivo em src/stores/carrinho.js com o seguinte conteúdo:

import { browser } from '$app/env';
import { writable } from 'svelte/store'

// valor padrão é uma lista vazia de produtos
let carrinhoInicial;

if (browser) {
  const dados = localStorage.getItem('carrinho');
  try {
    carrinhoInicial = dados ? JSON.parse(dados):[];
  } catch {
    carrinhoInicial = [];
  }
} else {
  carrinhoInicial = [];
}

export const carrinho = writable(carrinhoInicial);

carrinho.subscribe((carrinhoAtualizado) => {
  if (browser) {
    localStorage.setItem('carrinho', JSON.stringify(carrinhoAtualizado));
  }
})

Essa store especial chamada "carrinho" tem algumas partes importantes no código:

Primeiramente é crido uma variável chamada carrinhoInicial, sem valor definido.

Depois é feita uma checagem if (browser). Isso pergunta se o código está rodando no navegador e não no servidor. Isso é importante pois o LocalStorage não está disponível no servidor (somente no navegador) e o SvelteKit tem recursos de renderização de páginas no servidor (SSR), mas não estamos usando isso no nosso projeto. De toda forma é necessário fazer essa checagem para não rodar código no servidor que é incompatível.

Se o localStorage está disponível, é resgatado o valor do carrinho dele com o comando:


const dados = localStorage.getItem('carrinho');
 try {
    carrinhoInicial = dados ? JSON.parse(dados):[];
  } catch {
    carrinhoInicial = [];
  }

Isso pega os dados do localStorage e tenta converter de JSON para objeto Javascript os dados. Caso um erro acontece, um array vazio é usado no lugar (representando um carrinho vazio).

Depois de definir nesses códigos acima o valor de "carrinhoInicial" é criada a store "carrinho" com esse valor e se configurado o método .subscrtibe que será invocado quando o valor mudar (um item for adicionado ao carrinho, por exemplo), alterando o localStorage com o novo valor também com o comando:

localStorage.setItem('carrinho', JSON.stringify(carrinhoAtualizado));

Essa store do carrinho é assim sincronizada com o localStorage do navegador e mesmo que você feche a página e abra novamente, seus itens do carrinho estarão ainda lá, até que você deseje limpar o carrinho setando a store para um array vazio.


Versão 5.3 - Todos os Direitos reservados