Tinymce6+tinymce-vue5+vue3+ts

相關(guān)包

 "tinymce": "^6.3.1"
 "@tinymce/tinymce-vue": "^5.0.0"
 "element-plus": "^2.2.28"

復制icons寨昙、skins

安裝完成后页慷,在 public文件夾 下創(chuàng)建 tinymce文件夾察郁,然后在node_modules下找到 tinymce待逞,注意不是 @tinymce,復制 icons垦搬、skins 文件夾到 public/tinymce6

下載中文語言包

下載地址:https://www.tiny.cloud/get-tiny/language-packages/呼寸,下載 zh_CN,下載后猴贰,把解壓后的 langs文件夾 放到 public/tinymce6

組件代碼

<template>
  <div>
    <Editor v-model="myValue" :init="init" :disabled="disabled"/>
    <input type="file" hidden :id="id" :accept="imgAccept"/>
    <div class="oe-editor-del-btn" v-if="showDel">
      <img src="../assets/img/editor_del.png" alt="">
    </div>
  </div>
</template>

<script lang="ts" setup>
import {computed, onMounted, reactive, ref} from "vue"
import tinymce from 'tinymce/tinymce'
import Editor from '@tinymce/tinymce-vue'
import 'tinymce/themes/silver/theme'
import 'tinymce/icons/default'
import 'tinymce/models/dom'
import 'tinymce/plugins/advlist'
import 'tinymce/plugins/autolink'
import 'tinymce/plugins/lists'
import 'tinymce/plugins/link'
import 'tinymce/plugins/image'
import 'tinymce/plugins/charmap'
import 'tinymce/plugins/preview'
import 'tinymce/plugins/anchor'
import 'tinymce/plugins/searchreplace'
import 'tinymce/plugins/visualblocks'
import 'tinymce/plugins/code'
import 'tinymce/plugins/fullscreen'
import 'tinymce/plugins/insertdatetime'
import 'tinymce/plugins/media'
import 'tinymce/plugins/table'
import 'tinymce/plugins/help'
import 'tinymce/plugins/wordcount'
import {editUploadFile} from "../api/common";
import {ElMessage} from "element-plus";

interface Props {
  id?: string,
  modelValue?: string,
  height?: string | number,
  width?: string | number,
  disabled?: boolean,
  showDel?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: '',
  id: 'vue-tinymce-' + +new Date() + ((Math.random() * 1000).toFixed(0) + ''),
  height: 200,
  width: 'auto',
  disabled: false,
  showDel: false
})

const emits = defineEmits<{
  (e: 'update:modelValue', value: string): void
}>()

const myValue = computed({
  get() {
    return props.modelValue
  },
  set(value) {
    emits('update:modelValue', value);
  },
});

const oldValue = ref<string>()
const imgAccept = ref<string>('.bmp,.jpg,.png,.tif,.gif,.pcx,.tga,.exif,.fpx,.svg,.psd,.cdr,.pcd,.dxf,.ufo,.eps,.ai,.raw,.WMF,.webp,.avif,.apng')

const example_image_upload_handler = (blobInfo: any, progress: any) => new Promise((resolve, reject) => {
  let fd = new FormData();
  fd.append('file', blobInfo.blob(), blobInfo.filename());
  editUploadFile(fd).then((res: any) => {
    if (res.code === 1) {
      resolve(res.data)
    } else {
      resolve('')
    }
  })
})

const setup = (editor: any) => {
  editor.ui.registry.addButton('imageUpload', {
    tooltip: '圖片',
    icon: 'image',
    onAction: (api: any) => {
      //點擊按鈕后執(zhí)行
      oldValue.value = props.modelValue;
      const input: any = document.getElementById(props.id);
      input.click();
      input.onchange = function () {
        let file = input.files[0];
        let fd = new FormData();
        fd.append('file', file);
        if (!imgAccept.value.includes(file.name.substring(file.name.indexOf('.')))) {
          ElMessage.warning('請選擇圖片上傳')
          input.value = '';
          return
        }
        editUploadFile(fd).then((res: any) => {
          if (res.code === 1) {
            editor.insertContent("<img src='" + res.data + "' alt=''/>");
            input.value = '';
          } else {
            editor.setContent(oldValue.value as string);
          }
        })
      }
    }
  });
}

const init = reactive({
  selector: `#${props.id}`,
  content_style: "p {margin: 0; border:0; padding: 0;}",
  content_css: '/tinymce6/skins/content/default/content.css',
  language_url: '/tinymce6/langs/zh-Hans.js', // https://www.tiny.cloud/get-tiny/language-packages/
  language: 'zh-Hans',
  skin_url: '/tinymce6/skins/ui/oxide',
  height: props.height,
  promotion: false, //隱藏右上角upgrade按鈕
  branding: false, //隱藏右下角由TINY驅(qū)動
  menubar: false, // 是否隱藏頂部菜單
  contextmenu_never_use_native: true, //防止瀏覽器上下文菜單出現(xiàn)在編輯器中
  elementpath: false, //隱藏底欄的元素路徑(隱藏右下角元素顯示)
  object_resizing: true,//是否允許調(diào)整圖像大小.
  toolbar: 'undo redo | blocks | fontfamily forecolor |' +
    'bold italic backcolor | alignleft aligncenter ' +
    'alignright alignjustify | bullist numlist outdent indent | ' +
    'removeformat | table | imageUpload | help',
  plugins: ['advlist', 'autolink', 'lists', 'link', 'image', 'charmap', 'preview',
    'anchor', 'searchreplace', 'visualblocks', 'code', 'fullscreen',
    'insertdatetime', 'media', 'table', 'help', 'wordcount'],
  // paste_data_images: false, //此選項指定是否應從粘貼的內(nèi)容中刪除圖像
  paste_webkit_styles: 'all', //此選項允許您指定粘貼到 WebKit 中時要保留的樣式 'none' 或者 'all'
  // paste_merge_formats: true, //此選項在粘貼內(nèi)容時啟用合并格式功能对雪。這將合并相同的文本格式元素,以減少生成的 HTML 元素的數(shù)量
  advlist_bullet_styles: 'default,circle,disc,square',
  // advlist_number_styles: 'default,lower-alpha,lower-greek,lower-roman,upper-alpha,upper-roman',
  link_default_target: '_blank',
  link_title: false, //此選項允許您禁用對話框中的鏈接輸入字段
  nonbreaking_force_tab: true, //tab鍵插入三個&nbsp;
  images_upload_handler: example_image_upload_handler,
  setup: setup
})

onMounted(() => {
  tinymce.init({})
})

</script>

<style scoped>

</style>
<style>
.tox-tinymce-aux {
  z-index: 3035 !important;
}

.tox .tox-toolbar__group {
  padding: 0 3px 0 5px !important;
}
</style>

vue2+tinymce5+tinymce-vue3 - 簡書 (jianshu.com)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末米绕,一起剝皮案震驚了整個濱河市瑟捣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌义郑,老刑警劉巖蝶柿,帶你破解...
    沈念sama閱讀 218,451評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異非驮,居然都是意外死亡交汤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,172評論 3 394
  • 文/潘曉璐 我一進店門劫笙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芙扎,“玉大人,你說我怎么就攤上這事填大〗渫荩” “怎么了?”我有些...
    開封第一講書人閱讀 164,782評論 0 354
  • 文/不壞的土叔 我叫張陵允华,是天一觀的道長圈浇。 經(jīng)常有香客問我寥掐,道長,這世上最難降的妖魔是什么磷蜀? 我笑而不...
    開封第一講書人閱讀 58,709評論 1 294
  • 正文 為了忘掉前任召耘,我火速辦了婚禮,結(jié)果婚禮上褐隆,老公的妹妹穿的比我還像新娘污它。我一直安慰自己,他們只是感情好庶弃,可當我...
    茶點故事閱讀 67,733評論 6 392
  • 文/花漫 我一把揭開白布衫贬。 她就那樣靜靜地躺著,像睡著了一般歇攻。 火紅的嫁衣襯著肌膚如雪固惯。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,578評論 1 305
  • 那天掉伏,我揣著相機與錄音缝呕,去河邊找鬼。 笑死斧散,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的摊聋。 我是一名探鬼主播鸡捐,決...
    沈念sama閱讀 40,320評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼麻裁!你這毒婦竟也來了箍镜?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,241評論 0 276
  • 序言:老撾萬榮一對情侶失蹤煎源,失蹤者是張志新(化名)和其女友劉穎色迂,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體手销,經(jīng)...
    沈念sama閱讀 45,686評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡歇僧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,878評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锋拖。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片诈悍。...
    茶點故事閱讀 39,992評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖兽埃,靈堂內(nèi)的尸體忽然破棺而出侥钳,到底是詐尸還是另有隱情,我是刑警寧澤柄错,帶...
    沈念sama閱讀 35,715評論 5 346
  • 正文 年R本政府宣布舷夺,位于F島的核電站苦酱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏给猾。R本人自食惡果不足惜躏啰,卻給世界環(huán)境...
    茶點故事閱讀 41,336評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望耙册。 院中可真熱鬧给僵,春花似錦、人聲如沸详拙。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,912評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽饶辙。三九已至蹲诀,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間弃揽,已是汗流浹背脯爪。 一陣腳步聲響...
    開封第一講書人閱讀 33,040評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留矿微,地道東北人痕慢。 一個月前我還...
    沈念sama閱讀 48,173評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像涌矢,于是被迫代替她去往敵國和親掖举。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,947評論 2 355

推薦閱讀更多精彩內(nèi)容