yunmiao-jobSelect.vue 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306
  1. <template>
  2. <view class="">
  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. <view :class="[value==item[valueName]? 'item-active' : '']">
  13. <text>{{item.pname}}-{{item[labelName]}}</text>
  14. </view>
  15. <u-icon v-if="value==item[valueName]" name="checkbox-mark" :color="iconColor" size="28">
  16. </u-icon>
  17. </view>
  18. </scroll-view>
  19. </view>
  20. <view class="u-menu-wrap">
  21. <scroll-view scroll-y scroll-with-animation class="u-tab-view menu-scroll-view" :scroll-top="scrollTop">
  22. <view v-for="(item,index) in list" :key="index" class="u-tab-item"
  23. :class="[current==index ? 'u-tab-item-active' : '']" :data-current="index"
  24. @tap.stop="swichMenu(index)">
  25. <text class="u-line-2">{{item[labelName]}}</text>
  26. </view>
  27. </scroll-view>
  28. <block v-for="(item,index) in list" :key="index">
  29. <scroll-view scroll-y class="right-box" v-if="current==index">
  30. <view class="page-view">
  31. <view class="class-item">
  32. <view class="item-container">
  33. <view class="thumb-box" v-for="(item1, index1) in item.children" :key="index1"
  34. @click="selval(item1)">
  35. <view :class="[value==item1[valueName] ? 'item-active' : '']">
  36. <text>{{item1[labelName]}}</text>
  37. </view>
  38. <!-- <u-icon v-if="value==item1[valueName]" name="checkbox-mark" :color="iconColor"
  39. size="28">
  40. </u-icon> -->
  41. </view>
  42. </view>
  43. </view>
  44. </view>
  45. </scroll-view>
  46. </block>
  47. </view>
  48. </view>
  49. <!-- </u-popup> -->
  50. </view>
  51. </template>
  52. <script>
  53. export default {
  54. name: 'jobSelect',
  55. props: {
  56. //label展示字段
  57. labelName: {
  58. type: String,
  59. default: 'name'
  60. },
  61. //value选中字段
  62. valueName: {
  63. type: String,
  64. default: 'id'
  65. },
  66. //初始选中值
  67. selectValue: {
  68. type: Number,
  69. default: 0
  70. },
  71. //选择数据
  72. listData: {
  73. type: Array,
  74. default: () => {
  75. return [];
  76. }
  77. }
  78. },
  79. data() {
  80. return {
  81. showModel: true,
  82. list: JSON.parse(JSON.stringify(this.listData)),
  83. scrollTop: 0, //tab标题的滚动条位置
  84. current: 0, // 预设当前项的值
  85. menuHeight: 0, // 左边菜单的高度
  86. menuItemHeight: 0, // 左边菜单item的高度
  87. value: this.selectValue,
  88. keyword: '',
  89. iconColor: 'primary',
  90. showAction: false,
  91. searchList: [],
  92. scrollHeight: 500
  93. }
  94. },
  95. watch: {
  96. listData: {
  97. handler(newName, oldName) {
  98. this.list = JSON.parse(JSON.stringify(newName))
  99. },
  100. deep: true,
  101. }
  102. },
  103. created() {
  104. var that = this;
  105. uni.getSystemInfo({
  106. success: function(res) {
  107. let windowHeight = res.windowHeight;
  108. let windowWidth = res.windowWidth;
  109. //#ifdef H5
  110. let headHeight = 110 / 750 * windowWidth;
  111. //#endif
  112. //#ifndef H5
  113. let headHeight = 200 / 750 * windowWidth;
  114. //#endif
  115. let scrollHeight = (windowHeight - headHeight);
  116. that.scrollHeight = scrollHeight;
  117. }
  118. });
  119. },
  120. methods: {
  121. show() {
  122. this.showModel = true;
  123. },
  124. hide() {
  125. this.showModel = false;
  126. },
  127. selval(item) {
  128. this.value = item[this.valueName];
  129. // this.showModel = false;
  130. this.keyword = '';
  131. this.showAction = false;
  132. this.$emit('confirem', item);
  133. },
  134. // 点击左边的栏目切换
  135. async swichMenu(index) {
  136. if (index == this.current) return;
  137. this.current = index;
  138. // 如果为0,意味着尚未初始化
  139. if (this.menuHeight == 0 || this.menuItemHeight == 0) {
  140. await this.getElRect('menu-scroll-view', 'menuHeight');
  141. await this.getElRect('u-tab-item', 'menuItemHeight');
  142. }
  143. // 将菜单菜单活动item垂直居中
  144. this.scrollTop = index * this.menuItemHeight + this.menuItemHeight / 2 - this.menuHeight / 2;
  145. },
  146. // 获取一个目标元素的高度
  147. getElRect(elClass, dataVal) {
  148. new Promise((resolve, reject) => {
  149. const query = uni.createSelectorQuery().in(this);
  150. query.select('.' + elClass).fields({
  151. size: true
  152. }, res => {
  153. // 如果节点尚未生成,res值为null,循环调用执行
  154. if (!res) {
  155. setTimeout(() => {
  156. this.getElRect(elClass);
  157. }, 10);
  158. return;
  159. }
  160. this[dataVal] = res.height;
  161. }).exec();
  162. })
  163. },
  164. focus() {
  165. this.showAction = true;
  166. },
  167. cancle() {
  168. this.showAction = false;
  169. this.keyword = '';
  170. },
  171. toSearch() {
  172. let arr = [];
  173. this.list.map((item, index) => {
  174. item.children.map((it, ix) => {
  175. if (it[this.labelName].indexOf(this.keyword) >= 0) {
  176. it['pname'] = item[this.labelName];
  177. arr.push(it);
  178. }
  179. })
  180. })
  181. this.searchList = arr;
  182. }
  183. }
  184. }
  185. </script>
  186. <style lang="scss" scoped>
  187. .u-wrap {
  188. // height: 100%;
  189. // width: 100%;
  190. // display: flex;
  191. // flex-direction: column;
  192. // position: relative;
  193. // overflow: hidden;
  194. }
  195. .u-search-box {
  196. padding: 0rpx 30rpx;
  197. box-sizing: border-box;
  198. background-color: white;
  199. display: flex;
  200. // flex-direction: row;
  201. align-items: center;
  202. height: 100rpx;
  203. width: 100%;
  204. }
  205. .search-warp {
  206. display: flex;
  207. overflow: hidden;
  208. background-color: #FFFFFF;
  209. position: absolute;
  210. z-index: 10;
  211. top: 200rpx;
  212. left: 0;
  213. width: 100%;
  214. }
  215. .u-menu-wrap {
  216. flex: 1;
  217. display: flex;
  218. overflow: hidden;
  219. background-color: #F8F8F8;
  220. }
  221. .u-tab-view {
  222. width: 300rpx;
  223. height: 100%;
  224. }
  225. .u-tab-item {
  226. height: 100rpx;
  227. background: #f6f6f6;
  228. box-sizing: border-box;
  229. display: flex;
  230. align-items: center;
  231. font-size: 26rpx;
  232. padding: 0 20rpx;
  233. color: #444;
  234. font-weight: 400;
  235. }
  236. .u-tab-item-active {
  237. position: relative;
  238. color: #333333;
  239. font-size: 28rpx;
  240. font-weight: 600;
  241. background: #fff;
  242. }
  243. .u-tab-item-active::before {
  244. content: "";
  245. position: absolute;
  246. border-left: 4px solid #ccc;
  247. height: 32rpx;
  248. left: 0;
  249. top: 39rpx;
  250. }
  251. .u-tab-view {
  252. height: 100%;
  253. }
  254. .right-box {
  255. background-color: white;
  256. }
  257. .page-view {
  258. background-color: white;
  259. }
  260. .class-item {
  261. background-color: #fff;
  262. border-radius: 8rpx;
  263. }
  264. .item-menu-name {
  265. font-weight: normal;
  266. font-size: 24rpx;
  267. color: $u-main-color;
  268. }
  269. .item-container {
  270. display: flex;
  271. flex-direction: column;
  272. flex: 1;
  273. }
  274. .item-active {
  275. color: #ccc;
  276. }
  277. .thumb-box {
  278. display: flex;
  279. flex-direction: row;
  280. justify-content: space-between;
  281. height: 100rpx;
  282. width: 100%;
  283. padding: 0 20rpx;
  284. align-items: center;
  285. font-size: 32rpx;
  286. }
  287. </style>