Bootstrap

vue 使用vue-quill-editor 富文本添加源码模式,查看源码功能和表格功能

今天接到个需求,在富文本中增加查看源码和增加表格功能,感觉这种功能手拿把掐,但是奈于平时沉迷于移动端有段时间没写pc了,看了下官方感觉一个头两个大,于是在茫茫文档中各种借鉴(抄袭)完成了功能

1.源码功能相对来说比较简单 就是自定义工具栏

options: {
 theme: 'snow',
 modules: {
  toolbar: {
     container: [
	  ['bold', 'italic', 'underline', 'strike'], // 加粗 斜体 下划线 删除线
  	  ['blockquote', 'code-block'], // 引用  代码块
	  [{ header: 1 }, { header: 2 }], // 1、2 级标题
	  [{ list: 'ordered' }, { list: 'bullet' }], // 有序、无序列表
	  [{ script: 'sub' }, { script: 'super' }], // 上标/下标
	  [{ indent: '-1' }, { indent: '+1' }], // 缩进
	  [{ direction: 'rtl' }], // 文本方向
	  ['link', 'image', 'video'], // 链接、图片、视频
	  [{ align: [] }], // 添加居中按钮
	  [{ color: [] }], // 文字颜色按钮
	  ['sourceEditor'],//新添加源码的工具
	 ]
   }
 }
}

在handlers中添加事件

handlers: {
     sourceEditor: function () {     //添加工具方法
       const reg = /\<br\>/g,
         container = this.container,
         firstChild = container.nextElementSibling.firstChild;
       if (!this.shadeBox) {
         let shadeBox = this.shadeBox = document.createElement('div');
         shadeBox.style.cssText = 'position:absolute; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); cursor:pointer';
         container.style.position = 'relative';
         shadeBox.addEventListener('click', function () {
           this.style.display = 'none';
           firstChild.innerHTML = firstChild.innerText.trim();
         }, false);
         container.appendChild(shadeBox);
         let innerHTML = firstChild.innerHTML;
         innerHTML = innerHTML.replace(reg, '');
         firstChild.innerText = innerHTML;
       } else {
         let innerHTML = firstChild.innerHTML;
         innerHTML = innerHTML.replace(reg, '');
         firstChild.innerText = innerHTML;
         this.shadeBox.style.display = 'block';
       }
     }
   },
            

在mounted中增加显示图标

mounted() {
this.$el.querySelector(
  '.ql-sourceEditor'
 ).innerHTML = `<i class="el-icon-edit"></i>`
}

效果图
在这里插入图片描述

增加表格功能

1.将quill的版本升级到2.0 切记 切记 切记

npm install quill@2.0.0-dev.4

2.将富文本封装成一个子组件 (和查看源码的代码一起,太懒了懒得拆分讲解)

<template>
 
  <div>
    <div class="editor"></div>
  </div>
 
</template>
 
<script>
import Quill from 'quill'
import 'quill/dist/quill.snow.css'
import 'quill/dist/quill.core.css'
import 'quill/dist/quill.bubble.css'
const titleConfig = {
  'ql-bold': '加粗',
  'ql-color': '颜色',
  'ql-font': '字体',
  'ql-code': '插入代码',
  'ql-italic': '斜体',
  'ql-link': '添加链接',
  'ql-background': '颜色',
  'ql-size': '字体大小',
  'ql-strike': '删除线',
  'ql-script': '上标/下标',
  'ql-underline': '下划线',
  'ql-blockquote': '引用',
  'ql-header': '标题',
  'ql-indent': '缩进',
  'ql-list': '列表',
  'ql-align': '文本对齐',
  'ql-direction': '文本方向',
  'ql-code-block': '代码块',
  'ql-formula': '公式',
  'ql-image': '图片',
  'ql-video': '视频',
  'ql-clean': '清除字体样式',
  'ql-upload': '文件',
  'ql-table': '插入表格',
  'ql-table-insert-row': '插入行',
  'ql-table-insert-column': '插入列',
  'ql-table-delete-row': '删除行',
  'ql-table-delete-column': '删除列',
  'ql-sourceEditor': '源码编辑'
}
export default {
  name: 'editorQuill',
  props: {
    value: {
 
    }
  },
  data() {
    return {
      quill: null,
      options: {
        theme: 'snow',
        modules: {
          toolbar: {
            container: [
 
              ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
              ["blockquote", "code-block"], // 引用  代码块
                [{ header: 1 }, { header: 2 }], // 1、2 级标题
              [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
              [{ script: "sub" }, { script: "super" }], // 上标/下标
              [{ indent: "-1" }, { indent: "+1" }], // 缩进
              [{'direction': 'rtl'}],                         // 文本方向
              [{ size: ["small", false, "large", "huge"] }], // 字体大小
              [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
              [{ font: [] }], // 字体种类
              [{ align: [] }], // 对齐方式
              ["clean"], // 清除文本格式
              // ["link","image"], // 链接、图片、视频
              ['sourceEditor'],//新添加的工具
              [
                { table: 'TD' },
                { 'table-insert-row': 'TIR' },
                { 'table-insert-column': 'TIC' },
                { 'table-delete-row': 'TDR' },
                { 'table-delete-column': 'TDC' }
              ]
            ],
            handlers: {
              table: function (val) {
                this.quill.getModule('table').insertTable(3, 3)
              },
              'table-insert-row': function () {
                this.quill.getModule('table').insertRowBelow()
              },
              'table-insert-column': function () {
                this.quill.getModule('table').insertColumnRight()
              },
              'table-delete-row': function () {
                this.quill.getModule('table').deleteRow()
              },
              'table-delete-column': function () {
                this.quill.getModule('table').deleteColumn()
              },
              sourceEditor: function () {     //添加工具方法
                const reg = /\<br\>/g,
                  container = this.container,
                  firstChild = container.nextElementSibling.firstChild;
                if (!this.shadeBox) {
                  let shadeBox = this.shadeBox = document.createElement('div');
                  shadeBox.style.cssText = 'position:absolute; top:0; left:0; width:100%; height:100%; background:rgba(0,0,0,0.5); cursor:pointer';
                  container.style.position = 'relative';
                  shadeBox.addEventListener('click', function () {
                    this.style.display = 'none';
                    firstChild.innerHTML = firstChild.innerText.trim();
                  }, false);
                  container.appendChild(shadeBox);
                  let innerHTML = firstChild.innerHTML;
                  innerHTML = innerHTML.replace(reg, '');
                  firstChild.innerText = innerHTML;
                } else {
                  let innerHTML = firstChild.innerHTML;
                  innerHTML = innerHTML.replace(reg, '');
                  firstChild.innerText = innerHTML;
                  this.shadeBox.style.display = 'block';
                }
              }
            },
            
          },
          table: true
        },
       // readOnly: true, //是否只读
        placeholder: ''
      }
    }
  },
  methods: {
    addQuillTitle() {
      const oToolBar = document.querySelector('.ql-toolbar')
      const aButton = oToolBar.querySelectorAll('button')
      const aSelect = oToolBar.querySelectorAll('select')
      aButton.forEach(function (item) {
        if (item.className === 'ql-script') {
          item.value === 'sub' ? (item.title = '下标') : (item.title = '上标')
        } else if (item.className === 'ql-indent') {
          item.value === '+1' ? (item.title = '向右缩进') : (item.title = '向左缩进')
        } else {
          item.title = titleConfig[item.classList[0]]
        }
      })
      aSelect.forEach(function (item) {
        item.parentNode.title = titleConfig[item.classList[0]]
      })
    },
    getContentData() {
      return this.quill.getContents()
    }
  },
  mounted() {
    const dom = this.$el.querySelector('.editor')
    this.quill = new Quill(dom, this.options)
    this.quill.clipboard.dangerouslyPasteHTML(0, this.value)  // html格式数据
    this.quill.on('text-change', () => {
      // console.log(this.quill.getContents())//detla格式数据
      // this.$emit('contentData', this.quill.getContents()) 
      // console.log(this.quill.root.innerHTML)//html格式数据
      this.$emit('contentData', this.quill.root.innerHTML)
    })
    this.$el.querySelector(
      '.ql-table-insert-row'
    ).innerHTML = `<svg t="1591862376726" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6306" width="18" height="200"><path d="M500.8 604.779L267.307 371.392l-45.227 45.27 278.741 278.613L779.307 416.66l-45.248-45.248z" p-id="6307"></path></svg>`
    this.$el.querySelector(
      '.ql-table-insert-column'
    ).innerHTML = `<svg t="1591862238963" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6509" width="18" height="200"><path d="M593.450667 512.128L360.064 278.613333l45.290667-45.226666 278.613333 278.762666L405.333333 790.613333l-45.226666-45.269333z" p-id="6510"></path></svg>`
    this.$el.querySelector(
      '.ql-table-delete-row'
    ).innerHTML = `<svg t="1591862253524" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6632" width="18" height="200"><path d="M500.8 461.909333L267.306667 695.296l-45.226667-45.269333 278.741333-278.613334L779.306667 650.026667l-45.248 45.226666z" p-id="6633"></path></svg>`
    this.$el.querySelector(
      '.ql-table-delete-column'
    ).innerHTML = `<svg t="1591862261059" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6755" width="18" height="200"><path d="M641.28 278.613333l-45.226667-45.226666-278.634666 278.762666 278.613333 278.485334 45.248-45.269334-233.365333-233.237333z" p-id="6756"></path></svg>`
    this.$el.querySelector(
      '.ql-sourceEditor'
    ).innerHTML = `<i class="el-icon-edit"></i>`
    this.addQuillTitle()
  },
  activated() {
    this.quill.setContents({})
  }
}
</script>

3.在父组件中用

<template>
  <div>
	  <editor-quill
	   ref="myQuillEditor"
	   v-model="content"
	   class="my-quill-editor"
	   />
 </div>
</template>
<script>
import editorQuill from '../editorQuill'
export default {
  components: {
    editorQuill,
  },
  data() {
    return {
       content:''
    }
  }
}
</script>

4.总体效果图
在这里插入图片描述
本人菜鸡各位大哥请轻点喷,有啥问题可以私

;