TransportMode.vue 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. <script setup lang="ts">
  2. import type { DropdownInstance } from 'element-plus'
  3. import { cloneDeep } from 'lodash'
  4. import { useFiltersStore } from '@/stores/modules/filtersList'
  5. const filtersStore = useFiltersStore()
  6. interface ListItem {
  7. name: string
  8. sname: string
  9. number: number
  10. icon: string
  11. checked: boolean
  12. }
  13. interface Props {
  14. transportListItem: ListItem[]
  15. }
  16. const props = withDefaults(defineProps<Props>(), {})
  17. const transportList = ref()
  18. const checkAll = ref(false)
  19. const dropdownVisible = ref<DropdownInstance>()
  20. const updateTransportList = (data: any) => {
  21. transportList.value = cloneDeep(data)
  22. const isCheckedAll = transportList.value?.every((item: any) => item.checked)
  23. isCheckedAll ? (checkAll.value = true) : (checkAll.value = false)
  24. }
  25. watch(
  26. () => props.transportListItem,
  27. (current) => {
  28. updateTransportList(current)
  29. },
  30. {
  31. immediate: true,
  32. deep: true
  33. }
  34. )
  35. const totalNumber = computed(() => {
  36. return (
  37. transportList.value?.filter((item) => {
  38. return item.checked
  39. }).length || 0
  40. )
  41. })
  42. const handleCheckAllChange = (checked: any) => {
  43. transportList.value.forEach((item: any) => {
  44. item.checked = checked
  45. })
  46. }
  47. const handleCheckedTransportChange = (item: any) => {
  48. const isCheckedAll = transportList.value.every((item: any) => item.checked)
  49. isCheckedAll ? (checkAll.value = true) : (checkAll.value = false)
  50. }
  51. // 清除选中
  52. const clearList = () => {
  53. checkAll.value = false
  54. if (transportList.value != undefined) {
  55. transportList.value.forEach((item: any) => {
  56. item.checked = false
  57. })
  58. }
  59. }
  60. const emit = defineEmits(['transportSearch'])
  61. const transportSearch = () => {
  62. const allChecked = transportList.value.every((item) => item.checked)
  63. const selectedNames = allChecked
  64. ? ['All']
  65. : transportList.value.filter((item) => item.checked).map((item) => item.sname)
  66. filtersStore.updateFilter({
  67. title: 'Transport Mode',
  68. value: selectedNames,
  69. keyType: 'array',
  70. key: 'transport_mode'
  71. })
  72. dropdownVisible.value.handleClose()
  73. emit('transportSearch', transportList.value)
  74. }
  75. // 每次打开时都应该重新赋值
  76. const handleDropdownVisibleChange = (visible: boolean) => {
  77. if (visible) {
  78. updateTransportList(props.transportListItem)
  79. }
  80. }
  81. </script>
  82. <template>
  83. <div class="select">
  84. <el-dropdown
  85. ref="dropdownVisible"
  86. trigger="click"
  87. :hide-on-click="false"
  88. @visible-change="handleDropdownVisibleChange"
  89. >
  90. <div class="el-dropdown-link">
  91. <div class="select_title">Transport Mode</div>
  92. <span class="iconfont_icon">
  93. <svg class="iconfont icon_dark" aria-hidden="true">
  94. <use xlink:href="#icon-icon_dropdown_b"></use>
  95. </svg>
  96. </span>
  97. </div>
  98. <template #dropdown>
  99. <div class="dropdownwidth">
  100. <div class="title">Transport Mode</div>
  101. <el-dropdown-menu>
  102. <el-dropdown-item>
  103. <el-checkbox v-model="checkAll" class="checkbox" @change="handleCheckAllChange">
  104. <div class="checkbox_title">
  105. <span class="iconfont_icon">
  106. <svg class="iconfont iconfont_select" aria-hidden="true">
  107. <use xlink:href="#icon-icon_all_b"></use>
  108. </svg>
  109. </span>
  110. Select All
  111. </div>
  112. <div class="checkbox_number">({{ totalNumber }})</div>
  113. </el-checkbox>
  114. </el-dropdown-item>
  115. <el-divider></el-divider>
  116. <el-dropdown-item v-for="(item, index) in transportList" :key="index">
  117. <el-checkbox
  118. :value="item.name"
  119. v-model="item.checked"
  120. class="checkbox"
  121. @change="handleCheckedTransportChange(item)"
  122. >
  123. <div class="checkbox_title">
  124. <span class="iconfont_icon">
  125. <svg class="iconfont iconfont_select" aria-hidden="true">
  126. <use :xlink:href="item.icon"></use>
  127. </svg>
  128. </span>
  129. {{ item.name }}
  130. </div>
  131. <div class="checkbox_number">({{ item.number }})</div>
  132. </el-checkbox>
  133. </el-dropdown-item>
  134. <div class="transport_bottom">
  135. <div>
  136. <el-button class="clear" type="default" @click="clearList">Reset</el-button>
  137. </div>
  138. <div>
  139. <el-button class="search el-button--dark" @click="transportSearch"
  140. >Search</el-button
  141. >
  142. </div>
  143. </div>
  144. </el-dropdown-menu>
  145. </div>
  146. </template>
  147. </el-dropdown>
  148. </div>
  149. </template>
  150. <style lang="scss" scoped>
  151. .iconfont_icon {
  152. margin-right: 8px;
  153. }
  154. .iconfont_select {
  155. width: 17px;
  156. height: 17px;
  157. fill: var(--color-neutral-1);
  158. }
  159. .select {
  160. width: 186px;
  161. margin-left: 8px;
  162. cursor: pointer;
  163. display: flex;
  164. align-items: center;
  165. border: 1px solid var(--color-select-border);
  166. border-radius: var(--border-radius-6);
  167. }
  168. .select:hover {
  169. border: 1px solid var(--color-theme);
  170. }
  171. .el-dropdown-link {
  172. width: 186px;
  173. display: flex;
  174. align-items: center;
  175. justify-content: space-between;
  176. }
  177. .select_title {
  178. font-size: var(--font-size-3);
  179. font-weight: 400;
  180. margin-left: 8.53px;
  181. color: var(--color-neutral-1);
  182. }
  183. .title {
  184. font-weight: 700;
  185. font-size: var(--font-size-5);
  186. background-color: var(--color-header-bg);
  187. height: 48px;
  188. display: flex;
  189. align-items: center;
  190. padding-left: 16px;
  191. }
  192. .checkbox {
  193. width: 100%;
  194. font-weight: 400;
  195. font-size: var(--font-size-3);
  196. padding: 0 12px;
  197. height: 40px;
  198. }
  199. :deep(.el-popper__arrow, .el-popper__arrow:before) {
  200. height: 0;
  201. width: 0;
  202. }
  203. :deep(.el-checkbox__label) {
  204. width: 100%;
  205. padding-left: 13px;
  206. display: flex;
  207. align-items: center;
  208. justify-content: space-between;
  209. }
  210. .checkbox_title {
  211. color: var(--color-neutral-1);
  212. }
  213. .checkbox_number {
  214. color: var(--color-neutral-3);
  215. }
  216. .transport_bottom {
  217. display: flex;
  218. justify-content: flex-end;
  219. align-items: center;
  220. height: 48px;
  221. border-top: 1px solid var(--border-color-2);
  222. margin-top: 5px;
  223. font-weight: 400;
  224. font-size: var(--font-size-3);
  225. }
  226. .clear {
  227. width: 81px;
  228. height: 32px;
  229. margin-right: 7.82px;
  230. }
  231. .search {
  232. width: 86px;
  233. height: 32px;
  234. margin-right: 16px;
  235. }
  236. .search:hover {
  237. color: var(--color-theme);
  238. }
  239. :deep(.el-dropdown-menu__item:hover) {
  240. background-color: var(--border-hover-color);
  241. border-radius: var(--border-radius-6);
  242. border-color: var(--border-hover-color);
  243. }
  244. :deep(.el-dropdown-menu__item) {
  245. padding: 0;
  246. margin: 10px 16px;
  247. }
  248. :deep(.el-dropdown-menu__item:not(.is-disabled):focus) {
  249. background-color: var(--border-hover-color);
  250. border-radius: var(--border-radius-6);
  251. border-color: var(--border-hover-color);
  252. }
  253. :deep(.el-dropdown-menu) {
  254. background-color: var(--management-bg-color);
  255. }
  256. .dropdownwidth {
  257. width: 248px;
  258. background-color: var(--management-bg-color);
  259. border-color: var(--management-bg-color);
  260. }
  261. @media only screen and (min-width: 1280px) {
  262. .el-dropdown-link,
  263. .select {
  264. width: 224px;
  265. }
  266. .dropdownwidth {
  267. width: 248px;
  268. }
  269. }
  270. @media only screen and (min-width: 1440px) {
  271. .el-dropdown-link,
  272. .select {
  273. width: 336px;
  274. }
  275. .dropdownwidth {
  276. width: 336px;
  277. }
  278. }
  279. .el-divider--horizontal {
  280. margin: 8px 0;
  281. border-top-color: var(--border-color-2);
  282. }
  283. </style>