promotionList.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788
  1. <template>
  2. <!-- 促销列表 -->
  3. <view v-show="!isSortType">
  4. <common-wrapper :config="configData">
  5. <view class="index-product-wrapper">
  6. <view :style="{ height: navBdH + 'px' }" class="nav-bd-box">
  7. <view
  8. class="nav-bd"
  9. :class="{
  10. 'nav-bd2': dataConfig.styleConfig.tabVal == 1,
  11. 'nav-bd3': dataConfig.styleConfig.tabVal == 2,
  12. 'nav-bd4': dataConfig.styleConfig.tabVal == 3,
  13. 'nav-bd5': dataConfig.styleConfig.tabVal == 4,
  14. }"
  15. :style="{
  16. position: sticky ? 'fixed' : 'static',
  17. top: positionTop + 'px',
  18. background: sticky ? '#FFFFFF' : 'none',
  19. }"
  20. >
  21. <scroll-view class="scroll-view" scroll-x="true">
  22. <view
  23. class="item"
  24. v-for="(item, index) in explosiveMoney"
  25. :key="index"
  26. :class="{ on: index == ProductNavindex }"
  27. @click="ProductNavTab(item, index)"
  28. >
  29. <view
  30. v-if="dataConfig.styleConfig.tabVal == 4"
  31. class="image-wrap"
  32. >
  33. <image :src="item.image" class="image"></image>
  34. </view>
  35. <view
  36. class="txt"
  37. :style="[index == ProductNavindex ? textColor : {}]"
  38. >{{ item.chiild[0].val }}</view
  39. >
  40. <view
  41. v-if="[1, 2].includes(dataConfig.styleConfig.tabVal)"
  42. class="line"
  43. :style="[index == ProductNavindex ? lineColor : {}]"
  44. ></view>
  45. <view
  46. class="label"
  47. v-if="
  48. dataConfig.styleConfig.tabVal == 0 && item.chiild[1].val
  49. "
  50. :style="[index == ProductNavindex ? decorateColor : {}]"
  51. >
  52. {{ item.chiild[1].val }}
  53. </view>
  54. </view>
  55. </scroll-view>
  56. </view>
  57. </view>
  58. <goodList
  59. ref="goodLists"
  60. v-if="goodDataConfig"
  61. :dataConfig="goodDataConfig"
  62. @detail="goDetail"
  63. ></goodList>
  64. </view>
  65. </common-wrapper>
  66. </view>
  67. </template>
  68. <script>
  69. import commonWrapper from "./commonWrapper.vue";
  70. // import {
  71. // getProductslist
  72. // } from '@/api/store.js';
  73. import goodList from "./goodList.vue";
  74. export default {
  75. name: "promotionList",
  76. props: {
  77. dataConfig: {
  78. type: Object,
  79. default: () => {},
  80. },
  81. isSortType: {
  82. type: String | Number,
  83. default: 0,
  84. },
  85. productVideoStatus: {
  86. type: Boolean,
  87. default: false,
  88. },
  89. positionTop: {
  90. type: Number,
  91. default: 0,
  92. },
  93. },
  94. components: {
  95. goodList,
  96. commonWrapper
  97. },
  98. data() {
  99. return {
  100. tempArr: [],
  101. iSshowH: false,
  102. ProductNavindex: 0,
  103. explosiveMoney: this.dataConfig.tabConfig.list,
  104. numConfig: this.dataConfig.tabConfig.list[0].numConfig.val,
  105. // imgStyle: this.dataConfig.imgStyle.type,
  106. mbConfig: 0,
  107. themeColor: "",
  108. titleShow: 0, //标题是否显示
  109. opriceShow: 0, //划线价是否显示
  110. priceShow: 0, //价格是否显示
  111. couponShow: 0, //优惠券标签是否显示
  112. titleConfig: 0, //标题位置
  113. fontColor: "",
  114. labelColor: "",
  115. txtColor: "",
  116. infoColor: "",
  117. goodType: this.dataConfig.tabConfig.list[0].tabVal,
  118. loadend: false,
  119. loading: false,
  120. limit: this.$config.LIMIT,
  121. page: 1,
  122. canPlay: false,
  123. autoplay: false,
  124. activeValue: this.dataConfig.tabConfig.list[0],
  125. goodDataConfig: null,
  126. sticky: false,
  127. navBdH: 0,
  128. };
  129. },
  130. computed: {
  131. configData() {
  132. return {
  133. ...this.dataConfig,
  134. paddingConfig: this.dataConfig.paddingConfig || {
  135. isAll: false,
  136. valList: [
  137. {
  138. val: this.dataConfig.topConfig
  139. ? this.dataConfig.topConfig.val
  140. : 0,
  141. },
  142. {
  143. val: this.dataConfig.prConfig ? this.dataConfig.prConfig.val : 0,
  144. },
  145. {
  146. val: this.dataConfig.bottomConfig
  147. ? this.dataConfig.bottomConfig.val
  148. : 0,
  149. },
  150. {
  151. val: this.dataConfig.prConfig ? this.dataConfig.prConfig.val : 0,
  152. },
  153. ],
  154. },
  155. marginConfig: this.dataConfig.marginConfig || {
  156. isAll: false,
  157. valList: [
  158. {
  159. val: this.dataConfig.mbConfig ? this.dataConfig.mbConfig.val : 0,
  160. },
  161. {
  162. val: 0,
  163. },
  164. {
  165. val: 0,
  166. },
  167. {
  168. val: 0,
  169. },
  170. ],
  171. },
  172. };
  173. },
  174. decorateColor() {
  175. if (this.dataConfig.toneConfig.tabVal) {
  176. let color = this.dataConfig.decorateColor.color;
  177. let background = `linear-gradient(90deg, ${color[0].item} 0%, ${color[1].item} 100%)`;
  178. if (this.dataConfig.styleConfig.tabVal == 2) {
  179. color = this.dataConfig.decorateColor2.color;
  180. background = color[0].item;
  181. }
  182. return {
  183. background: background,
  184. };
  185. } else {
  186. return {
  187. background: `linear-gradient(90deg, var(--view-gradient) 0%, var(--view-theme) 100%)`,
  188. };
  189. }
  190. },
  191. textColor() {
  192. if (this.dataConfig.toneConfig.tabVal) {
  193. let color = this.dataConfig.textColor.color[0].item;
  194. let bgColor = this.dataConfig.decorateColor.color;
  195. let background = "";
  196. if ([0, 1, 2].includes(this.dataConfig.styleConfig.tabVal)) {
  197. color = this.dataConfig.textColor.color[0].item;
  198. } else if ([3, 4].includes(this.dataConfig.styleConfig.tabVal)) {
  199. color = "#ffffff";
  200. background = `linear-gradient(90deg, ${bgColor[0].item} 0%, ${bgColor[1].item} 100%)`;
  201. } else if (this.dataConfig.styleConfig.tabVal == 1) {
  202. color = "#282828";
  203. }
  204. return {
  205. color: color,
  206. background: background,
  207. };
  208. } else {
  209. if (this.dataConfig.styleConfig.tabVal == 1) {
  210. return {
  211. color: "#282828",
  212. };
  213. } else if ([3, 4].includes(this.dataConfig.styleConfig.tabVal)) {
  214. return {
  215. background:
  216. "linear-gradient(90deg, var(--view-gradient) 0, var(--view-theme) 100%)",
  217. color: "#ffffff",
  218. };
  219. } else {
  220. return {
  221. color: "var(--view-theme)",
  222. };
  223. }
  224. }
  225. },
  226. // bottomBgColor() {
  227. // return {
  228. // padding: `${this.dataConfig.topConfig.val * 2}rpx ${this.dataConfig.prConfig.val * 2}rpx ${this.dataConfig.bottomConfig.val * 2}rpx`,
  229. // 'margin-top': `${this.dataConfig.mbConfig.val * 2}rpx`,
  230. // background: this.dataConfig.bottomBgColor.color[0].item
  231. // };
  232. // },
  233. lineColor() {
  234. let diy = this.dataConfig.toneConfig.tabVal;
  235. let type = this.dataConfig.styleConfig.tabVal;
  236. let color = this.dataConfig.decorateColor.color;
  237. let bgColor = `linear-gradient(90deg, ${color[0].item} 0%, ${color[1].item} 100%)`;
  238. if (type == 1) {
  239. return {
  240. background: diy
  241. ? bgColor
  242. : "linear-gradient(90deg, var(--view-gradient) 0, var(--view-theme) 100%)",
  243. };
  244. } else if (type == 2) {
  245. return {
  246. "border-bottom-color": diy
  247. ? this.dataConfig.textColor2.color[0].item
  248. : "var(--view-theme)",
  249. };
  250. }
  251. },
  252. },
  253. watch: {
  254. activeValue: {
  255. handler(value) {
  256. let that = this;
  257. let type = that.goodType == 0 ? 3 : that.goodType;
  258. let goodDataConfig = {
  259. styleConfig: {
  260. tabVal: 1,
  261. },
  262. goodsList: this.activeValue.goodsList,
  263. brandList: this.activeValue.brandConfig,
  264. classList: {
  265. classVal: this.activeValue.selectConfig.activeValue,
  266. },
  267. goodsLabel: this.activeValue.goodsLabel,
  268. typeConfig: {
  269. activeValue: type,
  270. },
  271. goodsSort: {
  272. tabVal: this.activeValue.goodsSort,
  273. },
  274. numberConfig: {
  275. val: that.numConfig,
  276. },
  277. bntStyleConfig: this.dataConfig.bntStyleConfig,
  278. cartConfig: this.dataConfig.cartConfig,
  279. bntConfig: this.dataConfig.bntConfig,
  280. filletImg: {
  281. type: 0,
  282. val: 8,
  283. },
  284. checkboxInfo: {
  285. type: [0, 1, 2, 3, 4, 5],
  286. },
  287. toneConfig: {
  288. tabVal: 0,
  289. },
  290. toneCartConfig: this.dataConfig.toneCartConfig,
  291. bntBgColor: this.dataConfig.bntBgColor,
  292. goodsName: {
  293. tabVal: 1,
  294. },
  295. goodsNameColor: {
  296. color: [
  297. {
  298. item: "#333333",
  299. },
  300. ],
  301. },
  302. goodsPriceColor: {
  303. color: [
  304. {
  305. item: this.dataConfig.toneCartConfig.tabVal
  306. ? this.dataConfig.goodsPriceColor.color[0].item
  307. : "var(--view-theme)",
  308. },
  309. ],
  310. },
  311. topConfig: {
  312. val: 0,
  313. },
  314. prConfig: {
  315. val: 0,
  316. },
  317. bottomConfig: {
  318. val: 0,
  319. },
  320. mbConfig: {
  321. val: 0,
  322. },
  323. bottomBgColor: {
  324. color: [
  325. {
  326. item: "",
  327. },
  328. ],
  329. },
  330. fillet: this.dataConfig.fillet,
  331. name: "promotionList",
  332. };
  333. that.goodDataConfig = goodDataConfig;
  334. },
  335. immediate: true,
  336. },
  337. goodType: {
  338. handler(value) {
  339. //value !== undefined && this.getGroomList();
  340. },
  341. immediate: true,
  342. },
  343. tempArr() {
  344. // #ifndef APP-PLUS
  345. this.$nextTick(() => {
  346. if (this.productVideoStatus) {
  347. uni.getNetworkType({
  348. success: (res) => {
  349. if (["wifi", "unknown"].includes(res.networkType)) {
  350. // 监听
  351. this.observeVideo();
  352. }
  353. if (["2g", "3g", "4g", "5g"].includes(res.networkType)) {
  354. if (this.$store.state.app.autoplay) {
  355. // 监听
  356. this.observeVideo();
  357. } else {
  358. this.$eventHub.$emit("confirm_video_status");
  359. }
  360. }
  361. },
  362. });
  363. }
  364. });
  365. // #endif
  366. },
  367. },
  368. created() {
  369. // #ifndef APP-PLUS
  370. this.$eventHub.$on("product_video_observe", () => {
  371. this.observeVideo();
  372. });
  373. // #endif
  374. // this.getGroomList();
  375. let that = this;
  376. let type = that.goodType == 0 ? 3 : that.goodType;
  377. let goodDataConfig = {
  378. styleConfig: {
  379. tabVal: 1,
  380. },
  381. goodsList: this.activeValue.goodsList,
  382. brandList: this.activeValue.brandConfig,
  383. classList: {
  384. classVal: this.activeValue.selectConfig.activeValue,
  385. },
  386. goodsLabel: this.activeValue.goodsLabel,
  387. typeConfig: {
  388. activeValue: type,
  389. },
  390. goodsSort: {
  391. tabVal: this.activeValue.goodsSort,
  392. },
  393. numberConfig: {
  394. val: that.numConfig,
  395. },
  396. bntStyleConfig: this.dataConfig.bntStyleConfig,
  397. cartConfig: this.dataConfig.cartConfig,
  398. bntConfig: this.dataConfig.bntConfig,
  399. filletImg: {
  400. type: 0,
  401. val: 8,
  402. },
  403. checkboxInfo: {
  404. type: [0, 1, 2, 3, 4, 5],
  405. },
  406. toneConfig: {
  407. tabVal: 0,
  408. },
  409. toneCartConfig: this.dataConfig.toneCartConfig,
  410. bntBgColor: this.dataConfig.bntBgColor,
  411. goodsName: {
  412. tabVal: 1,
  413. },
  414. goodsNameColor: {
  415. color: [
  416. {
  417. item: "#333333",
  418. },
  419. ],
  420. },
  421. goodsPriceColor: {
  422. color: [
  423. {
  424. item: this.dataConfig.toneCartConfig.tabVal
  425. ? this.dataConfig.goodsPriceColor.color[0].item
  426. : "var(--view-theme)",
  427. },
  428. ],
  429. },
  430. topConfig: {
  431. val: 0,
  432. },
  433. prConfig: {
  434. val: 0,
  435. },
  436. bottomConfig: {
  437. val: 0,
  438. },
  439. mbConfig: {
  440. val: 0,
  441. },
  442. bottomBgColor: {
  443. color: [
  444. {
  445. item: "",
  446. },
  447. ],
  448. },
  449. fillet: this.dataConfig.fillet,
  450. name: "promotionList",
  451. };
  452. that.goodDataConfig = goodDataConfig;
  453. },
  454. mounted() {
  455. let view = uni.createSelectorQuery().in(this).select(".nav-bd");
  456. let views = uni.createSelectorQuery().in(this).select(".nav-bd-box");
  457. view
  458. .boundingClientRect((data) => {
  459. this.navBdH = data.height;
  460. })
  461. .exec();
  462. if (!this.dataConfig.slideConfig.tabVal) {
  463. uni.$on("onPageScroll", () => {
  464. views
  465. .boundingClientRect((data) => {
  466. this.sticky = data.top <= this.positionTop;
  467. })
  468. .exec();
  469. });
  470. }
  471. },
  472. methods: {
  473. observeVideo() {
  474. this.autoplay = true;
  475. // let observer = uni.createIntersectionObserver(this, { observeAll: true });
  476. // observer.relativeToViewport().observe('.video', res => {
  477. // if (res.intersectionRatio) {
  478. // uni.createVideoContext(res.id, this).play();
  479. // } else{
  480. // uni.createVideoContext(res.id, this).pause();
  481. // }
  482. // });
  483. },
  484. // 促销列表的点击事件;
  485. changeTab(item) {
  486. this.goodType = item.tabVal;
  487. this.activeValue = item;
  488. // this.tempArr = [];
  489. // this.page = 1;
  490. // this.loadend = false;
  491. // let onloadH = true;
  492. // this.getGroomList(onloadH);
  493. },
  494. // 精品推荐
  495. getGroomList(onloadH) {
  496. let that = this;
  497. let type = that.goodType == 0 ? 3 : that.goodType;
  498. if (that.loadend) return false;
  499. if (that.loading) return false;
  500. if (onloadH) {
  501. that.$set(that, "iSshowH", true);
  502. }
  503. let datas = {
  504. page: that.page,
  505. limit: this.numConfig,
  506. };
  507. if (type == 1) {
  508. datas.ids = that.activeValue.goodsList.ids.join();
  509. } else if (type == 2) {
  510. datas.brand_id = that.activeValue.brandConfig.brandVal.join();
  511. } else if (type == 3) {
  512. datas.cate_id = that.activeValue.selectConfig.activeValue.join();
  513. } else if (type == 4) {
  514. datas.store_label_id = that.activeValue.goodsLabel.activeValue.join();
  515. }
  516. getProductslist(datas)
  517. .then(({ data }) => {
  518. that.$set(that, "iSshowH", false);
  519. let maxPage = Math.ceil(this.numConfig / this.limit);
  520. let list = data,
  521. loadend = list.length < that.limit || that.page >= maxPage;
  522. let tempArr = that.$util.SplitArray(list, that.tempArr);
  523. that.$set(that, "tempArr", tempArr.slice(0, this.numConfig));
  524. that.loadend = loadend;
  525. that.loadTitle = loadend ? "没有更多内容啦~" : "加载更多";
  526. that.page = that.page + 1;
  527. that.loading = false;
  528. })
  529. .catch((res) => {
  530. that.loading = false;
  531. that.loadTitle = "加载更多";
  532. });
  533. },
  534. // 首发新品切换
  535. ProductNavTab(item, index) {
  536. this.ProductNavindex = index;
  537. this.changeTab(item);
  538. },
  539. goDetail(item) {
  540. this.$emit("detail", item);
  541. },
  542. },
  543. };
  544. </script>
  545. <style lang="scss">
  546. // 这里可以自行配置
  547. $border-radius: 10px;
  548. .index-product-wrapper {
  549. &.on {
  550. min-height: 1500rpx;
  551. }
  552. .nav-bd {
  553. position: relative;
  554. top: 0;
  555. right: 0;
  556. left: 0;
  557. z-index: 99;
  558. &.nav-bd2 {
  559. .item {
  560. position: relative;
  561. padding: 18rpx 0;
  562. margin-right: 56rpx;
  563. &:first-child {
  564. // margin-left: 24rpx;
  565. }
  566. &:last-child {
  567. margin-right: 24rpx;
  568. }
  569. &.on {
  570. .txt {
  571. font-weight: 500;
  572. font-size: 32rpx;
  573. color: #333333;
  574. }
  575. // .line {
  576. // background: linear-gradient(90deg, var(--view-gradient) 0, var(--view-theme) 100%);
  577. // }
  578. }
  579. .txt {
  580. position: relative;
  581. z-index: 1;
  582. font-size: 28rpx;
  583. line-height: 44rpx;
  584. }
  585. .line {
  586. position: absolute;
  587. bottom: 22rpx;
  588. left: 0;
  589. width: 100%;
  590. height: 8rpx;
  591. border-radius: 4rpx;
  592. }
  593. }
  594. }
  595. &.nav-bd3 {
  596. .item {
  597. position: relative;
  598. padding: 18rpx 0;
  599. margin-right: 56rpx;
  600. &:first-child {
  601. // margin-left: 24rpx;
  602. }
  603. &:last-child {
  604. margin-right: 24rpx;
  605. }
  606. &.on {
  607. .txt {
  608. font-weight: 500;
  609. font-size: 32rpx;
  610. color: #e93323;
  611. }
  612. // .line {
  613. // border-bottom-color: var(--view-theme);
  614. // }
  615. }
  616. .txt {
  617. font-size: 28rpx;
  618. line-height: 44rpx;
  619. }
  620. .line {
  621. position: absolute;
  622. bottom: 8rpx;
  623. left: 50%;
  624. width: 64rpx;
  625. height: 64rpx;
  626. border: 4rpx solid transparent;
  627. border-radius: 50%;
  628. transform: translateX(-50%);
  629. }
  630. }
  631. }
  632. &.nav-bd4 {
  633. .item {
  634. padding: 16rpx 0;
  635. margin-right: 16rpx;
  636. &:first-child {
  637. // margin-left: 20rpx;
  638. }
  639. &:last-child {
  640. margin-right: 20rpx;
  641. }
  642. &.on {
  643. .txt {
  644. background: linear-gradient(90deg, #ff7931 0%, #e93323 100%);
  645. font-size: 26rpx;
  646. color: #ffffff;
  647. }
  648. }
  649. .txt {
  650. height: 48rpx;
  651. padding: 0 20rpx;
  652. border-radius: 24rpx;
  653. font-size: 28rpx;
  654. line-height: 48rpx;
  655. }
  656. }
  657. }
  658. &.nav-bd5 {
  659. padding-left: 20rpx;
  660. .item {
  661. padding: 20rpx 0;
  662. margin-right: 16rpx;
  663. &:first-child {
  664. // margin-left: 24rpx;
  665. }
  666. &:last-child {
  667. margin-right: 24rpx;
  668. }
  669. &.on {
  670. .image-wrap {
  671. border-color: var(--view-theme);
  672. background: #ffffff;
  673. }
  674. .txt {
  675. // background: linear-gradient(90deg, #FF7931 0%, #E93323 100%);
  676. color: #ffffff;
  677. }
  678. }
  679. .image-wrap {
  680. display: flex;
  681. justify-content: center;
  682. align-items: center;
  683. width: 104rpx;
  684. height: 104rpx;
  685. border: 3rpx solid transparent;
  686. border-radius: 50%;
  687. margin: 0 auto;
  688. }
  689. .image {
  690. width: 92rpx;
  691. height: 92rpx;
  692. border: 1rpx solid #eeeeee;
  693. border-radius: 50%;
  694. }
  695. .txt {
  696. height: 40rpx;
  697. padding: 0 12rpx;
  698. border-radius: 20rpx;
  699. margin-top: 8rpx;
  700. font-size: 24rpx;
  701. line-height: 40rpx;
  702. color: #333333;
  703. }
  704. }
  705. }
  706. .scroll-view {
  707. white-space: nowrap;
  708. }
  709. .item {
  710. display: inline-block;
  711. padding: 20rpx 0 14rpx;
  712. margin-right: 66rpx;
  713. text-align: center;
  714. &:first-child {
  715. // margin-left: 36rpx;
  716. }
  717. &:last-child {
  718. margin-right: 36rpx;
  719. }
  720. &.on {
  721. .txt {
  722. font-weight: 500;
  723. color: #e93323;
  724. }
  725. .label {
  726. background: linear-gradient(90deg, #ff7931 0%, #e93323 100%);
  727. font-size: 22rpx;
  728. color: #ffffff;
  729. }
  730. }
  731. .txt {
  732. font-size: 30rpx;
  733. line-height: 42rpx;
  734. color: #282828;
  735. }
  736. .label {
  737. display: inline-block;
  738. height: 38rpx;
  739. padding: 0 12rpx;
  740. border-radius: 19rpx;
  741. margin-top: 6rpx;
  742. font-size: 24rpx;
  743. line-height: 38rpx;
  744. color: #999999;
  745. }
  746. }
  747. }
  748. }
  749. </style>