欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

TinyMCE富文本編輯器在Vue中的使用方式

 更新時(shí)間:2024年04月26日 11:31:34   作者:球球和皮皮  
這篇文章主要介紹了TinyMCE富文本編輯器在Vue中的使用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

簡(jiǎn)介

公司的后臺(tái)管理系統(tǒng)要做一個(gè)文檔編輯器,最開始選型是 toast-ui/editor ,但是同事用起來指出功能太少、不好用、沒有字體功能。。。

好好好,本著為人民服務(wù)的精神,我重新篩選編輯器組件,最終選定了TinyMCE這個(gè)編輯器。

一、TinyMCE文檔

在開發(fā)過程中,免不了要站在巨人的肩膀上。我參考了莫若卿大佬的TinyMCE中文文檔,大家可以參考。

順便加上官方文檔,英文的看著費(fèi)勁 TinyMCE官方文檔

部分插件地址

二、實(shí)現(xiàn)成果

無圖無真相!這里我就把實(shí)現(xiàn)前后的效果圖先放出來,大家如果需要的話,再往后看。

1、toast-ui/editor效果

2、TinyMCE效果

對(duì)比兩個(gè)編輯器,可以發(fā)現(xiàn)TinyMCE多了很多功能,包括字體大小,字體風(fēng)格,行間距等等。

三、引用TinyMCE的方法

對(duì)比完兩個(gè)編輯器的優(yōu)劣,直接跳過toast-ui/editor,只介紹TinyMCE的實(shí)現(xiàn)。

1、引入TinyMCE

由于我是在vue中引用,跟莫若卿大佬的不太一樣,所以我介紹一下我的用法。

(1)、首先,我引用了vue-tinymce,這是提供給 vue 開發(fā)者使用的 TinyMCE 組件。

  • 1.安裝組件:
npm install @packy-tang/vue-tinymce
  • 2.引入:
import VueTinymce from “@packy-tang/vue-tinymce”
Vue.use(VueTinymce)
  • 3.使用:
<vue-tinymce ref="tinymce" v-model="content" :setting="setting" />
import tinymce from './components/tinymce/'
import VueTinymce from './components/vue-tinymce'

Vue.prototype.$tinymce = tinymce
Vue.use(VueTinymce)

(2)、由于我改了插件中的一些方法,所以我把TinyMCE整個(gè)插件放到了代碼了,當(dāng)作組件使用。

廢話不多說,上代碼

<template>
    <vue-tinymce ref="tinymce" v-model="content" :setting="setting" />
</template>

<script>
//樣式
import './skins/content/default/content.min.css'
import './skins/ui/oxide/skin.min.css'
import './skins/ui/oxide/content.min.css'

//主題
import './themes/silver'

//插件
import './plugins/link' //鏈接插件
import './plugins/image' //圖片插件
import './plugins/imagetools'
import './plugins/media' //媒體插件
import './plugins/table' //表格插件
import './plugins/lists' //列表插件
import './plugins/quickbars' //快速欄插件
import './plugins/fullscreen' //全屏插件
import './plugins/lineheight'
import './plugins/uploadimage'
import './plugins/charmap'
import './plugins/codesample'
import './plugins/upfile'
import './plugins/code'

/**
 * 注:
 * 5.3.x版本需要額外引進(jìn)圖標(biāo),沒有所有按鈕就會(huì)顯示not found
 */
import './icons/default/icons'

//本地化
import './plugins/zh_CN.js'
import { uploadFile } from '@/api/document/doc'

export default {
  name: 'tinymceEditor',
  props: {
    initialValue: {
      type: String,
      default: ''
    }
  },
  watch: {
    initialValue (newValue) {
      this.content = newValue
    },
  },
  data(){
    return {
      tinymceHtml: '',
      resVideo: null,
      uploaded: false,
      content: '',
      setting: {
        menubar: false,
        toolbar: "undo redo | fullscreen | formatselect alignleft aligncenter alignright alignjustify | upfile link unlink code | numlist bullist lineheight | image media table | fontselect fontsizeselect forecolor backcolor | bold italic underline strikethrough charmap | indent outdent | superscript subscript | removeformat |",
        toolbar_drawer: "sliding",
        quickbars_selection_toolbar: "removeformat | bold italic underline strikethrough | fontsizeselect forecolor backcolor",
        plugins: "code lineheight link image upfile imagetools media table lists fullscreen quickbars charmap",
        language: 'zh_CN',
        height: 500,
        deprecation_warnings: false,
        images_upload_handler: (blob, callback) => {
            this.upload(blob, url => {
                callback(url)
            })
        },
        file_picker_types: 'media',
        file_picker_callback: (callback, value, meta) => {
          //當(dāng)點(diǎn)擊meidia圖標(biāo)上傳時(shí),判斷meta.filetype == 'media'有必要,因?yàn)閒ile_picker_callback是media(媒體)、image(圖片)、file(文件)的共同入口
          if (meta.filetype == 'media'){
            let filetype = '.mp4'
            //創(chuàng)建一個(gè)隱藏的type=file的文件選擇input
            let input = document.createElement('input');
            input.setAttribute('type', 'file');
            input.setAttribute('accept', filetype);
            let that = this;
            input.onchange = function() {
              let file = this.files[0];
              that.uploadImg(file, url => {
                callback(url)
              });
            }
            //觸發(fā)點(diǎn)擊
            input.click();
          }
        },
        file_callback: (file, callback) => {
          // 自定義處理文件操作部分
          this.uploadFile(file, url => {
              callback(url)
          })
        }
      },
    }
  },
  methods: {
    upload (file, callback) {
      const formData = new FormData()
      if (file.size / 1024 / 1024 > 50) {
        this.$message.error('圖片大小應(yīng)小于50M')
        return false
      }
      formData.append('file', file.blob(), file.name)
      uploadFile(formData).then(res => {
        const imageSrc = res.data.objectUrl
        callback(imageSrc)
      });
    },
    uploadFile (file, callback) {
      const fileName = file.name;
      const fileSize = (file.size / 1024 / 1024).toFixed(1);
      if (fileSize > 200) {
        Message.error("文件大小應(yīng)小于200M");
        return false;
      }
      const formData = new FormData();
      formData.append("file", file, fileName);
      var timestamp = new Date().getTime();
      formData.append("batchKey", timestamp);
      axios.post(`/xxx/xxx/uploadFile`, formData).then(res => {
        const imageSrc = res.data.objectUrl
        callback(imageSrc)
      });
    },
    async uploadImg (file, callback) {
      let loadText = document.createElement('span');
      let fileName = file.name;
      const fileSize = (file.size / 1024 / 1024).toFixed(1);
      if (fileSize > 200) {
        Message.error("文件大小應(yīng)小于200M");
        return false;
      }
      const formData = new FormData();
      formData.append("file", file, fileName);
      var timestamp = new Date().getTime();
      formData.append("batchKey", timestamp);
      // 上傳信息顯示為位置
      const supMessagePos = document.getElementsByClassName('tox-dialog__footer')[0]
      const messagePos = document.getElementsByClassName('tox-dialog__footer-start')[0]
      var config = {
        onUploadProgress: progressEvent => {
          var complete =
            ((progressEvent.loaded / progressEvent.total) * 100) | 0;
          if (complete == 100) {
            loadText.innerHTML = "加載完成,等待上傳...";
            supMessagePos.insertBefore(loadText, messagePos)
          } else {
            loadText.innerHTML = "正在加載...  " + complete + " %";
            supMessagePos.insertBefore(loadText, messagePos)
          }
        }
      };
      await axios.post(`/xxx/xxx/uploadFile`, formData, config).then(res => {
        if (res.data) {
          loadText.innerHTML = "上傳完成!"
          callback(res.data.objectKey, { title: fileName })
          supMessagePos.insertBefore(loadText, messagePos)
          // myWebSocket.closeSocket();
        }
      })
    }
  }
}
</script>

<style>
.tox-statusbar__branding {
  display: none;
}
</style>

2、說明

我這里加上了上傳圖片、上傳文件和上傳視頻的方法,不需要的可以省略。

“setting”里的“toolbar”和"plugins"是控制編輯器中的插件功能的。toolbar代表上方引入的功能按鈕,plugins列舉需要引入的插件。

“images_upload_handler”這個(gè)屬性是上傳圖片的回調(diào),加上之后上傳圖片的組件會(huì)增加一個(gè)“上傳”按鈕,方便很多。

實(shí)現(xiàn)效果如下:

“file_picker_callback”屬性也是上傳回調(diào),與上邊那個(gè)類似,不過可以配置。

我添加了判斷 meta.filetype == 'media' ,因?yàn)?ldquo;file_picker_callback”是media(媒體)、image(圖片)、file(文件)的共同入口,我只需要上傳視頻,所以我加了判斷。

加完后的效果如下:

"file_callback"屬性比較特別,它是“upfile”插件專屬的屬性,可以添加上傳文檔的回調(diào)。我因?yàn)樾枰蟼鱬df文件,所以引入了這個(gè)插件到編輯器中。

3、其他配置項(xiàng)

(1)、在光標(biāo)位置顯示快速工具欄

quickbars_insert_toolbar([插入]快捷工具欄)

這個(gè)功能是當(dāng)你的光標(biāo)在【空的一行】時(shí),顯示可以快速插入的工具項(xiàng)。

setting: {
	quickbars_insert_toolbar: 'quickimage quicktable'
}

如果不需要,可以把這一項(xiàng)設(shè)置為空。

setting: {
	quickbars_insert_toolbar: ''
}

(2)、選中文字后,顯示快速工具欄

quickbars_selection_toolbar([選擇]快捷工具欄)

這個(gè)功能是當(dāng)你選中文字后,顯示可以對(duì)文字操作的工具項(xiàng)。

setting: {
	quickbars_selection_toolbar: "removeformat | bold italic underline strikethrough | fontsizeselect forecolor backcolor"
}

(3)、向編輯器粘貼圖片后,自動(dòng)將圖片從base64格式轉(zhuǎn)換為url地址

urlconverter_callback(粘貼圖片后,不自動(dòng)上傳,而是使用base64編碼)

前兩天同事問了我這個(gè)問題,我順便加在這里分享一下。

這個(gè)功能是為了解決向編輯器粘貼圖片的問題。正常通過插件上傳圖片時(shí),會(huì)自動(dòng)處理成url格式,通過ctrl+v粘貼的圖片則不處理。

在“setting”里加上以下這段代碼就可以解決。

setting: {
	urlconverter_callback: (url, node, onSave, name) => {
      if (node === 'img' && url.startsWith('blob:')) {
          tinymce.activeEditor && tinymce.activeEditor.uploadImages()
      }
      return url
    },
}

總結(jié)

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • vue訪問未定義的路由時(shí)重定向404問題

    vue訪問未定義的路由時(shí)重定向404問題

    這篇文章主要介紹了vue訪問未定義的路由時(shí)重定向404問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • Avue實(shí)現(xiàn)動(dòng)態(tài)查詢與數(shù)據(jù)展示的示例代碼

    Avue實(shí)現(xiàn)動(dòng)態(tài)查詢與數(shù)據(jù)展示的示例代碼

    Avue是一個(gè)基于Vue.js的前端框架,它是由阿里云開發(fā)的一款企業(yè)級(jí)UI組件庫(kù),旨在提供一套全面、易用且高性能的界面解決方案本文介紹了Avue實(shí)現(xiàn)動(dòng)態(tài)查詢與數(shù)據(jù)展示的示例,需要的朋友可以參考下
    2024-08-08
  • vue動(dòng)態(tài)配置模板 ''component is''代碼

    vue動(dòng)態(tài)配置模板 ''component is''代碼

    這篇文章主要介紹了vue動(dòng)態(tài)配置模板 'component is'代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • vue3配置代理實(shí)現(xiàn)axios請(qǐng)求本地接口返回PG庫(kù)數(shù)據(jù)

    vue3配置代理實(shí)現(xiàn)axios請(qǐng)求本地接口返回PG庫(kù)數(shù)據(jù)

    這篇文章主要為大家詳細(xì)介紹了vue3配置代理實(shí)現(xiàn)axios請(qǐng)求本地接口返回PG庫(kù)數(shù)據(jù)的相關(guān)知識(shí),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2025-03-03
  • Vue.set()動(dòng)態(tài)的新增與修改數(shù)據(jù),觸發(fā)視圖更新的方法

    Vue.set()動(dòng)態(tài)的新增與修改數(shù)據(jù),觸發(fā)視圖更新的方法

    今天小編就為大家分享一篇Vue.set()動(dòng)態(tài)的新增與修改數(shù)據(jù),觸發(fā)視圖更新的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-09-09
  • vant組件庫(kù)之tag漸變色不起作用的原因及解決

    vant組件庫(kù)之tag漸變色不起作用的原因及解決

    這篇文章主要介紹了vant組件庫(kù)之tag漸變色不起作用的原因及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-04-04
  • Vue3定義全局變量的方式總結(jié)(附代碼)

    Vue3定義全局變量的方式總結(jié)(附代碼)

    vue創(chuàng)建全局變量和方法有很多種,下面這篇文章主要給大家介紹了關(guān)于Vue3定義全局變量的方式,文中通過代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用vue3具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2024-04-04
  • Vue實(shí)現(xiàn)一個(gè)圖片懶加載插件

    Vue實(shí)現(xiàn)一個(gè)圖片懶加載插件

    這篇文章主要給大家介紹了關(guān)于利用Vue實(shí)現(xiàn)一個(gè)圖片懶加載的插件的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者使用vue具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-03-03
  • vue3中關(guān)于路由hash與History的設(shè)置

    vue3中關(guān)于路由hash與History的設(shè)置

    這篇文章主要介紹了vue3中關(guān)于路由hash與History的設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • vue3實(shí)現(xiàn)自定義導(dǎo)航菜單的示例代碼

    vue3實(shí)現(xiàn)自定義導(dǎo)航菜單的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何使用vue3實(shí)現(xiàn)自定義導(dǎo)航菜單,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-11-11

最新評(píng)論