引:
基于Vue CLI 3脚手架搭建的项目整合tinymce 5富文本编辑器,vue cli 2版本及tinymce 4版本参考:https://blog.csdn.net/liub37/article/details/83310879
做了些小修改,详情见github
npm install tinymce@5.6.2
npm install @tinymce/tinymce-vue@3.2.0
不进行封装也可以,按照官网上来就好。
- <template>
- <div class="tinymce-editor" v-if="editversion">
- <Editor v-model="editorValue" :init="editorInit" :disabled="disabled" @onClick="handleClick"/>
- </div>
- </template>
- <script>
- // 引入组件
- import tinymce from 'tinymce/tinymce'
- import Editor from '@tinymce/tinymce-vue'
- // 引入富文本编辑器主题的js和css
- import 'tinymce/themes/silver/theme.min.js'
- import 'tinymce/icons/default/icons.js'
- // 扩展插件
- import 'tinymce/plugins/image'
- import 'tinymce/plugins/link'
- import 'tinymce/plugins/code'
- import 'tinymce/plugins/table'
- import 'tinymce/plugins/lists'
- import 'tinymce/plugins/wordcount' // 字数统计插件
- import 'tinymce/plugins/media'
- import '@/assets/langs/zh_CN.js'//下载后的语言包的文职
- import { upload } from '@/http/upload'//上传文件方法
-
- export default {
- name: 'TinymceWmc',
- components: { Editor },
- props: {
- id: {
- type: String,
- default: 'tinymceEditor'
- },
- value: {
- type: String,
- default: ''
- },
- disabled: {
- type: Boolean,
- default: false
- },
- plugins: {
- type: [String, Array],
- default: 'link lists image code table wordcount media'
- },
- toolbar: {
- type: [String, Array],
- default: 'bold italic underline strikethrough | fontsizeselect | forecolor backcolor'
- }
- },
- data() {
- return {
- //判断组件是否已经加载过,如果加载过加不在渲染,如果重复加载渲染会导致,富文本不能使用
- editversion: false,
- editorInit: {
- language: 'zh_CN',
- skin_url: '/tinymce/skins/ui/oxide',
- height: 300,
- plugins: this.plugins,
- toolbar: this.toolbar,
- statusbar: true, // 底部的状态栏
- menubar: true, // 最上方的菜单
- branding: false, // 水印“Powered by TinyMCE”
- images_upload_handler: (blobInfo, success, failure) => {
- const isJPG = blobInfo.blob().type === 'image/jpeg' || blobInfo.blob().type === 'image/png' || blobInfo.blob().type === 'image/gif'
-
- const isLt2M = blobInfo.blob().size / 1024 / 1024 < 2
- if (!isJPG) {
- failure('上传头像封面只能是JPG、PNG、GIF 格式!')
- }
- if (!isLt2M) {
- failure('上传头像图片大小不能超过 2MB!')
- }
-
- const formData = new FormData()
- formData.set('file', blobInfo.blob())
- upload(formData).then(data => {
- console.log("富文本文件",data)
- if (data && data.code == 2000) {
- success(data.data.url)
- } else {
- failure(data.msg)
- },err=>{
- console.log("err富文本文件",err)
- })
- },
- file_picker_types: 'media',
- file_picker_callback: (callback, value, meta) => {
- if (meta.filetype == 'media') {
- const input = document.createElement('input') // 创建一个隐藏的input
- input.setAttribute('type', 'file')
- const that = this
- input.onchange = function() {
- const file = this.files[0] // 选取第一个文件
- that.uploadImg(file, 'video') // 上传视频拿到url
- if (that.uploaded) {
- callback(that.resVideo, { title: file.name }) // 将url显示在弹框输入框中
- } else {
- setTimeout(() => {
- callback(that.resVideo, { title: file.name })
- }, 2000)
- }
- }
- // 触发点击
- input.click()
- }
- },
- media_url_resolver: function(data, resolve) {
- try {
- const videoUri = encodeURI(data.url)
- const embedHtml = `<p>
- <span
- class="mce-object mce-object-video"
- data-mce-selected="1"
- data-mce-object="video"
- data-mce-p-width="100%"
- data-mce-p-height="auto"
- data-mce-p-controls="controls"
- data-mce-p-controlslist="nodownload"
- data-mce-p-allowfullscreen="true"
- data-mce-p-src=${videoUri} >
- <video src=${data.url} width="100%" height="auto" controls="controls" controlslist="nodownload">
- </video>
- </span>
- </p>
- <p style="text-align: left;"></p>`
- resolve({ html: embedHtml })
- } catch (e) {
- resolve({ html: '' })
- }
- }
- },
- editorId: this.id,
- editorValue: this.value,
- resVideo: null, // 返回的视频url
- uploaded: false // 有没有上传完成
- }
- },
- watch: {
- value(newValue) {
- console.log('bbbbbbbbbbbbbbbbbbbbb', newValue)
- this.editorValue = newValue
- },
- editorValue(newValue) {
- this.$emit('changeValue', newValue)
- }
- },
- mounted() {
- tinymce.init({})
- this.$nextTick(() => {
- this.editversion = true
- })
- },
- methods: {
- // https://github.com/tinymce/tinymce-vue => All available events
- handleClick(e) {
- this.$emit('onClick', e, tinymce)
- },
- clear() {
- this.editorValue = ''
- },
- // 上传视频拿到url
- uploadImg(file) {
- const content = file
- const formData = new FormData()
- formData.append('file', content)
- upload(formData).then(({ data }) => {
- if (data && data.code == 2000) {
- // success(data.data.url);
- this.resVideo = data.data.url
- this.uploaded = true
- }
- })
- }
- }
- }
- </script>
-
- <style>
- .tox-silver-sink {
- z-index: 13000 !important;
- }
- </style>
- <template>
- <div>
- <TinymceEditor
- :value="formData.content"
- @changeValue="changeValue" />
- </div>
- </template>
-
- <script>
- export default {
- methods: {
- //富文本
- changeValue(value) {
- this.formData.content= value
- },
- }
- }
-
- </script>