| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692 |
- <template>
- <view class="page-design" :class="bgClass">
- <view v-if="!errorNetwork" :style="colorStyle">
- <!-- #ifdef MP -->
- <view
- class="fixed z-1000"
- :style="[appletStyle]"
- v-if="myApplet && isHome"
- >
- <view
- class="myApplet w-324 h-62 text-center rd-12rpx lh-62rpx fs-24 bg--w111-fff text-w111-303133"
- >
- 点击添加到我的小程序
- <text
- class="iconfont icon-ic_close2 text--w111-ccc ml-16"
- @click="myApplet = false"
- ></text>
- </view>
- </view>
- <!-- #endif -->
- <!-- 轮播搜索 -->
- <homeComb
- v-if="showHomeComb"
- :dataConfig="homeCombData"
- :belongIndex="belongIndex"
- @bindSortId="bindSortId"
- :isScrolled="isScrolled"
- @storeTap="storeTap"
- ></homeComb>
- <!-- 顶部搜索框 -->
- <headerSerch
- v-if="isHeaderSerch"
- :dataConfig="headerSerchCombData"
- :belongIndex="belongIndex"
- @storeTap="storeTap"
- ></headerSerch>
- <tabNav
- v-if="showCateNav"
- :dataConfig="cateNavData"
- @bindHeight="bindHeight"
- @bindSortId="bindSortId"
- :isFixed="isFixed && !cateNavData.stickyConfig.tabVal"
- ></tabNav>
- <view class="index">
- <!-- 自定义样式 -->
- <block v-for="(item, index) in styleConfig" :key="index">
- <view :id="item.id">
- <userInfor
- v-if="item.name == 'userInfor'"
- :dataConfig="item"
- @changeLogin="changeLogin"
- ></userInfor>
- <homeUserInfor
- v-else-if="item.name == 'member'"
- :dataConfig="item"
- @changeLogin="changeLogin"
- ></homeUserInfor>
- <newVip
- v-else-if="item.name == 'newVip'"
- :dataConfig="item"
- ></newVip>
- <!-- 文章列表 -->
- <articleList
- v-else-if="item.name == 'articleList'"
- :dataConfig="item"
- ></articleList>
- <bargain
- v-else-if="item.name == 'bargain'"
- :dataConfig="item"
- @changeBarg="changeBarg"
- ></bargain>
- <blankPage
- v-else-if="item.name == 'blankPage'"
- :dataConfig="item"
- ></blankPage>
- <combination
- v-else-if="item.name == 'combination'"
- :dataConfig="item"
- ></combination>
- <!-- 优惠券 -->
- <coupon
- v-else-if="item.name == 'coupon'"
- :dataConfig="item"
- @changeLogin="changeLogin"
- ></coupon>
- <!-- 客户服务 -->
- <customerService
- v-else-if="item.name == 'customerService'"
- :dataConfig="item"
- ></customerService>
- <!-- 商品列表 -->
- <goodList
- ref="goodLists"
- v-else-if="
- item.name == 'goodList' || item.name == 'goodRecommend'
- "
- :dataConfig="item"
- :list="goodList"
- ></goodList>
- <!-- <homeGoodRecommend
- v-else-if="
- item.name == 'goodList' || item.name == 'goodRecommend'
- "
- :dataConfig="item"
- ></homeGoodRecommend> -->
- <guide v-else-if="item.name == 'guide'" :dataConfig="item"></guide>
- <!-- 直播模块 -->
- <!-- #ifdef MP-WEIXIN -->
- <liveBroadcast
- v-else-if="item.name == 'liveBroadcast'"
- :dataConfig="item"
- ></liveBroadcast>
- <!-- #endif -->
- <menus v-else-if="item.name == 'menus'" :dataConfig="item"></menus>
- <!-- 实时消息 -->
- <news v-else-if="item.name == 'news'" :dataConfig="item"></news>
- <!-- 图片库 -->
- <pictureCube
- v-else-if="item.name == 'pictureCube'"
- :dataConfig="item"
- ></pictureCube>
- <!-- 促销列表 -->
- <promotionList
- ref="promotionLists"
- v-else-if="item.name == 'promotionList'"
- :dataConfig="item"
- :productVideoStatus="productVideoStatus"
- :positionTop="positionTop"
- ></promotionList>
- <seckill
- v-else-if="item.name == 'seckill'"
- :dataConfig="item"
- ></seckill>
- <!-- 轮播图-->
- <swiperBg
- v-else-if="item.name == 'swiperBg'"
- :dataConfig="item"
- ></swiperBg>
- <swipers
- v-else-if="item.name == 'swipers'"
- :dataConfig="item"
- ></swipers>
- <!-- 标题 -->
- <titles
- v-else-if="item.name == 'titles'"
- :dataConfig="item"
- ></titles>
- <presale
- v-else-if="item.name == 'presale'"
- :dataConfig="item"
- ></presale>
- <pointsMall
- v-else-if="item.name == 'pointsMall'"
- :dataConfig="item"
- ></pointsMall>
- <!-- #ifndef APP -->
- <richText
- v-else-if="item.name == 'richText'"
- :dataConfig="item"
- ></richText>
- <videos
- v-else-if="item.name == 'videos'"
- :dataConfig="item"
- ></videos>
- <!-- #endif -->
- <signIn
- v-else-if="item.name == 'signIn'"
- :dataConfig="item"
- ></signIn>
- <hotspot
- v-else-if="item.name == 'hotspot'"
- :dataConfig="item"
- ></hotspot>
- <follow
- v-else-if="item.name == 'follow'"
- :dataConfig="item"
- ></follow>
- <!-- 商品详情 -->
- <productInfo
- v-else-if="item.name == 'productInfo'"
- :dataConfig="item"
- :productData="productData"
- :priceData="priceData"
- :skuList="skuList"
- @changeSpec="onChangeSpec"
- @showSpecModal="onShowSpecModal"
- @share="onShare"
- @goActivity="onGoActivity"
- ></productInfo>
- <homePaidVip
- v-else-if="item.name == 'home_paid_vip'"
- :dataConfig="item"
- :productData="productData"
- :isShowPaidVip="isShowPaidVip"
- :priceData="priceData"
- ></homePaidVip>
- <homeProductService
- v-else-if="item.name == 'productService'"
- :dataConfig="item"
- :productData="productData"
- :couponList="couponList"
- :activity="activity"
- :attr="attr"
- :attrTxt="attrTxt"
- :attrValue="attrValue"
- @showCoupon="onShowCoupon"
- @showSpecModal="onShowSpecModal"
- @openModal="onOpenModal"
- @goActivity="onGoActivity"
- ></homeProductService>
- <homeReviews
- v-else-if="item.name == 'reviews'"
- :dataConfig="item"
- :reply="reply"
- :replyCount="replyCount"
- :replyChance="replyChance"
- :productId="productId"
- ></homeReviews>
- <productDesc
- v-else-if="item.name == 'productDesc'"
- :dataConfig="item"
- :productData="productData"
- ></productDesc>
- <customComponent
- v-else-if="item.name == 'customComponent'"
- :dataConfig="item"
- @changeLogin="changeLogin"
- ></customComponent>
- </view>
- </block>
- <!-- 插槽:用于展示分类商品列表或其他底部内容 -->
- <slot name="bottom"></slot>
- <view class="pb-safe" :style="[pdHeights]" v-if="isFooter"></view>
- <pageFooter
- v-if="footerConfigData"
- :configData="footerConfigData"
- @newDataStatus="newDataStatus"
- ></pageFooter>
- </view>
- </view>
- <view v-else>
- <view class="error-network">
- <image :src="imgHost + '/statics/images/error-network.gif'"></image>
- <view class="title">{{ $t(`网络连接断开`) }}</view>
- <view class="btn" @click="reconnect">{{ $t(`重新连接`) }}</view>
- </view>
- </view>
- </view>
- </template>
- <script>
- import pageFooter from "@/components/pageFooter/index.vue";
- import { HTTP_REQUEST_URL } from "@/config/app";
- import colors from "@/mixins/color";
- // diyComponents - 同目录使用相对路径
- import homeComb from "./homeComb.vue";
- import headerSerch from "./headerSerch.vue";
- import tabNav from "./tabNav.vue";
- import userInfor from "./userInfor.vue";
- import homeUserInfor from "./homeUserInfor.vue";
- import newVip from "./newVip.vue";
- import articleList from "./articleList.vue";
- import bargain from "./bargain.vue";
- import blankPage from "./blankPage.vue";
- import combination from "./combination.vue";
- import coupon from "./coupon.vue";
- import customerService from "./customerService.vue";
- import goodList from "./goodList.vue";
- import guide from "./guide.vue";
- import liveBroadcast from "./liveBroadcast.vue";
- import menus from "./menus.vue";
- import news from "./news.vue";
- import pictureCube from "./pictureCube.vue";
- import promotionList from "./promotionList.vue";
- import seckill from "./seckill.vue";
- import swiperBg from "./swiperBg.vue";
- import swipers from "./swipers.vue";
- import titles from "./titles.vue";
- import presale from "./presale.vue";
- import pointsMall from "./pointsMall.vue";
- import richText from "./richText.vue";
- import videos from "./videos.vue";
- import signIn from "./signIn.vue";
- import hotspot from "./hotspot.vue";
- import follow from "./follow.vue";
- import productInfo from "./productInfo.vue";
- import homePaidVip from "./homePaidVip.vue";
- import homeProductService from "./homeProductService.vue";
- import homeReviews from "./homeReviews.vue";
- import productDesc from "./productDesc.vue";
- import customComponent from "./customComponent.vue";
- export default {
- name: "PageDesign",
- components: {
- pageFooter,
- homeComb,
- headerSerch,
- tabNav,
- userInfor,
- homeUserInfor,
- newVip,
- articleList,
- bargain,
- blankPage,
- combination,
- coupon,
- customerService,
- goodList,
- guide,
- liveBroadcast,
- menus,
- news,
- pictureCube,
- promotionList,
- seckill,
- swiperBg,
- swipers,
- titles,
- presale,
- pointsMall,
- richText,
- videos,
- signIn,
- hotspot,
- follow,
- productInfo,
- homePaidVip,
- homeProductService,
- homeReviews,
- productDesc,
- customComponent,
- },
- mixins: [colors],
- props: {
- // DIY配置数据
- diyData: {
- type: Object,
- default: () => ({}),
- },
- // 是否为首页(用于控制小程序添加到我的小程序提示等)
- isHome: {
- type: Boolean,
- default: false,
- },
- // 页面滚动状态
- isScrolled: {
- type: Boolean,
- default: false,
- },
- // 是否固定(用于吸顶)
- isFixed: {
- type: Boolean,
- default: false,
- },
- productData: {
- type: Object,
- default: () => ({}),
- },
- priceData: {
- type: Object,
- default: () => ({}),
- },
- skuList: {
- type: Array,
- default: () => [],
- },
- reply: {
- type: Array,
- default: () => [],
- },
- replyCount: {
- type: Number,
- default: 0,
- },
- replyChance: {
- type: String | Number,
- default: 0,
- },
- productId: {
- type: Number | String,
- default: 0,
- },
- goodList: {
- type: Array,
- default: () => [],
- },
- // 视频播放状态
- productVideoStatus: {
- type: Boolean,
- default: false,
- },
- // 进店规则归属门店排序位置
- belongIndex: {
- type: Number,
- default: 0,
- },
- // 网络错误状态
- errorNetwork: {
- type: Boolean,
- default: false,
- },
- couponList: {
- type: Array,
- default: () => [],
- },
- activity: {
- type: Array,
- default: () => [],
- },
- attr: {
- type: Object,
- default: () => ({}),
- },
- attrTxt: {
- type: String,
- default: "",
- },
- attrValue: {
- type: String,
- default: "",
- },
- // 微页面
- microPage: {
- type: Boolean,
- default: false,
- },
- // 商品 vip 模块
- isShowPaidVip: {
- type: Boolean,
- default: false,
- },
- },
- data() {
- return {
- styleConfig: [],
- homeCombData: {},
- headerSerchCombData: {},
- cateNavData: {},
- footerConfigData: null,
- showHomeComb: false,
- isHeaderSerch: false,
- showCateNav: false,
- bgColor: "",
- bgPic: "",
- bgTabVal: "",
- positionTop: 0,
- isFooter: false,
- pdHeight: 0,
- myApplet: true,
- getHeight: this.$util.getWXStatusHeight(),
- imgHost: HTTP_REQUEST_URL,
- };
- },
- computed: {
- // #ifdef MP
- appletStyle() {
- return {
- top: this.getHeight.menuButtonInfo.bottom + 8 + "px",
- right: "10px",
- };
- },
- // #endif
- pageStyle() {
- return {
- backgroundColor: this.bgColor,
- backgroundImage: this.bgPic ? `url(${this.bgPic})` : "",
- minHeight: "100vh", // 确保背景铺满
- };
- },
- bgClass() {
- if (this.bgTabVal == 2) return "fullsize noRepeat";
- if (this.bgTabVal == 1) return "repeat ysize";
- return "noRepeat ysize";
- },
- pdHeights() {
- let H = `${this.pdHeight * 2 + 100}rpx`;
- return {
- height: this.isFooter ? H : "100rpx",
- };
- },
- },
- watch: {
- diyData: {
- handler(val) {
- if (val && Object.keys(val).length > 0) {
- this.setDiyData(val);
- } else {
- // 重置数据
- this.styleConfig = [];
- this.homeCombData = {};
- this.headerSerchCombData = {};
- this.cateNavData = {};
- this.footerConfigData = null;
- this.showHomeComb = false;
- this.isHeaderSerch = false;
- this.showCateNav = false;
- this.bgColor = "";
- this.bgPic = "";
- this.bgTabVal = "";
- }
- },
- deep: true,
- immediate: true,
- },
- },
- methods: {
- reconnect() {
- this.$emit("reconnect");
- },
- onChangeSpec(item) {
- this.$emit("changeSpec", item);
- },
- onShowSpecModal() {
- this.$emit("showSpecModal");
- },
- onShowCoupon() {
- this.$emit("showCoupon");
- },
- onOpenModal(type) {
- this.$emit("openModal", type);
- },
- onGoActivity(item) {
- this.$emit("goActivity", item);
- },
- onShare() {
- this.$emit("share");
- },
- // 对象转数组
- objToArr(data) {
- if (!data) return [];
- let obj = Object.keys(data).sort();
- let m = obj.map((key) => data[key]);
- return m;
- },
- setDiyData(data) {
- if (!data) return;
- if (data.is_bg_color) {
- this.bgColor = data.color_picker;
- }
- if (data.is_bg_pic) {
- this.bgPic = data.bg_pic;
- this.bgTabVal = data.bg_tab_val;
- }
- let temp = [];
- // 重置状态
- this.showHomeComb = false;
- this.isHeaderSerch = false;
- this.showCateNav = false;
- this.footerConfigData = null;
- if (data.value) {
- let lastArr = this.objToArr(data.value);
- lastArr.forEach((item) => {
- if (item.name == "pageFoot" && !this.microPage) {
- this.footerConfigData = item;
- }
- if (item.name === "homeComb" && !item.isHide) {
- this.showHomeComb = true;
- this.homeCombData = item;
- if (item.searchConfig && item.searchConfig.tabVal) {
- this.positionTop = uni.getWindowInfo().statusBarHeight + 43;
- }
- }
- if (item.name == "headerSerch" && !item.isHide) {
- this.isHeaderSerch = true;
- this.headerSerchCombData = item;
- }
- if (item.name == "tabNav" && !item.isHide) {
- this.showCateNav = true;
- this.cateNavData = item;
- }
- if (!item.isHide) {
- temp.push(item);
- }
- });
- // 排序
- temp.sort((a, b) => a.timestamp - b.timestamp);
- this.styleConfig = temp;
- }
- },
- bindSortId(data) {
- this.$emit("bindSortId", data);
- },
- bindHeight(data) {
- this.$emit("bindHeight", data);
- },
- storeTap(id) {
- this.$emit("storeTap", id);
- },
- changeLogin() {
- this.$emit("changeLogin");
- },
- changeBarg(item) {
- this.$emit("changeBarg", item);
- },
- newDataStatus(val, num) {
- this.isFooter = val ? true : false;
- this.pdHeight = num;
- this.$emit("newDataStatus", { val, num });
- },
- reconnect() {
- this.$emit("reconnect");
- },
- },
- };
- </script>
- <style lang="scss" scoped>
- .page-design {
- overflow-y: scroll;
- overflow-x: hidden;
- min-height: 100vh;
- }
- .myApplet {
- position: relative;
- &::after {
- position: absolute;
- right: 55px;
- top: -5px;
- content: "";
- width: 0;
- height: 0;
- border-left: 7px solid transparent;
- border-right: 7px solid transparent;
- border-bottom: 7px solid #fff;
- }
- }
- .ysize {
- background-size: 100%;
- }
- .fullsize {
- background-size: 100% 100%;
- }
- .repeat {
- background-repeat: repeat;
- }
- .noRepeat {
- background-repeat: no-repeat;
- }
- .error-network {
- position: fixed;
- left: 0;
- top: 0;
- display: flex;
- flex-direction: column;
- align-items: center;
- width: 100%;
- height: 100%;
- padding-top: 40rpx;
- background: #fff;
- image {
- width: 414rpx;
- height: 336rpx;
- }
- .title {
- position: relative;
- top: -40rpx;
- font-size: 32rpx;
- color: #666;
- }
- .btn {
- display: flex;
- align-items: center;
- justify-content: center;
- width: 508rpx;
- height: 86rpx;
- margin-top: 100rpx;
- border: 1px solid #d74432;
- color: #e93323;
- font-size: 30rpx;
- border-radius: 120rpx;
- }
- }
- </style>
|