index.vue 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. <template>
  2. <div>
  3. <div class="mdeditor-box">
  4. <MarkdownPro ref="md1" v-model="content" :height="height" :toolbars="toolbars" :is-custom-fullscreen="transfer" @on-custom="customClick"></MarkdownPro>
  5. <img-upload ref="myUpload" class="teditor-upload" type="callback" @on-callback="editorImage" num="50" style="display:none;"></img-upload>
  6. </div>
  7. <Modal v-model="transfer" class="mdeditor-transfer" footer-hide fullscreen transfer :closable="false">
  8. <div class="mdeditor-transfer-body">
  9. <MarkdownPro ref="md2" v-if="transfer" v-model="content" :toolbars="toolbars" :is-custom-fullscreen="transfer" height="100%" @on-custom="customClick"></MarkdownPro>
  10. </div>
  11. </Modal>
  12. <Modal v-model="html2md" title="html转markdown" okText="转换成markdown" width="680" class-name="simple-modal" @on-ok="htmlOk" transfer>
  13. <Input type="textarea" v-model="htmlValue" :rows="14" placeholder="请输入html代码..." />
  14. </Modal>
  15. </div>
  16. </template>
  17. <style lang="scss">
  18. .mdeditor-transfer {
  19. background-color: #ffffff;
  20. .ivu-modal-header {
  21. display: none;
  22. }
  23. .ivu-modal-close {
  24. top: 7px;
  25. }
  26. .mdeditor-transfer-body {
  27. position: absolute;
  28. top: 0;
  29. left: 0;
  30. width: 100%;
  31. height: 100%;
  32. padding: 0;
  33. margin: 0;
  34. }
  35. }
  36. </style>
  37. <style lang="scss" scoped>
  38. .mdeditor-box {
  39. position: relative;
  40. }
  41. </style>
  42. <script>
  43. import MarkdownPro from './pro';
  44. import ImgUpload from "../ImgUpload";
  45. export default {
  46. name: 'MDEditor',
  47. components: {ImgUpload, MarkdownPro},
  48. props: {
  49. value: {
  50. default: ''
  51. },
  52. height: {
  53. default: 380,
  54. },
  55. toolbars: {
  56. type: Object,
  57. default: () => {
  58. return {
  59. strong: true,
  60. italic: true,
  61. overline: true,
  62. h1: true,
  63. h2: true,
  64. h3: true,
  65. h4: false,
  66. h5: false,
  67. h6: false,
  68. hr: true,
  69. quote: true,
  70. ul: true,
  71. ol: true,
  72. code: true,
  73. link: true,
  74. image: false,
  75. uploadImage: false,
  76. table: true,
  77. checked: true,
  78. notChecked: true,
  79. split: true,
  80. preview: true,
  81. fullscreen: false,
  82. theme: false,
  83. exportmd: false,
  84. importmd: false,
  85. save: false,
  86. clear: false,
  87. custom_image: true,
  88. custom_uploadImage: true,
  89. custom_fullscreen: true,
  90. };
  91. }
  92. }
  93. },
  94. data() {
  95. return {
  96. content: '',
  97. transfer: false,
  98. html2md: false,
  99. htmlValue: '',
  100. };
  101. },
  102. mounted() {
  103. this.content = this.value;
  104. },
  105. activated() {
  106. this.content = this.value;
  107. },
  108. watch: {
  109. value(newValue) {
  110. if (newValue == null) {
  111. newValue = "";
  112. }
  113. this.content = newValue;
  114. },
  115. content(val) {
  116. this.$emit('input', val);
  117. },
  118. },
  119. methods: {
  120. editorImage(lists) {
  121. for (let i = 0; i < lists.length; i++) {
  122. let item = lists[i];
  123. if (typeof item === 'object' && typeof item.url === "string") {
  124. if (this.transfer) {
  125. this.$refs.md2.insertContent('\n![image](' + item.url + ')');
  126. } else {
  127. this.$refs.md1.insertContent('\n![image](' + item.url + ')');
  128. }
  129. }
  130. }
  131. },
  132. customClick(act) {
  133. switch (act) {
  134. case "image-browse": {
  135. this.$refs.myUpload.browsePicture();
  136. break;
  137. }
  138. case "image-upload": {
  139. this.$refs.myUpload.handleClick();
  140. break;
  141. }
  142. case "fullscreen": {
  143. this.transfer = !this.transfer;
  144. break;
  145. }
  146. case "html2md": {
  147. this.html2md = true;
  148. break;
  149. }
  150. }
  151. },
  152. htmlOk() {
  153. this.loadScript(window.location.origin + '/js/html2md.js', () => {
  154. if (typeof toMarkdown !== 'function') {
  155. alert("组件加载失败!");
  156. return;
  157. }
  158. if (this.transfer) {
  159. this.$refs.md2.insertContent('\n' + toMarkdown(this.htmlValue, { gfm: true }));
  160. } else {
  161. this.$refs.md1.insertContent('\n' + toMarkdown(this.htmlValue, { gfm: true }));
  162. }
  163. this.htmlValue = "";
  164. });
  165. },
  166. loadScript(url, callback) {
  167. let script = document.createElement("script");
  168. script.type = "text/javascript";
  169. if (script.readyState) {
  170. script.onreadystatechange = () => {
  171. if (script.readyState === "loaded" || script.readyState === "complete") {
  172. script.onreadystatechange = null;
  173. callback();
  174. }
  175. };
  176. } else {
  177. script.onload = () => {
  178. callback();
  179. };
  180. }
  181. script.src = url;
  182. document.body.appendChild(script);
  183. }
  184. }
  185. }
  186. </script>