国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > JavaScript > 正文

VueJS 集成 Medium Editor的示例代碼 (自定義編輯器按鈕)

2019-11-19 15:41:41
字體:
供稿:網(wǎng)友

0x00 前言

VueJS 社區(qū)里面關(guān)于富文本編輯器的集成也不少了,但是之前小調(diào)研了一下,基本上就是 quill,medium-editor,因?yàn)橹坝?AngularJS 用過 medium-editor,并且需要自定義某些按鈕,而且最好還是選中彈出式的,所以就決定用 medium-editor。

社區(qū)里面 star 較多的就是這個(gè)了:vue-medium-editor,但是打開它官網(wǎng),看了看文檔,越看越別扭,來看看它用法:

<!-- index.html --><medium-editor :text='myText' :options='options' custom-tag='h2' v-on:edit='applyTextEdit'>

gosh,傳這么多參數(shù),我只想要一個(gè)簡單的 editor 啊

打開源碼一看,就 62 行,所以決定自己動(dòng)手來一個(gè)簡單點(diǎn)的

0x01 最簡版

最簡版,其實(shí)就在 vue 組件中實(shí)例化一下 medium-editor 就可以了

<template> <div class="textEditor" @input="handleInput"> </div></template><script>/* eslint-disable no-new */import MediumEditor from 'medium-editor'export default { props: {  value: String,  options: {   type: Object,   default: () => ({})  } }, data () {  return {   editor: null // 用來存放 editor   } }, watch: {  // refer: https://github.com/FranzSkuffka/vue-medium-editor/blob/master/index.js  value (newVal, oldVal) {   if (newVal !== this.$el.innerHTML) { // 用 $el.innerHTML 來解決 v-html 的光標(biāo)跳到行首的問題    this.$el.innerHTML = newVal || ''   }  } }, methods: {  handleInput (e) {   this.$emit('input', e.target.innerHTML)  } }, mounted () {  // 處理初始值的情況  this.$el.innerHTML = this.value  // 這里當(dāng)然可以自定義 options 啦  this.editor = new MediumEditor(this.$el, Object.assign({}, this.options))  // medium-editor 的 api,監(jiān)聽內(nèi)容改變化  this.editor.subscribe('editableInput', this.handleInput) }, beforeDestroy () {  this.editor.unsubscribe('editableInput', this.handleInput)  this.editor.destroy() }}</script>

完成~,是不是很簡單~~哈哈,最簡版是一個(gè) v-html 控制的,但是會(huì)有自動(dòng)跳轉(zhuǎn)到首行的問題,所以這里是最終版,細(xì)節(jié)問題看注釋啦

0x02 用法

咋用呢?很簡單,在其他組件中這樣:

<text-editor v-model="vm.richText"></text-editor>

當(dāng)然 你首先得安裝 medium-editor的 js 和 css了

0x03 自定義 button

下面是我項(xiàng)目中用到的自定義 button 的相關(guān)代碼,是一個(gè) buttonBuilder:

import MediumEditor from 'medium-editor'import rangy from 'rangy/lib/rangy-core.js'import 'rangy/lib/rangy-classapplier'import 'rangy/lib/rangy-highlighter'import 'rangy/lib/rangy-selectionsaverestore'import 'rangy/lib/rangy-textrange'import 'rangy/lib/rangy-serializer'const pHash = { p1: { name: 'p1', class: 'fs-36' }, p2: { name: 'p2', class: 'fs-30' }, p3: { name: 'p3', class: 'fs-24' }, p4: { name: 'p4', class: 'fs-18' }, p5: { name: 'p5', class: 'fs-14' }, p6: { name: 'p6', class: 'fs-12' }}function pButtonCreator (p) { return MediumEditor.Extension.extend({  name: p.name,  init: function () {   this.classApplier = rangy.createClassApplier(p.class, {    elementTagName: 'span',    normalize: false   })   this.button = this.document.createElement('button')   this.button.classList.add('medium-editor-action')   this.button.innerHTML = p.name   this.button.title = p.class   this.on(this.button, 'click', this.handleClick.bind(this))  },  getButton: function () {   return this.button  },  clearFontSize: function () {   MediumEditor.selection.getSelectedElements(this.document).forEach(function (el) {    if (el.nodeName.toLowerCase() === 'span' && el.hasAttribute('class')) {     el.removeAttribute('class')    }   })  },  handleClick: function (event) {   this.clearFontSize()   this.classApplier.toggleSelection()   // Ensure the editor knows about an html change so watchers are notified   // ie: <textarea> elements depend on the editableInput event to stay synchronized   this.base.checkContentChanged()  } })}export default { P1: pButtonCreator(pHash['p1']), P2: pButtonCreator(pHash['p2']), P3: pButtonCreator(pHash['p3']), P4: pButtonCreator(pHash['p4']), P5: pButtonCreator(pHash['p5']), P6: pButtonCreator(pHash['p6'])}

簡單來說就是給選中的文字加一些 class (上面是 fs-xx 之類的),其中需要引一個(gè)鼠標(biāo)選中的庫 rangy,挺煩人的也是,然后在 text-editor 中這樣用:

先實(shí)例化

import ButtonBuilder from './buttonBuilder'var editorOptions = { toolbar: {  buttons: ['bold', 'italic', 'underline', 'removeFormat', 'p3', 'p4', 'p5', 'p6'] }, buttonLabels: 'fontawesome', // use font-awesome icons for other buttons extensions: {  p3: new ButtonBuilder.P3(),  p4: new ButtonBuilder.P4(),  p5: new ButtonBuilder.P5(),  p6: new ButtonBuilder.P6() }, placeholder: false}

再放到 editor 上

復(fù)制代碼 代碼如下:

this.editor = new MediumEditor(this.$el, Object.assign({}, editorOptions, this.options))

當(dāng)然上面實(shí)例化的步驟不一定要寫到這個(gè)組件里面,配置 options 也可以從組件外傳入

0x04 細(xì)節(jié)和坑

1、這里用到了 v-model 的自定義實(shí)現(xiàn),詳見官方文檔:v-model

簡單來說呢就是 props: value ,和 this.$emit('input', model) 就可以實(shí)現(xiàn)在組件中模擬 v-model 啦

2、多個(gè) editor 使用的自定義button 實(shí)例的問題。由于我自己應(yīng)用的時(shí)候有兩個(gè)挨著的 <text-editor>,用的上面的代碼會(huì)導(dǎo)致兩個(gè) editor 實(shí)例用的是同一個(gè) button 實(shí)例,這會(huì)導(dǎo)致一個(gè)很嚴(yán)重的問題:即編輯下面編輯器的內(nèi)容,可能會(huì)修改的上面的編輯器!!

要解決這個(gè)也很簡單,修改這一行:

復(fù)制代碼 代碼如下:

this.editor = new MediumEditor(this.$el, Object.assign({}, _.cloneDeep(editorOptions), this.options))

將自定義的 options 深復(fù)制一下,這里借助了 lodash 的函數(shù)。

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持武林網(wǎng)。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 花垣县| 临西县| 长垣县| 中方县| 榕江县| 嵩明县| 来宾市| 长沙市| 六盘水市| 稻城县| 邹城市| 米易县| 胶州市| 金塔县| 朝阳区| 乐安县| 九江县| 象山县| 广宁县| 五大连池市| 泰来县| 东台市| 新乐市| 拜城县| 连州市| 新昌县| 元氏县| 个旧市| 鄂托克旗| 吐鲁番市| 蒲江县| 和静县| 遵化市| 霍州市| 柳州市| 古丈县| 河津市| 永德县| 扬州市| 五峰| 岑溪市|