index.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. <template>
  2. <div>
  3. <!-- 图片上传组件辅助 -->
  4. <el-upload
  5. class="avatar-uploader quill-img"
  6. :action="uploadImgUrl"
  7. name="file"
  8. :headers="headers"
  9. :show-file-list="false"
  10. :on-success="quillImgSuccess"
  11. :on-error="uploadError"
  12. :before-upload="quillImgBefore"
  13. accept='.jpg,.jpeg,.png,.gif'
  14. ></el-upload>
  15. <!-- 富文本组件 -->
  16. <quill-editor
  17. class="editor"
  18. v-model="content"
  19. ref="quillEditor"
  20. :options="editorOption"
  21. @blur="onEditorBlur($event)"
  22. @focus="onEditorFocus($event)"
  23. @change="onEditorChange($event)"
  24. ></quill-editor>
  25. </div>
  26. </template>
  27. <script>
  28. import { getToken } from '@/utils/auth'
  29. // 工具栏配置
  30. const toolbarOptions = [
  31. ["bold", "italic", "underline", "strike"], // 加粗 斜体 下划线 删除线
  32. ["blockquote", "code-block"], // 引用 代码块
  33. [{ list: "ordered" }, { list: "bullet" }], // 有序、无序列表
  34. [{ indent: "-1" }, { indent: "+1" }], // 缩进
  35. [{ size: ["small", false, "large", "huge"] }], // 字体大小
  36. [{ header: [1, 2, 3, 4, 5, 6, false] }], // 标题
  37. [{ color: [] }, { background: [] }], // 字体颜色、字体背景颜色
  38. [{ align: [] }], // 对齐方式
  39. ["clean"], // 清除文本格式
  40. ["link", "image", "video"] // 链接、图片、视频
  41. ];
  42. import { quillEditor } from "vue-quill-editor";
  43. import "quill/dist/quill.core.css";
  44. import "quill/dist/quill.snow.css";
  45. import "quill/dist/quill.bubble.css";
  46. export default {
  47. props: {
  48. /* 编辑器的内容 */
  49. value: {
  50. type: String
  51. },
  52. /* 图片大小 */
  53. maxSize: {
  54. type: Number,
  55. default: 4000 //kb
  56. }
  57. },
  58. components: { quillEditor },
  59. data() {
  60. return {
  61. content: this.value,
  62. uploadImgUrl: "",
  63. editorOption: {
  64. theme: "snow", // or 'bubble'
  65. placeholder: "请输入内容",
  66. modules: {
  67. toolbar: {
  68. container: toolbarOptions,
  69. handlers: {
  70. image: function(value) {
  71. if (value) {
  72. // 触发input框选择图片文件
  73. document.querySelector(".quill-img input").click();
  74. } else {
  75. this.quill.format("image", false);
  76. }
  77. }
  78. }
  79. }
  80. }
  81. },
  82. uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
  83. headers: {
  84. Authorization: 'Bearer ' + getToken()
  85. }
  86. };
  87. },
  88. watch: {
  89. value: function() {
  90. this.content = this.value;
  91. }
  92. },
  93. methods: {
  94. onEditorBlur() {
  95. //失去焦点事件
  96. },
  97. onEditorFocus() {
  98. //获得焦点事件
  99. },
  100. onEditorChange() {
  101. //内容改变事件
  102. this.$emit("input", this.content);
  103. },
  104. // 富文本图片上传前
  105. quillImgBefore(file) {
  106. let fileType = file.type;
  107. if(fileType === 'image/jpeg' || fileType === 'image/png'){
  108. return true;
  109. }else {
  110. this.$message.error('请插入图片类型文件(jpg/jpeg/png)');
  111. return false;
  112. }
  113. },
  114. quillImgSuccess(res, file) {
  115. // res为图片服务器返回的数据
  116. // 获取富文本组件实例
  117. let quill = this.$refs.quillEditor.quill;
  118. // 如果上传成功
  119. if (res.code == 200) {
  120. // 获取光标所在位置
  121. let length = quill.getSelection().index;
  122. // 插入图片 res.url为服务器返回的图片地址
  123. quill.insertEmbed(length, "image", res.url);
  124. // 调整光标到最后
  125. quill.setSelection(length + 1);
  126. } else {
  127. this.$message.error("图片插入失败");
  128. }
  129. },
  130. // 富文本图片上传失败
  131. uploadError() {
  132. // loading动画消失
  133. this.$message.error("图片插入失败");
  134. }
  135. }
  136. };
  137. </script>
  138. <style>
  139. .editor {
  140. white-space: pre-wrap!important;
  141. line-height: normal !important;
  142. height: 192px;
  143. }
  144. .quill-img {
  145. display: none;
  146. }
  147. .ql-snow .ql-tooltip[data-mode="link"]::before {
  148. content: "请输入链接地址:";
  149. }
  150. .ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  151. border-right: 0px;
  152. content: "保存";
  153. padding-right: 0px;
  154. }
  155. .ql-snow .ql-tooltip[data-mode="video"]::before {
  156. content: "请输入视频地址:";
  157. }
  158. .ql-snow .ql-picker.ql-size .ql-picker-label::before,
  159. .ql-snow .ql-picker.ql-size .ql-picker-item::before {
  160. content: "14px";
  161. }
  162. .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
  163. .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  164. content: "10px";
  165. }
  166. .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
  167. .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  168. content: "18px";
  169. }
  170. .ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
  171. .ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  172. content: "32px";
  173. }
  174. .ql-snow .ql-picker.ql-header .ql-picker-label::before,
  175. .ql-snow .ql-picker.ql-header .ql-picker-item::before {
  176. content: "文本";
  177. }
  178. .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
  179. .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  180. content: "标题1";
  181. }
  182. .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
  183. .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  184. content: "标题2";
  185. }
  186. .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
  187. .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  188. content: "标题3";
  189. }
  190. .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
  191. .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  192. content: "标题4";
  193. }
  194. .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
  195. .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  196. content: "标题5";
  197. }
  198. .ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
  199. .ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  200. content: "标题6";
  201. }
  202. .ql-snow .ql-picker.ql-font .ql-picker-label::before,
  203. .ql-snow .ql-picker.ql-font .ql-picker-item::before {
  204. content: "标准字体";
  205. }
  206. .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
  207. .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  208. content: "衬线字体";
  209. }
  210. .ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
  211. .ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  212. content: "等宽字体";
  213. }
  214. </style>