如何在 Nuxt 中进行动态导入?

How to make a dynamic import in Nuxt?

在我的 nuxt 组件中,我想使用 ace editor:

import Ace from "ace-builds/src-noconflict/ace"

安装组件后,我正在执行以下操作:

this.editor = Ace.edit...

显然 the window is not defined 在服务器上重新加载页面。但不幸的是我找不到解决这个问题的方法。

有没有办法在 mounted() 挂钩上导入包? 我已经试过了

const Ace = require("ace-builds/src-noconflict/ace")

但这似乎不太奏效。你有解决这个问题的想法吗?

我已经尝试注册一个插件plugins/ace.js:

import Vue from "vue"
import Ace from "ace-builds/src-noconflict/ace"
Vue.use(Ace)

已在 nuxt.config.js 中注册:

plugins: [
    { src: "~/plugins/ace", mode: "client" }
],

但是我现在如何在我的组件中使用 Ace?它仍然是未定义的...

由于在导入语句期间抛出错误,我建议使用 dynamic imports as explained in my

async mounted() {
  if (process.client) {
    const Ace = await import('ace-builds/src-noconflict/ace')
    Ace.edit...
  }
},

来自官方文档:https://nuxtjs.org/docs/2.x/internals-glossary/context


编辑:我不确定 Ace,这可能是一个巨大的变化,但你也可以看看 vue-monaco,这是一个比较流行的明智选择(vanilla Monaco 编辑)。

EDIT2:mounted 实际上在客户端上只有 运行s,所以你可以去除 process.client 条件。同时,如果你想 运行 其他挂钩中的一些逻辑,比如 created(在服务器和客户端上都是 运行),我确实在这里放了它。更多信息 here.


EDIT3:与问题没有直接关系,但有些包公开了一个仅在客户端可用的组件(不支持 SSR),在这些情况下,您只能在 client side 并轻松防止任何其他错误。

Nuxt 插件

恕我直言,您的“插件”解决方案是正确的。唯一的错误是 Vue.use(Ace) 部分。这仅适用于 vue plugins.

插件文件可能看起来像这样:

import Ace from 'ace-builds/src-noconflict/ace'
import Theme from 'ace-builds/src-noconflict/theme-monokai'

export default ({ app }, inject) => {
  inject('ace', {
    editor: Ace,
    theme: Theme
  })
}

然后您可以使用此插件并以这种方式在组件中启动编辑器:

<template>
  <div id="editor">
    function foo(items) {
    var x = "All this is syntax highlighted";
    return x;
    }
  </div>
</template>

<script>
export default {
  data () {
    return {
      editor: {}
    }
  },
  mounted () {
    this.editor = this.$ace.editor.edit('editor')
    this.editor.setTheme(this.$ace.theme)
  }
}
</script>