ankurk91 / vue-loading-overlay

Vue.js component for full screen loading indicator :cyclone:
https://ankurk91.github.io/vue-loading-overlay/
MIT License
1.25k stars 102 forks source link

[Nuxt-3] Component is missing template or render function. #117

Closed ideafm closed 1 year ago

ideafm commented 1 year ago

I'm submitting a ... (check one with "x")

[x] Bug report => search github for a similar issue or PR before submitting
[ ] Feature request
[ ] Other, please describe

Tell about your platform

Current behavior When I using Loading component in production build (Nuxt 3) I get an error [Vue warn]: Component <Anonymous> is missing template or render function.

Is it possible to fix this?

ankurk91 commented 1 year ago

You did not fill the issue template

ideafm commented 1 year ago

What issue template I should fill? Here is reproduction https://stackblitz.com/edit/nuxt-starter-lthsle?file=pages%2Findex.vue,components%2FTest.vue For Production build you need to exec yarn build && NITRO_HOST=127.0.0.1 node .output/server/index.mjs

here is 2 problems: First of all: content duplicates Second one is message in console: [Vue warn]: Component <Anonymous> is missing template or render function.

ankurk91 commented 1 year ago

Can you make this change and try again

- import Loading from 'vue-loading-overlay';
+ import {Component as Loading} from 'vue-loading-overlay';
ideafm commented 1 year ago

SyntaxError: Named export 'Component' not found. The requested module 'vue-loading-overlay' is a CommonJS module, which may not support all module.exports as named exports.

ankurk91 commented 1 year ago

I was able to make it work like

<template>
  <form @submit.prevent="submit"
        class="vl-parent"
        ref="formContainer">
      <!-- your form inputs goes here-->
      <label><input type="checkbox" v-model="fullPage">Full page?</label>
      <button type="submit">Login</button>
  </form>
</template>

<script setup>
    import {ref, inject} from 'vue'
    import {useLoading} from 'vue-loading-overlay';
    import 'vue-loading-overlay/dist/css/index.css';

    const $loading = useLoading({
        // options
    });
    // or use inject without importing useLoading
    // const $loading =  inject('$loading')

    const fullPage = ref(false)

    const submit = () => {
        const loader = $loading.show({
            // Optional parameters
        });
        // simulate AJAX
        setTimeout(() => {
            loader.hide()
        }, 5000)
    }
</script>

Above code should work fine.

I am still trying to find why your example is not working.

ankurk91 commented 1 year ago

It looks like codesandbox and stackblitz does not work well with nuxt.

I tried on my local machine and everything worked well.

cd ~
pnpm dlx nuxi init nuxt-demo
cd nuxt-demo
pnpm add vue-loading-overlay@^6
pnpm run dev

Now replace app.vue code with (Copied from readme.md)


<template>
  <div class="vl-parent">
    <loading v-model:active="isLoading"
             :can-cancel="true"
             :on-cancel="onCancel"
             :is-full-page="fullPage"/>

    <label><input type="checkbox" v-model="fullPage">Full page?</label>
    <button @click.prevent="doAjax">fetch Data</button>
  </div>
</template>

<script>
import Loading from 'vue-loading-overlay';
import 'vue-loading-overlay/dist/css/index.css';

export default {
  data() {
    return {
      isLoading: false,
      fullPage: true
    }
  },
  components: {
    Loading
  },
  methods: {
    doAjax() {
      this.isLoading = true;
      // simulate AJAX
      setTimeout(() => {
        this.isLoading = false
      }, 5000)
    },
    onCancel() {
      console.log('User cancelled the loader.')
    }
  }
}
</script>

It worked like a charm.

zymotik commented 1 year ago

I have this problem when using vue-loading-overlay inside a plugin compiled with Vite. In an app that consumes my plugin, I get the Component is missing template or render function error. To fix, I used the following config for my plugin (note my code comment):

import MyPluginName from "./MyPluginName.vue";
import { App } from "vue";

// This next line fixed my issue:
import VueLoadingOverlay from "vue-loading-overlay/src/js/Component.vue";
import "vue-loading-overlay/dist/css/index.css";

const Plugin = {
  install: (app: App) => {
    app.component("VueLoadingOverlay", VueLoadingOverlay);
    app.component("MyPluginName", MyPluginName);
  }
};

export default Plugin;
export { MyPluginName };

I am then referencing the component in my plugin templates like so:

<VueLoadingOverlay :active="true" :width="20" :height="20" :enforce-focus="false" :is-full-page="false" :opacity="0" />
ankurk91 commented 1 year ago

It is not recommend to import from src