首先贴一下官方文档
http://doc.quilljs.cn/1409423
以及我参考的 很好的 一篇文章(在此表示感谢)
https://segmentfault.com/a/1190000019606714
然后是我的最终效果
其中红框1部分是插件自带的一下功能,我删除了一些不常用的(你们可以根据自己需要定制)
红框2部分是需要自己做的表格功能, 图标可以选择自己想用的svg
由于我不是专业前端,所以在项目中如何引入quill就不做赘述了,主要是提一些容易踩坑的点
先放一下代码 需要参考的大佬自取
略微注意一下
quill v1 版本不支持插入表格,v2的dev版本支持表格编辑。
npm install [email protected] -dev–save
(我没有做验证,但是挺多人这么说的,我就直接装了v2dev)
editor.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 | <template> <keep-alive> <div> <div class="editor"></div> </div> </keep-alive> </template> <script> import Quill from 'quill' import 'quill/dist/quill.snow.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': '删除列' } export default { name: 'Editor', props: { value: Object }, data () { return { quill: null, options: { theme: 'snow', modules: { toolbar: { container: [ ['bold', 'italic', 'underline', 'strike'], [{ header: 1 }, { header: 2 }], [{ list: 'ordered' }, { list: 'bullet' }], [{ indent: '-1' }, { indent: '+1' }], [{ color: [] }, { background: [] }], [{ font: [] }], [{ align: [] }], ['clean'], [ { 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(2, 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() } } }, table: 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.setContents(this.value) this.quill.on('text-change', () => { // console.log(this.quill.getContents()) // this.$emit('contentData', this.quill.getContents()) // console.log(this.quill.root.innerHTML) 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.addQuillTitle() }, activated () { this.quill.setContents({}) } } </script> |
需要引入editor的vue
1 2 3 | <el-form-item label="内容"> <editor v-model="content" @contentData="change($event)"></editor> </el-form-item> |
需要展示editor的vue
1 2 3 4 5 | <el-form-item label="内容"> <div class="ql-container ql-snow"> <div class="ql-editor" v-html="form.content"></div> </div> </el-form-item> |
1.this.quill.root.innerHTML 可以获取富文本中的html格式内容,存入数据库后,在需要显示的地方取出,用v-html 展示。 (虽然目前官方不推荐使用)
2.在展示的时候需要class ql-container ql-snow 的div包裹起来,否则会丢失一些样式
3.this.quill.getContents() 取出的是Delta 格式的内容,我没有选择用这个办法。
4.quill 默认支持图片