You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

116 lines
2.6 KiB

9 months ago
  1. <template>
  2. <!-- #ifdef APP-NVUE -->
  3. <cell>
  4. <!-- #endif -->
  5. <view
  6. class="u-list-item"
  7. :ref="`u-list-item-${anchor}`"
  8. :anchor="`u-list-item-${anchor}`"
  9. :class="[`u-list-item-${anchor}`]"
  10. >
  11. <slot />
  12. </view>
  13. <!-- #ifdef APP-NVUE -->
  14. </cell>
  15. <!-- #endif -->
  16. </template>
  17. <script>
  18. import props from './props.js';
  19. // #ifdef APP-NVUE
  20. const dom = uni.requireNativePlugin('dom')
  21. // #endif
  22. /**
  23. * List 列表
  24. * @description 该组件为高性能列表组件
  25. * @tutorial https://www.uviewui.com/components/list.html
  26. * @property {String | Number} anchor 用于滚动到指定item
  27. * @example <u-list-ite v-for="(item, index) in indexList" :key="index" ></u-list-item>
  28. */
  29. export default {
  30. name: 'u-list-item',
  31. mixins: [uni.$u.mpMixin, uni.$u.mixin,props],
  32. data() {
  33. return {
  34. // 节点信息
  35. rect: {},
  36. index: 0,
  37. show: true,
  38. sys: uni.$u.sys()
  39. }
  40. },
  41. computed: {
  42. },
  43. inject: ['uList'],
  44. watch: {
  45. // #ifndef APP-NVUE
  46. 'uList.innerScrollTop'(n) {
  47. const preLoadScreen = this.uList.preLoadScreen
  48. const windowHeight = this.sys.windowHeight
  49. if(n <= windowHeight * preLoadScreen) {
  50. this.parent.updateOffsetFromChild(0)
  51. } else if (this.rect.top <= n - windowHeight * preLoadScreen) {
  52. this.parent.updateOffsetFromChild(this.rect.top)
  53. }
  54. }
  55. // #endif
  56. },
  57. created() {
  58. this.parent = {}
  59. },
  60. mounted() {
  61. this.init()
  62. },
  63. methods: {
  64. init() {
  65. // 初始化数据
  66. this.updateParentData()
  67. this.index = this.parent.children.indexOf(this)
  68. this.resize()
  69. },
  70. updateParentData() {
  71. // 此方法在mixin中
  72. this.getParentData('u-list')
  73. },
  74. resize() {
  75. this.queryRect(`u-list-item-${this.anchor}`).then(size => {
  76. const lastChild = this.parent.children[this.index - 1]
  77. this.rect = size
  78. const preLoadScreen = this.uList.preLoadScreen
  79. const windowHeight = this.sys.windowHeight
  80. // #ifndef APP-NVUE
  81. if (lastChild) {
  82. this.rect.top = lastChild.rect.top + lastChild.rect.height
  83. }
  84. if (size.top >= this.uList.innerScrollTop + (1 + preLoadScreen) * windowHeight) this.show =
  85. false
  86. // #endif
  87. })
  88. },
  89. // 查询元素尺寸
  90. queryRect(el) {
  91. return new Promise(resolve => {
  92. // #ifndef APP-NVUE
  93. this.$uGetRect(`.${el}`).then(size => {
  94. resolve(size)
  95. })
  96. // #endif
  97. // #ifdef APP-NVUE
  98. const ref = this.$refs[el]
  99. dom.getComponentRect(ref, res => {
  100. resolve(res.size)
  101. })
  102. // #endif
  103. })
  104. }
  105. }
  106. }
  107. </script>
  108. <style lang="scss" scoped>
  109. @import "../../libs/css/components.scss";
  110. .u-list-item {}
  111. </style>