如何仅在客户端动态导入 Vue.js 3 中的 CKEditor?

How to dynamically import CKEditor in Vue.js 3 only on client-side?

我正在尝试将 CKEditor 5 包含在我的 Vue.js 3 应用程序中,但我正在努力将其包含在客户端 only 中。我正在使用无法处理 CKEditor 使用的 window 的服务器端渲染,因此它必须仅在浏览器请求时才加载,而不是 Node.js.

在 setup() 方法中,我可以这样测试 IsBrowser

const IsBrowser = typeof window !== 'undefined';

如何仅在 IsBrowser 为真时执行 import 和初始化组件?

我必须执行以下代码才能使 CKEditor-5 工作:

    <CKEditor v-if="IsBrowser" id="PostContent" class="ck-content" contenteditable="true" :editor="CKEditorInline" ></CKEditor>
<script>
    import CKEditor from '@ckeditor/ckeditor5-vue/dist/ckeditor'
    import CKEditorInline from '@ckeditor/ckeditor5-editor-inline/src/inlineeditor';
    
    export default {
    
      name: "ComponentCreate",
      components: {
        CKEditor: CKEditor.component
      }, 
    data() {
    return {
      CKEditorInline: CKEditorInline,
</script>

TLDR

工作解决方案(解释如下):

<CKEditor v-if="IsBrowser && CKEditorInline"
  id="PostContent"
  class="ck-content"
  contenteditable="true"
  :editor="CKEditorInline"
></CKEditor>
<script>
import { ref, defineAsyncComponent } from 'vue';

export default {
  name: "ComponentCreate",
  components: {
    CKEditor: defineAsyncComponent(() => {
      return import('@ckeditor/ckeditor5-vue/dist/ckeditor')
      .then(module => module.component)
    })
  },
  setup() {
    const IsBrowser = typeof window !== 'undefined';
    let CKEditorInline = ref(null);

    if (IsBrowser) {
      import('@ckeditor/ckeditor5-editor-inline/src/inlineeditor')
      .then(e => CKEditorInline.value = e.default)
    }

    return { IsBrowser, CKEditorInline }
  },
};
</script>

这里有两个挑战:

  1. 有条件地加载 <CKEditor> 组件
  2. 有条件地加载 CKEditorInline 模块 的导出

有条件地加载 <CKEditor> 组件

使用defineAsyncComponent延迟加载和注册组件。它仅在模板实际呈现它时才加载和注册。所以只有当 v-if 为真时。

components: {
  CKEditor: defineAsyncComponent(() => {
    return import('@ckeditor/ckeditor5-vue/dist/ckeditor')
    .then(module => module.component)
  })
},

额外的挑战,不是模块,而是 component 属性 是你的情况

有条件地加载CKEditorInline模块导出

对于这个动态模块,我们要默认导出

let CKEditorInline = ref(null);
if (IsBrowser) {
  import('@ckeditor/ckeditor5-editor-inline/src/inlineeditor')
  .then(e => CKEditorInline.value = e.default)
}

更改 v-if 条件

<CKEditor v-if="IsBrowser && CKEditorInline" :editor="CKEditorInline"></CKEditor>