parse.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  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. this.setHtml()
  109. },
  110. methods: {
  111. setHtml() {
  112. this.getWidth().then((data) => {
  113. this.wxParseWidth.value = data;
  114. })
  115. let {
  116. content,
  117. noData,
  118. imageProp,
  119. startHandler,
  120. endHandler,
  121. charsHandler
  122. } = this;
  123. let parseData = content || noData;
  124. let customHandler = {
  125. start: startHandler,
  126. end: endHandler,
  127. chars: charsHandler
  128. };
  129. let results = HtmlToJson(parseData, customHandler, imageProp, this);
  130. this.imageUrls = results.imageUrls;
  131. // this.nodes = results.nodes;
  132. this.nodes = [];
  133. results.nodes.forEach((item) => {
  134. setTimeout(() => {
  135. this.nodes.push(item)
  136. }, 0);
  137. })
  138. },
  139. getWidth() {
  140. return new Promise((res, rej) => {
  141. // #ifndef MP-ALIPAY || MP-BAIDU
  142. uni.createSelectorQuery()
  143. .in(this)
  144. .select('.wxParse')
  145. .fields({
  146. size: true,
  147. scrollOffset: true
  148. },
  149. data => {
  150. res(data.width);
  151. }
  152. ).exec();
  153. // #endif
  154. // #ifdef MP-BAIDU
  155. const query = swan.createSelectorQuery();
  156. query.select('.wxParse').boundingClientRect();
  157. query.exec(obj => {
  158. const rect = obj[0]
  159. if (rect) {
  160. res(rect.width);
  161. }
  162. });
  163. // #endif
  164. // #ifdef MP-ALIPAY
  165. my.createSelectorQuery()
  166. .select('.wxParse')
  167. .boundingClientRect().exec((ret) => {
  168. res(ret[0].width);
  169. });
  170. // #endif
  171. });
  172. },
  173. navigate(href, $event, attr) {
  174. console.log(href, attr);
  175. this.$emit('navigate', href, $event);
  176. },
  177. preview(src, $event) {
  178. if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') {
  179. } else {
  180. uni.previewImage({
  181. current: src,
  182. urls: this.imageUrls,
  183. loop: this.imgOptions.loop,
  184. indicator: this.imgOptions.indicator,
  185. longPressActions: this.imgOptions.longPressActions
  186. });
  187. }
  188. this.$emit('preview', src, $event);
  189. },
  190. removeImageUrl(src) {
  191. const {
  192. imageUrls
  193. } = this;
  194. imageUrls.splice(imageUrls.indexOf(src), 1);
  195. }
  196. },
  197. // 父组件中提供
  198. provide() {
  199. return {
  200. parseWidth: this.wxParseWidth,
  201. parseSelect: this.userSelect
  202. // 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
  203. };
  204. },
  205. watch: {
  206. content(){
  207. this.setHtml()
  208. }
  209. // content: {
  210. // handler: function(newVal, oldVal) {
  211. // if (newVal !== oldVal) {
  212. //
  213. // }
  214. // },
  215. // deep: true
  216. // }
  217. }
  218. };
  219. </script>