index.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <template>
  2. <div class='tinymce-container editor-container'>
  3. <textarea class='tinymce-textarea' :id="id"></textarea>
  4. </div>
  5. </template>
  6. <script>
  7. // import { getToken, upload } from 'api/qiniu'; // 七牛
  8. export default {
  9. name: 'tinymce',
  10. props: {
  11. id: {
  12. type: String,
  13. default: 'tinymceEditor'
  14. },
  15. value: {
  16. type: String,
  17. default: ''
  18. },
  19. toolbar: {
  20. type: Array,
  21. required: false,
  22. default() {
  23. return ['removeformat undo redo | bullist numlist | outdent indent | forecolor | fullscreen code', 'bold italic blockquote | h2 p media link | alignleft aligncenter alignright']
  24. }
  25. },
  26. data() {
  27. return {
  28. hasChange: false,
  29. hasInit: false
  30. }
  31. },
  32. menubar: {
  33. default: ''
  34. },
  35. height: {
  36. type: Number,
  37. required: false,
  38. default: 360
  39. }
  40. },
  41. watch: {
  42. value(val) {
  43. if (!this.hasChange && this.hasInit) {
  44. this.$nextTick(() => tinymce.get(this.id).setContent(val))
  45. }
  46. }
  47. },
  48. mounted() {
  49. const _this = this;
  50. tinymce.init({
  51. selector: `#${this.id}`,
  52. height: this.height,
  53. body_class: 'panel-body ',
  54. object_resizing: false,
  55. // language: 'zh_CN',
  56. // language_url: '/static/tinymce/langs/zh_CN.js',
  57. toolbar: this.toolbar,
  58. menubar: this.menubar,
  59. plugins: 'advlist,autolink,code,paste,textcolor, colorpicker,fullscreen,link,lists,media,wordcount, imagetools,watermark',
  60. end_container_on_empty_block: true,
  61. powerpaste_word_import: 'clean',
  62. code_dialog_height: 450,
  63. code_dialog_width: 1000,
  64. advlist_bullet_styles: 'square',
  65. advlist_number_styles: 'default',
  66. block_formats: '普通标签=p;小标题=h2;',
  67. imagetools_cors_hosts: ['wpimg.wallstcn.com', 'wallstreetcn.com'],
  68. imagetools_toolbar: 'watermark',
  69. default_link_target: '_blank',
  70. link_title: false,
  71. init_instance_callback: editor => {
  72. if (_this.value) {
  73. editor.setContent(_this.value)
  74. }
  75. _this.hasInit = true;
  76. editor.on('NodeChange Change KeyUp', () => {
  77. this.hasChange = true;
  78. this.$emit('input', editor.getContent({ format: 'raw' }));
  79. });
  80. },
  81. // 整合七牛上传
  82. // images_dataimg_filter(img) {
  83. // setTimeout(() => {
  84. // const $image = $(img);
  85. // $image.removeAttr('width');
  86. // $image.removeAttr('height');
  87. // if ($image[0].height && $image[0].width) {
  88. // $image.attr('data-wscntype', 'image');
  89. // $image.attr('data-wscnh', $image[0].height);
  90. // $image.attr('data-wscnw', $image[0].width);
  91. // $image.addClass('wscnph');
  92. // }
  93. // }, 0);
  94. // return img
  95. // },
  96. // images_upload_handler(blobInfo, success, failure, progress) {
  97. // progress(0);
  98. // const token = _this.$store.getters.token;
  99. // getToken(token).then(response => {
  100. // const url = response.data.qiniu_url;
  101. // const formData = new FormData();
  102. // formData.append('token', response.data.qiniu_token);
  103. // formData.append('key', response.data.qiniu_key);
  104. // formData.append('file', blobInfo.blob(), url);
  105. // upload(formData).then(() => {
  106. // success(url);
  107. // progress(100);
  108. // })
  109. // }).catch(err => {
  110. // failure('出现未知问题,刷新页面,或者联系程序员')
  111. // console.log(err);
  112. // });
  113. // },
  114. setup(editor) {
  115. editor.addButton('h2', {
  116. title: '小标题', // tooltip text seen on mouseover
  117. text: '小标题',
  118. onclick() {
  119. editor.execCommand('mceToggleFormat', false, 'h2');
  120. },
  121. onPostRender() {
  122. const btn = this;
  123. editor.on('init', () => {
  124. editor.formatter.formatChanged('h2', state => {
  125. btn.active(state);
  126. });
  127. });
  128. }
  129. });
  130. editor.addButton('p', {
  131. title: '正文',
  132. text: '正文',
  133. onclick() {
  134. editor.execCommand('mceToggleFormat', false, 'p');
  135. },
  136. onPostRender() {
  137. const btn = this;
  138. editor.on('init', () => {
  139. editor.formatter.formatChanged('p', state => {
  140. btn.active(state);
  141. });
  142. });
  143. }
  144. });
  145. }
  146. });
  147. },
  148. destroyed() {
  149. tinymce.get(this.id).destroy();
  150. }
  151. }
  152. </script>
  153. <style scoped>
  154. .tinymce-container {
  155. position: relative
  156. }
  157. .tinymce-textarea {
  158. visibility: hidden;
  159. z-index: -1;
  160. }
  161. .editor-custom-btn-container {
  162. position: absolute;
  163. right: 15px;
  164. top: 18px;
  165. }
  166. .editor-upload-btn {
  167. display: inline-block;
  168. }
  169. </style>