当前位置:   article > 正文

vue-quill-editor (好用的富文本编辑器,带表格编辑)_vue-quill-editor表格

vue-quill-editor表格

安装依赖

npm i vue-quill-editor@"^3.0.6"    //3版本以上

组件QuillEditor.vue文件:
 

  1. <template>
  2. <keep-alive>
  3. <div class="vue-quill-editor">
  4. <div class="editor"></div>
  5. </div>
  6. </keep-alive>
  7. </template>
  8. <script>
  9. import Quill from "quill";
  10. import "quill/dist/quill.snow.css";
  11. // 设置字体大小
  12. const fontSizeStyle = Quill.import("attributors/style/size"); // 引入这个后会把样式写在style上
  13. fontSizeStyle.whitelist = [
  14. "12px",
  15. "14px",
  16. "16px",
  17. "18px",
  18. "20px",
  19. "24px",
  20. "28px",
  21. "32px",
  22. "36px",
  23. ];
  24. Quill.register(fontSizeStyle, true);
  25. // 设置字体样式
  26. const Font = Quill.import("attributors/style/font"); // 引入这个后会把样式写在style上
  27. const fonts = ["SimSun", "SimHei", "Microsoft-YaHei", "KaiTi", "FangSong"];
  28. Font.whitelist = fonts; // 将字体加入到白名单
  29. Quill.register(Font, true);
  30. const titleConfig = {
  31. "ql-bold": "加粗",
  32. "ql-color": "颜色",
  33. "ql-font": "字体",
  34. "ql-code": "插入代码",
  35. "ql-italic": "斜体",
  36. "ql-link": "添加链接",
  37. "ql-background": "颜色",
  38. "ql-size": "字体大小",
  39. "ql-strike": "删除线",
  40. "ql-script": "上标/下标",
  41. "ql-underline": "下划线",
  42. "ql-blockquote": "引用",
  43. "ql-header": "标题",
  44. "ql-indent": "缩进",
  45. "ql-list": "列表",
  46. "ql-align": "文本对齐",
  47. "ql-direction": "文本方向",
  48. "ql-code-block": "代码块",
  49. "ql-formula": "公式",
  50. "ql-image": "图片",
  51. "ql-video": "视频",
  52. "ql-clean": "清除字体样式",
  53. "ql-upload": "文件",
  54. "ql-table": "插入表格",
  55. "ql-table-insert-row": "插入行",
  56. "ql-table-insert-column": "插入列",
  57. "ql-table-delete-row": "删除行",
  58. "ql-table-delete-column": "删除列",
  59. };
  60. export default {
  61. name: "Editor",
  62. props: {
  63. value: Object,
  64. },
  65. data() {
  66. return {
  67. quill: null,
  68. options: {
  69. theme: "snow",
  70. modules: {
  71. toolbar: {
  72. container: [
  73. ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线 -----['bold', 'italic', 'underline', 'strike']
  74. [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色-----[{ color: [] }, { background: [] }]
  75. [{ align: [] }], // 对齐方式-----[{ align: [] }]
  76. [
  77. {
  78. size: fontSizeStyle.whitelist,
  79. },
  80. ], // 字体大小-----[{ size: ['small', false, 'large', 'huge'] }]
  81. [{ font: fonts }], // 字体种类-----[{ font: [] }]
  82. [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
  83. [{ direction: "ltl" }], // 文本方向-----[{'direction': 'rtl'}]
  84. [{ direction: "rtl" }], // 文本方向-----[{'direction': 'rtl'}]
  85. [{ indent: "-1" }, { indent: "+1" }], // 缩进-----[{ indent: '-1' }, { indent: '+1' }]
  86. [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表-----[{ list: 'ordered' }, { list: 'bullet' }]
  87. [{ script: "sub" }, { script: "super" }], // 上标/下标-----[{ script: 'sub' }, { script: 'super' }]
  88. ["blockquote", "code-block"], // 引用 代码块-----['blockquote', 'code-block']
  89. ["clean"], // 清除文本格式-----['clean']
  90. // ['link', 'image', 'video'] // 链接、图片、视频-----['link', 'image', 'video']
  91. [
  92. { table: "TD" },
  93. { "table-insert-row": "TIR" },
  94. { "table-insert-column": "TIC" },
  95. { "table-delete-row": "TDR" },
  96. { "table-delete-column": "TDC" },
  97. ],
  98. ],
  99. handlers: {
  100. table: function (val) {
  101. this.quill.getModule("table").insertTable(2, 3);
  102. },
  103. "table-insert-row": function () {
  104. this.quill.getModule("table").insertRowBelow();
  105. },
  106. "table-insert-column": function () {
  107. this.quill.getModule("table").insertColumnRight();
  108. },
  109. "table-delete-row": function () {
  110. this.quill.getModule("table").deleteRow();
  111. },
  112. "table-delete-column": function () {
  113. this.quill.getModule("table").deleteColumn();
  114. },
  115. },
  116. },
  117. table: true,
  118. },
  119. placeholder: "",
  120. },
  121. };
  122. },
  123. methods: {
  124. addQuillTitle() {
  125. const oToolBar = document.querySelector(".ql-toolbar");
  126. const aButton = oToolBar.querySelectorAll("button");
  127. const aSelect = oToolBar.querySelectorAll("select");
  128. aButton.forEach(function (item) {
  129. if (item.className === "ql-script") {
  130. item.value === "sub" ? (item.title = "下标") : (item.title = "上标");
  131. } else if (item.className === "ql-indent") {
  132. item.value === "+1"
  133. ? (item.title = "向右缩进")
  134. : (item.title = "向左缩进");
  135. } else {
  136. item.title = titleConfig[item.classList[0]];
  137. }
  138. });
  139. aSelect.forEach(function (item) {
  140. item.parentNode.title = titleConfig[item.classList[0]];
  141. });
  142. },
  143. getContentData() {
  144. return this.quill.getContents();
  145. },
  146. },
  147. mounted() {
  148. const dom = this.$el.querySelector(".editor");
  149. this.quill = new Quill(dom, this.options);
  150. // this.quill.setContents(this.value)
  151. this.quill.on("text-change", () => {
  152. // console.log(this.quill.getContents())
  153. // this.$emit('contentData', this.quill.getContents())
  154. // console.log(this.quill.root.innerHTML)
  155. this.$emit("contentData", this.quill.root.innerHTML);
  156. });
  157. this.$el.querySelector(
  158. ".ql-table-insert-row"
  159. ).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>`;
  160. this.$el.querySelector(
  161. ".ql-table-insert-column"
  162. ).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>`;
  163. this.$el.querySelector(
  164. ".ql-table-delete-row"
  165. ).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>`;
  166. this.$el.querySelector(
  167. ".ql-table-delete-column"
  168. ).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>`;
  169. this.addQuillTitle();
  170. },
  171. activated() {
  172. this.quill.setContents({});
  173. },
  174. };
  175. </script>
  176. <style lang="scss">
  177. .vue-quill-editor {
  178. line-height: normal;
  179. .ql-container.ql-snow {
  180. line-height: normal !important;
  181. height: 460px !important;
  182. font-size: 14px;
  183. }
  184. .ql-snow {
  185. .ql-tooltip[data-mode="link"]::before {
  186. content: "请输入链接地址:";
  187. }
  188. .ql-tooltip.ql-editing a.ql-action::after {
  189. border-right: 0px;
  190. content: "保存";
  191. padding-right: 0px;
  192. }
  193. .ql-tooltip[data-mode="video"]::before {
  194. content: "请输入视频地址:";
  195. }
  196. .ql-picker.ql-size {
  197. .ql-picker-label[data-value="12px"]::before,
  198. .ql-picker-item[data-value="12px"]::before {
  199. content: "12px";
  200. }
  201. .ql-picker-label[data-value="14px"]::before,
  202. .ql-picker-item[data-value="14px"]::before {
  203. content: "14px";
  204. }
  205. .ql-picker-label[data-value="16px"]::before,
  206. .ql-picker-item[data-value="16px"]::before {
  207. content: "16px";
  208. }
  209. .ql-picker-label[data-value="18px"]::before,
  210. .ql-picker-item[data-value="18px"]::before {
  211. content: "18px";
  212. }
  213. .ql-picker-label[data-value="20px"]::before,
  214. .ql-picker-item[data-value="20px"]::before {
  215. content: "20px";
  216. }
  217. .ql-picker-label[data-value="24px"]::before,
  218. .ql-picker-item[data-value="24px"]::before {
  219. content: "24px";
  220. }
  221. .ql-picker-label[data-value="28px"]::before,
  222. .ql-picker-item[data-value="28px"]::before {
  223. content: "28px";
  224. }
  225. .ql-picker-label[data-value="32px"]::before,
  226. .ql-picker-item[data-value="32px"]::before {
  227. content: "32px";
  228. }
  229. .ql-picker-label[data-value="36px"]::before,
  230. .ql-picker-item[data-value="36px"]::before {
  231. content: "36px";
  232. }
  233. }
  234. .ql-picker.ql-header {
  235. .ql-picker-label::before,
  236. .ql-picker-item::before {
  237. content: "文本";
  238. }
  239. .ql-picker-label[data-value="1"]::before,
  240. .ql-picker-item[data-value="1"]::before {
  241. content: "标题1";
  242. }
  243. .ql-picker-label[data-value="2"]::before,
  244. .ql-picker-item[data-value="2"]::before {
  245. content: "标题2";
  246. }
  247. .ql-picker-label[data-value="3"]::before,
  248. .ql-picker-item[data-value="3"]::before {
  249. content: "标题3";
  250. }
  251. .ql-picker-label[data-value="4"]::before,
  252. .ql-picker-item[data-value="4"]::before {
  253. content: "标题4";
  254. }
  255. .ql-picker-label[data-value="5"]::before,
  256. .ql-picker-item[data-value="5"]::before {
  257. content: "标题5";
  258. }
  259. .ql-picker-label[data-value="6"]::before,
  260. .ql-picker-item[data-value="6"]::before {
  261. content: "标题6";
  262. }
  263. }
  264. .ql-picker.ql-font {
  265. .ql-picker-label[data-value="SimSun"]::before,
  266. .ql-picker-item[data-value="SimSun"]::before {
  267. content: "宋体";
  268. font-family: "SimSun" !important;
  269. }
  270. .ql-picker-label[data-value="SimHei"]::before,
  271. .ql-picker-item[data-value="SimHei"]::before {
  272. content: "黑体";
  273. font-family: "SimHei";
  274. }
  275. .ql-picker-label[data-value="Microsoft-YaHei"]::before,
  276. .ql-picker-item[data-value="Microsoft-YaHei"]::before {
  277. content: "微软雅黑";
  278. font-family: "Microsoft YaHei";
  279. }
  280. .ql-picker-label[data-value="KaiTi"]::before,
  281. .ql-picker-item[data-value="KaiTi"]::before {
  282. content: "楷体";
  283. font-family: "KaiTi" !important;
  284. }
  285. .ql-picker-label[data-value="FangSong"]::before,
  286. .ql-picker-item[data-value="FangSong"]::before {
  287. content: "仿宋";
  288. font-family: "FangSong";
  289. }
  290. }
  291. }
  292. .ql-align-center {
  293. text-align: center;
  294. }
  295. .ql-align-right {
  296. text-align: right;
  297. }
  298. .ql-align-left {
  299. text-align: left;
  300. }
  301. }
  302. </style>

父组件使用:

  1. // 编辑状态
  2. <QuillEditor v-if="isEdit" ref="QuillEditor" />
  3. // 展示状态(为保证格式正确,要命名为"ql-editor",外面盒子要命名为"ql-container ql-snow")
  4. <div v-else class="ql-container ql-snow">
  5. <div
  6. class="ql-editor"
  7. style="height: 500px; padding: 20px 20px; width: 100%"
  8. v-html="content"
  9. />
  10. </div>

main.js:
 

  1. import VueQuillEditor from 'vue-quill-editor' // 富文本编辑器
  2. import 'quill/dist/quill.core.css'
  3. import 'quill/dist/quill.snow.css'
  4. import 'quill/dist/quill.bubble.css'
  5. Vue.use(VueQuillEditor)

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/889581
推荐阅读
相关标签
  

闽ICP备14008679号