亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > JavaScript > 正文

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

2019-11-19 15:41:41
字體:
來源:轉載
供稿:網友

0x00 前言

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

社區里面 star 較多的就是這個了:vue-medium-editor,但是打開它官網,看了看文檔,越看越別扭,來看看它用法:

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

gosh,傳這么多參數,我只想要一個簡單的 editor 啊

打開源碼一看,就 62 行,所以決定自己動手來一個簡單點的

0x01 最簡版

最簡版,其實就在 vue 組件中實例化一下 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 的光標跳到行首的問題    this.$el.innerHTML = newVal || ''   }  } }, methods: {  handleInput (e) {   this.$emit('input', e.target.innerHTML)  } }, mounted () {  // 處理初始值的情況  this.$el.innerHTML = this.value  // 這里當然可以自定義 options 啦  this.editor = new MediumEditor(this.$el, Object.assign({}, this.options))  // medium-editor 的 api,監聽內容改變化  this.editor.subscribe('editableInput', this.handleInput) }, beforeDestroy () {  this.editor.unsubscribe('editableInput', this.handleInput)  this.editor.destroy() }}</script>

完成~,是不是很簡單~~哈哈,最簡版是一個 v-html 控制的,但是會有自動跳轉到首行的問題,所以這里是最終版,細節問題看注釋啦

0x02 用法

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

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

當然 你首先得安裝 medium-editor的 js 和 css了

0x03 自定義 button

下面是我項目中用到的自定義 button 的相關代碼,是一個 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 之類的),其中需要引一個鼠標選中的庫 rangy,挺煩人的也是,然后在 text-editor 中這樣用:

先實例化

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 上

復制代碼 代碼如下:

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

當然上面實例化的步驟不一定要寫到這個組件里面,配置 options 也可以從組件外傳入

0x04 細節和坑

1、這里用到了 v-model 的自定義實現,詳見官方文檔:v-model

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

2、多個 editor 使用的自定義button 實例的問題。由于我自己應用的時候有兩個挨著的 <text-editor>,用的上面的代碼會導致兩個 editor 實例用的是同一個 button 實例,這會導致一個很嚴重的問題:即編輯下面編輯器的內容,可能會修改的上面的編輯器??!

要解決這個也很簡單,修改這一行:

復制代碼 代碼如下:

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日本精品久久电影| 一区二区欧美亚洲| 久久久久在线观看| 欧美日韩中文字幕在线视频| 国产精品久久婷婷六月丁香| 国产精品 欧美在线| 日韩黄色av网站| 国产午夜精品全部视频在线播放| 亚洲国产小视频在线观看| 欧美激情xxxxx| 国产精品欧美日韩一区二区| 久久久免费观看视频| 国产成人综合久久| 91亚洲国产成人精品性色| 亚洲欧美在线免费观看| 亚洲精品二三区| 亚洲女同性videos| 亚洲第一av网| 午夜免费日韩视频| 91精品久久久久久久久久久久久久| 91av免费观看91av精品在线| 777午夜精品福利在线观看| 日韩在线免费av| 亚洲一区免费网站| 91欧美精品成人综合在线观看| 日韩久久精品成人| 亚洲视频在线观看| 伊人一区二区三区久久精品| 亚洲在线一区二区| 国产香蕉精品视频一区二区三区| 久久天天躁狠狠躁夜夜爽蜜月| 久久久久久久网站| 日韩在线视频观看| 成人网在线观看| 国产精品最新在线观看| 亚洲乱码一区二区| 亚洲精品之草原avav久久| 91啪国产在线| 亚洲变态欧美另类捆绑| 亚洲开心激情网| 伊人久久男人天堂| 亚洲肉体裸体xxxx137| 正在播放欧美一区| 久久人人爽人人爽人人片av高清| 亚洲精品第一国产综合精品| 成人国产亚洲精品a区天堂华泰| 欧美激情欧美狂野欧美精品| 国内精品久久久久影院 日本资源| 国产69精品久久久久99| 亚洲女人天堂视频| 2019中文字幕免费视频| 国产精品亚洲视频在线观看| 国产精品高潮呻吟久久av黑人| 青青精品视频播放| 亚洲欧美日韩精品久久奇米色影视| 丝袜美腿亚洲一区二区| 日韩在线一区二区三区免费视频| 91色视频在线导航| 最近2019免费中文字幕视频三| www.国产一区| 亚洲人成网站777色婷婷| 欧美日韩免费网站| 亚洲第一二三四五区| 精品亚洲精品福利线在观看| 久久久久久尹人网香蕉| 国产一区二区三区18| 51精品在线观看| 国产精品视频专区| 成人自拍性视频| 97婷婷大伊香蕉精品视频| 伊人伊人伊人久久| 91精品久久久久久久久| 欧美最近摘花xxxx摘花| 成人妇女淫片aaaa视频| 亚洲精品www久久久| 欧美国产高跟鞋裸体秀xxxhd| 中文字幕精品在线| 国产成人在线一区二区| 136fldh精品导航福利| 精品国产依人香蕉在线精品| 欧美午夜精品久久久久久人妖| 亚洲一区二区久久久| 欧美日韩亚洲天堂| 91视频九色网站| 最近2019年日本中文免费字幕| 亚洲一区二区三区在线免费观看| 亚洲精品久久久久久下一站| 久久久久一本一区二区青青蜜月| 亚洲国内高清视频| 欧美激情亚洲另类| 91精品久久久久久久久| 国产999在线| 疯狂做受xxxx高潮欧美日本| 亚洲欧洲在线视频| 91在线高清免费观看| 国产一区二区三区三区在线观看| 欧美激情精品久久久久久大尺度| 日韩精品极品视频免费观看| 欧美性猛交xxxx免费看漫画| 中文字幕精品影院| 中文字幕欧美专区| 免费成人高清视频| 日本三级韩国三级久久| 亚洲一区二区日本| 欧美在线不卡区| 国产精品久久久久久久app| 亚洲加勒比久久88色综合| 欧美精品免费看| 日本一欧美一欧美一亚洲视频| 国产视频精品va久久久久久| 欧美自拍视频在线观看| 欧美www视频在线观看| 欧美大尺度激情区在线播放| 欧美高清在线观看| 亚洲欧美一区二区三区久久| 国产精品第七影院| 亚洲欧美日韩国产成人| 国产91免费看片| 欧美日韩免费网站| 在线成人中文字幕| 日韩在线观看免费高清| www.亚洲人.com| 色与欲影视天天看综合网| 色综合久久天天综线观看| 国产精品永久免费视频| 亚洲一区二区免费在线| 亚洲中国色老太| 国产精品久久久久久久久| 日韩av电影国产| 日韩欧美国产黄色| 日韩av在线资源| 欧美成人精品在线| 色综合老司机第九色激情| 97精品国产97久久久久久春色| 久久久久久久久电影| 欧美午夜激情视频| 狠狠躁18三区二区一区| 欧美成人午夜影院| 国产成人高清激情视频在线观看| 亚洲a级在线播放观看| 国产精品wwww| 性色av一区二区三区免费| 国产精品成人av性教育| 亚洲精品理论电影| 搡老女人一区二区三区视频tv| 97精品一区二区三区| 欧美一区二区三区图| 亚洲欧美激情精品一区二区| 欧美丰满少妇xxxxx| 色香阁99久久精品久久久| 亚洲人成欧美中文字幕| 国产成人精品日本亚洲| 亚洲视频欧美视频| 91久久久久久久久久久| 国产精品一区二区av影院萌芽| 中文字幕不卡av| 成人免费观看a| 国产精品成av人在线视午夜片| 97人人模人人爽人人喊中文字| 欧美疯狂性受xxxxx另类| 亚洲欧美日韩中文在线| 清纯唯美亚洲综合| 久热精品视频在线观看| 欧美激情久久久久|