Nuxt.jsにCKEditorを導入し、CKEditorに独自プラグインを導入する

# はじめに

以前、Nuxt.jsで開発をしていてCKEditorを試行錯誤で導入しました。

そちらの経験を、[Nuxt.jsにCKEditorを導入し、エディタ内の画像の移動、リサイズをドラッグで実現する](https://qiita.com/idani/items/6ae7dd149f4bc5cb17fb)としてまとめました。

その後、少し経験値を積みまして、変わったというか、あぁ、恥ずかしいという箇所を修正します。


# CKEDITR4の導入方法の変更

CKEditorにプラグインを追加するのが手間だと思っていましたが、以下のように、あっさりと実現ができました（汗）

```vue
<template>
  <ckEditor
    v-model="contents"
    :editor-url="editorUrl"
    :config="editorConfig"
  ></ckEditor>
</template>

<script>
import CKEditor from 'ckeditor4-vue'
export default {
  name: 'CKEditor4',
  components: { ckEditor: CKEditor.component },
  props: {
    value: {
      type: String,
      required: true
    },
    height: {
      type: Number,
      required: false,
      default: 500
    }
  },
  data() {
    return {
      editorUrl: 'https://cdn.ckeditor.com/4.15.1/full-all/ckeditor.js',
      editorConfig: {
        height: this.height,
        extraPlugins: ['image2'],
        removePlugins: ['image']
      }
    }
  },
  computed: {
    contents: {
      get() {
        return this.value
      },
      set(value) {
        this.$emit('input', value)
      }
    }
  }
}
</script>

<style scoped></style>

```

`editorUrl`にローカルに設置したCKEditorを使用していましたが、CDN経由からのダウンロードに変更しました。

この背景には、プラグインを設定ファイルで自由に変更できることがわかったからです。
`editorConfig`の`extraPlugins`で追加のプラグインを指定でき、`removePlugins`で除外するプラグインを指定できました。

# 独自プラグインを導入する

前回の記事には書きませんでしたが、独自プラグインを導入することを視野に入れていましたので、CKEditor自体をダウンロードすることにも抵抗がありませんでした。

今回CDN経由にして、独自プラグインを呼び出す方法がわかったのでお伝えしようと思います。

CKEDITORで[addExternal](https://ckeditor.com/docs/ckeditor4/latest/api/CKEDITOR_plugins.html#method-addExternal)メソッドを呼び出すと、独自のプラグインが読み込まれます。

`ckeditor4-vue`ならどうするのかな？って思ったら、以下のようにするようです。

```vue
<template>
  <ckEditor
    v-model="contents"
    :editor-url="editorUrl"
    :config="editorConfig"
    @namespaceloaded="onNamespaceLoaded"
  ></ckEditor>
</template>

<script>
import CKEditor from 'ckeditor4-vue'
export default {
  name: 'CKEditor4',
  components: { ckEditor: CKEditor.component },
  props: {
    value: {
      type: String,
      required: true
    },
    height: {
      type: Number,
      required: false,
      default: 500
    }
  },
  data() {
    return {
      editorUrl: 'https://cdn.ckeditor.com/4.15.1/full-all/ckeditor.js',
      editorConfig: {
        height: this.height,
        extraPlugins: ['image2', 'timestamp'],
        removePlugins: ['image']
      }
    }
  },
  computed: {
    contents: {
      get() {
        return this.value
      },
      set(value) {
        this.$emit('input', value)
      }
    }
  },
  methods: {
    onNamespaceLoaded(CKEDITOR) {
      // Add external `placeholder` plugin which will be available for each
      // editor instance on the page.

      let pluginBaseDir = '/ckeditor/plugins/timestamp/'
      if (process.env.NUXT_ENV_DEPLOY_SUBDIR) {
        pluginBaseDir =
          process.env.NUXT_ENV_DEPLOY_SUBDIR + '/ckeditor/plugins/timestamp/'
      }
      CKEDITOR.plugins.addExternal('timestamp', pluginBaseDir, 'plugin.js')
    }
  }
}
</script>

<style scoped></style>

```

`ckeditr`コンポーネントに対して、`namespaceloaded`というイベントを受信するようにします。
こちらは、`ckeditor4-vue`がCKEDitorインスタンスをロードした場合に呼ばれるそうです。

それをVueのMethodsで定義した、`onNamespaceLoaded`メソッドで処理をして、外部のプラグインを読み込みます。

`onNamespaceLoaded`メソッドは、ckeditor4-vueで1.2で実装されているので、動かなかった場合は、バージョンを確認してください。

プラグインは、[プラグインのチュートリアル](https://ckeditor.com/docs/ckeditor4/latest/guide/plugin_sdk_sample.html)で記載された、現在時刻の挿入プラグインとなります。

![2020-11-30_20h28_32.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/133291/dc8a25ff-ac6c-c67a-9ab1-cb655701e4df.gif)


[デモサイト](https://idani.github.io/ckeditor4-vue-external-plugin/)