简体   繁体   English

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

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

I am trying to include CKEditor 5 in my Vue.js 3 app but am struggling with including it only on client-side.我正在尝试将CKEditor 5包含在我的 Vue.js 3 应用程序中,但我正在努力将其包含在客户端。 I am using server-side rendering which cannot handle window that CKEditor uses, so it must only load only if the browser requests it, and not Node.js.我正在使用服务器端渲染,它无法处理window使用的 window,因此它只能在浏览器请求时才加载,而不是 Node.js。

In the setup() method I can test for IsBrowser like this:在 setup() 方法中,我可以像这样测试IsBrowser

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

How can I perform import and initialise a component only if IsBrowser is true?仅当IsBrowser为 true 时,如何执行import和初始化组件?

I have to do the following code to make CKEditor-5 work:我必须执行以下代码才能使 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 TLDR

Working solution (explanation is below):工作解决方案(解释如下):

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

There are two challenges here:这里有两个挑战:

  1. Conditionally load the <CKEditor> component有条件地加载<CKEditor>组件
  2. Conditionally load the CKEditorInline module 's export有条件地加载CKEditorInline模块的导出

Conditionally Load <CKEditor> component有条件地加载<CKEditor>组件

Use defineAsyncComponent to lazy load and register the component.使用defineAsyncComponent延迟加载和注册组件。 It only loads and registers if the template actually renders it.如果模板实际呈现它,它只会加载和注册。 So only when the v-if is true.所以只有当v-if为真时。

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

Extra challenge, not the module but the component property is needed in your case在您的情况下,需要额外的挑战,而不是模块,而是component属性

Conditionally load CKEditorInline module export有条件地加载CKEditorInline模块导出

For this dynamic module, we want the default export对于这个动态模块,我们想要默认导出

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

Change the v-if condition改变v-if条件

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM