Ckeditor5 富文本

安装

npm install --save @ckeditor/ckeditor5-build-decoupled-document

API

https://ckeditor.com/docs/ckeditor5/latest/api/index.html

组件

<template>
  <div class="rich-container">
    <div class="rich-editor document-editor">
      <div id="toolbar-container" class="document-editor__toolbar" />
      <div class="document-editor__editable-container">
        <div id="editor" class="document-editor__editable" />
      </div>
    </div>
  </div>
</template>
<script>

import DecoupledEditor from '@ckeditor/ckeditor5-build-decoupled-document'
import '@ckeditor/ckeditor5-build-decoupled-document/build/translations/zh-cn' // 中文包
import viewToPlainText from '@ckeditor/ckeditor5-clipboard/src/utils/viewtoplaintext';
import UploadAdapter from './uploadAdapter.js'
export default {
  data() {
    return {
      editor: null, // 编辑器实例
      content: '', // 编辑内容
    }
  },
  mounted() {
    this.initCKEditor()
  },
  methods: {
    initCKEditor() {
      // 初始化编辑器
      DecoupledEditor.create(document.querySelector('#editor'), {
        language: 'zh-cn', // 中文
        removePlugins: ['MediaEmbed'] // 除去视频按钮
      }).then(editor => {
        editor.plugins.get('FileRepository').createUploadAdapter = (loader) => {
            return new UploadAdapter(loader)
          }
          const toolbarContainer = document.querySelector('#toolbar-container')
          toolbarContainer.appendChild(editor.ui.view.toolbar.element)
          this.editor = editor // 将编辑器保存起来,用来随时获取编辑器中的内容等,执行一些操
          editor.model.document.on('change:data', () => {
            //把富文本编辑器获取到的内容
            this.content = editor.getData();
          });
        }).catch(error => {
          console.error(error)
        })
      },
    // 设置值
    setContent(val) {
      this.editor.setData(val)
    },
    // 获取值
    getContent(textType) {
      // 纯文本
      if(textType == 'text'){
        return viewToPlainText(this.editor.editing.view.document.getRoot())
      }
      // html文本
      return this.content
    }
  }
}
</script>
<style lang="scss">
.rich-editor {
  width: 100%;
  min-height: 500px;
  margin: 20px auto;
}
</style>
<style>
.document-editor {
		border: 1px solid var(--ck-color-base-border);
		border-radius: var(--ck-border-radius);
		display: flex;
		flex-flow: column nowrap;
	}
  .ck.ck-editor__editable:not(.ck-editor__nested-editable).ck-focused {
    border: none;
  }
	.document-editor__toolbar {
		z-index: 1;
		box-shadow: 0 0 5px hsla( 0,0%,0%,.2 );
		border-bottom: 1px solid var(--ck-color-toolbar-border);
	}
	.document-editor__toolbar .ck-toolbar {
		border: 0;
		border-radius: 0;
	}
	.document-editor__editable-container {
		/* padding: 20px; */
		background: var(--ck-color-base-foreground);
		overflow-y: scroll;
	}

	.document-editor__editable-container .document-editor__editable.ck-editor__editable {
		min-height: 500px;
		padding: 20px;
		border: 1px hsl( 0,0%,82.7% ) solid;
		border-radius: var(--ck-border-radius);
		background: white;
		box-shadow: 0 0 5px hsla( 0,0%,0%,.1 );
		margin: 0 auto;
	}

	.main__content-wide .document-editor__editable-container .document-editor__editable.ck-editor__editable {
		width: 18cm;
	}

	.document-editor .ck-content,
	.document-editor .ck-heading-dropdown .ck-list .ck-button__label {
		font: 16px/1.6 "Helvetica Neue", Helvetica, Arial, sans-serif;
	}

	.document-editor .ck-heading-dropdown .ck-list .ck-button__label {
		line-height: calc( 1.7 * var(--ck-line-height-base) * var(--ck-font-size-base) );
		min-width: 6em;
	}

	.document-editor .ck-heading-dropdown .ck-list .ck-heading_heading1 .ck-button__label,
	.document-editor .ck-heading-dropdown .ck-list .ck-heading_heading2 .ck-button__label {
		transform: scale(0.8);
		transform-origin: left;
	}

	.document-editor .ck-content h2,
	.document-editor .ck-heading-dropdown .ck-heading_heading1 .ck-button__label {
		font-size: 2.18em;
		font-weight: normal;
	}

	.document-editor .ck-content h2 {
		line-height: 1.37em;
		padding-top: .342em;
		margin-bottom: .142em;
	}

	.document-editor .ck-content h3,
	.document-editor .ck-heading-dropdown .ck-heading_heading2 .ck-button__label {
		font-size: 1.75em;
		font-weight: normal;
		color: hsl( 203, 100%, 50% );
	}

	.document-editor .ck-heading-dropdown .ck-heading_heading2.ck-on .ck-button__label {
		color: var(--ck-color-list-button-on-text);
	}

	.document-editor .ck-content h3 {
		line-height: 1.86em;
		padding-top: .171em;
		margin-bottom: .357em;
	}

	.document-editor .ck-content h4,
	.document-editor .ck-heading-dropdown .ck-heading_heading3 .ck-button__label {
		font-size: 1.31em;
		font-weight: bold;
	}

	.document-editor .ck-content h4 {
		line-height: 1.24em;
		padding-top: .286em;
		margin-bottom: .952em;
	}

	.document-editor .ck-content blockquote {
		font-family: Georgia, serif;
		margin-left: calc( 2 * var(--ck-spacing-large) );
		margin-right: calc( 2 * var(--ck-spacing-large) );
	}
	.document-editor .ck-content .image {
		margin: 0 !important;
	}
	@media only screen and (max-width: 960px) {
		.document-editor__editable-container .document-editor__editable.ck-editor__editable {
			padding: 1.5em;
		}
	}

	@media only screen and (max-width: 1200px) {
		.main__content-wide .document-editor__editable-container .document-editor__editable.ck-editor__editable {
			width: 100%;
		}
	}

	@media only screen and (min-width: 1360px) {
		.main .main__content.main__content-wide {
			padding-right: 0;
		}
	}

	@media only screen and (min-width: 1600px) {
		.main .main__content.main__content-wide {
			width: 24cm;
		}
		.main .main__content.main__content-wide .main__content-inner {
			width: auto;
			margin: 0 50px;
		}
		.main__content-wide .document-editor__editable-container .document-editor__editable.ck-editor__editable {
			width: 60%;
		}
	}
</style>

uploadAdapter(图片上传的地址)

import axios from 'axios'
import { getImgList} from '@/utils/index'
export default class UploadAdapter {
  constructor(loader) {
    this.loader = loader
  }
  upload() {
    // let URl = process.env.NODE_ENV === 'development' ? '/api' + '/main//sys/api/file/upload' : process.env.VUE_APP_BASE_API + '/main//sys/api/file/upload'
    return this.loader.file.then(file => new Promise((resolve, reject) => {
      const data = new FormData()
      data.append('file', file)
      axios.request({
        url: '/main//sys/api/file/upload',// 上传文件的接口地址,实际请填写完整地址
        method: 'post',
        data,
        headers: {
          'Content-Type': 'multipart/form-data'
        }
      }).then(res => {
        if (res.data.code === 0) {
          getImgList({picIds:res.data.data},val=>{         
            const url = val // 后台返回的上传成功后的图片地址
            url?resolve({default: url}):resolve({default: ''})
          })
        }
      }).catch(error => {
        reject(error)
      })
    }))
  }
  abort() {
    //可以书写删除服务器图片的逻辑
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值