Slots é a funcionalidade mais poderosa do Vue.js

Fotografia de capa por Yusuf Evli, tirado por uma Fujifilm, X-E1

Recentemente chegou uma demanda da operação aqui na EXT sobre o certificado digital que é incluso no nosso plano premium. O certificado digital em contabilidade no geral é útil para que consigamos agir pela empresa do cliente e conseguir fazer as ações necessárias.

Para emitir esse certificado você precisa de uma certificadora que vai fazer uma vídeo chamada com você para gerar um arquivo (no caso o certificado) que funciona como uma assinatura, assim a contabilidade não precisa te chamar o tempo todo no dia-a-dia.

A demanda que chegou foi por conta que só é possível emitir o certificado digitalmente (via chamada) se o cliente possuir uma CNH, se só tiver o RG o processo é outro e bem mais chato. Isso não é nem uma questão da contabilidade em si e sim das certificadoras que precisam de um documento com um determinado conjunto de dados para validar veracidade (nada mais justo dado que o certificado será sua assinatura).

Como você consegue ver aqui nesse print da sessão de planos da home do site

Eu coloquei uma pequena observação detalhando esse edge case, mas ainda sim a situação se repetia na operação pois o usuário não lia direito.

Quando você cria ou migra sua empresa pra cá, você cai no passo a passo que chamamos aqui de onboarding, e dentro dele tem um passo de seleção de plano. Nessa seleção resolvemos colocar também o aviso para lembrar o usuário desse detalhe do certificado digital e aí que entra o tema desse artigo.

No final ficou assim

Como você já deve imaginar, esses planos é um array de objetos que eu renderizo com o v-for tanto lá na home quanto no onboarding e aí no final a listagem fica assim

<SubscriptionSelectItem
	v-for="plan in plans"
	:id="plan.id"
	:key="plan.title"
	:title="plan.title"
	:description="plan.description"
	:highlighted="plan.mostPopular"
	:is-base-price="plan.isBasePrice"
	:price="plan.price"
	:included="plan.included"
	:loading="props.loading"
	button-label="Selecionar"
	@selected="handlePlanSelect">
</SubscriptionSelectItem>

Repara que não tem uma prop falando esse detalhe do plano premium porquê é só ele que tem essa observação e se eu fizesse dessa forma teria algum if dentro de SubscriptionSelectItem fazendo um acoplamento forte com o tipo de plano.

A solução para isso foi named slots! Dentro de SubscriptionSelectItem eu só precisei criar um slot com o plan.id que já é passado.

<slot :name="props.id"></slot>

Assim é só eu passar o slot nomeado sem ter acoplamento algum e abrindo possibilidade para que os outros planos também tenham suas observações caso necessário.

<SubscriptionSelectItem
	v-for="plan in plans"
	:id="plan.id"
	:key="plan.title"
	:title="plan.title"
	:description="plan.description"
	:highlighted="plan.mostPopular"
	:is-base-price="plan.isBasePrice"
	:price="plan.price"
	:included="plan.included"
	:loading="props.loading"
	button-label="Selecionar"
	@selected="handlePlanSelect">
	<template v-slot:premium>
		<div class="p-4 mb-5 text-xs text-gray-500 text-left rounded-lg bg-gray-50 animate-in fade-in duration-500"
			role="alert">
			Certificado digital incluso, desde que o(a) empresário(a)
			possua CNH. Caso não possua, certificado não incluso.
		</div>
	</template>
</SubscriptionSelectItem>

Read next...