parse.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <!--**
  2. * forked from:https://github.com/F-loat/mpvue-wxParse
  3. *
  4. * github地址: https://github.com/dcloudio/uParse
  5. *
  6. * for: uni-app框架下 富文本解析
  7. *
  8. * 优化 by gaoyia@qq.com https://github.com/gaoyia/parse
  9. */-->
  10. <template>
  11. <!--基础元素-->
  12. <div class="wxParse" :class="className" :style="'user-select:' + userSelect">
  13. <block v-for="(node, index) of nodes" :key="index" v-if="!loading">
  14. <wxParseTemplate :node="node" />
  15. </block>
  16. </div>
  17. </template>
  18. <script>
  19. import HtmlToJson from './libs/html2json';
  20. import wxParseTemplate from './components/wxParseTemplate0';
  21. export default {
  22. name: 'wxParse',
  23. props: {
  24. // user-select:none;
  25. userSelect: {
  26. type: String,
  27. default: 'text' //none |text| all | element
  28. },
  29. imgOptions: {
  30. type: [Object, Boolean],
  31. default: function() {
  32. return {
  33. loop: false,
  34. indicator: 'number',
  35. longPressActions: false
  36. // longPressActions: {
  37. // itemList: ['发送给朋友', '保存图片', '收藏'],
  38. // success: function (res) {
  39. // console.log('选中了第' + (res.tapIndex + 1) + '个按钮');
  40. // },
  41. // fail: function (res) {
  42. // console.log(res.errMsg);
  43. // }
  44. // }
  45. // }
  46. }
  47. }
  48. },
  49. loading: {
  50. type: Boolean,
  51. default: false
  52. },
  53. className: {
  54. type: String,
  55. default: ''
  56. },
  57. content: {
  58. type: String,
  59. default: ''
  60. },
  61. noData: {
  62. type: String,
  63. default: '<div style="color: red;">数据不能为空</div>'
  64. },
  65. startHandler: {
  66. type: Function,
  67. default () {
  68. return node => {
  69. node.attr.class = null;
  70. node.attr.style = null;
  71. };
  72. }
  73. },
  74. endHandler: {
  75. type: Function,
  76. default: null
  77. },
  78. charsHandler: {
  79. type: Function,
  80. default: null
  81. },
  82. imageProp: {
  83. type: Object,
  84. default () {
  85. return {
  86. mode: 'aspectFit',
  87. padding: 0,
  88. lazyLoad: false,
  89. domain: ''
  90. };
  91. }
  92. }
  93. },
  94. components: {
  95. wxParseTemplate
  96. },
  97. data() {
  98. return {
  99. nodes: {},
  100. imageUrls: [],
  101. wxParseWidth: {
  102. value: 0
  103. }
  104. };
  105. },
  106. computed: {},
  107. mounted() {
  108. },
  109. methods: {
  110. setHtml() {
  111. this.getWidth().then((data) => {
  112. this.wxParseWidth.value = data;
  113. })
  114. let {
  115. content,
  116. noData,
  117. imageProp,
  118. startHandler,
  119. endHandler,
  120. charsHandler
  121. } = this;
  122. let parseData = content || noData;
  123. let customHandler = {
  124. start: startHandler,
  125. end: endHandler,
  126. chars: charsHandler
  127. };
  128. let results = HtmlToJson(parseData, customHandler, imageProp, this);
  129. this.imageUrls = results.imageUrls;
  130. // this.nodes = results.nodes;
  131. this.nodes = [];
  132. results.nodes.forEach((item) => {
  133. setTimeout(() => {
  134. this.nodes.push(item)
  135. }, 0);
  136. })
  137. },
  138. getWidth() {
  139. return new Promise((res, rej) => {
  140. // #ifndef MP-ALIPAY || MP-BAIDU
  141. uni.createSelectorQuery()
  142. .in(this)
  143. .select('.wxParse')
  144. .fields({
  145. size: true,
  146. scrollOffset: true
  147. },
  148. data => {
  149. res(data.width);
  150. }
  151. ).exec();
  152. // #endif
  153. // #ifdef MP-BAIDU
  154. swan.createSelectorQuery().select('.wxParse').boundingClientRect(function(rect) {
  155. rect[0].width
  156. }).exec()
  157. // #endif
  158. // #ifdef MP-ALIPAY
  159. my.createSelectorQuery()
  160. .select('.wxParse')
  161. .boundingClientRect().exec((ret) => {
  162. res(ret[0].width);
  163. });
  164. // #endif
  165. });
  166. },
  167. navigate(href, $event, attr) {
  168. console.log(href, attr);
  169. this.$emit('navigate', href, $event);
  170. },
  171. preview(src, $event) {
  172. if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') {
  173. } else {
  174. uni.previewImage({
  175. current: src,
  176. urls: this.imageUrls,
  177. loop: this.imgOptions.loop,
  178. indicator: this.imgOptions.indicator,
  179. longPressActions: this.imgOptions.longPressActions
  180. });
  181. }
  182. this.$emit('preview', src, $event);
  183. },
  184. removeImageUrl(src) {
  185. const {
  186. imageUrls
  187. } = this;
  188. imageUrls.splice(imageUrls.indexOf(src), 1);
  189. }
  190. },
  191. // 父组件中提供
  192. provide() {
  193. return {
  194. parseWidth: this.wxParseWidth,
  195. parseSelect: this.userSelect
  196. // 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
  197. };
  198. },
  199. watch: {
  200. content(){
  201. this.setHtml()
  202. }
  203. // content: {
  204. // handler: function(newVal, oldVal) {
  205. // if (newVal !== oldVal) {
  206. //
  207. // }
  208. // },
  209. // deep: true
  210. // }
  211. }
  212. };
  213. </script>