uv-drop-down.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. <template>
  2. <uv-sticky :disabled="!isSticky">
  3. <view ref="dropDownRef" class="uv-drop-down" :style="[$uv.addStyle(customStyle)]">
  4. <slot></slot>
  5. </view>
  6. </uv-sticky>
  7. </template>
  8. <script>
  9. import uvSticky from '@/uni_modules/uv-sticky/components/uv-sticky/uv-sticky.vue';
  10. import mpMixin from '@/uni_modules/uv-ui-tools/libs/mixin/mpMixin.js';
  11. import mixin from '@/uni_modules/uv-ui-tools/libs/mixin/mixin.js';
  12. // #ifdef APP-NVUE
  13. const dom = uni.requireNativePlugin('dom');
  14. // #endif
  15. /**
  16. * DropDown 下拉框
  17. * @description 下拉筛选
  18. * @tutorial https://ext.dcloud.net.cn/plugin?name=uv-drop-down
  19. * @property {String | Number} sign 组件唯一标识,需要手动传
  20. * @property {Boolean} is-sticky = [true|false] 是否吸顶
  21. * @property {Array} default-value 默认值,表示参数value属于这里面的值,就说明是未选中即是默认展示的值。eg:上面示例中的{label: '全部',value: 'all'} 即是默认值。后续处理逻辑也可以根据是否是其中值进行过滤。
  22. * @property {String} textSize 每项字体大小
  23. * @property {String} textColor 每项文本颜色
  24. * @property {String} textActiveSize 每项选中状态字体大小
  25. * @property {String} textActiveColor 每项选中状态文本颜色
  26. * @property {Object} extraIcon 每项右侧图标
  27. * @property {Object} extraActiveIcon 每项选中后右侧图标
  28. */
  29. export default {
  30. name: 'uv-drop-down',
  31. mixins: [mpMixin, mixin],
  32. emits: ['click'],
  33. props: {
  34. isSticky: {
  35. type: Boolean,
  36. default: true
  37. },
  38. sign: {
  39. type: [String, Number],
  40. default: 'UVDROPDOWN'
  41. },
  42. defaultValue: {
  43. type: Array,
  44. default: () => [0, '0', 'all']
  45. },
  46. textSize: {
  47. type: String,
  48. default: '30rpx'
  49. },
  50. textColor: {
  51. type: String,
  52. default: '#333'
  53. },
  54. textActiveSize: {
  55. type: String,
  56. default: '30rpx'
  57. },
  58. textActiveColor: {
  59. type: String,
  60. default: '#3c9cff'
  61. },
  62. extraIcon: {
  63. type: Object,
  64. default () {
  65. return {
  66. name: 'arrow-down',
  67. size: '30rpx',
  68. color: '#333'
  69. }
  70. }
  71. },
  72. extraActiveIcon: {
  73. type: Object,
  74. default () {
  75. return {
  76. name: 'arrow-up',
  77. size: '30rpx',
  78. color: '#3c9cff'
  79. }
  80. }
  81. }
  82. },
  83. computed: {
  84. parentData() {
  85. return [this.defaultValue, this.textSize, this.textColor, this.textActiveColor, this.textActiveSize, this.extraIcon, this.extraActiveIcon, this.sign, this.clickHandler];
  86. }
  87. },
  88. components:{
  89. uvSticky
  90. },
  91. mounted() {
  92. this.init();
  93. },
  94. methods: {
  95. init() {
  96. uni.$emit(`${this.sign}_CLICKMENU`, {
  97. show: false
  98. });
  99. this.$nextTick(async () => {
  100. const rect = await this.queryRect();
  101. uni.$emit(`${this.sign}_GETRECT`, rect);
  102. })
  103. },
  104. // 查询内容高度
  105. queryRect() {
  106. // #ifndef APP-NVUE
  107. // 组件内部一般用this.$uvGetRect,对外的为getRect,二者功能一致,名称不同
  108. return new Promise(resolve => {
  109. this.$uvGetRect(`.uv-drop-down`).then(size => {
  110. resolve(size)
  111. })
  112. })
  113. // #endif
  114. // #ifdef APP-NVUE
  115. // nvue下,使用dom模块查询元素高度
  116. // 返回一个promise,让调用此方法的主体能使用then回调
  117. return new Promise(resolve => {
  118. dom.getComponentRect(this.$refs.dropDownRef, res => {
  119. res.size.top = res.size.top <= 0 ? 0 : res.size.top;
  120. resolve(res.size)
  121. })
  122. })
  123. // #endif
  124. },
  125. clickHandler(data) {
  126. this.$emit('click', data);
  127. }
  128. }
  129. }
  130. </script>
  131. <style scoped lang="scss">
  132. @import '@/uni_modules/uv-ui-tools/libs/css/components.scss';
  133. .uv-drop-down {
  134. @include flex;
  135. justify-content: space-between;
  136. background-color: #fff;
  137. border-bottom: 1px solid #dadbde;
  138. }
  139. </style>