8
respostas

Erro ao implementar o "Lazy Loading" do componente "Cadastro" - Módulo 2 - Curso Vue.js

No meu caso "lazy loading do componente não fuincionou:

const Cadastro = () => System.import('./components/cadastro/Cadastro.vue');

O erro apresentado no servidor foi:

ERROR in ./src/components/Cadastro/Cadastro.vue Module build failed: Error: ENOENT: no such file or directory, open '/home/breno/code/alurapic/src/components/Cadastro/Cadastro.vue' @ ./src/routes.js 2:0-58 @ ./src/main.js @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js Hash: c05cefcefad3165ddce0 Version: webpack 3.12.0 Time: 80ms

Alguém passou por isso?

8 respostas

Fala aí Breno, tudo bem? Parece que o erro está no caminho para seu componente Cadatro.vue, verifica se realmente ele está no caminho:

/home/breno/code/alurapic/src/components/Cadastro/Cadastro.vue

Se quiser poste como está a estrutura de pasta do seu projeto.

Para fazer lazy loading no Vue é bem simples, você vai criar seus componentes normais, como sempre fez, o segredo está na forma de importá-los:

import Home from './components/Home.vue'
import A from './components/A.vue'
import B from './components/B.vue'
import C from './components/C.vue'

Troque essar importações padrão do ES6 modules para:

const Home = () => import('./components/Home')
const A = () => import('./components/A')
const B = () => import('./components/B')
const C = () => import('./components/C')

O resto não muda nada, ou seja, seus componentes e rotas continuam do mesmo jeito.

Espero ter ajudado.

Olá Matheus,

Muito obrigado! Eu vou testar suas dicas. Eu cheguei a modificar o caminho mas mesmo assim o erro persistiu, porém vou refazer novos testes e qualquer novidade volto a entrar em contato.

Eu verifiquei e meu caminho está correto, agora o erro não é o mesmo, a aplicação não carrega o componente e ocorrem um erro apenas no console:

 vue-resource.common.js?929a:1071 GET http://localhost:3000/v1/fotos net::ERR_CONNECTION_REFUSED vue.esm.js?efeb:610 [Vue warn]: Failed to mount component: template or render function not defined.

found in

---> at src/App.vue vue-resource.common.js?929a:1071 GET http://localhost:3000/v1/fotos net::ERR_CONNECTION_REFUSED 

A declaração do meu componente não funciona sem o "System.", se eu usar apenas "import" como no seu exemplo ocorre erro:

const Cadastro = () => System.import('./components/cadastro/Cadastro.vue');

Fala aí Breno, tudo bem? Agora o problema parece ser no seu componente Cadastro.vue, consegue postar o código dele completo? Parece que ele não tem o template ou render implementados (um deles deve existir).

Se possível, também poste o código das rotas e como está importando os componentes que precisam ser lazy.

Fico no aguardo.

Beleza Matheus, vou postar:

CADASTRO:

<template>
  <div>
    <h1 class="centralizado">Cadastro</h1>
    <h2 class="centralizado">{{ foto.titulo }}</h2>

    <h2 v-if="foto._id" class="centralizado">Alterando</h2>
    <h2 v-else class="centralizado">Incluindo</h2>

    <form @submit.prevent="grava()">
      <div class="controle">
        <label for="titulo">TÍTULO</label>
        <input
          v-validate
          data-vv-rules="required|min:3|max:30"
          data-vv-as="título"
          name="titulo"
          id="titulo"
          autocomplete="off"
          v-model="foto.titulo"
        >
        <span class="erro" v-show="errors.has('titulo')">{{errors.first('titulo')}}</span>
      </div>

      <div class="controle">
        <label for="url">URL</label>
        <input
          v-validate
          data-vv-rules="required"
          name="url"
          id="url"
          autocomplete="off"
          v-model.lazy="foto.url"
        >
        <span class="erro" v-show="errors.has('url')">{{errors.first('url')}}</span>
        <imagem-responsiva v-show="foto.url" :url="foto.url" :titulo="foto.titulo"/>
      </div>

      <div class="controle">
        <label for="descricao">DESCRIÇÃO</label>
        <textarea id="descricao" autocomplete="off" v-model="foto.descricao"/>
      </div>

      <div class="centralizado">
        <meu-botao rotulo="GRAVAR" tipo="submit"/>
        <router-link :to="{name: 'home'}">
          <meu-botao rotulo="VOLTAR" tipo="button"/>
        </router-link>
      </div>
    </form>
  </div>
</template>

<script>
import ImagemResponsiva from "../shared/imagem-responsiva/ImagemResponsiva.vue";
import Botao from "../shared/botao/Botao.vue";
import Foto from "../../domain/foto/Foto";
import FotoService from "../../domain/foto/FotoService";

export default {
  components: {
    "imagem-responsiva": ImagemResponsiva,
    "meu-botao": Botao
  },

  methods: {
    grava() {
      console.log(
        `Enviar dados para API: 
        titulo: `,
        this.foto.titulo,
        `url: `,
        this.foto.url,
        `descricao: `,
        this.foto.descricao
      );
      this.$validator.validateAll().then(success => {
        if (success) {
          this.service.cadastra(this.foto).then(
            () => {
              if (this.id) this.$router.push({ name: "home" });
              this.foto = new Foto();
            },
            err => console.log(err)
          );
        }
      });
    }
  },

  created() {
    this.service = new FotoService(this.$resource);

    if (this.id) {
      this.service.busca(this.id).then(foto => (this.foto = foto));
    }
  },

  data() {
    return {
      foto: new Foto(),
      id: this.$route.params.id
    };
  }
};
</script>
<style scoped>
.centralizado {
  text-align: center;
}
.controle {
  font-size: 1.2em;
  margin-bottom: 20px;
}
.controle label {
  display: block;
  font-weight: bold;
}

.controle label + input,
.controle textarea {
  width: 100%;
  font-size: inherit;
  border-radius: 5px;
}

.centralizado {
  text-align: center;
}

.erro {
  color: red;
}
</style>

ROTAS:

import Home from './components/home/Home.vue';
const Cadastro = () => System.import('./components/cadastro/Cadastro.vue');

export const routes = [
    { path: '/', name: 'home', component: Home, titulo: "Home", menu: true },
    { path: '/cadastro', name: 'cadastro', component: Cadastro, titulo:"Cadastro", menu: true },
    { path: '/cadastro/:id', name: 'altera', component: Cadastro, menu: false },
    { path: '*', component: Home, menu: false }
];

Fala aí Breno, tudo bem? Acho que o problema está na forma do seu import do componente Cadastro:

const Cadastro = () => System.import('./components/cadastro/Cadastro.vue');

Tente trocar para:

const Cadastro = () => import('./components/cadastro/Cadastro');

Espero ter ajudado.

Valeu pela ajuda Matheus, vou testar e assim que o fizer respondo novamente falando se está OK.

Fala aí Breno, tudo bem? Deu certo?

Fico no aguardo

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software