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

Posted

技术标签:

【中文标题】如何在 Nuxt 中进行动态导入?【英文标题】:How to make a dynamic import in Nuxt? 【发布时间】:2021-08-21 18:40:04 【问题描述】:

在我的 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?它仍然未定义...

【问题讨论】:

至于“客户端”主题:插件文档的this part 应该有所帮助 你对如何访问插件的疑问得到了回答here 我确实了解inject的原理,但肯定需要多练习。感谢@Tino 澄清可以以这种方式使用插件的事实(如果不提供 Vue 友好的导出/组件)。真的很感激! 是的,我真的很喜欢注入机制。在根上下文中使用“非 vue”包非常有用。 【参考方案1】:

由于在导入语句期间引发错误,我建议使用 dynamic imports,如我的 other answer here 中所述。

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,它是肘部到肘部的普及明智(香草摩纳哥编辑)。

EDIT2:mounted 实际上仅在客户端上运行,因此您可以剥离 process.client 条件。同时,如果你想在其他钩子中运行一些逻辑,比如created(在服务器+客户端上运行),我确实让它在这里。更多信息here.

【讨论】:

不幸的是,这不起作用。由于导入语句而不是由于Ace.edit 而引发错误 不过,我还有一个小问题。由于我现在在我的组件中动态导入包,它似乎只与我在上面的初始问题中所述的插件一起使用。所以目前我正在将一个包导入到我的整个应用程序中,即使我只需要在一个组件中使用它。这看起来不太理想:/ 当您执行 import(而不是 require)时,Webpack 将处理编辑器的 tree-shaking。更重要的是,您可以加载点击或特定事件。在完成之前,它不会在您的应用程序中全局可用。因此,实际上这是将其导入单个特定组件的最佳方式(据我所知)。将它用作 Nuxt 插件将是通过您的应用程序在全球范围内使用它的解决方案。动态导入 => 如果需要,请导入。在任何情况下都需要 => 导入 whole 包。 require 是坏孩子,也是老一套的做事方式。 好的,实际上它应该只在组件中导入它就可以工作,对吧?不知何故,我仍然需要 nuxt 插件对我来说没有意义。也许我这里没有完全理解 Nuxt 的概念,但是当我在我的 nuxt 插件中console.log("hello") 时。它记录在我的应用程序的每条路线上。因此,包会在每条路线上导入(在页面重新加载时)。这就是我所说的非最优的意思。 哈哈,很抱歉没有直接解释这个。如果您想在组件中本地使用它,则可以完全放弃该插件。插件确实在您的应用程序开始时全局导入。组件中的本地导入 => 本地使用,Nuxt 插件 => 全局使用。两者 => 毫无意义。【参考方案2】:

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>

【讨论】:

支持插件使用示例! OP 只想在一个地方使用它,所以不确定这里的插件是否理想。 我试过了,作为一个全球性的解决方案,它非常完美。谢谢蒂诺!但是,就我而言,我只需要在一个组件中使用它,因此 Kissu 的解决方案更适合我的情况。 @lucamario 乐于助人。很酷,我们为此找到了全局和本地解决方案。随意对这两个答案进行投票。

以上是关于如何在 Nuxt 中进行动态导入?的主要内容,如果未能解决你的问题,请参考以下文章

您如何在 Google 表格中进行动态/依赖下拉菜单?

如何在红移中进行动态正则表达式匹配?

使用 XMLRPC 在 Python 中进行动态函数调用

在CodeIgniter中进行动态路由

使用 HTML 输入在 D3 中进行动态过滤

使用gorm golang在多个表中进行动态列搜索