yunmiao-jobSelect.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392
  1. <template>
  2. <view class="container">
  3. <!-- <u-popup mode="right" width="100%" height="100%"> -->
  4. <view class="u-wrap">
  5. <view class="u-search-box">
  6. <u-search placeholder="请输入关键词" @focus="focus" @change="toSearch" @custom="cancle" v-model="keyword"
  7. :show-action="showAction" action-text="取消"></u-search>
  8. </view>
  9. <view class="search-warp" v-if="showAction">
  10. <scroll-view scroll-y :style="{'height': scrollHeight+'px'}" class="item-container">
  11. <view class="thumb-box" v-for="(item, index) in searchList" :key="index" @click="selval(item)">
  12. <!-- {{item}} -->
  13. <view :class="[value==item[valueName]? 'item-active' : '']">
  14. <text>{{item.secondName}}</text>
  15. </view>
  16. <u-icon v-if="value==item[valueName]" name="checkbox-mark" :color="iconColor" size="28">
  17. </u-icon>
  18. </view>
  19. </scroll-view>
  20. </view>
  21. <view class="u-menu-wrap">
  22. <scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop">
  23. <view v-for="(item,index) in first" :key="index" class="u-tab-item"
  24. :class="[current==index ? 'u-tab-item-active' : '']" :data-current="index"
  25. @tap.stop="swichMenu(index,item)">
  26. <text class="u-line-2">{{item[labelName]}}</text>
  27. </view>
  28. </scroll-view>
  29. <block v-for="(item,index) in first" :key="index">
  30. <scroll-view scroll-y class="right-box" v-if="current==index">
  31. <view class="page-view">
  32. <view class="class-item">
  33. <view class="item-container">
  34. <view class="thumb-box" v-for="(item1, index1) in second" :key="index1"
  35. @click="selval(item1)">
  36. <view :class="[value==item1[valueName] ? 'item-active' : '']"
  37. class="img-content">
  38. <image :src="item2" mode="" v-for="item2 in item1.urlPath.split(',')"
  39. class="img">
  40. </image>
  41. <text class="right-text"
  42. style="margin-left: 20rpx;">{{item1.secondName}}</text>
  43. </view>
  44. <!-- <u-icon v-if="value==item1[valueName]" name="checkbox-mark" :color="iconColor"
  45. size="28">
  46. </u-icon> -->
  47. </view>
  48. </view>
  49. </view>
  50. </view>
  51. </scroll-view>
  52. </block>
  53. </view>
  54. </view>
  55. <!-- </u-popup> -->
  56. </view>
  57. </template>
  58. <script>
  59. export default {
  60. name: 'jobSelect',
  61. props: {
  62. //label展示字段
  63. labelName: {
  64. type: String,
  65. default: 'typeName'
  66. },
  67. //value选中字段
  68. valueName: {
  69. type: String,
  70. default: 'id'
  71. },
  72. //初始选中值
  73. selectValue: {
  74. type: Number,
  75. default: 0
  76. },
  77. //选择数据
  78. listData: {
  79. type: Array,
  80. default: () => {
  81. return [];
  82. }
  83. },
  84. typeOneData: {
  85. type: Array,
  86. default: () => {
  87. return [];
  88. }
  89. },
  90. typeTwoData: {
  91. type: Array,
  92. default: () => {
  93. return [];
  94. }
  95. }
  96. },
  97. data() {
  98. return {
  99. first: JSON.parse(JSON.stringify(this.typeOneData)),
  100. second: JSON.parse(JSON.stringify(this.typeTwoData)),
  101. showModel: true,
  102. list: JSON.parse(JSON.stringify(this.listData)),
  103. scrollTop: 0, //tab标题的滚动条位置
  104. current: 0, // 预设当前项的值
  105. menuHeight: 0, // 左边菜单的高度
  106. menuItemHeight: 0, // 左边菜单item的高度
  107. value: this.selectValue,
  108. keyword: '',
  109. iconColor: 'primary',
  110. showAction: false,
  111. searchList: [],
  112. scrollHeight: 500
  113. }
  114. },
  115. watch: {
  116. listData: {
  117. handler(newName, oldName) {
  118. this.list = JSON.parse(JSON.stringify(newName))
  119. },
  120. deep: true,
  121. },
  122. typeOneData: {
  123. handler(newName, oldName) {
  124. this.first = JSON.parse(JSON.stringify(newName))
  125. },
  126. deep: true,
  127. },
  128. typeTwoData: {
  129. handler(newName, oldName) {
  130. this.second = JSON.parse(JSON.stringify(newName))
  131. },
  132. deep: true,
  133. }
  134. },
  135. created() {
  136. var that = this;
  137. uni.getSystemInfo({
  138. success: function(res) {
  139. let windowHeight = res.windowHeight;
  140. let windowWidth = res.windowWidth;
  141. //#ifdef H5
  142. let headHeight = 110 / 750 * windowWidth;
  143. //#endif
  144. //#ifndef H5
  145. let headHeight = 200 / 750 * windowWidth;
  146. //#endif
  147. let scrollHeight = (windowHeight - headHeight);
  148. that.scrollHeight = scrollHeight;
  149. }
  150. });
  151. },
  152. methods: {
  153. show() {
  154. this.showModel = true;
  155. },
  156. hide() {
  157. this.showModel = false;
  158. },
  159. selval(item) {
  160. this.value = item[this.valueName];
  161. // this.showModel = false;
  162. this.keyword = '';
  163. this.showAction = false;
  164. this.$emit('confirem', item);
  165. },
  166. // 点击左边的栏目切换
  167. async swichMenu(index, val) {
  168. this.$request.baseRequest('admin.gubi.gubiTypeSecond', 'list', {
  169. page: 1,
  170. limit: 1000,
  171. typeId: val.id
  172. },
  173. failres => {
  174. console.log('res+++++', failres.errmsg)
  175. this.$refs.uToast.show({
  176. type: 'error',
  177. message: failres.errmsg,
  178. })
  179. uni.hideLoading()
  180. }).then(res => {
  181. console.log(res.data.items)
  182. this.second = res.data.items
  183. if (index == this.current) return;
  184. this.current = index;
  185. // 如果为0,意味着尚未初始化
  186. if (this.menuHeight == 0 || this.menuItemHeight == 0) {
  187. this.getElRect('menu-scroll-view', 'menuHeight');
  188. this.getElRect('u-tab-item', 'menuItemHeight');
  189. }
  190. // 将菜单菜单活动item垂直居中
  191. this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight /
  192. 2;
  193. })
  194. },
  195. // 获取一个目标元素的高度
  196. getElRect(elClass, dataVal) {
  197. new Promise((resolve, reject) => {
  198. const query = uni.createSelectorQuery().in(this);
  199. query.select('.' + elClass).fields({
  200. size: true
  201. }, res => {
  202. // 如果节点尚未生成,res值为null,循环调用执行
  203. if (!res) {
  204. setTimeout(() => {
  205. this.getElRect(elClass);
  206. }, 10);
  207. return;
  208. }
  209. this[dataVal] = res.height;
  210. }).exec();
  211. })
  212. },
  213. focus() {
  214. this.showAction = true;
  215. },
  216. cancle() {
  217. this.showAction = false;
  218. this.keyword = '';
  219. },
  220. toSearch() {
  221. let arr = [];
  222. // this.list.map((item, index) => {
  223. this.second.map((it, ix) => {
  224. console.log(123)
  225. console.log(it, ix)
  226. console.log(it.secondName.indexOf(this.keyword))
  227. if (it.secondName.indexOf(this.keyword) > -1 && this.keyword) {
  228. // it['pname'] = item[this.secondName];
  229. arr.push(it);
  230. }
  231. })
  232. // })
  233. console.log('arr', arr)
  234. this.searchList = arr;
  235. }
  236. }
  237. }
  238. </script>
  239. <style lang="scss" scoped>
  240. .u-wrap {
  241. // height: 100%;
  242. // width: 100%;
  243. // display: flex;
  244. // flex-direction: column;
  245. // position: relative;
  246. // overflow: hidden;
  247. }
  248. .u-search-box {
  249. padding: 0rpx 30rpx;
  250. box-sizing: border-box;
  251. background-color: white;
  252. display: flex;
  253. // flex-direction: row;
  254. align-items: center;
  255. height: 100rpx;
  256. width: 100%;
  257. position: fixed;
  258. top: 85px;
  259. z-index: 99;
  260. }
  261. .search-warp {
  262. display: flex;
  263. overflow: hidden;
  264. background-color: #FFFFFF;
  265. position: absolute;
  266. z-index: 10;
  267. // top: 200rpx;
  268. left: 0;
  269. width: 100%;
  270. }
  271. .u-menu-wrap {
  272. padding-bottom: 100rpx;
  273. flex: 1;
  274. display: flex;
  275. overflow: hidden;
  276. background-color: #F8F8F8;
  277. }
  278. .u-tab-view {
  279. width: 300rpx;
  280. height: 100vh;
  281. overflow: hidden;
  282. }
  283. .u-tab-item {
  284. height: 100rpx;
  285. background: #f6f6f6;
  286. box-sizing: border-box;
  287. display: flex;
  288. align-items: center;
  289. font-size: 26rpx;
  290. padding: 0 20rpx;
  291. color: #444;
  292. font-weight: 400;
  293. }
  294. .u-tab-item-active {
  295. position: relative;
  296. color: red;
  297. font-size: 28rpx;
  298. font-weight: 600;
  299. background: #fff;
  300. }
  301. .u-tab-item-active::before {
  302. content: "";
  303. position: absolute;
  304. border-left: 4px solid red;
  305. height: 32rpx;
  306. left: 0;
  307. top: 39rpx;
  308. }
  309. .u-tab-view {
  310. // height: 100%;
  311. }
  312. .right-box {
  313. background-color: white;
  314. height: 100vh;
  315. overflow: hidden;
  316. }
  317. .page-view {
  318. background-color: white;
  319. }
  320. .class-item {
  321. background-color: #fff;
  322. border-radius: 8rpx;
  323. }
  324. .item-menu-name {
  325. font-weight: normal;
  326. font-size: 24rpx;
  327. color: $u-main-color;
  328. }
  329. .item-container {
  330. display: flex;
  331. flex-direction: column;
  332. flex: 1;
  333. }
  334. .item-active {
  335. color: #ccc;
  336. }
  337. .thumb-box {
  338. display: flex;
  339. flex-direction: row;
  340. justify-content: space-between;
  341. padding: 20rpx;
  342. align-items: center;
  343. font-size: 32rpx;
  344. }
  345. .img {
  346. width: 300rpx;
  347. height: 150rpx;
  348. }
  349. .img-content {
  350. width: 100%;
  351. display: flex;
  352. align-items: center;
  353. // justify-content: space-between;
  354. // width: 90%;
  355. .right-text {
  356. width: calc(100% - 320rpx);
  357. }
  358. }
  359. .container {
  360. position: relative;
  361. top: 100px;
  362. }
  363. </style>