"文件未定义"在Nuxt.js

时间:2017-09-05 15:24:58

标签: 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']
}

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>

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

在我出错的地方有任何想法吗?

感谢。

8 个答案:

答案 0 :(得分:10)

启动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>

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

答案 1 :(得分:5)

接受的答案(虽然正确)太短,我无法理解并正确使用它,所以我写了一个更详细的版本。我正在寻找一种方法来使用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>

<强> 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>

答案 2 :(得分:4)

您需要将其添加为插件,然后为其禁用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
],

答案 3 :(得分:2)

我发现现在no-ssr被替换为,我在使用echart并遇到相同的问题,但是现在它可以正常工作了!

Sub ORANGE()


Selection.Font.Bold = True
    With Selection.Interior
        .Pattern = xlSolid
        .PatternColorIndex = xlAutomatic
        .Color = 49407
        .TintAndShade = 0
        .PatternTintAndShade = 0
    End With
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    Selection.Borders(xlInsideVertical).LineStyle = xlNone
    Selection.Borders(xlInsideHorizontal).LineStyle = xlNone

    With Selection
        .HorizontalAlignment = xlCenter
        .VerticalAlignment = xlCenter
        'CAMBIO 2
        .WrapText = False
        .Orientation = 0
        .AddIndent = False
        .IndentLevel = 0
        .ShrinkToFit = False
        .ReadingOrder = xlContext
        .MergeCells = False
    End With
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .ColorIndex = 0
        .TintAndShade = 0
        .Weight = xlMedium
    End With
    Selection.Borders(xlInsideVertical).LineStyle = xlNone
    Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
     Selection.NumberFormat = "General"    

End Sub

答案 4 :(得分:2)

我在使用 lightgallery.js 添加模式时遇到了这个错误:'client' 似乎有帮助

nuxt.config.js

 plugins: [
    { src: '~/plugins/lightgallery.js',  mode: 'client' }
  ],

plugins/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)

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>

答案 5 :(得分:0)

<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>

我想这应该会有所帮助,nuxt会在服务器和窗口上呈现之后触及计算内部

答案 6 :(得分:0)

该线程有点旧,但是我将解决方案留在这里,以便有人发现它有用。

我最近在vue-star-rating和其他几个插件上也遇到了类似的问题。


可以根据插件名称,导入/使用设置来遵循和调整以下步骤:

  1. 转到您的plugins文件夹并创建新的js文件(在本例中为vue-star-rating.js),然后将其编辑为setup the plugin

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)
  1. 转到您的nuxt.config.js文件并添加plugin

  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'
    }]
  1. 现在您可以在应用程序中的任何位置使用插件了。但是,为此,您需要将其包装在容器<client-only>中。示例:

<client-only placeholder="loading...">
   <vue-star-rating />
</client-only>

注释:

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

请确保您在第1步和第3步这两个位置都以相同的方式命名该插件。在这种情况下,其名称为vue-star-rating

答案 7 :(得分:0)

如果还想做,可以这样取document对象:

const d = typeof document === 'undefined' ? null : document