nav-bar.vue 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. <template>
  2. <uni-nav-bar :class="{'custom_uni_nav_bar':!onlyTitle,'custom_navbar_only_title':onlyTitle}"
  3. :height="`${height}rpx`" :backgroundColor="backgroundColor" :title="title" color="#333333" :fixed="true"
  4. :border="showHeaderborder" :statusBar="true" :leftWidth="leftWidth" :rightWidth="rightWidth" left-icon="left"
  5. @clickLeft="GoBack()">
  6. <!-- 表头内容 -->
  7. <view class="nav_head" v-if="!onlyTitle">
  8. <text class="nav_title">{{title}}</text>
  9. <uni-easyinput class="search_box" v-model="state.searchWord" trim="all" :styles="state.searchInputStyles"
  10. :placeholderStyle="state.searchInputPlaceholderStyle" placeholder="请输入关键字搜索" @input="HandleSearchInput">
  11. <template #left>
  12. <image src="/static/image/overview/search.png" class="search_icon"></image>
  13. </template>
  14. </uni-easyinput>
  15. </view>
  16. <!-- 条件选择器 -->
  17. <view class="filter_picker" v-if="showFilterPicker">
  18. <template v-for="(item,index) in filterPickerData" :key="index">
  19. <picker mode="selector" v-if="item?.list?.length > 0" :range="item.list" :value="item.valueIndex" range-key="label" style="width: calc((100% - 32rpx * 2) / 3);" @change="(e)=>ChangeFilterPicker(e,index)">
  20. <view class="filter_item">
  21. <text class="filter_text">{{ item?.list?.[item.valueIndex]?.label || '' }}</text>
  22. <uni-icons type="down" size="16" color="#999999"></uni-icons>
  23. </view>
  24. </picker>
  25. </template>
  26. </view>
  27. <!-- tabs -->
  28. <scroll-view v-if="showTabs" class="scroll_tabs" scroll-x="true" scroll-left="0" :show-scrollbar="false">
  29. <view :class="['tab_item',{'selected':item.value==state.tabsSelected}]" v-for="item in tabList" :key="item.value" @click="SelectTabsValue(item.value)">
  30. {{item.label}}
  31. </view>
  32. </scroll-view>
  33. </uni-nav-bar>
  34. </template>
  35. <script setup>
  36. import uniNavBar from '@/uni_modules/uni-nav-bar/components/uni-nav-bar/uni-nav-bar.vue';
  37. import uniIcons from '@/uni_modules/uni-icons/components/uni-icons/uni-icons.vue';
  38. import {
  39. reactive,
  40. onMounted,
  41. watch
  42. } from 'vue';
  43. const emit = defineEmits(['GoBack','CommonFilterData']);
  44. const props = defineProps({
  45. height: { //高度
  46. type: String,
  47. default: () => ''
  48. },
  49. leftWidth: { //导航栏左侧插槽宽度
  50. type: String,
  51. default: () => '96rpx'
  52. },
  53. rightWidth: { //导航栏右侧插槽宽度
  54. type: String,
  55. default: () => '96rpx'
  56. },
  57. title: { //标题
  58. type: String,
  59. default: () => ''
  60. },
  61. showHeaderborder: { //是否显示边框 默认不显示
  62. type: Boolean,
  63. default: false
  64. },
  65. backgroundColor: { //背景色
  66. type: String,
  67. default: () => '#FFFFFF'
  68. },
  69. backPath: { //返回路径
  70. type: String,
  71. default: () => ''
  72. },
  73. onlyTitle: { //是否只显示标题
  74. type: Boolean,
  75. default: true
  76. },
  77. filterPickerData: { //条件选择器
  78. type: Array,
  79. default: () => []
  80. },
  81. tabList: { //tabs
  82. type: Array,
  83. default: () => []
  84. },
  85. showFilterPicker: { //是否显示条件选择器
  86. type: Boolean,
  87. default: false
  88. },
  89. showTabs: { //是否显示条件选择器tabs
  90. type: Boolean,
  91. default: false
  92. }
  93. });
  94. const state = reactive({
  95. searchWord: '', //关键字
  96. filterPickerValue: [], //条件选择器默认值
  97. tabsSelected: '', //tabs 默认选中
  98. searchInputStyles: { //搜素框样式
  99. borderColor: '#DCDFE6',
  100. color: '#333333'
  101. },
  102. searchInputPlaceholderStyle: 'color: #C0C4CC;fontSize: 28rpx' //搜素框样式
  103. })
  104. watch(()=>props.tabList,(newVal, oldVal)=>{
  105. if(newVal){
  106. state.tabsSelected = props?.tabList?.[0]?.value || ''; //tab 默认值
  107. }
  108. })
  109. //关键字搜索
  110. const HandleSearchInput = (e) => {
  111. state.searchWord = e;
  112. CommonFilterData(state.searchWord, {
  113. filterPickerValue: [...state.filterPickerValue]
  114. }, state.tabsSelected, 'search');
  115. }
  116. //切换条件选择器 index:数组filterPickerData索引
  117. const ChangeFilterPicker = (e, index) => {
  118. const valueIndex = e.detail.value; //下拉框选中值的索引
  119. const selectedValue = props.filterPickerData?.[index]?.list?.[valueIndex]?.value ?? '';
  120. state.filterPickerValue[index] = selectedValue;
  121. //处理下一级默认值
  122. for(let i = 0; i < props.filterPickerData.length; i++){
  123. if(i > index){
  124. const list = props.filterPickerData?.[i]?.list || [];
  125. state.filterPickerValue[i] = list.length > 0 ? list[0].value : '';
  126. }
  127. }
  128. console.log(state.filterPickerValue,props.filterPickerData,37888)
  129. CommonFilterData(state.searchWord, {
  130. valueIndex,
  131. index,
  132. filterPickerValue: [...state.filterPickerValue]
  133. }, state.tabsSelected, 'filterPicker');
  134. }
  135. //tabs切换
  136. const SelectTabsValue = (value) => {
  137. state.tabsSelected = value;
  138. CommonFilterData(state.searchWord, {
  139. filterPickerValue: [...state.filterPickerValue]
  140. }, state.tabsSelected, 'tabs');
  141. }
  142. //条件发生改变进行数据查询
  143. const CommonFilterData = (searchWord, filterPickerValue, tabsSelected, type) => {
  144. emit('CommonFilterData', searchWord, filterPickerValue, tabsSelected, type);
  145. }
  146. const GoBack = () => {
  147. if (props.backPath == 'myIndex') {
  148. uni.switchTab({
  149. url: '/pages/my/index'
  150. });
  151. } else if (props.backPath == 'workspace') { //跳转工作台
  152. uni.switchTab({
  153. url: '/pages/workspace/index'
  154. });
  155. } else {
  156. emit('GoBack');
  157. }
  158. }
  159. onMounted(() => {
  160. state.tabsSelected = props?.tabList?.[0]?.value || ''; //tab 默认值
  161. state.filterPickerValue = props.filterPickerData.map(item => item?.defaultValue ?? '');
  162. })
  163. </script>
  164. <style scoped lang="scss">
  165. :deep(.uni-navbar__header) {
  166. padding: 0;
  167. position: relative;
  168. z-index: 999;
  169. }
  170. :deep(.uni-navbar__header-container) {
  171. padding: 0;
  172. }
  173. </style>