1
resposta

Ocultar componentes vuejs enquanto a carregamento não for concluído

Olá,

Estou trabalhando com o VueJS num projeto Django, templates Jinja2, usando o CDN ou seja não é um projeto VueJS 100% desacoplado do backend.

Já consegui implementar o código em VueJs consumindo a API tudo tranquilo. Entretanto está acontecendo um comportamento conforme figura abaixo onde os elementos do VueJS, que no meu caso estão dentro dos delimitadores [[]], são mostrados na tela enquanto ocorre o carregamento do resto do código, tentei aplicar a abordagem do css [v-cloack] mas mesmo assim ainda são mostrados.

Gostaria de saber como solucionar o problema.

imagem 01

A div, do compoente VueJS está declarada assim:

<div id="componente-auto-complete-produto-pedido" class="form-group col-md-6" v-cloack>
                                <div id="produto-pedido-results">
                                    <label for="produto-pedido">Produto</label>
                                    <input type="text" id="produto-pedido" class="form-control" 
                                        v-model="searchProduto" 
                                        placeholder="Digite o nome do produto para filtrar"
                                        @input="autoCompleteProdutoPedido">
                                    <div class="position-absolute autocomplete-result" v-if="produtos.length && produtoSelecionado == null">
                                        <table class="table table-striped table-bordered table-sm">
                                            <thead class="table-primary">
                                                <tr>
                                                    <th class="font-weight-bold">Escolha o produto clicando sobre ele.</th>
                                                </tr>
                                            </thead>
                                            <tbody>
                                                <tr v-for="produto in produtos" :key="produto.id">
                                                    <td @click="selectProduto(produto)">[[ produto.titulo ]] = [[ produto.id ]]</td>
                                                </tr>
                                            </tbody>
                                        </table>
                                    </div>
                                </div> 
                                <template v-if="produtoSelecionado != null">
                                    <input type="hidden" name="produto" id="id_produto" :value="produtoSelecionado.id">
                                </template>
                            </div>

A única forma que conseguir fazer para não mostrar os elementos foi colocando o link do CDN no topo do arquivo HTML, mas sei que isso não é boa prática.

1 resposta

Olá Afrânio.

Tudo bem?

Parece que você está enfrentando um problema comum ao trabalhar com frameworks JavaScript em conjunto com templates do servidor, onde o conteúdo dinâmico é visível antes de ser processado pelo Vue.js.

Primeiro, note que há um pequeno erro de digitação na sua declaração do atributo v-cloak. Está escrito v-cloack quando deveria ser v-cloak. Isso pode ser a razão pela qual o Vue.js não está ocultando os elementos corretamente.

Além disso, para que o v-cloak funcione, você precisa definir um estilo CSS que oculte os elementos que possuem esse atributo. Aqui está um exemplo de como você pode fazer isso:

[v-cloak] {
  display: none;
}

Você deve incluir essa regra CSS no cabeçalho do seu documento HTML para garantir que ela seja aplicada desde o início do carregamento da página. Isso deve impedir que os elementos sejam exibidos até que o Vue.js esteja pronto para processá-los.

Se mesmo após corrigir o erro de digitação e garantir que o CSS está definido corretamente o problema persistir, você pode considerar a utilização de uma estratégia de renderização condicional no Vue.js. Por exemplo, você pode definir uma variável de dados isLoaded no seu componente Vue e usar v-if para renderizar condicionalmente seu conteúdo apenas quando o Vue estiver pronto:

data() {
  return {
    isLoaded: false,
    // ... outras propriedades de dados
  };
},
mounted() {
  this.isLoaded = true;
}

E no seu template:

<div id="componente-auto-complete-produto-pedido" class="form-group col-md-6" v-if="isLoaded">
  <!-- conteúdo do componente -->
</div>

Assim, o componente só será renderizado quando isLoaded for verdadeiro, o que só acontecerá após o componente ser montado pelo Vue.js.

Espero que essas sugestões resolvam o seu problema. Lembre-se de verificar se o estilo v-cloak está sendo aplicado corretamente e se não há outros estilos ou scripts que possam estar interferindo com a renderização do seu componente Vue.js.

Qualquer coisa manda aqui de novo. Bons estudos!