vue ckeditor5 富文本使用及自定义阿里上传

1、npm 包安装 

npm i -s @ckeditor/ckeditor5-build-decoupled-document @ckeditor/ckeditor5-vue2

2、引入

在vue main.js或者nuxt plugins文件夹下的文件中

import Vue from 'vue'
import '@ckeditor/ckeditor5-build-decoupled-document/build/translations/zh-cn'
import CKEditor from '@ckeditor/ckeditor5-vue2'

Vue.use(CKEditor)

3、富文本组件定义

<template>
  <div
    ref="editorContent"
    style="height: calc(100% - 2.5rem)"
    class="overflow-hidden z-50"
  >
    <div id="toolbar-container"></div>
    <ckeditor
      ref="editor"
      v-model="editorStr"
      style="height: calc(100% - 3rem)"
      :editor="editor"
      placeholder="请编辑消息内容"
      :config="config"
      @ready="onEditorReady"
    />
  </div>
</template>

<script>
import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document'
import UploadAdapter from '@/components/UploadAdapter' // 自定义上传
import { mapActions } from 'vuex'
export default {
  name: 'Editor',
  model: {
    prop: 'content',
    event: 'change',
  },
  props: {
    content: {
      type: String,
      default: '',
    },
  },
  data() {
    return {
      editor: DecoupledEditor,
      showPreview: false,
      previewMsg: {},
      config: {
        // removeDialogTabs: 'image:advanced;image:Link',
        language: 'zh-cn',
        previewText: '',
        // removePlugins: ['Table', 'BlockQuote', 'indent'],
        extraPlugins: [],
        toolbar: {
          items: [
            'undo',
            'redo',
            '|',
            'heading',
            '|',
            'fontfamily',
            'fontsize',
            'fontColor',
            'fontBackgroundColor',
            '|',
            'bold',
            'italic',
            'underline',
            'strikethrough',
            '|',
            'alignment',
            'uploadImage',
            '|',
            'numberedList',
            'bulletedList',
            '|',
            'outdent',
            'indent',
            '|',
            'link',
            'blockquote',
            'insertTable',
            'mediaEmbed',
          ],
        },
      },
      editorStr: '',
      el: '',
    }
  },
  watch: {
    content(val) {
      this.editorStr = val
    },
    editorStr(val) {
      this.$emit('change', val)
    },
  },
  mounted() {},
  methods: {
    ...mapActions(['upload']),
    onEditorReady(editor) {
      const that = this
      document
        .querySelector('#toolbar-container')
        .appendChild(editor.ui.view.toolbar.element)
      window.editor = editor
      that.editorStr = that.content
      // console.log(
      //   editor,
      //   '》》》》',
      //   Array.from(editor.ui.componentFactory.names())
      // )
      editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
        // 将当前vue对象挂载到loader,使得自定义上传可以访问vue对象中的上传方法及其他属性
        loader.that = that
        return new UploadAdapter(loader)
      }
    },
  },
}
</script>
<style>
.ck.ck-editor__main {
  height: calc(100% - 2.5rem);
}
.ck.ck-editor {
  height: 100%;
}
.ck-editor__editable {
  height: 100%;
  overflow-x: auto;
}
.ck.ck-editor__editable_inline {
  border: #e2e3e5 solid 1px;
  border-top: 0;
}
.ck ck-balloon-rotator {
  z-index: 199999;
}
</style>

在components自定义上传UploadAdapter.js

/**
 * 自定义上传图片插件
 */
class UploadAdapter {
  constructor(loader) {
    this.loader = loader
  }

  async upload() {
    const file = await this.loader.file
    const { that } = this.loader
    const date = that.$moment().format('YYYY-MM-DD')// vue全局属性
    const path = `/images/notice/${date}/${file.name}`
    // 方法返回数据格式: {default: "url"}
    // eslint-disable-next-line no-async-promise-executor
    return new Promise(async (resolve, reject) => {
      try {
         // 阿里云oss上传封装的upload方法
        const { code, url, msg } = await that.upload({ file, path })
        if (code === 0) resolve({ default: url })
        else reject(msg)
      } catch (e) {
        reject(e)
      }
    })
  }
}

export default UploadAdapter

在 store.js actions 中定义upload上传

import crypto from 'crypto'
import OSS from 'ali-oss'

export const actions = {
  md5(ctx, val) {
    const md5 = crypto.createHash('md5')
    md5.update(val)
    return md5.digest('hex')
  },
  // 获取oss上传信息
  async ossToken({ dispatch, state, commit }) {
    const format = 'YYYY-MM-DD HH:mm'
    const now = this.$moment().format(format)
    const { Expiration = '' } = state.sts
    const expire = this.$moment(Expiration).format(format)
    if (Expiration && expire > now) return { code: 0, result: state.sts }
    const data = await dispatch('get', { url: '/api/oss/sts' })
    commit('setSts', data.result || {})
    return data
  },
  // oss 上传文件
  async upload({ dispatch }, { path, file }) {
    const data = await dispatch('ossToken')
    if (data.code > 0) return data
    else {
      const {
        AccessKeyId: accessKeyId,
        AccessKeySecret: accessKeySecret,
        SecurityToken: stsToken,
        region,
        bucket,
      } = data.result
      const client = new OSS({
        region,
        accessKeyId,
        accessKeySecret,
        stsToken,
        bucket,
      })
      try {
        const { name } = await client.put(path, file)
        return {
          code: 0,
          url: `http://${bucket}.${region}.aliyuncs.com/${name}`,
        }
      } catch (e) {
        return { code: 201, msg: e }
      }
    }
  },
  async get(ctx, { url, params = {} }) {
    //在vue main.js 中 store.$axios = axios,nuxt项目中不用处理
    const { data } = await this.$axios.get(url, { params })
    return data
  }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,你需要安装 `@ckeditor/ckeditor5-vue` 和 `@ckeditor/ckeditor5-build-classic` 两个依赖包。 ``` npm install --save @ckeditor/ckeditor5-vue @ckeditor/ckeditor5-build-classic ``` 然后在你的 Vue 组件中引入 CKEditor 组件: ```vue <template> <div> <ckeditor :editor="editor" v-model="content" :config="editorConfig"></ckeditor> </div> </template> <script> import ClassicEditor from '@ckeditor/ckeditor5-build-classic' import CKEditor from '@ckeditor/ckeditor5-vue' export default { components: { ckeditor: CKEditor.component }, data() { return { content: '', editorConfig: { // 配置项 }, editor: ClassicEditor } } } </script> ``` 在上面的代码中,我们引入了 `ClassicEditor`,它是一个预先配置好的编辑器,包含了常用的插件,如加粗、斜体、链接等。我们也可以自定义 `editorConfig`,来配置编辑器。 下面是一个常用的配置项示例: ```js editorConfig: { toolbar: { items: [ 'bold', 'italic', 'link', '|', 'bulletedList', 'numberedList', '|', 'imageUpload', 'blockQuote', 'insertTable', 'undo', 'redo' ] }, image: { toolbar: [ 'imageTextAlternative', '|', 'imageStyle:full', 'imageStyle:side', '|', 'imageResize', '|', 'imageUpload', 'imageUpload', 'imageUpload', 'imageUpload' ], styles: [ 'full', 'side' ] }, language: 'zh-cn', table: { contentToolbar: [ 'tableColumn', 'tableRow', 'mergeTableCells', 'tableCellProperties', 'tableProperties' ] }, licenseKey: '', simpleUpload: { uploadUrl: '/your/upload/url', headers: { 'X-CSRF-TOKEN': 'CSRF-Token' } } } ``` 上面的配置中,我们开启了图片上功能,并且添加了表格插入、图片上、撤销、重做等常用功能。同时也设置了语言为中文。 如果需要添加额外的插件,可以使用 `@ckeditor/ckeditor5-*` 的包名,比如添加字数统计插件: ``` npm install --save @ckeditor/ckeditor5-word-count ``` 然后在 `editorConfig` 中添加: ```js import WordCount from '@ckeditor/ckeditor5-word-count/src/wordcount'; editorConfig: { plugins: [WordCount], toolbar: [ 'wordCount' ] } ``` 这样就可以在编辑器中添加字数统计功能了。 我们也可以自定义图片的方法,需要在配置项中添加 `simpleUpload` 选项: ```js editorConfig: { simpleUpload: { uploadUrl: '/your/upload/url', headers: { 'X-CSRF-TOKEN': 'CSRF-Token' }, // 自定义方法 async upload(file) { // 这里写上逻辑 const formData = new FormData(); formData.append('file', file); const response = await axios.post('/your/upload/url', formData, { headers: { 'Content-Type': 'multipart/form-data', 'X-CSRF-TOKEN': 'CSRF-Token' } }); return { default: response.data.url }; } } } ``` 在上面的代码中,我们使用了 axios 发送了一个 `multipart/form-data` 的请求,然后返回上的图片地址。 希望以上内容能够帮到你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

少十步

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值