Nuxt.js中的"文档未定义"

Mic*_*umo 4 javascript vue.js vuejs2 nuxt.js

我想在Vue组件中使用Choices.js.组件成功编译,但随后会触发错误:

[vue-router]无法解析异步组件默认值:ReferenceError:未定义文档

在浏览器中,我看到:

未定义ReferenceError文档

我认为这与Nuxt.js中的SSR有关?我只需要在客户端上运行Choices.js,因为我认为它只是一个客户端方面.

nuxt.config.js

build: {
  vendor: ['choices.js']
}
Run Code Online (Sandbox Code Playgroud)

AppCountrySelect.vue

<script>
import Choices from 'choices.js'

export default {
  name: 'CountrySelect',
  created () {
    console.log(this.$refs, Choices)
    const choices = new Choices(this.$refs.select)
    console.log(choices)
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

在经典的Vue中,这样可以正常工作,所以我仍然非常关注如何让Nuxt.js以这种方式工作.

在我出错的任何想法?

谢谢.

Nic*_*nec 15

当你启动一个Nuxt项目时,这是一个常见的错误;-)

Choices.js LIB仅适用于客户端!所以Nuxt试图从服务器端渲染,但是从Node.js window.document不存在,那么你就有错误.
nb:window.document仅在浏览器渲染器中可用.

Nuxt 1.0.0 RC7开始,您可以使用<no-ssr>元素仅允许您的组件用于客户端.

<template>
  <div>
    <no-ssr placeholder="loading...">
      <your-component>
    </no-ssr>
  </div>
</template>
Run Code Online (Sandbox Code Playgroud)

看看这里的官方示例:https://github.com/nuxt/nuxt.js/blob/dev/examples/no-ssr/pages/index.vue

  • `&lt;your-component /&gt;``文件应如何显示?我有YourComponent.vue:`&lt;template&gt; &lt;div&gt; &lt;/ div&gt; &lt;/ template&gt; &lt;script&gt;从'plotly.js / dist / plotly'导入Plotly导出默认{} &lt;/ script&gt;`,它仍然以`文档未定义` (2认同)
  • https://nuxtjs.org/guide/plugins#client-side-only `plugins: [ { src: '~/plugins/vue-notifications', mode: 'client' } ]` 我会建议那些仍然像我一样努力寻找解决方案。 (2认同)
  • @JeffBluemel,在我敲了半天的头来寻找解决方案后,你的解决方案是唯一对我有用的解决方案。我确实尝试了在互联网上可以找到的所有内容。 (2认同)

Mic*_*kop 11

可接受的答案(虽然正确)太短了,我无法理解并正确使用它,因此我编写了更详细的版本。我一直在寻找一种使用plotly.js + nuxt.js的方法,但是它应该与OP的Choice.js + nuxt.js问题相同。

MyComponent.vue

<template>
  <div>
    <no-ssr>
      <my-chart></my-chart>
    </no-ssr>
  </div>
</template>
<script>
export default {
  components: {
    // this different (webpack) import did the trick together with <no-ssr>:
    'my-chart': () => import('@/components/MyChart.vue')
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

MyChart.vue

<template>
  <div>
  </div>
</template>
<script>
import Plotly from 'plotly.js/dist/plotly'
export default {
  mounted () {
    // exists only on client:
    console.log(Plotly)
  },
  components: {
    Plotly
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)


Yus*_*emo 8

您需要将其添加为插件,然后为其禁用 SSR。

由于文档和窗口未在服务器端定义。

您的 nuxt.config.js 应如下所示

plugins: [
{ src: '~/plugins/choices.js' } // both sides
{ src: '~/plugins/client-only.js', mode: 'client' }, // only on client side
{ src: '~/plugins/server-only.js', mode: 'server' } // only on server side
],
Run Code Online (Sandbox Code Playgroud)


小智 7

我发现现在 no-ssr 被替换了,我正在使用 echart 并且有同样的问题,但现在它正在工作!

    <client-only>
        <chart-component></chart-component>
    </client-only>
Run Code Online (Sandbox Code Playgroud)


ata*_*min 7

我在 lightgallery.js 添加模式时遇到此错误:“client”似乎有帮助

nuxt.config.js

 plugins: [
    { src: '~/plugins/lightgallery.js',  mode: 'client' }
  ],
Run Code Online (Sandbox Code Playgroud)

插件/lightgallery.js

import Vue from 'vue'
import lightGallery from 'lightgallery.js/dist/js/lightgallery.min.js'
import 'lightgallery.js/dist/css/lightgallery.min.css'

Vue.use(lightGallery)
Run Code Online (Sandbox Code Playgroud)

ImageGallery.vue

<template>
  <section class="image-gallery-container">
    <div class="image-gallery-row">
      <div
        ref="lightgallery"
        class="image-gallery"
      >
        <a
          v-for="image in group.images"
          :key="image.mediaItemUrl"
          :href="image.mediaItemUrl"
          class="image-gallery__link"
        >
          <img
            :src="image.sourceUrl"
            :alt="image.altText"
            class="image-gallery__image"
          >
        </a>
      </div>
    </div>
  </section>
</template>

<script>
export default {
  name: 'ImageGallery',
  props: {
    group: {
      type: Object,
      required: true
    }
  },
  mounted() {
    let vm = this;

    if (this.group && vm.$refs.lightgallery !== 'undefined') {
      window.lightGallery(this.$refs.lightgallery, {
        cssEasing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'
      });
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)


Jak*_*cki 6

该线程有点旧,但我将在这里留下我的解决方案,这样也许有人会发现它有用。

vue-star-rating最近也遇到了类似的问题和其他一些插件。


可以按照以下步骤进行操作并根据插件名称、导入/使用设置进行调整:

  1. 转到您的插件文件夹并创建新js文件(在本例中)vue-star-rating.js,然后编辑它以设置插件

import Vue from 'vue'
import VueStarRating from 'vue-star-rating'

Vue.component('vue-star-rating', VueStarRating); //<--- the name you used to register the plugin will be the same to use when in the component (vue-star-rating)
Run Code Online (Sandbox Code Playgroud)
  1. 转到您的nuxt.config.js文件并添加插件

  plugins: [{
      src: '~/plugins/vue-star-rating', // <--- file name
      mode: 'client'
    },
    //you can simply keep adding plugins like this:
    {
      src: '~/plugins/vue-slider-component',
      mode: 'client'
    }]
Run Code Online (Sandbox Code Playgroud)
  1. 现在您可以在应用程序中的任何位置使用该插件了。但是,要做到这一点,您需要将其包装在容器中<client-only>。例子:

<client-only placeholder="loading...">
   <vue-star-rating />
</client-only>
Run Code Online (Sandbox Code Playgroud)

笔记:

您不需要在组件本地导入任何内容,只需像上面那样使用它就可以解决问题。

请确保您在步骤 1 和步骤 3 中以相同的方式命名插件。在本例中,它将是vue-star-rating.


小智 5

<script>
import Choices from 'choices.js'

export default {
  name: 'CountrySelect',
  created () {
    if(process.client) {
      console.log(this.$refs, Choices)
      const choices = new Choices(this.$refs.select)
      console.log(choices)
    }
  }
}
</script>
Run Code Online (Sandbox Code Playgroud)

我想这应该有帮助,nuxt 在服务器上渲染后会触及计算的内部,并且窗口将被定义