<!-- * @Author: your name * @Date: 2020-10-26 11:16:20 * @LastEditTime: 2020-11-05 13:43:24 * @LastEditors: Please set LastEditors * @Description: In User Settings Edit * @FilePath: \ant-unified-store_decoration\components\basic\cube-nav\index.vue --> <template> <div class="cube-nav" :style="{ 'padding-top': datas.componentData.verticalMargin + 'px', 'padding-bottom': datas.componentData.verticalMargin + 'px', 'padding-left': datas.componentData.levelMargin + 'px', 'padding-right': datas.componentData.levelMargin + 'px' }" > <div class="cube1 clearfix" v-if="datas.componentData['layoutType'] == 0" :style="{ backgroundColor: getBackgroundColor, borderRadius: moduleRadius + 'px' }" > <div class="cube-item" v-for="(item, index) in imgList" :key="index" @click="onclickHandle(item)" :style="{ paddingTop: datas.componentData.lineHeight + 'px', paddingBottom: datas.componentData.lineHeight + 'px', width: getColumnWidth }" style="position:relative" > <div :style="{ paddingLeft: getImgSize + '%', paddingRight: getImgSize + '%' }" > <div class="item-img" :class="item.imageUrl == '' ? 'item-bg' : ''"> <img v-show="item.imageUrl" :src="item.imageUrl | DFSImg(400,400)" alt="" /> </div> </div> <div class="item-title" :style="{ fontSize: textSize + 'px', color: getFontsizeColor, height: textSize / 12 + 'em', lineHeight: textSize / 12 + 'em' }" > {{ item.title }} </div> </div> </div> <div :style="{ backgroundColor: getBackgroundColor, borderRadius: moduleRadius + 'px', paddingBottom: navShow ? '10px' : '0px' }" style="position:relative" v-if="datas.componentData['layoutType'] == 1" > <div class="cube2 clearfix" ref="cube2" @scroll="touchstart" style="overflow-x:auto;overflow-y:hidden" > <div class="clearfix" :style="{ width: wrapW + 'px' }"> <div class="cube-item" v-for="(item, index) in imgList" @click="onclickHandle(item)" :key="index" :style="{ paddingTop: datas.componentData.lineHeight + 'px', paddingBottom: datas.componentData.lineHeight + 'px', width: w + 'px' }" style="position:relative" > <div :style="{ paddingLeft: getImgSize + '%', paddingRight: getImgSize + '%' }" > <div class="item-img" :class="item.imageUrl == '' ? 'item-bg' : ''" > <img v-show="item.imageUrl" :src="item.imageUrl | DFSImg(400,400)" alt="" /> </div> </div> <div class="item-title" :style="{ fontSize: textSize + 'px', color: getFontsizeColor, height: textSize / 12 + 'em', lineHeight: textSize / 12 + 'em' }" > {{ item.title }} </div> </div> </div> </div> <div class="nav-wrap" v-if="navShow && datas.componentData['layoutType'] == 1" > <div class="nav"> <div class="inner-nav" :style="{ left: navLeft + 'px', }" ></div> </div> </div> </div> <div class="cube3 clearfix" v-if="datas.componentData['layoutType'] == 2" :style="{ backgroundColor: getBackgroundColor, borderRadius: moduleRadius + 'px' }" > <van-swipe class="my-swipe" ref="my-swipe" > <van-swipe-item v-for="(item1, index1) in swiperList" :style="{ width: swiperItemW + 'px' }" :key="index1" > <div class="cube-item" v-for="(item, index) in item1" :key="index" @click="onclickHandle(item)" :style="{ paddingTop: datas.componentData.lineHeight + 'px', paddingBottom: datas.componentData.lineHeight + 'px', width: getColumnWidth }" style="position:relative" > <div :style="{ paddingLeft: getImgSize + '%', paddingRight: getImgSize + '%' }" > <div class="item-img" :class="item.imageUrl == '' ? 'item-bg' : ''" > <img v-show="item.imageUrl" :src="item.imageUrl | DFSImg(400,400)" alt="" /> </div> </div> <div class="item-title" :style="{ fontSize: textSize + 'px', color: getFontsizeColor, height: textSize / 12 + 'em', lineHeight: textSize / 12 + 'em' }" > {{ item.title }} </div> </div> </van-swipe-item> </van-swipe> </div> </div> </template> <script> const debounce = (func, wait) => { let timeout = ""; return v => { if (timeout) { clearTimeout(timeout); } timeout = setTimeout(() => { func(v); }, wait); }; }; export default { name: "cube-nav", props: { datas: { type: Object, default: {} }, render: { type: Boolean, default: false } }, data() { return { w: 0, wrapW: 0, navShow: false, navLeft: 0, swiperItemW: 0 }; }, watch: { "datas.componentData.columnNum": function(val) { this.getColumnW(1, this.datas.componentData.levelMargin); }, "imgList.length": function(val) { this.getColumnW(1, this.datas.componentData.levelMargin); }, "datas.componentData.rowNum": function(val) { this.getColumnW(1, this.datas.componentData.levelMargin); }, "datas.componentData.levelMargin": function(val) { this.swiperItemW = this.$el.offsetWidth - val * 2 - 2; // this.getColumnW(1, this.datas.componentData.levelMargin) // this.debounce(this.getColumnW, 1000, this); this.getColumnW1({ vm: this }); }, "datas.componentData.layoutType": function(val) { this.swiperItemW = this.$el.offsetWidth - this.datas.componentData.levelMargin * 2; this.getColumnW(1, this.datas.componentData.levelMargin); } }, mounted() { if (this.datas.componentData["layoutType"] == 1) { this.getColumnW(1, this.datas.componentData.levelMargin); } if (this.datas.componentData["layoutType"] == 2) { this.swiperItemW = this.$el.offsetWidth - this.datas.componentData.levelMargin * 2; } }, computed: { imgList:{ get() { return this.datas.componentData.imgList.filter(item=>item.visible==undefined || item.visible==1); }, set(newValue) { this.datas.componentData.imgList = newValue; } }, getBackgroundColor: { get() { return this.datas.componentData["backgroundColor"] || ""; }, set(val) { this.datas.componentData["backgroundColor"] = val; } }, getImgSize() { // get() { // return this.datas.componentData.imgSize; // }, // set(newValue) { // this.datas.componentData.imgSize = newValue; // } return (100 - this.datas.componentData.imgSize) / 2; }, textSize: { get() { return this.datas.componentData.textSize; }, set(newValue) { this.datas.componentData.textSize = newValue; } }, moduleRadius: { get() { return this.datas.componentData.moduleRadius; }, set(newValue) { this.datas.componentData.moduleRadius = newValue; } }, lineHeight: { get() { return this.datas.componentData.lineHeight; }, set(newValue) { this.datas.componentData.lineHeight = newValue; } }, getColumnWidth() { if (this.datas.componentData.columnNum == 1) { return "100%"; } else if (this.datas.componentData.columnNum == 2) { return "50%"; } else if (this.datas.componentData.columnNum == 3) { return "33.3%"; } else if (this.datas.componentData.columnNum == 4) { return "25%"; } else if (this.datas.componentData.columnNum == 5) { return "20%"; } else if (this.datas.componentData.columnNum == 6) { return "16.6%"; } }, swiperList() { let arr = []; let count = this.datas.componentData.columnNum * this.datas.componentData.rowNum; let num = Math.ceil(this.imgList.length / count); for (let i = 0; i < num; i++) { arr.push([]); } this.imgList.forEach((item, index) => { let i = Math.floor(index / count); // let j = index % count arr[i].push(item); }); return arr; }, //字体颜色 getFontsizeColor: { get() { return this.datas.componentData.fontColor; }, set(newValue) { this.datas.componentData.fontColor = newValue; } } }, created() {}, methods: { getColumnW1: debounce(({ vm }) => { if (vm.$refs["my-swipe"]) { vm.$refs["my-swipe"].resize(); } let w = vm.$el.offsetWidth - vm.datas.componentData.levelMargin * 2; // if (type == 1) { // w = this.$el.offsetWidth - val * 2; // } else { // w = this.$el.offsetWidth; // } if (vm.datas.componentData.columnNum == 1) { vm.w = w / 1; } else if (vm.datas.componentData.columnNum == 2) { vm.w = w / 2; } else if (vm.datas.componentData.columnNum == 3) { vm.w = w / 3; } else if (vm.datas.componentData.columnNum == 4) { vm.w = w / 4; } else if (vm.datas.componentData.columnNum == 5) { vm.w = w / 5; } else if (vm.datas.componentData.columnNum == 6) { vm.w = w / 6; } if ( Math.floor( vm.imgList.length / (vm.datas.componentData.columnNum * vm.datas.componentData.rowNum) ) == 0 ) { vm.wrapW = w; } else { vm.wrapW = Math.floor( vm.imgList.length / (vm.datas.componentData.columnNum * vm.datas.componentData.rowNum) ) * w + (vm.imgList.length % (vm.datas.componentData.columnNum * vm.datas.componentData.rowNum)) * vm.w; } vm.$nextTick(() => { if (vm.wrapW > w) { vm.navShow = true; } else { vm.navShow = false; } }); }, 300), touchstart(e) { let moveX = this.wrapW - (this.$el.offsetWidth - this.datas.componentData.levelMargin * 2); let x = e.target.scrollLeft / moveX; this.navLeft = 30 * x; }, onclickHandle(item) { if (!this.render) return; this.$themeToLink(item.link); }, // 非立即执行版 debounce(func, wait, _this) { let timer; return function() { let context = this; // 注意 this 指向 let args = arguments; // arguments中存着e if (timer) clearTimeout(timer); timer = setTimeout(() => { func(); }, wait); }; }, getColumnW() { console.log("11111111"); if (this.$refs["my-swipe"]) { this.$refs["my-swipe"].resize(); } let w = this.$el.offsetWidth - this.datas.componentData.levelMargin * 2; // if (type == 1) { // w = this.$el.offsetWidth - val * 2; // } else { // w = this.$el.offsetWidth; // } if (this.datas.componentData.columnNum == 1) { this.w = w / 1; } else if (this.datas.componentData.columnNum == 2) { this.w = w / 2; } else if (this.datas.componentData.columnNum == 3) { this.w = w / 3; } else if (this.datas.componentData.columnNum == 4) { this.w = w / 4; } else if (this.datas.componentData.columnNum == 5) { this.w = w / 5; } else if (this.datas.componentData.columnNum == 6) { this.w = w / 6; } if ( Math.floor( this.imgList.length / (this.datas.componentData.columnNum * this.datas.componentData.rowNum) ) == 0 ) { this.wrapW = w; } else { this.wrapW = Math.floor( this.imgList.length / (this.datas.componentData.columnNum * this.datas.componentData.rowNum) ) * w + (this.imgList.length % (this.datas.componentData.columnNum * this.datas.componentData.rowNum)) * this.w; } this.$nextTick(() => { if (this.wrapW > w) { this.navShow = true; } else { this.navShow = false; } }); } } }; </script> <style lang="scss" scoped> .cube-nav { width: 100%; height: 100%; box-sizing: border-box; font-size: 16px; .cube1, .cube2, .cube3 { width: 100%; height: 100%; box-sizing: border-box; overflow: hidden; position: relative; .cube-item { float: left; .item-img { position: relative; overflow: hidden; width: 100%; height: 0; padding-bottom: 100%; // background-image: linear-gradient(#8bd3fb, #4e98f8); // background-image: -webkit-linear-gradient(#8bd3fb, #4e98f8); // border-radius: 50%; // overflow: hidden; img { width: 100%; height: 100%; position: absolute; margin: auto; top: -9999px; right: -9999px; bottom: -9999px; left: -9999px; object-fit: contain; } } .item-bg { background-image: linear-gradient(#8bd3fb, #4e98f8); background-image: -webkit-linear-gradient(#8bd3fb, #4e98f8); } .item-title { width: 100%; text-align: center; margin-top: 8px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } } } .cube2 { // padding-bottom: 10px; &::-webkit-scrollbar { display: none; /* Chrome Safari */ } } .cube3 { .van-swipe__indicators { bottom: 4px !important; } /deep/ .van-swipe__indicator--active { background-color: var(--main-color); } // /deep/ .van-swipe__indicator{ // background-color: #ccc !important; // } } .nav-wrap { width: 100%; position: absolute; text-align: center; bottom: 4px; // height: 8px; text-align: center; .nav { width: 60px; height: 4px; border-radius: 2px; position: relative; overflow: hidden; margin: 0 auto; // background-color: rgba(233,72,103,.3); background-color: #ccc; .inner-nav { width: 30px; height: 4px; background-color: #333; border-radius: 2px; position: absolute; background-color: var(--main-color); top: 0; } } } } </style> <style lang="scss"> .van-swipe__indicators { bottom: 4px !important; } </style>