代码提交

This commit is contained in:
黄少君
2023-11-14 17:21:03 +08:00
parent d0b337c596
commit dcab74274f
567 changed files with 22414 additions and 7375 deletions

View File

@ -0,0 +1,130 @@
<!--
@name: HomeGoodItem
@author: kahu4
@date: 2023-10-27 14:47
@descriptionHomeGoodItem
@update: 2023-10-27 14:47
-->
<script setup>
import { useRouter } from "@/hooks/useRouter";
const {push} = useRouter()
const props = defineProps({
good: {
type: Object
},
size: {
type: String,
default: 'small'
},
mode: {
type: String,
default: 'col'
}
})
const toDetail = () => {
push({url: '/pages/goodsDetail/goodsDetail'}, {
data: {
id: props.good.id
}
})
}
</script>
<template>
<view
:class="{'good-item':true,row:props.mode==='row'}"
@tap="toDetail"
>
<view class="image">
<image
:src="props.good.image"
mode="aspectFill"
/>
</view>
<view
class="info-box"
:class="{'padding-box':props.size==='big'}"
>
<view class="title-row">
{{ props.good.storeName }}
</view>
<view class="price-row">
<slot
name="bottom"
:good="good"
>底部
</slot>
</view>
</view>
</view>
</template>
<style
scoped
lang="scss"
>
.good-item {
position: relative;
width: 100%;
.image {
width: 100%;
aspect-ratio: 1 / 1;
image {
width: 100%;
height: 100%;
border-radius: 10rpx;
}
}
.info-box {
width: 100%;
.title-row {
margin: 14rpx 0;
max-width: 25vw;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
font-weight: 500;
font-size: 26rpx;
}
}
.padding-box {
box-sizing: border-box;
padding: 14rpx 20rpx;
}
}
.row {
display: flex;
align-items: center;
padding: 16rpx;
box-sizing: border-box;
background: #fff;
margin-bottom: 20rpx;
border-radius: 15rpx;
.image {
width: 220rpx;
}
.info-box {
padding: 20rpx 40rpx;
box-sizing: border-box;
height: 220rpx;
display: flex;
flex-direction: column;
justify-content: space-between;
.title-row {
margin-bottom: 30rpx;
}
}
}
</style>

View File

@ -0,0 +1,234 @@
<!--
@name: LiveCards
@author: kahu4
@date: 2023-11-01 17:04
@descriptionLiveCards
@update: 2023-11-01 17:04
-->
<script setup>
import { computed, onMounted, ref, unref } from "vue";
import { useSystem } from "@/hooks/useSystem";
const liveCardList = [
{
id: 1,
isLive: true,
title: '买一送一',
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
peopleNum: 168
},
{
id: 2,
isLive: false,
title: '买一送二',
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
peopleNum: 16858
},
{
id: 3,
isLive: true,
title: '买一送三',
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
peopleNum: 22343
},
{
id: 4,
isLive: true,
title: '买一送三',
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
peopleNum: 22343
},
{
id: 4,
isLive: true,
title: '买一送三',
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
peopleNum: 22343
},
{
id: 4,
isLive: true,
title: '买一送三',
background: 'https://alipic.lanhuapp.com/XDSlicePNGMAXc18a81ef73fc74664ef83df1de77da21f12619ff86653931ed809710b31c2e82.png',
peopleNum: 22343
}
]
const {getSystemInfo} = useSystem();
// ============================== 设置card选中相关 ================================
const current = ref(1) // 当前选中的索引
const systemInfo = ref({windowWidth: 0}) // 系统信息
const scrollLeft = ref(0) // 当前滑动到的位置
const scrollWidth = ref(0) // 滑轨总大小
// 计算单张宽度
const cardWidth = computed(() => {
if (unref(systemInfo).windowWidth <= 0) return 0
return Math.floor((unref(systemInfo).windowWidth) / 3) - 25
})
/**
* 滑动
* @param e
*/
function handleScroll(e) {
scrollLeft.value = e.detail.scrollLeft
scrollWidth.value = e.detail.scrollWidth
setCurrent()
}
/**
* 设置选中card
* @returns {number}
*/
function setCurrent() {
// 小于单张宽度直接设置1选中第2张
if (scrollLeft.value <= cardWidth.value) return current.value = 1
// 否则 current = (当前位置 / 单张宽度)= 当前屏幕左侧顶到图片的索引
// +1选中后一张
current.value = Math.floor(scrollLeft.value / cardWidth.value) + 1
}
function clickCard() {
}
onMounted(async () => {
systemInfo.value = await getSystemInfo()
})
</script>
<template>
<view class="live-cards">
<scroll-view
class="live-cards__inner"
scroll-x
@scroll="handleScroll"
>
<view class="track">
<view
:class="{'card-item':true,'current':index===current}"
v-for="(item,index) in liveCardList"
:key="item.id"
@click="clickCard"
>
<image
class="live-img"
:src="item.background"
mode="aspectFill"
/>
<view class="mask">
<view :class="{'status-box':true}">
<view :class="{status:true,close:item.isLive===false}">
{{ item.isLive ? '直播中' : '暂未开始' }}
</view>
<view class="number">
{{ item.isLive ? item.peopleNum : 0 }}
</view>
</view>
<view class="title">
{{ item.title }}
</view>
</view>
</view>
</view>
</scroll-view>
</view>
</template>
<style
scoped
lang="scss"
>
.live-cards {
width: 100%;
padding: 70rpx 0;
aspect-ratio: 750/480;
&__inner {
width: 100%;
height: 100%;
.track {
height: 100%;
display: flex;
align-items: center;
.card-item {
flex-shrink: 0;
width: calc(100% / 3);
height: 80%;
background: #fff;
border-radius: 15rpx;
overflow: hidden;
position: relative;
transition: all .3s;
scale: 1;
z-index: 1;
.live-img {
width: 100%;
height: 100%;
}
.mask {
position: absolute;
top: 0;
left: 0;
z-index: 10;
width: 100%;
height: 100%;
padding: 35rpx 20rpx;
box-sizing: border-box;
color: #fff;
font-size: 18rpx;
.status-box {
position: absolute;
display: flex;
align-items: center;
top: 18rpx;
left: 20rpx;
height: 33rpx;
line-height: 33rpx;
border-radius: 33rpx;
background: rgba(0, 0, 0, 0.6);
.status {
background: #ee6d46;
border-radius: 33rpx;
padding: 0 10rpx;
}
.close {
background: grey;
}
.number {
padding: 0 1rpx;
}
}
.title {
font-size: 28rpx;
position: absolute;
width: 100%;
color: #fff;
left: 20rpx;
bottom: 20rpx;
}
}
}
.current {
scale: 1.2 1.2;
z-index: 11;
}
}
}
}
</style>

View File

@ -0,0 +1,107 @@
<!--
@name: ScrollGoodRow
@author: kahu4
@date: 2023-11-01 15:56
@descriptionScrollGoodRow
@update: 2023-11-01 15:56
-->
<script setup>
import Goods from "@/components/goodsComponents/Goods.vue";
import Options from "@/components/goodsComponents/components/Options.vue";
const props = defineProps({
products: {
type: Array
}
})
</script>
<template>
<scroll-view
scroll-x
class="scroll-view"
>
<view
class="scroll-inner"
>
<template
v-for="good in props.products"
:key="good.id"
>
<Goods
class="scroll-item"
info-padding="15rpx 20rpx"
:goods="good"
>
<template #options>
<Options
:goods="good"
show-btn
></Options>
</template>
</Goods>
</template>
</view>
</scroll-view>
</template>
<style
scoped
lang="scss"
>
.scroll-view {
width: 100%;
overflow: hidden;
.scroll-inner {
display: flex;
flex-wrap: nowrap;
gap: 20rpx;
.scroll-item {
flex-shrink: 0;
max-width: 290rpx;
background: #fff;
border-radius: 15rpx;
overflow: hidden;
.good-bottom {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 20rpx;
.price {
color: #EE6D46;
font-size: 30rpx;
.tip {
color: #999999;
font-size: 24rpx;
}
}
.sale {
color: #999999;
}
.btn {
background: #ee6d46;
color: #fff;
font-size: 24rpx;
padding: 10rpx 24rpx;
transition: all .3s;
&:active {
transform-origin: right bottom;
scale: .9;
}
}
}
}
}
}
</style>

View File

@ -0,0 +1,87 @@
<!--
@name: 一行三个
@author: kahu4
@date: 2023-10-27 14:47
@descriptionTreeGoodRow
@update: 2023-10-27 14:47
-->
<script setup>
import Goods from "@/components/goodsComponents/Goods.vue";
import Options from "@/components/goodsComponents/components/Options.vue";
import { useRouter } from "@/hooks/useRouter";
const props = defineProps({
products: {
type: Array
}
})
const {push} = useRouter()
const toDetail = (id) => {
push({url: '/pages/goodsDetail/goodsDetail'}, {
data: {
id
}
})
}
</script>
<template>
<view class="three-row">
<template v-for="item in props.products">
<view class="good-item">
<Goods
:goods="item"
@click="toDetail(item.id)"
>
<template #options>
<Options :goods="item"></Options>
</template>
</Goods>
</view>
</template>
</view>
</template>
<style
scoped
lang="scss"
>
.three-row {
width: 100%;
position: relative;
display: flex;
align-items: center;
justify-content: space-between;
gap: 10rpx;
.good-item {
position: relative;
width: 31%;
}
.good-bottom {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 20rpx;
.price {
color: #EE6D46;
font-size: 30rpx;
.tip {
color: #999999;
font-size: 24rpx;
}
}
.sale {
color: #999999;
}
}
}
</style>

View File

@ -0,0 +1,96 @@
<!--
@name: 两行商品
@author: kahu4
@date: 2023-11-01 16:49
@descriptionTwoRowGoodROw
@update: 2023-11-01 16:49
-->
<script setup>
import Goods from "@/components/goodsComponents/Goods.vue";
import Options from "@/components/goodsComponents/components/Options.vue";
const props = defineProps({
products: {
type: Array
}
})
</script>
<template>
<view
class="two-row"
v-if=" props.products"
>
<template v-for="item in props.products.slice(0,2)">
<view class="row-item">
<Goods
row
:goods="item"
img-width="220rpx"
info-padding="20rpx 20rpx"
>
<template #options>
<Options
style="width: 100%;"
:goods="item"
btn-text="立即抢购"
show-btn
></Options>
</template>
</Goods>
</view>
</template>
</view>
</template>
<style
scoped
lang="scss"
>
.two-row {
width: 100%;
.row-item {
@include usePadding(15, 14);
background: #fff;
margin: 20rpx 0;
border-radius: 15rpx;
}
.good-bottom {
display: flex;
align-items: center;
justify-content: space-between;
font-size: 20rpx;
.price {
display: flex;
align-items: center;
color: #EE6D46;
font-size: 30rpx;
.tip {
color: #999999;
font-size: 24rpx;
}
}
.sale {
color: #999999;
}
.btn {
background: #ee6d46;
color: #fff;
font-size: 24rpx;
padding: 10rpx 24rpx;
transition: all .3s;
&:active {
transform-origin: right bottom;
scale: .9;
}
}
}
}
</style>