rightSlider.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446
  1. <template>
  2. <view class="right-wrapper" @touchmove.stop.prevent="moveStop" :style="viewColor">
  3. <view class="control-wrapper animated" :class="showBox?'slideInRight':''">
  4. <view class="wrapper-count">
  5. <view class="header">
  6. <view class="title">价格区间</view>
  7. <view class="input-wrapper">
  8. <input placeholder="最低价" v-model="min" type="number"/>
  9. <view class="line"></view>
  10. <input placeholder="最高价" v-model="max" type="number"/>
  11. </view>
  12. </view>
  13. <view class="store_type content-border">
  14. <view class="title">商户类别</view>
  15. <view class="brand-wrapper">
  16. <view class="wrapper">
  17. <view class="item line1" v-for="(item,index) in storeCateList" :key="index" :class="item.check?'on':''" @tap="bindChenckType(item,index)">
  18. {{item.name}}
  19. </view>
  20. </view>
  21. </view>
  22. </view>
  23. <view class="content-box">
  24. <view class="content-title">
  25. <view class="title">品牌</view>
  26. <view v-if="list.length>3">
  27. <view class="btns" @click="isShowBrand = !isShowBrand">{{isShowBrand?'收起':'展开'}}<text class="iconfont" :class="isShowBrand ? 'icon-xiangshang' : 'icon-xiangxia'"></text></view>
  28. </view>
  29. </view>
  30. <view class="brand-wrapper">
  31. <scroll-view :style="{'max-height':isShowBrand?'90%':'100rpx'}" :scroll-y="isShowBrand">
  32. <view class="wrapper">
  33. <view class="item line1" v-for="(item,index) in list" :key="index" :class="item.check?'on':''" @tap="bindChenck(item,'brand')">
  34. {{item.brand_name}}
  35. </view>
  36. </view>
  37. </scroll-view>
  38. </view>
  39. </view>
  40. <!--店铺类型-->
  41. <view class="content-box">
  42. <view class="content-title">
  43. <view class="title">店铺类型</view>
  44. <view v-if="storeTypeList.length>3">
  45. <view class="btns" @click="isShowType = !isShowType">{{isShowType?'收起':'展开'}}<text class="iconfont" :class="isShowType ? 'icon-xiangshang' : 'icon-xiang'"></text></view>
  46. </view>
  47. </view>
  48. <view class="brand-wrapper">
  49. <scroll-view :scroll-y="isShowType">
  50. <view class="wrapper">
  51. <view class="item line1" v-for="(item,index) in storeTypeList" :key="index" :class="item.check?'on':''" @tap="bindChenck(item)">
  52. {{item.type_name}}
  53. </view>
  54. </view>
  55. </scroll-view>
  56. </view>
  57. </view>
  58. <!--商品参数-->
  59. <view class="content-border">
  60. <scroll-view style="max-height:400rpx" scroll-y="true">
  61. <view class="content-box" v-for="(item,index) in productParmasList">
  62. <view class="content-title">
  63. <view class="title">{{item.name}}</view>
  64. <view>
  65. <view class="btns" @click="getParmasValue(item)">{{item.showValue?'收起':'展开'}}<text class="iconfont" :class="item.showValue ? 'icon-xiangshang' : 'icon-xiangxia'"></text></view>
  66. </view>
  67. </view>
  68. <view v-if="item.parmasValue.length>0 && item.showValue" class="brand-wrapper">
  69. <scroll-view :scroll-y="isShowParmas">
  70. <view class="wrapper">
  71. <view class="item line1" v-for="(itm,idx) in item.parmasValue" :key="idx" :class="itm.check?'on':''" @tap="bindChenck(itm)">
  72. {{itm.value}}
  73. </view>
  74. </view>
  75. </scroll-view>
  76. </view>
  77. </view>
  78. </scroll-view>
  79. </view>
  80. </view>
  81. <view class="foot-btn">
  82. <view class="btn-item" @click="reset">重置</view>
  83. <view class="btn-item confirm" @click="confirm">确定</view>
  84. </view>
  85. </view>
  86. <view class="right-bg" @click="close"></view>
  87. </view>
  88. </template>
  89. <script>
  90. // +----------------------------------------------------------------------
  91. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  92. // +----------------------------------------------------------------------
  93. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  94. // +----------------------------------------------------------------------
  95. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  96. // +----------------------------------------------------------------------
  97. // | Author: CRMEB Team <admin@crmeb.com>
  98. // +----------------------------------------------------------------------
  99. import { mapGetters } from "vuex";
  100. import { getParmasValue } from '@/api/store.js';
  101. export default{
  102. props: {
  103. brandList: {
  104. type: Array,
  105. },
  106. storeTypeArr: { //店铺类型
  107. type: Array,
  108. },
  109. parmasList: { //商品参数
  110. type: Array,
  111. },
  112. status:{
  113. type:Boolean,
  114. default:false
  115. },
  116. isCate:{
  117. type:Boolean,
  118. default:false
  119. },
  120. price_on:{
  121. type:String,
  122. default:''
  123. },
  124. price_off:{
  125. type:String,
  126. default:''
  127. },
  128. activeIndex:{
  129. type:Number,
  130. default:0
  131. }
  132. },
  133. computed: mapGetters(['viewColor']),
  134. data(){
  135. return {
  136. min: '',
  137. max:'',
  138. is_trader: '',
  139. isShow:false,
  140. isShowBrand: false,
  141. isShowType: false,
  142. isShowParmas: false,
  143. list:[],
  144. storeTypeList: [],
  145. productParmasList: [],
  146. storeCateList: [
  147. {name: '全部', value: '',check: true},
  148. {name: '自营', value: 'trader',check: false},
  149. {name: '非自营', value: 'trader',check: false},
  150. ],
  151. activeList:[],
  152. showBox:false,
  153. index: this.activeIndex
  154. }
  155. },
  156. mounted() {
  157. // 重要组件挂载后
  158. this.list = this.brandList
  159. this.storeTypeList = this.storeTypeArr
  160. this.productParmasList = this.parmasList
  161. this.showBox = this.status
  162. this.min = this.price_on
  163. this.max = this.price_off
  164. this.bindChenckType({},this.activeIndex)
  165. },
  166. methods:{
  167. bindChenck(item,key){
  168. item.check = !item.check
  169. // this.arrFilter()
  170. },
  171. bindChenckType(item,index){
  172. this.storeCateList = [
  173. {name: '全部', value: '',check: false},
  174. {name: '自营', value: 'trader',check: false},
  175. {name: '非自营', value: 'trader',check: false},
  176. ]
  177. this.storeCateList[index]['check'] = true
  178. this.is_trader = this.storeCateList[0]['check'] ? '' : this.storeCateList[1]['check'] ? 1 : 0
  179. this.index = index
  180. },
  181. /*获取参数值*/
  182. getParmasValue(item){
  183. item.showValue = !item.showValue
  184. getParmasValue(item.parameter_id).then(res => {
  185. res.data.forEach((data, index) => {
  186. data.check = false
  187. })
  188. if(item.parmasValue.length>0)return
  189. item.parmasValue = res.data
  190. });
  191. },
  192. arrFilter(list){
  193. let arr = []
  194. arr = list.filter(item=>{
  195. return item.check == true
  196. })
  197. return arr
  198. },
  199. reset(){
  200. this.list.forEach((el,index)=>{
  201. el.check = false
  202. })
  203. this.storeTypeList.forEach((el,index)=>{
  204. el.check = false
  205. })
  206. this.productParmasList.forEach((item,index)=>{
  207. item.parmasValue.forEach((el,idx)=>{
  208. el.check = false
  209. })
  210. })
  211. this.storeCateList = [
  212. {name: '全部', value: '',check: true},
  213. {name: '自营', value: 'trader',check: false},
  214. {name: '非自营', value: 'trader',check: false}
  215. ]
  216. this.min = this.max = ''
  217. // this.arrFilter()
  218. },
  219. confirm(){
  220. let parmas = {}
  221. this.productParmasList.forEach((item,index)=>{
  222. parmas[item.parameter_id]=[]
  223. item.parmasValue.forEach((el,idx)=>{
  224. if(el.check){
  225. parmas[item.parameter_id].push(el.value)
  226. }
  227. })
  228. })
  229. let obj = {
  230. brandList: this.arrFilter(this.list),
  231. typeList: this.arrFilter(this.storeTypeList),
  232. parmasList: parmas,
  233. price_on: this.min,
  234. price_off: this.max,
  235. status: false,
  236. is_trader: this.is_trader
  237. }
  238. this.showBox = false
  239. this.$emit('confirm',obj,this.index)
  240. },
  241. close(){
  242. this.showBox = false
  243. this.$emit('close')
  244. },
  245. moveStop(){}
  246. }
  247. }
  248. </script>
  249. <style lang="scss">
  250. .slideInRight{
  251. animation-duration:.5s
  252. }
  253. .right-wrapper{
  254. z-index: 99;
  255. position: fixed;
  256. left: 0;
  257. top: 0;
  258. width: 100%;
  259. height: 100%;
  260. .control-wrapper{
  261. z-index: 90;
  262. position: absolute;
  263. right: 0;
  264. top: 0;
  265. display: flex;
  266. flex-direction: column;
  267. width: 635rpx;
  268. height: 100%;
  269. background-color: #FFFFFF;
  270. .wrapper-count{
  271. height: calc(100% - 120rpx);
  272. overflow-y: auto;
  273. }
  274. .header{
  275. padding: 50rpx 26rpx 40rpx;
  276. background-color: #fff;
  277. .content-title{
  278. display: flex;
  279. align-items: center;
  280. justify-content: space-between;
  281. }
  282. .title{
  283. font-size: 26rpx;
  284. font-weight: bold;
  285. color: #282828;
  286. }
  287. .input-wrapper{
  288. display: flex;
  289. align-items: center;
  290. justify-content: space-between;
  291. margin-top: 28rpx;
  292. input{
  293. width:260rpx;
  294. height:56rpx;
  295. padding: 0 10rpx;
  296. background:rgba(242,242,242,1);
  297. border-radius:28rpx;
  298. font-size: 22rpx;
  299. text-align: center;
  300. }
  301. .line{
  302. width:15rpx;
  303. height:2rpx;
  304. background:#7D7D7D;
  305. }
  306. }
  307. }
  308. .content-border{
  309. border-top: 20rpx solid #f5f5f5;
  310. }
  311. .content-box{
  312. position: relative;
  313. display: flex;
  314. flex-direction: column;
  315. padding: 0 26rpx;
  316. .content-title{
  317. display: flex;
  318. align-items: center;
  319. justify-content: space-between;
  320. padding: 40rpx 0 20rpx;
  321. .title{
  322. font-size: 26rpx;
  323. font-weight: bold;
  324. color: #282828;
  325. }
  326. .btns{
  327. display: flex;
  328. align-items: center;
  329. justify-content: center;
  330. font-size: 22rpx;
  331. color: #999;
  332. .iconfont{
  333. margin-left: 10rpx;
  334. margin-top: 5rpx;
  335. font-size: 20rpx;
  336. }
  337. }
  338. }
  339. .brand-wrapper{
  340. flex: 1;
  341. overflow: hidden;
  342. .wrapper{
  343. display: flex;
  344. flex-wrap: wrap;
  345. padding-bottom: 20rpx;
  346. }
  347. .item{
  348. display: block;
  349. width:186rpx;
  350. height:56rpx;
  351. line-height: 56rpx;
  352. text-align: center;
  353. background:rgba(242,242,242,1);
  354. border-radius:28rpx;
  355. margin-top: 25rpx;
  356. padding: 0 10rpx;
  357. margin-right: 12rpx;
  358. &:nth-child(3n){
  359. margin-right: 0;
  360. }
  361. &.on{
  362. background: var(--view-minorColor);
  363. border:1px solid var(--view-theme);
  364. color: var(--view-theme);
  365. }
  366. }
  367. }
  368. }
  369. .foot-btn{
  370. display: flex;
  371. align-items: center;
  372. justify-content: space-between;
  373. padding-bottom: 30rpx;
  374. position: absolute;
  375. bottom: 0;
  376. left: 20rpx;
  377. .btn-item{
  378. display: flex;
  379. align-items: center;
  380. justify-content: center;
  381. width:286rpx;
  382. height:68rpx;
  383. background:rgba(255,255,255,1);
  384. border:1px solid rgba(170,170,170,1);
  385. border-radius:34rpx;
  386. font-size: 26rpx;
  387. color: #282828;
  388. &.confirm{
  389. background: var(--view-theme);
  390. border-color: var(--view-theme);
  391. color: #fff;
  392. margin-left: 20rpx;
  393. }
  394. }
  395. }
  396. .store_type{
  397. position: relative;
  398. border-top: 20rpx solid #f5f5f5;
  399. padding: 0 26rpx;
  400. .title{
  401. padding: 40rpx 0 20rpx;
  402. font-size: 26rpx;
  403. font-weight: bold;
  404. color: #282828;
  405. }
  406. .brand-wrapper{
  407. overflow: hidden;
  408. .wrapper{
  409. display: flex;
  410. flex-wrap: wrap;
  411. }
  412. .item{
  413. display: block;
  414. width:186rpx;
  415. height:56rpx;
  416. line-height: 56rpx;
  417. text-align: center;
  418. background:rgba(242,242,242,1);
  419. border-radius:28rpx;
  420. margin-top: 25rpx;
  421. padding: 0 10rpx;
  422. margin-right: 12rpx;
  423. &:nth-child(3n){
  424. margin-right: 0;
  425. }
  426. &.on{
  427. background: var(--view-minorColor);
  428. border:1px solid var(--view-theme);
  429. color: var(--view-theme);
  430. }
  431. }
  432. }
  433. }
  434. }
  435. .right-bg{
  436. position: absolute;
  437. left: 0;
  438. top: 0;
  439. width: 100%;
  440. height: 100%;
  441. background-color: rgba(0,0,0,.5);
  442. }
  443. }
  444. </style>