vue通用商品详情页

<template>
	<div class="goodsinfo-container">
		<transition
			@before-enter="beforeEnter"
			@enter="enter"
			@after-enter="afterEnter">
			<div class="ball" v-show="ballFlag"></div>
		</transition>
		<div class="ball"></div>
		<div class="mui-card">
			<div class="mui-card-content">
				<div class="mui-card-content-inner">
					<swiper :swiperList="swiperList" :isfull="true"></swiper>
				</div>
			</div>
		</div>
		<div class="mui-card">
			<div class="mui-card-header"></div>
			<div class="mui-card-content">
				<div class="mui-card-content-inner">
					<p class="price">
						市场价:<del>{{ goodsinfo.market_price }}</del>&nbsp;&nbsp;销售价:<span class="now_price">{{ goodsinfo.sell }}</span>
					</p>
					<p>购买数量:<numbox @getcount="getSelectedCount" :max="goodsinfo.stock_quantity"></numbox></p>
					<p>
						<mt-button type="primary" size="small">立即购买</mt-button>
						<mt-button type="danger" size="small">加入购物车</mt-button>

					</p>
				</div>
			</div>
			<div class="mui-card-footer"></div>
		</div>
		<div class="mui-card">
			<div class="mui-card-header">{{ goodsinfo.title }}</div>
			<div class="mui-card-content">
				<div class="mui-card-content-inner">
					<p>商品货号:{{ goodsinfo.goods_no }}</p>
					<p>库存情况:{{ goodsinfo.stock_quantity }}</p>
					<p>上架时间:{{ goodsinfo.add_time | dataFormat }}</p>
				</div>
			</div>
			<div class="mui-card-footer">
				<mt-button type="primary" size="large" plain>图文介绍</mt-button>
				<mt-button type="danger" size="large" plain>商品评论</mt-button>
			</div>
		</div>
	</div>
</template>

<script>
	import swiper from '../subcomponents/swiper.vue'
	import numbox from '../subcomponents/numbox.vue'

	export default {
		data(){
			return {
				id: this.$route.params.id,
				lunbotu: [],
				goodsinfo: {},
				ballFlag: false,
				selectedCount: 1
			}
		},
		created(){
			this.getLunbotu()
		},
		methods:{
			getLunbotu(){
				this.$http.get("数据接口" + this.id).then(result => {
					if (result.body.status === 0) {
						result.body.message.forEach(item => {
							item.img = item.src
						})
						this.lunbotu = result.body.message
					}
				})
			},
			getGoodsInfo(){
				this.$http.get('数据接口' + this.id).then(result => {
					if (result.body.status === 0) {
						this.goodsinfo = result.body.message[0];
					}
				})
			},
			goDesc(id) {
				this.$router.push({ name: "goodsdesc", params: { id } });
			},
			goComment(id) {
				this.$router.push({ name: "goodscomment", params: { id } });
			}addToshopCar(){
				this.ballFlag = this.ballFlag
			},
			beforeEnter(el){
				el.style.transform = "translate(0, 0)"
			},
			enter(el, done){
				el.offsetWidth;
				const ballPosition = this.$refs.ball.getBoundingClientRect();
				const badgePosition = document.getElementById('badge').getBoundingClientRect();
				const xDist = badgePosition.left - ballPosition.left;
				const yDist = badgePosition.top - ballPosition.top;
				el.style.transform = `translate($(xDist)px, $(yDist)px)`;
				el.style.transition = "all 1s cubic-bezier(.4,-0.3,1,.68)";
				done();
			},
			afterEnter(el){
				this.ballFlag = !this.ballFlag
			},
			getSelectedCount(count){
				this.selectedCount = count;
			}
		},
		components: {
			swiper,
			numbox
		}

	}
</script>
<style lang="scss" scoped>
	.goodsinfo-container {
		background-color: #eee;
		overflow: hidden;
		.now_price {
			color: red;
			font-size: 16px;
			font-weight: bold;
		}
		.mui-card-footer{
			display: block;
			button{
				margin: 10px 0;
			}
		}
		.ball{
			width: 90px;
			height: 90px;
			border-radius: 50%;
			background-color: red;
			z-index: 99;
			top: 390px;
			left: 146px;
			transform: translate(88px, 230px)
		}
	}
</style>

数字盒子

<template>
	<div class="mui-numbox" data-numbox-min='1' data-numbox-max='max'>
		<button class="mui-btn mui-btn-numbox-minus" type="button">-</button>
		<input id="test" class="mui-input-numbox" type="number" value="1" @change="countChanged" ref="numbox" />
		<button class="mui-btn mui-btn-numbox-plus" type="button">+</button>
	</div>
</template>

<script>
	import mui from '../../lib/mui/js/mui.min.js'
	export default {
		mounted(){
			mui(".mui-numbox").numbox();
		},
		methods:{
			countChanged(){
				this.$emit("getcount", parseInt(this.$refs.numbox.value));
			}
		},
		props: ["max"],
		watch:{
			'max':function(newVal, oldVal){
				mui(Selector).numbox().setOption("max", newVal)
			}
		}
	}
</script>

<style lang="scss" scoped>
	
</style>

轮播图组件

<template>
	<div>
		<mt-swipe :auto="4000">
			<mt-swipe-item v-for="item in swiperList" :key="item.url">
				<img src="item.img" alt="" :class="{'full': isfull}">
			</mt-swipe-item>
		</mt-swipe>
	</div>
</template>

<script>
	export default {
		props: ["swiperList", "isfull"]
	}
</script>

<style lang="scss" scoped>
	.mint-swipe {
		height: 200px;

		.mint-swipe-item {
			&:nth-child(1){

			}
			&:nth-child(2){
				
			}
			&:nth-child(3){
				
			}

			img{
				height: 100%;
			}
		}
	}
	.full{
		width: 100%;
	}
</style>

关键问题

  1. 轮播图的自适应问题:
<img src="item.img" alt="" :class="{'full': isfull}">
.full{
		width: 100%;
	}
  1. 小球动画
    半场动画+ref组件操作+@change事件绑定+滚动条和分辨率适配算法
<input id="test" class="mui-input-numbox" type="number" value="1" @change="countChanged" ref="numbox"
beforeEnter(el){
				el.style.transform = "translate(0, 0)"
			},
enter(el, done){
				el.offsetWidth;
				const ballPosition = this.$refs.ball.getBoundingClientRect();
				const badgePosition = document.getElementById('badge').getBoundingClientRect();
				const xDist = badgePosition.left - ballPosition.left;
				const yDist = badgePosition.top - ballPosition.top;
				el.style.transform = `translate($(xDist)px, $(yDist)px)`;
				el.style.transition = "all 1s cubic-bezier(.4,-0.3,1,.68)";
				done();
			},
afterEnter(el){
				this.ballFlag = !this.ballFlag
			},
  1. $emit 子组件向父组件传值
<p>购买数量:<numbox @getcount="getSelectedCount" 
methods:{
			countChanged(){
				this.$emit("getcount", parseInt(this.$refs.numbox.value));
			}
		},
  1. watch监听max
watch:{
			'max':function(newVal, oldVal){
				mui(Selector).numbox().setOption("max", newVal)
			}
		}
Logo

前往低代码交流专区

更多推荐