u-dropdown.vue 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <view class="u-drawdown">
  3. <view
  4. class="u-dropdown__menu"
  5. :style="{
  6. height: $u.addUnit(height)
  7. }"
  8. ref="u-dropdown__menu"
  9. >
  10. <view
  11. class="u-dropdown__menu__item"
  12. v-for="(item, index) in menuList"
  13. :key="index"
  14. @tap.stop="clickHandler(item, index)"
  15. >
  16. <view class="u-dropdown__menu__item__content">
  17. <text
  18. class="u-dropdown__menu__item__content__text"
  19. :style="[index === current ? activeStyle : inactiveStyle]"
  20. >{{item.title}}</text>
  21. <view
  22. class="u-dropdown__menu__item__content__arrow"
  23. :class="[index === current && 'u-dropdown__menu__item__content__arrow--rotate']"
  24. >
  25. <u-icon
  26. :name="menuIcon"
  27. :size="$u.addUnit(menuIconSize)"
  28. ></u-icon>
  29. </view>
  30. </view>
  31. </view>
  32. </view>
  33. <view class="u-dropdown__content">
  34. <slot />
  35. </view>
  36. </view>
  37. </template>
  38. <script>
  39. import props from './props.js';
  40. /**
  41. * Dropdown
  42. * @description
  43. * @tutorial url
  44. * @property {String}
  45. * @event {Function}
  46. * @example
  47. */
  48. export default {
  49. name: 'u-dropdown',
  50. mixins: [uni.$u.mixin, props],
  51. data() {
  52. return {
  53. // 菜单数组
  54. menuList: [],
  55. current: 0
  56. }
  57. },
  58. computed: {
  59. },
  60. created() {
  61. // 引用所有子组件(u-dropdown-item)的this,不能在data中声明变量,否则在微信小程序会造成循环引用而报错
  62. this.children = [];
  63. },
  64. methods: {
  65. clickHandler(item, index) {
  66. this.children.map(child => {
  67. if(child.title === item.title) {
  68. // this.queryRect('u-dropdown__menu').then(size => {
  69. child.$emit('click')
  70. child.setContentAnimate(child.show ? 0 : 300)
  71. child.show = !child.show
  72. // })
  73. } else {
  74. child.show = false
  75. child.setContentAnimate(0)
  76. }
  77. })
  78. },
  79. // 获取标签的尺寸位置
  80. queryRect(el) {
  81. // #ifndef APP-NVUE
  82. // $uGetRect为uView自带的节点查询简化方法,详见文档介绍:https://www.uviewui.com/js/getRect.html
  83. // 组件内部一般用this.$uGetRect,对外的为this.$u.getRect,二者功能一致,名称不同
  84. return new Promise(resolve => {
  85. this.$uGetRect(`.${el}`).then(size => {
  86. resolve(size)
  87. })
  88. })
  89. // #endif
  90. // #ifdef APP-NVUE
  91. // nvue下,使用dom模块查询元素高度
  92. // 返回一个promise,让调用此方法的主体能使用then回调
  93. return new Promise(resolve => {
  94. dom.getComponentRect(this.$refs[el], res => {
  95. resolve(res.size)
  96. })
  97. })
  98. // #endif
  99. },
  100. },
  101. }
  102. </script>
  103. <style lang="scss">
  104. @import '../../libs/css/components.scss';
  105. .u-dropdown {
  106. &__menu {
  107. @include flex;
  108. &__item {
  109. flex: 1;
  110. @include flex;
  111. justify-content: center;
  112. &__content {
  113. @include flex;
  114. align-items: center;
  115. }
  116. }
  117. }
  118. }
  119. </style>