parse.vue 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  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 zhiqiang.feng@qq.com
  9. */-->
  10. <template>
  11. <!--基础元素-->
  12. <view 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. </view>
  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: ''
  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() {
  77. return node => {
  78. node = node
  79. };
  80. }
  81. },
  82. charsHandler: {
  83. type: Function,
  84. default() {
  85. return node => {
  86. node = node
  87. };
  88. }
  89. },
  90. imageProp: {
  91. type: Object,
  92. default () {
  93. return {
  94. mode: 'aspectFit',
  95. padding: 0,
  96. lazyLoad: false,
  97. domain: ''
  98. };
  99. }
  100. }
  101. },
  102. components: {
  103. wxParseTemplate
  104. },
  105. data() {
  106. return {
  107. nodes: {},
  108. imageUrls: [],
  109. wxParseWidth: {
  110. value: 0
  111. }
  112. };
  113. },
  114. computed: {},
  115. mounted() {
  116. this.setHtml()
  117. },
  118. methods: {
  119. setHtml() {
  120. this.getWidth().then((data) => {
  121. this.wxParseWidth.value = data;
  122. })
  123. let {
  124. content,
  125. noData,
  126. imageProp,
  127. startHandler,
  128. endHandler,
  129. charsHandler
  130. } = this;
  131. let parseData = content || noData;
  132. let customHandler = {
  133. start: startHandler,
  134. end: endHandler,
  135. chars: charsHandler
  136. };
  137. let results = HtmlToJson(parseData, customHandler, imageProp, this);
  138. this.imageUrls = results.imageUrls;
  139. // this.nodes = results.nodes;
  140. this.nodes = [];
  141. results.nodes.forEach((item) => {
  142. setTimeout(() => {
  143. if(item.node){
  144. this.nodes.push(item)
  145. }
  146. }, 0);
  147. })
  148. },
  149. getWidth() {
  150. return new Promise((res, rej) => {
  151. // #ifndef MP-ALIPAY || MP-BAIDU
  152. uni.createSelectorQuery()
  153. .in(this)
  154. .select('.wxParse')
  155. .fields({
  156. size: true,
  157. scrollOffset: true
  158. },
  159. data => {
  160. res(data.width);
  161. }
  162. ).exec();
  163. // #endif
  164. // #ifdef MP-BAIDU
  165. const query = swan.createSelectorQuery();
  166. query.select('.wxParse').boundingClientRect();
  167. query.exec(obj => {
  168. const rect = obj[0]
  169. if (rect) {
  170. res(rect.width);
  171. }
  172. });
  173. // #endif
  174. // #ifdef MP-ALIPAY
  175. my.createSelectorQuery()
  176. .select('.wxParse')
  177. .boundingClientRect().exec((ret) => {
  178. res(ret[0].width);
  179. });
  180. // #endif
  181. });
  182. },
  183. navigate(href, $event, attr) {
  184. console.log(href, attr);
  185. this.$emit('navigate', href, $event);
  186. },
  187. preview(src, $event) {
  188. if (!this.imageUrls.length || typeof this.imgOptions === 'boolean') {
  189. } else {
  190. uni.previewImage({
  191. current: src,
  192. urls: this.imageUrls,
  193. loop: this.imgOptions.loop,
  194. indicator: this.imgOptions.indicator,
  195. longPressActions: this.imgOptions.longPressActions
  196. });
  197. }
  198. this.$emit('preview', src, $event);
  199. },
  200. removeImageUrl(src) {
  201. const {
  202. imageUrls
  203. } = this;
  204. imageUrls.splice(imageUrls.indexOf(src), 1);
  205. }
  206. },
  207. // 父组件中提供
  208. provide() {
  209. return {
  210. parseWidth: this.wxParseWidth,
  211. parseSelect: this.userSelect
  212. // 提示:provide 和 inject 绑定并不是可响应的。这是刻意为之的。然而,如果你传入了一个可监听的对象,那么其对象的属性还是可响应的。
  213. };
  214. },
  215. watch: {
  216. content(val){
  217. this.setHtml()
  218. }
  219. // content: {
  220. // handler: function(newVal, oldVal) {
  221. // if (newVal !== oldVal) {
  222. //
  223. // }
  224. // },
  225. // deep: true
  226. // }
  227. }
  228. };
  229. </script>