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.

132 lines
4.2 KiB

3 years ago
  1. <template>
  2. <view class="u-dropdown-item" v-if="active" @touchmove.stop.prevent="() => {}" @tap.stop.prevent="() => {}">
  3. <block v-if="!$slots.default && !$slots.$default">
  4. <scroll-view scroll-y="true" :style="{
  5. height: $u.addUnit(height)
  6. }">
  7. <view class="u-dropdown-item__options">
  8. <u-cell-group>
  9. <u-cell-item @click="cellClick(item.value)" :arrow="false" :title="item.label" v-for="(item, index) in options"
  10. :key="index" :title-style="{
  11. color: value == item.value ? activeColor : inactiveColor
  12. }">
  13. <u-icon v-if="value == item.value" name="checkbox-mark" :color="activeColor" size="32"></u-icon>
  14. </u-cell-item>
  15. </u-cell-group>
  16. </view>
  17. </scroll-view>
  18. </block>
  19. <slot v-else />
  20. </view>
  21. </template>
  22. <script>
  23. /**
  24. * dropdown-item 下拉菜单
  25. * @description 该组件一般用于向下展开菜单同时可切换多个选项卡的场景
  26. * @tutorial http://uviewui.com/components/dropdown.html
  27. * @property {String | Number} v-model 双向绑定选项卡选择值
  28. * @property {String} title 菜单项标题
  29. * @property {Array[Object]} options 选项数据如果传入了默认slot此参数无效
  30. * @property {Boolean} disabled 是否禁用此选项卡默认false
  31. * @property {String | Number} duration 选项卡展开和收起的过渡时间单位ms默认300
  32. * @property {String | Number} height 弹窗下拉内容的高度(内容超出将会滚动)默认auto
  33. * @example <u-dropdown-item title="标题"></u-dropdown-item>
  34. */
  35. export default {
  36. name: 'u-dropdown-item',
  37. props: {
  38. // 当前选中项的value值
  39. value: {
  40. type: [Number, String, Array],
  41. default: ''
  42. },
  43. // 菜单项标题
  44. title: {
  45. type: [String, Number],
  46. default: ''
  47. },
  48. // 选项数据,如果传入了默认slot,此参数无效
  49. options: {
  50. type: Array,
  51. default () {
  52. return []
  53. }
  54. },
  55. // 是否禁用此菜单项
  56. disabled: {
  57. type: Boolean,
  58. default: false
  59. },
  60. // 下拉弹窗的高度
  61. height: {
  62. type: [Number, String],
  63. default: 'auto'
  64. },
  65. },
  66. data() {
  67. return {
  68. active: false, // 当前项是否处于展开状态
  69. activeColor: '#2979ff', // 激活时左边文字和右边对勾图标的颜色
  70. inactiveColor: '#606266', // 未激活时左边文字和右边对勾图标的颜色
  71. }
  72. },
  73. computed: {
  74. // 监听props是否发生了变化,有些值需要传递给父组件u-dropdown,无法双向绑定
  75. propsChange() {
  76. return `${this.title}-${this.disabled}`;
  77. }
  78. },
  79. watch: {
  80. propsChange(n) {
  81. // 当值变化时,通知父组件重新初始化,让父组件执行每个子组件的init()方法
  82. // 将所有子组件数据重新整理一遍
  83. if (this.parent) this.parent.init();
  84. }
  85. },
  86. created() {
  87. // 父组件的实例
  88. this.parent = false;
  89. },
  90. methods: {
  91. init() {
  92. // 获取父组件u-dropdown
  93. let parent = this.$u.$parent.call(this, 'u-dropdown');
  94. if (parent) {
  95. this.parent = parent;
  96. // 将子组件的激活颜色配置为父组件设置的激活和未激活时的颜色
  97. this.activeColor = parent.activeColor;
  98. this.inactiveColor = parent.inactiveColor;
  99. // 将本组件的this,放入到父组件的children数组中,让父组件可以操作本(子)组件的方法和属性
  100. // push进去前,显判断是否已经存在了本实例,因为在子组件内部数据变化时,会通过父组件重新初始化子组件
  101. let exist = parent.children.find(val => {
  102. return this === val;
  103. })
  104. if (!exist) parent.children.push(this);
  105. if (parent.children.length == 1) this.active = true;
  106. // 父组件无法监听children的变化,故将子组件的title,传入父组件的menuList数组中
  107. parent.menuList.push({
  108. title: this.title,
  109. disabled: this.disabled
  110. });
  111. }
  112. },
  113. // cell被点击
  114. cellClick(value) {
  115. // 修改通过v-model绑定的值
  116. this.$emit('input', value);
  117. // 通知父组件(u-dropdown)收起菜单
  118. this.parent.close();
  119. // 发出事件,抛出当前勾选项的value
  120. this.$emit('change', value);
  121. }
  122. },
  123. mounted() {
  124. this.init();
  125. }
  126. }
  127. </script>
  128. <style scoped lang="scss">
  129. @import "../../libs/css/style.components.scss";
  130. </style>