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.

119 lines
2.7 KiB

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