Toolbar.vue 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. <template lang="pug">
  2. .toolbar
  3. .container.is-content
  4. .level.is-mobile
  5. .level-left
  6. .level-item
  7. b-dropdown(
  8. :triggers="[isMobile ? 'click' : 'hover']"
  9. :append-to-body="isMobile"
  10. )
  11. .field.trigger(slot="trigger")
  12. span {{sortType === 1 ? '最新发布' : '综合排序'}}
  13. i.progico.progico-arrow
  14. b-dropdown-item(
  15. :focusable="false"
  16. @click="changeSortType(0)"
  17. ) 综合排序
  18. b-dropdown-item(
  19. :focusable="false"
  20. @click="changeSortType(1)"
  21. ) 最新发布
  22. .level-item
  23. b-dropdown.city-dropdown(
  24. ref="city-dropdown"
  25. :triggers="[isMobile ? 'click' : 'hover']"
  26. :class="{'is-force-hide': forceHideCityMenu}"
  27. :append-to-body="isMobile"
  28. custom
  29. )
  30. .field.trigger(
  31. slot="trigger"
  32. @mouseenter="onCityTriggerHover"
  33. )
  34. span {{cityId && cityMap[cityId] && cityMap[cityId].name || '所在地区'}}
  35. i.progico.progico-arrow
  36. .city-menu
  37. .row
  38. .tag.is-rounded(
  39. :class="!cityId || !cityMap[cityId] ? ['is-primary', 'is-light'] : []"
  40. @click="changeCity()"
  41. ) 不限城市
  42. .split
  43. .row.tags
  44. .tag.is-rounded(
  45. v-for="item in cities"
  46. :key="item.id"
  47. :class="cityId === item.id ? ['is-primary', 'is-light'] : []"
  48. @click="changeCity(item)"
  49. ) {{item.name}}
  50. .level-item
  51. .field
  52. b-checkbox(
  53. v-model="isChoiceCache"
  54. @input="changeIsChoice"
  55. ) 优选服务
  56. .level-right
  57. slot(name="right")
  58. </template>
  59. <script lang="ts">
  60. import Vue from 'vue'
  61. const enum SortType {
  62. Default,
  63. Recently
  64. }
  65. export default Vue.extend({
  66. name: 'Toolbar',
  67. props: {
  68. cities: {
  69. type: Array,
  70. default: () => [] as any[]
  71. },
  72. sortType: {
  73. type: Number,
  74. default: SortType.Default
  75. },
  76. cityId: {
  77. type: [Number, String],
  78. default: null
  79. },
  80. isChoice: {
  81. type: Boolean,
  82. default: false
  83. }
  84. },
  85. data() {
  86. return {
  87. isChoiceCache: false,
  88. forceHideCityMenu: false,
  89. // @ts-ignore
  90. isMobile: this.$deviceType.isMobile()
  91. }
  92. },
  93. computed: {
  94. cityMap(): any {
  95. return this.cities && this.cities.length ? this.cities.reduce((map, item) => {
  96. map[item.id] = item
  97. return map
  98. }, {}) : {}
  99. }
  100. },
  101. methods: {
  102. onCityTriggerHover() {
  103. this.forceHideCityMenu = false
  104. },
  105. changeSortType(type) {
  106. if (type !== this.sortType) {
  107. this.$emit('update:sortType', type)
  108. }
  109. },
  110. changeCity(item) {
  111. const id = item && item.id || null
  112. if (id !== this.cityId) {
  113. this.$emit('update:cityId', id)
  114. }
  115. if (this.isMobile) {
  116. // @ts-ignore
  117. this.$refs['city-dropdown'].toggle()
  118. }
  119. this.forceHideCityMenu = true
  120. },
  121. changeIsChoice(val) {
  122. if (val !== this.isChoice) {
  123. this.$emit('update:isChoice', val)
  124. }
  125. }
  126. },
  127. created() {
  128. this.isChoiceCache = this.isChoice
  129. }
  130. })
  131. </script>
  132. <style lang="scss">
  133. .kaifain-view {
  134. .toolbar {
  135. background: #f6f6f7;
  136. height: 36px;
  137. .level {
  138. margin: 0 -0.75rem;
  139. }
  140. .level-item {
  141. font-size: 0.75rem;
  142. color: #777;
  143. user-select: none;
  144. .field {
  145. height: 36px;
  146. min-width: 86px;
  147. padding: 0 0.75rem;
  148. display: flex;
  149. align-items: center;
  150. justify-content: center;
  151. &.trigger:hover {
  152. background: #fbfbfc;
  153. color: #555;
  154. }
  155. }
  156. .progico-arrow {
  157. transform: rotate(90deg);
  158. font-size: 10px;
  159. margin: 2px 0 0 4px;
  160. opacity: 0.86;
  161. }
  162. }
  163. .dropdown-menu {
  164. padding: 0;
  165. margin-top: -4px;
  166. }
  167. .dropdown-content {
  168. box-shadow: 0 0.5em 1em -0.125em rgba(10, 10, 10, 0.1);
  169. border-radius: 0;
  170. }
  171. .dropdown-item {
  172. font-size: 0.75rem;
  173. }
  174. @media screen and (max-width: 767px) {
  175. .level {
  176. margin: 0;
  177. }
  178. .level-left {
  179. flex: 1;
  180. }
  181. .level-right {
  182. display: none;
  183. }
  184. }
  185. }
  186. .city-dropdown {
  187. .city-menu {
  188. width: 392px;
  189. padding: 0.5rem 0 0.5rem 1rem;
  190. .split {
  191. height: 1px;
  192. background: #eee;
  193. margin: 0.75rem 1rem 0.75rem 0;
  194. }
  195. .tag {
  196. min-width: 68px;
  197. background: transparent;
  198. cursor: pointer;
  199. &:not(.is-primary):hover {
  200. background: #f2f3f3;
  201. }
  202. }
  203. .tags > .tag {
  204. margin: 0 0.25rem 0.3125rem 0;
  205. }
  206. }
  207. &.is-mobile-modal {
  208. @media screen and (max-width: 767px) {
  209. .city-menu {
  210. width: auto;
  211. }
  212. }
  213. }
  214. }
  215. .dropdown.is-hoverable.is-force-hide .dropdown-menu {
  216. display: none;
  217. }
  218. }
  219. </style>