homeComb.vue 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  1. <template>
  2. <view class="page_count">
  3. <view class="bg-img">
  4. <img :src="bgColor" alt="">
  5. </view>
  6. <!--搜索-->
  7. <view :class="{scrolled:isScrolled}" class="my-main">
  8. <!-- #ifdef H5 -->
  9. <view>
  10. <view class="header">
  11. <view class="sys-head tui-skeleton" :style="{ height: statusBarHeight }"></view>
  12. <view class="serch-box tui-skeleton">
  13. <view class="serch-wrapper flex">
  14. <view v-if="logoConfig || site_logo" class="logo skeleton-rect"><image :src="logoConfig || site_logo" mode="widthFix"></image></view>
  15. <navigator v-if="hotWords.length > 0" :url="'/pages/columnGoods/goods_search/index?searchVal='+searchVal" :class="(logoConfig || site_logo) ? 'input' : 'uninput'"
  16. hover-class="none" class="skeleton-rect box">
  17. <view class='swiperTxt'>
  18. <swiper :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval" :duration="duration" vertical="true"
  19. circular="true" @change="textChange">
  20. <block v-for="(item,index) in hotWords" :key='index'>
  21. <swiper-item catchtouchmove='catchTouchMove'>
  22. <view class='acea-row row-between-wrapper'>
  23. <view class='text acea-row row-between-wrapper'>
  24. <view class='newsTitle line1'>{{item.val}}</view>
  25. </view>
  26. </view>
  27. </swiper-item>
  28. </block>
  29. </swiper>
  30. </view>
  31. <text class="iconfont icon-xiazai5"></text>
  32. </navigator>
  33. <navigator v-else url="/pages/columnGoods/goods_search/index" :class="(logoConfig || site_logo) ? 'input' : 'uninput'"
  34. hover-class="none" class="skeleton-rect">
  35. 搜索商品
  36. <text class="iconfont icon-xiazai5"></text>
  37. </navigator>
  38. <navigator class="btn skeleton-rect" url="/pages/chat/customer_list/index?type=0" hover-class="none">
  39. <view class="iconfont icon-xiaoxi" style="color:#fff;"></view>
  40. <text class="iconnum" v-if="userInfo.total_unread">{{ userInfo.total_unread }}</text>
  41. </navigator>
  42. </view>
  43. </view>
  44. </view>
  45. <view :style="'height:'+isTop+'px'"></view>
  46. </view>
  47. <!-- #endif -->
  48. <!-- #ifdef MP || APP-PLUS -->
  49. <view>
  50. <view class="mp-header" id="home">
  51. <view class="sys-head tui-skeleton" :style="{ height: statusBarHeight }"></view>
  52. <view class="serch-box tui-skeleton">
  53. <view class="serch-wrapper flex">
  54. <view v-if="logoConfig || site_logo" class="logo skeleton-rect"><image :src="logoConfig || site_logo" mode="widthFix"></image></view>
  55. <navigator v-if="hotWords.length > 0" :url="'/pages/columnGoods/goods_search/index?searchVal='+searchVal" :class="(logoConfig || site_logo) ? 'input' : 'uninput'"
  56. hover-class="none" class="skeleton-rect box">
  57. <view class='swiperTxt'>
  58. <swiper :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval" :duration="duration" vertical="true"
  59. circular="true" @change="textChange">
  60. <block v-for="(item,index) in hotWords" :key='index'>
  61. <swiper-item catchtouchmove='catchTouchMove'>
  62. <view class='acea-row row-between-wrapper'>
  63. <view class='text acea-row row-between-wrapper'>
  64. <view class='newsTitle line1'>{{item.val}}</view>
  65. </view>
  66. </view>
  67. </swiper-item>
  68. </block>
  69. </swiper>
  70. </view>
  71. <text class="iconfont icon-xiazai5"></text>
  72. </navigator>
  73. <navigator v-else url="/pages/columnGoods/goods_search/index" :class="(logoConfig || site_logo) ? 'input' : 'uninput'"
  74. hover-class="none" class="skeleton-rect">
  75. 搜索商品
  76. <text class="iconfont icon-xiazai5"></text>
  77. </navigator>
  78. </view>
  79. </view>
  80. </view>
  81. <view :style="'height:'+marTop+'px;'"></view>
  82. <view :style="'height:'+statusBarHeight"></view>
  83. </view>
  84. <!-- #endif -->
  85. <!--选项卡-->
  86. <view v-if="tabTitle.length>0" style="visibility: hidden;" :style="{ height: navHeight + 'px' }"></view>
  87. <view v-if="tabTitle.length>0" class="navTabBox tabNav" :class="{bgwhite:isScrolled}" :style="'top:'+isTop+'px'">
  88. <view class="longTab" :style='"width:"+mainWidth+"px"'>
  89. <scroll-view scroll-x="true" style="white-space: nowrap; display: flex;" scroll-with-animation :scroll-left="tabLeft" show-scrollbar="true">
  90. <view class="longItem" :data-index="index" :class="index===tabClick?'click':''" @click="changeTab(item,index)" v-for="(item,index) in tabTitle" :key="index" :id="'id'+index">{{item.info[0].value}}</view>
  91. <view class="underlineBox" :style='"transform:translateX("+isLeft+"px);width:"+isWidth+"px"'>
  92. <view class="underline"></view>
  93. </view>
  94. </scroll-view>
  95. </view>
  96. </view>
  97. </view>
  98. <!--轮播图-->
  99. <view class="swiperBg" :style="{ marginTop: swiperTop+'px'}">
  100. <block>
  101. <view class="swiper page_swiper" v-if="imgUrls.length">
  102. <swiper
  103. :autoplay="true"
  104. :circular="circular"
  105. :interval="intervals"
  106. :duration="duration"
  107. indicator-color="rgba(255,255,255,0.6)"
  108. indicator-active-color="#fff"
  109. :current="swiperCur"
  110. previous-margin="30rpx"
  111. next-margin="30rpx"
  112. :style="'height:'+(imageH+10)+'rpx;'"
  113. @change="swiperChange"
  114. :class="{ scalex:isScale }"
  115. >
  116. <block v-for="(item,index) in imgUrls" :key="index">
  117. <swiper-item :class="{ active: index == swiperCur,scalex:isScale }">
  118. <view @click="goDetail(item)" class='slide-navigator acea-row row-between-wrapper'>
  119. <image :src="item.img" class="slide-image aa" :style="'height:'+ imageH +'rpx;'" mode="aspectFill"></image>
  120. </view>
  121. </swiper-item>
  122. </block>
  123. </swiper>
  124. <view class="dots">
  125. <block v-for="(item,index) in imgUrls" :key="index">
  126. <view class="dot" :class="index == swiperCur ? ' active' : ''"></view>
  127. </block>
  128. </view>
  129. </view>
  130. </block>
  131. </view>
  132. </view>
  133. </template>
  134. <script>
  135. // +----------------------------------------------------------------------
  136. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  137. // +----------------------------------------------------------------------
  138. // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
  139. // +----------------------------------------------------------------------
  140. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  141. // +----------------------------------------------------------------------
  142. // | Author: CRMEB Team <admin@crmeb.com>
  143. // +----------------------------------------------------------------------
  144. let statusBarHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
  145. import { configMap } from '@/utils';
  146. export default {
  147. name: 'homeComb',
  148. props: {
  149. dataConfig: {
  150. type: Object,
  151. default: () => {}
  152. },
  153. isScrolled: {
  154. type: Boolean,
  155. default: false
  156. },
  157. isScale: {
  158. type: Boolean,
  159. default: false
  160. },
  161. isMenu: {
  162. type: Boolean,
  163. default: false
  164. },
  165. userInfo: {
  166. type: Object,
  167. default: () => {}
  168. },
  169. },
  170. computed: configMap({site_logo: ''}),
  171. data() {
  172. return {
  173. statusBarHeight: statusBarHeight,
  174. scrollHeight: 0,
  175. autoplay: true,
  176. interval: this.dataConfig.titleConfig.value * 1000 || 2500,
  177. duration: 500,
  178. marTop: 50,
  179. searchH: 0,
  180. logoConfig: this.dataConfig.logoConfig.url,
  181. hotWords: this.dataConfig.hotWords.list || [],
  182. tabClick: 0, //导航栏被点击
  183. isLeft: 0, //导航栏下划线位置
  184. isWidth: 0, //每个导航栏占位
  185. mainWidth: 0,
  186. tabLeft:0,
  187. swiperIndex:0,
  188. childIndex:0,
  189. childID:0,
  190. tabTitle:this.dataConfig.listConfig.list || [],
  191. fixedTop: 0,
  192. isTop: 0,
  193. navHeight: 38,
  194. indicatorDots: false,
  195. circular: true,
  196. autoplay: true,
  197. intervals: 3000,
  198. duration: 500,
  199. imgUrls: [], //图片轮播数据
  200. imageH: 0,
  201. swiperCur: 0,
  202. swiperType: 1,
  203. searchVal: this.dataConfig.hotWords && this.dataConfig.hotWords.list[0]['val'] || '',
  204. bgColor: this.dataConfig.swiperConfig.list && this.dataConfig.swiperConfig.list[0]['img'],
  205. tabId: false,
  206. isCategory: false,
  207. swiperTop: 0,
  208. isFixed: true,
  209. };
  210. },
  211. watch: {
  212. imageH(nVal,oVal){
  213. this.imageH = nVal
  214. }
  215. },
  216. created() {
  217. var that = this
  218. // 获取设备宽度
  219. uni.getSystemInfo({
  220. success(e) {
  221. that.mainWidth = e.windowWidth
  222. that.isWidth = (e.windowWidth-65) / 8
  223. }
  224. })
  225. setTimeout((e) => {
  226. const query = uni.createSelectorQuery().in(this);
  227. if(that.tabTitle.length>0){
  228. query.select('.navTabBox').boundingClientRect(data => {
  229. that.navHeight = data.height > 42 ? data.height : 42
  230. }).exec();
  231. }else{
  232. that.navHeight = 0
  233. }
  234. // #ifdef H5
  235. query.select('.header').boundingClientRect(data => {
  236. that.isTop = data.height
  237. that.marTop = data.height
  238. }).exec();
  239. // #endif
  240. // #ifdef MP || APP-PLUS
  241. // #ifdef APP-PLUS
  242. const menuButton = 0
  243. //#endif
  244. // #ifdef MP
  245. const menuButton = uni.getMenuButtonBoundingClientRect();
  246. //#endif
  247. query
  248. .select('.serch-box')
  249. .boundingClientRect(data => {
  250. this.marTop = data.height
  251. }).exec();
  252. //#endif
  253. }, 500)
  254. that.isTop = (uni.getSystemInfoSync().statusBarHeight + this.marTop)
  255. that.imgUrls = that.dataConfig.swiperConfig.list
  256. that.$nextTick(function() {
  257. setTimeout((e) => {
  258. // #ifdef H5
  259. that.swiperTop = that.navHeight+that.marTop
  260. //#endif
  261. // #ifdef MP || APP-PLUS
  262. that.swiperTop = that.navHeight + uni.getSystemInfoSync().statusBarHeight + that.marTop
  263. //#endif
  264. }, 500)
  265. })
  266. },
  267. mounted(){
  268. let that = this;
  269. if(that.tabTitle.length>0 && that.tabTitle[0]['value'] != '推荐'){
  270. that.tabTitle.unshift({
  271. img: '',
  272. info: [{value: "推荐"},{value: false}]
  273. })
  274. }
  275. that.$nextTick(function() {
  276. uni.getImageInfo({
  277. src: that.setDomain(that.imgUrls[0].img),
  278. success: function(res) {
  279. if (res && res.height > 0) {
  280. let height = res.height * ((750-20) / res.width)
  281. that.$set(that, 'imageH', height);
  282. } else {
  283. that.$set(that, 'imageH', 375);
  284. }
  285. },
  286. fail: function(error) {
  287. that.$set(that, 'imageH', 375);
  288. }
  289. })
  290. })
  291. },
  292. methods: {
  293. goDetail(url){
  294. let urls = url.info[1].value
  295. this.$util.JumpPath(urls);
  296. },
  297. //替换安全域名
  298. setDomain: function(url) {
  299. url = url ? url.toString() : '';
  300. //本地调试打开,生产请注销
  301. if (url.indexOf("https://") > -1) return url;
  302. else return url.replace('http://', 'https://');
  303. },
  304. swiperChange(e) {
  305. let { current, source } = e.detail;
  306. if (source === 'autoplay' || source === 'touch') {
  307. this.swiperCur = e.detail.current;
  308. this.bgColor = this.imgUrls[e.detail.current]['img']
  309. }
  310. },
  311. textChange(e) {
  312. let { current, source } = e.detail;
  313. if (source === 'autoplay' || source === 'touch') {
  314. this.searchVal = this.hotWords[e.detail.current]['val']
  315. }
  316. },
  317. /**显示全部分类*/
  318. showCategory() {
  319. this.isCategory = true;
  320. },
  321. /*跳转为页面*/
  322. changeTab(item, index) {
  323. if(this.tabClick == index) return
  324. this.tabClick = index //设置导航点击了哪一个
  325. this.isLeft = index * this.isWidth + 16 //设置下划线位置
  326. this.tabId = item.info[1].value
  327. this.bgColor = this.tabId ? item.img : this.dataConfig.swiperConfig.list[0]['img']
  328. this.imgUrls = this.tabId ? [{img:item.img}] : this.dataConfig.swiperConfig.list
  329. this.$emit('changeDiy', this.tabId);
  330. }
  331. },
  332. }
  333. </script>
  334. <style lang="scss" scoped>
  335. .page_count {
  336. position: relative;
  337. overflow: hidden;
  338. .bg-img {
  339. position: absolute;
  340. width: 100%;
  341. height: 100%;
  342. top: 0;
  343. /* #ifdef MP || APP-PLUS */
  344. z-index: -1;
  345. /* #endif */
  346. /* #ifdef H5 */
  347. z-index: 0;
  348. /* #endif */
  349. z-index: 0;
  350. filter: blur(0);
  351. overflow: hidden;
  352. img {
  353. width: 100%;
  354. height: 100%;
  355. filter: blur(30rpx);
  356. transform: scale(1.5);
  357. }
  358. }
  359. }
  360. .my-main{
  361. // transition: background-color .5s ease;
  362. }
  363. .swiperTxt {
  364. width: 300rpx;
  365. line-height: 64rpx;
  366. height: 64rpx;
  367. overflow: hidden;
  368. }
  369. .swiperTxt .text {
  370. width: 480rpx;
  371. }
  372. .swiperTxt .text .newsTitle {
  373. width: 300rpx;
  374. font-size: 24rpx;
  375. color: #ffffff;
  376. }
  377. .swiperTxt swiper {
  378. height: 100%;
  379. }
  380. .header {
  381. z-index: 99;
  382. position: fixed;
  383. left: 0;
  384. width: 100%;
  385. .btn {
  386. position: relative;
  387. margin-left: 30rpx;
  388. .iconfont {
  389. font-size: 45rpx;
  390. }
  391. }
  392. .iconnum {
  393. min-width: 14rpx;
  394. color: #E93323;
  395. background: #fff;
  396. border-radius: 15rpx;
  397. position: absolute;
  398. right: -10rpx;
  399. top: -10rpx;
  400. font-size: 10px;
  401. padding: 0 5px;
  402. }
  403. .serch-wrapper {
  404. align-items: center;
  405. padding: 20rpx 30rpx 20rpx 30rpx;
  406. .logo {
  407. width: 133rpx;
  408. margin-right: 20rpx;
  409. }
  410. image {
  411. width: 133rpx;
  412. height: 66rpx;
  413. }
  414. .box{
  415. flex: 1;
  416. }
  417. .input,.uninput {
  418. line-height: 64rpx;
  419. height: 64rpx;
  420. padding: 0 0 0 30rpx;
  421. background: rgba(0,0,0,.2);
  422. color: #fff;
  423. border-radius: 30rpx;
  424. font-size: 28rpx;
  425. z-index: 2;
  426. position: relative;
  427. box-sizing: border-box;
  428. .iconfont {
  429. position: absolute;
  430. right: 20rpx;
  431. top: 0;
  432. color: #eeeeee;
  433. }
  434. }
  435. }
  436. }
  437. .mp-header {
  438. z-index: 99;
  439. position: fixed;
  440. left: 0;
  441. width: 100%;
  442. .box{
  443. flex: 1;
  444. }
  445. .serch-box{
  446. margin-top: 10rpx;
  447. }
  448. .serch-wrapper {
  449. display: flex;
  450. align-items: center;
  451. padding: 0 50rpx 20rpx 30rpx;
  452. height: 76rpx;
  453. .logo {
  454. width: 133rpx;
  455. margin-right: 20rpx;
  456. line-height: 0;
  457. }
  458. image {
  459. width: 118rpx;
  460. height: 42rpx;
  461. }
  462. .input,.uninput {
  463. display: flex;
  464. /* #ifdef MP */
  465. flex: 0;
  466. /* #endif */
  467. /* #ifdef APP-PLUS */
  468. flex: 1;
  469. /* #endif */
  470. flex: 1;
  471. align-items: center;
  472. height: 64rpx;
  473. line-height: 64rpx;
  474. padding: 0 50rpx 0 30rpx;
  475. background: rgba(0,0,0,.2);
  476. border-radius: 100rpx;
  477. color: #ffffff;
  478. font-size: 28rpx;
  479. position: relative;
  480. box-sizing: border-box;
  481. .iconfont {
  482. position: absolute;
  483. right: 20rpx;
  484. top: 0;
  485. color: #eeeeee;
  486. }
  487. }
  488. /* #ifdef MP */
  489. .uninput{
  490. max-width: 500rpx;
  491. }
  492. .input{
  493. max-width: 340rpx;
  494. }
  495. /* #endif */
  496. }
  497. }
  498. .tabNav {
  499. padding-top: 10rpx;
  500. }
  501. .navTabBox {
  502. color: rgba(255, 255, 255, 1);
  503. padding: 0 30rpx;
  504. z-index: 10;
  505. left: 0;
  506. width: 100%;
  507. box-sizing: border-box;
  508. position: fixed;
  509. scroll-view{
  510. width:100%;
  511. padding-right: 30rpx;
  512. height: 70rpx;
  513. }
  514. .click {
  515. color: white;
  516. }
  517. .longTab {
  518. .longItem{
  519. height: 50upx;
  520. display: inline-block;
  521. line-height: 50upx;
  522. text-align: center;
  523. font-size: 28rpx;
  524. color: #FFFFFF;
  525. max-width: 160rpx;
  526. margin-right: 30rpx;
  527. position: relative;
  528. &:last-child{
  529. margin-right: 0;
  530. }
  531. &.click{
  532. font-weight: bold;
  533. font-size: 30rpx;
  534. color: #FFFFFF;
  535. &::after{
  536. content: '';
  537. transition: .5s;
  538. width: 33rpx;
  539. height: 4rpx;
  540. background: #FFFFFF;
  541. position: absolute;
  542. bottom: -4rpx;
  543. left: 50%;
  544. margin-left: -16rpx;
  545. }
  546. }
  547. }
  548. }
  549. }
  550. .scrolled{
  551. z-index: 5000;
  552. position: fixed;
  553. min-height: 90rpx;
  554. left: 0;
  555. top: 0;
  556. width: 100%;
  557. background: #fff!important;
  558. transition: background-color .5s ease;
  559. .longItem,.click,.category text{
  560. color: #000000!important;
  561. }
  562. .navTabBox,.mp-header,.header{
  563. // transition: background-color .5s ease;
  564. background: #ffffff;
  565. }
  566. .btn .iconfont{
  567. color: #333333!important;
  568. }
  569. .iconnum{
  570. background: #333333!important;
  571. }
  572. .underline{
  573. background: #000000!important;
  574. }
  575. .click{
  576. &::after{
  577. background-color:#fff!important;
  578. }
  579. }
  580. }
  581. .swiperBg {
  582. z-index: 1;
  583. margin-top: 10rpx;
  584. padding-bottom: 30rpx;
  585. .colorBg {
  586. position: absolute;
  587. left: 0;
  588. top: 0;
  589. height: 130rpx;
  590. width: 100%;
  591. }
  592. .page_swiper {
  593. position: relative;
  594. width: 100%;
  595. height: auto;
  596. margin: 0 auto;
  597. border-radius: 10rpx;
  598. overflow-x: hidden;
  599. z-index: 8;
  600. padding: 0 10rpx;
  601. swiper-item{
  602. border-radius: 10rpx;
  603. }
  604. .swiper-item, image, .acea-row.row-between-wrapper {
  605. width: 100%;
  606. margin: 0 auto;
  607. border-radius: 10rpx;
  608. }
  609. swiper{
  610. width: 100%;
  611. display: block;
  612. height: auto;
  613. &.scalex{
  614. /deep/.uni-swiper-slide-frame{
  615. transform: translate(0,0)!important;
  616. }
  617. }
  618. }
  619. image {
  620. transform: scale(0.93);
  621. transition: all 0.6s ease;
  622. }
  623. swiper-item.active, swiper-item.scalex{
  624. image {
  625. transform: scale(1);
  626. }
  627. }
  628. /*用来包裹所有的小圆点 */
  629. .dots {
  630. width: 156rpx;
  631. height: 36rpx;
  632. display: flex;
  633. flex-direction: row;
  634. position: absolute;
  635. left: 320rpx;
  636. bottom: 0;
  637. }
  638. /*未选中时的小圆点样式 */
  639. .dot {
  640. width: 16rpx;
  641. height: 6rpx;
  642. border-radius: 6rpx;
  643. margin-right: 6rpx;
  644. background-color: rgba(255,255,255,.4);
  645. /*选中以后的小圆点样式 */
  646. &.active {
  647. width: 32rpx;
  648. height: 6rpx;
  649. background-color: rgba(255,255,255,.4);
  650. }
  651. }
  652. }
  653. }
  654. /deep/.dot0 .uni-swiper-dots-horizontal{
  655. left: 10%;
  656. }
  657. /deep/.dot1 .uni-swiper-dots-horizontal{
  658. left: 50%;
  659. }
  660. /deep/.dot2 .uni-swiper-dots-horizontal{
  661. left: 90%;
  662. }
  663. </style>