tui-skeleton.js 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. Component({
  2. properties: {
  3. //选择器(外层容器)
  4. selector: {
  5. type: String,
  6. value: "tui-skeleton"
  7. },
  8. //外层容器背景颜色
  9. backgroundColor: {
  10. type: String,
  11. value: "#fff"
  12. },
  13. //骨架元素背景颜色
  14. skeletonBgColor: {
  15. type: String,
  16. value: "#e9e9e9"
  17. },
  18. //骨架元素类型:矩形,圆形,带圆角矩形["rect","circular","fillet"]
  19. //默认所有,根据页面情况进行传值
  20. //页面对应元素class为:tui-skeleton-rect,tui-skeleton-circular,tui-skeleton-fillet
  21. //如果传入的值不在下列数组中,则为自定义class值,默认按矩形渲染
  22. skeletonType: {
  23. type: Array,
  24. value: ["rect", "circular", "fillet"]
  25. },
  26. //圆角值,skeletonType=fillet时生效
  27. borderRadius: {
  28. type: String,
  29. value: "16rpx"
  30. },
  31. //骨架屏预生成数据:提前生成好的数据,当传入该属性值时,则不会再次查找子节点信息
  32. preloadData: {
  33. type: Array,
  34. value: []
  35. },
  36. //是否需要loading
  37. loading: {
  38. type: Boolean,
  39. value: true
  40. },
  41. //loading类型[1-10]
  42. loadingType: {
  43. type: Number,
  44. value: 1
  45. }
  46. },
  47. lifetimes: {
  48. attached: function() {
  49. const res = wx.getSystemInfoSync();
  50. this.setData({
  51. winWidth: res.windowWidth,
  52. winHeight: res.windowHeight
  53. })
  54. this.isPreload(true)
  55. },
  56. ready: function() {
  57. this.nodesRef(`.${this.data.selector}`).then((res) => {
  58. this.setData({
  59. winHeight: res[0].height + res[0].top
  60. })
  61. });
  62. !this.isPreload() && this.selectorQuery()
  63. }
  64. },
  65. data: {
  66. winWidth: 375,
  67. winHeight: 800,
  68. skeletonElements: []
  69. },
  70. methods: {
  71. isPreload(init) {
  72. let preloadData = this.data.preloadData || []
  73. if (preloadData.length) {
  74. if (init) {
  75. this.setData({
  76. skeletonElements: preloadData
  77. })
  78. }
  79. return true
  80. }
  81. return false
  82. },
  83. async selectorQuery() {
  84. let skeletonType = this.data.skeletonType || []
  85. let nodes = []
  86. for (let item of skeletonType) {
  87. let className = `.${this.data.selector} >>> .${item}`
  88. if (~"rect_circular_fillet".indexOf(item)) {
  89. className = `.${this.data.selector} >>> .${this.data.selector}-${item}`
  90. }
  91. await this.nodesRef(className).then((res) => {
  92. res.map(d => {
  93. d.skeletonType = item
  94. })
  95. nodes = nodes.concat(res)
  96. })
  97. }
  98. this.setData({
  99. skeletonElements: nodes
  100. })
  101. },
  102. async nodesRef(className) {
  103. return await new Promise((resolve, reject) => {
  104. wx.createSelectorQuery().selectAll(className).boundingClientRect((res) => {
  105. if (res) {
  106. resolve(res);
  107. } else {
  108. reject(res)
  109. }
  110. }).exec();
  111. })
  112. }
  113. }
  114. })