index.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. import React from 'react';
  2. import ReactQuill from 'react-quill';
  3. import 'react-quill/dist/quill.snow.css';
  4. import { generateUUID } from '../../services/Tools';
  5. const modules = {
  6. toolbar: {
  7. container: [
  8. [{ header: '1' }, { header: '2' }],
  9. ['bold', 'underline', 'blockquote'],
  10. [{ color: [] }, { background: [] }],
  11. [{ list: 'ordered' }, { list: 'bullet' }, { indent: '-1' }, { indent: '+1' }],
  12. // ['image'],
  13. // ['link', 'video'],
  14. // ['clean'],
  15. ],
  16. handlers: {},
  17. },
  18. clipboard: {
  19. // toggle to add extra line breaks when pasting HTML:
  20. matchVisual: false,
  21. },
  22. };
  23. const formats = [
  24. 'header',
  25. 'font',
  26. 'size',
  27. 'bold',
  28. 'italic',
  29. 'underline',
  30. 'strike',
  31. 'blockquote',
  32. 'color',
  33. 'list',
  34. 'bullet',
  35. 'indent',
  36. 'link',
  37. 'image',
  38. // 'video',
  39. ];
  40. class Editor extends React.Component {
  41. constructor(props) {
  42. super(props);
  43. this.quillRef = null;
  44. this.state = {};
  45. this.loading = 0;
  46. this.modules = Object.assign({}, modules, props.modules);
  47. if (props.onUpload && (!props.modules || !props.modules.toolbar)) {
  48. this.modules.toolbar.container.unshift(['image']);
  49. }
  50. // console.log(this.modules);
  51. this.modules.toolbar.handlers.image = () => this.image();
  52. Object.keys(this.modules.toolbar.handlers).forEach(key => {
  53. const handler = this.modules.toolbar.handlers[key];
  54. this.modules.toolbar.handlers[key] = () => {
  55. handler(this.quillRef.getEditor());
  56. };
  57. });
  58. this.formats = Object.assign({}, formats, props.formats);
  59. }
  60. progress(data) {
  61. return done => {
  62. if (this.props.onProgress) this.props.onProgress(data);
  63. done();
  64. };
  65. }
  66. image() {
  67. const self = this;
  68. this.container = this.quillRef.editingArea;
  69. const quill = this.quillRef.getEditor();
  70. let fileInput = this.container.querySelector('input.ql-image[type=file]'); // fileInput
  71. if (fileInput == null) {
  72. fileInput = document.createElement('input');
  73. fileInput.setAttribute('type', 'file');
  74. fileInput.setAttribute('accept', 'image/png, image/gif, image/jpeg, image/bmp, image/x-icon');
  75. fileInput.classList.add('ql-image');
  76. fileInput.addEventListener('change', () => {
  77. if (fileInput.files != null && fileInput.files[0] != null) {
  78. // getSelection 选择当前光标位置咯 然后在下一个range.index用它自带的embed媒介插入方式插入你已经存储在阿里上的图片了
  79. const range = quill.getSelection(true);
  80. const file = fileInput.files[0];
  81. const suffix = file.name.substring(file.name.lastIndexOf('.')).toLowerCase();
  82. const name = generateUUID();
  83. self.props
  84. .onUpload(file, self.props.path, self.progress, `${self.props.path}/${name}${suffix}`)
  85. .then(data => {
  86. self.setState({ uploading: false, load: self.state.load + 1 });
  87. quill.insertEmbed(range.index, 'image', data.url || data);
  88. quill.setSelection(range.index + 1);
  89. })
  90. .catch(err => {
  91. self.setState({ uploading: false, load: self.state.load + 1 });
  92. if (self.props.onError) self.props.onError(err);
  93. });
  94. }
  95. });
  96. }
  97. fileInput.click();
  98. }
  99. render() {
  100. // console.log(this.props.value);
  101. return (
  102. <div>
  103. <ReactQuill
  104. ref={el => {
  105. this.quillRef = el;
  106. }}
  107. style={this.props.style}
  108. theme={this.props.theme || 'snow'}
  109. onChange={(content, delta, source, editor) => {
  110. if (this.props.onChange) this.props.onChange(content, delta, source, editor);
  111. }}
  112. defaultValue={this.props.defaultValue || ''}
  113. value={this.props.value || ''}
  114. modules={this.modules}
  115. formats={this.formats}
  116. placeholder={this.props.placeholder}
  117. />
  118. </div>
  119. );
  120. }
  121. }
  122. export default Editor;