fs-select.vue 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. <template>
  2. <fs-popover
  3. v-model="selectedAction"
  4. :placement="placement"
  5. :actions="actions"
  6. :width="width"
  7. :actionWidth="actionWidth"
  8. :valueKey="valueKey"
  9. @clickAction="handleClickAction"
  10. @visibleChange="handleChange"
  11. >
  12. <template #refer>
  13. <view class="fs-select" :class="[{ 'fs-select-border': border }]">
  14. <view class="fs-select-content line1">{{ selectedAction.text || placeholder }}</view>
  15. <view class="fs-select-icon"><fs-icon type="icon-d-down" :rotate="state.rotate" size="30rpx"></fs-icon></view>
  16. </view>
  17. </template>
  18. <!-- <slot></slot> -->
  19. </fs-popover>
  20. </template>
  21. <script>
  22. export default {
  23. name: 'fs-select'
  24. }
  25. </script>
  26. <script setup>
  27. import { ref, reactive, computed } from 'vue'
  28. const props = defineProps({
  29. modelValue: [Object],
  30. actions: Array,
  31. border: Boolean,
  32. placeholder: String,
  33. width: {
  34. type: String,
  35. default: '100%'
  36. },
  37. actionWidth: {
  38. type: String,
  39. default: 'auto'
  40. },
  41. placement: {
  42. type: String,
  43. default: 'bottom',
  44. validator(value) {
  45. return [
  46. 'top',
  47. 'top-start',
  48. 'top-end',
  49. 'bottom',
  50. 'bottom-start',
  51. 'bottom-end',
  52. 'left',
  53. 'left-start',
  54. 'left-end',
  55. 'right',
  56. 'right-start',
  57. 'right-end'
  58. ].includes(value)
  59. }
  60. },
  61. valueKey: {
  62. type: String,
  63. default: 'id'
  64. }
  65. })
  66. const emits = defineEmits(['change', 'update:modelValue'])
  67. const selectedAction = computed({
  68. get: () => props.modelValue,
  69. set: value => {
  70. emits('update:modelValue', value)
  71. }
  72. })
  73. const state = reactive({
  74. rotate: '0'
  75. })
  76. const handleClickAction = item => {
  77. emits('update:modelValue', item)
  78. emits('change', item)
  79. }
  80. const handleChange = () => {
  81. state.rotate = state.rotate === '0' ? '180' : '0'
  82. }
  83. </script>
  84. <style lang="scss" scoped>
  85. .fs-select {
  86. display: flex;
  87. height: 70rpx;
  88. align-items: center;
  89. justify-content: space-between;
  90. position: relative;
  91. background-color: inherit;
  92. position: relative;
  93. padding-right: 20rpx;
  94. max-width: 100%;
  95. &-border {
  96. border: 2rpx solid var(--border-color) !important;
  97. border-radius: 4rpx !important;
  98. padding-left: 20rpx;
  99. &.fs-select-content {
  100. padding: 20rpx;
  101. }
  102. }
  103. &-content {
  104. flex: 1;
  105. width: 400rpx;
  106. }
  107. &-icon {
  108. padding-left: 20rpx;
  109. flex-shrink: 0;
  110. }
  111. .visible {
  112. transform: rotate(180deg);
  113. transform-origin: center center;
  114. }
  115. }
  116. </style>