u-dropdown-item.vue 4.5 KB

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