feat: 添加移动端页面组件和图片资源

This commit is contained in:
wangqiao
2025-09-03 17:06:39 +08:00
parent 7f2edb91e4
commit b1d2378cec
37 changed files with 2426 additions and 56 deletions

View File

@ -0,0 +1,108 @@
<template>
<div class="activity-section">
<div class="section-header">
<span class="section-title">最新活动</span>
<a href="/mobile/activity/list" class="view-all">
<span>查看全部</span>
<span class="chevron"></span>
</a>
</div>
<div class="activity-scroll">
<div class="activity-container">
<div
class="activity-card"
v-for="(item, index) in activityList"
:key="index"
@click="goToActivity(item)"
:style="{ marginRight: index === activityList.length - 1 ? '40rpx' : '20rpx' }"
>
<img :src="item.image" class="activity-image" alt="activity" />
</div>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import { useRouter } from 'vue-router'
import { ref } from 'vue'
import activity1 from '~/assets/images/activity1.png'
import activity2 from '~/assets/images/activity2.png'
import activity3 from '~/assets/images/activity2.png'
const router = useRouter()
const activityList = ref([
{ id: 1, title: '积分兑换有好礼', image: activity1, url: '/mobile/activity/detail?id=1' },
{ id: 2, title: 'CAD高效学习', image: activity2, url: '/mobile/activity/detail?id=2' },
{ id: 3, title: '学习有奖', image: activity3, url: '/mobile/activity/detail?id=3' },
])
function goToActivity(item: { url: string }) {
router.push(item.url)
}
</script>
<style lang="scss" scoped>
.activity-section {
margin: 21.53rpx 0;
// padding: 0 20rpx;
}
.section-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 20rpx;
}
.section-title {
font-size: 31rpx;
font-weight: 500;
color: #333;
}
.view-all {
display: flex;
align-items: center;
font-size: 24rpx;
color: #666;
text-decoration: none;
}
.view-all .chevron {
margin-left: 4rpx;
font-size: 20rpx;
}
.activity-scroll {
width: 100%;
overflow-x: auto;
padding-left: 20rpx; // 左侧padding与section对齐
margin-left: -20rpx; // 抵消父容器的padding
}
.activity-container {
display: inline-flex;
padding: 10rpx 0; // 留出阴影空间
}
.activity-card {
width: 330rpx;
height: 160rpx;
border-radius: 12rpx;
overflow: hidden;
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
transition: all 0.2s;
&:active {
transform: scale(0.98);
opacity: 0.9;
}
}
.activity-image {
width: 100%;
height: 100%;
object-fit: contain;
}
</style>

View File

@ -0,0 +1,98 @@
<template>
<div class="recommend-section">
<div class="tab-navigation">
<div
v-for="(tab, index) in tabs"
:key="index"
class="tab-item"
:class="{ active: currentTab === index }"
@click="switchTab(index)"
>
<span>{{ tab.title }}</span>
</div>
<button class="view-all" @click="viewAll">
<span>查看全部</span>
<span class="icon-right"></span>
</button>
</div>
<!-- 内容区域 -->
<recommend-list />
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
const currentTab = ref(0)
const tabs = ref([
{ title: '推荐图纸', type: 'drawings' },
{ title: '推荐模型', type: 'models' },
{ title: '推荐文本', type: 'documents' },
])
function switchTab(index: number) {
currentTab.value = index
}
function viewAll() {
const type = tabs.value[currentTab.value].type
router.push(`/mobile/${type}/list`)
}
</script>
<style lang="scss" scoped>
.recommend-section {
// padding: 0 20rpx;
// margin: 30rpx 0 50rpx;
}
.tab-navigation {
display: flex;
align-items: center;
margin-bottom: 25rpx;
}
.tab-item {
padding: 8rpx 0;
margin-right: 40rpx;
font-size: 29rpx;
color: #333;
position: relative;
transition: all 0.3s ease;
&.active {
color: #2970ff;
position: relative;
&::after {
content: "";
background-image: url("@/static/images/bg-yy.png");
background-size: 100% 100%;
background-repeat: no-repeat;
position: absolute;
bottom: 0rpx;
left: 0;
width: 100%;
height: 8px;
}
}
}
.view-all {
margin-left: auto;
display: flex;
align-items: center;
font-size: 24rpx;
color: #666;
background: transparent;
border: none;
cursor: pointer;
}
.view-all .icon-right {
margin-left: 4rpx;
font-size: 20rpx;
}
</style>

View File

@ -0,0 +1,64 @@
<template>
<div class="search-container">
<div class="search-input">
<span class="icon">🔍</span>
<input
v-model="searchValue"
type="text"
class="input"
placeholder="搜一搜"
@keyup.enter="onSearch"
/>
</div>
<button class="search-btn" @click="onSearch">
<img src="~/assets/images/info.png" alt="info" />
</button>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
const searchValue = ref('')
function onSearch() {
console.log('Search for:', searchValue.value)
}
</script>
<style scoped lang="scss">
.search-container {
background-color: #fff;
display: flex;
justify-content: space-between;
align-items: center;
}
.search-input {
display: flex;
align-items: center;
background: #efeff1;
border-radius: 32rpx;
padding: 0 22.11rpx;
flex: 1;
}
.search-input .icon { margin-right: 8px; }
.search-input .input {
flex: 1;
height: 64rpx;
border: none;
outline: none;
background: transparent;
}
.search-btn {
margin-left: 19.44rpx;
width: 43.75rpx;
height: 43.75rpx;
background-color: #fff;
border: none;
padding: 0;
}
.search-btn img {
width: 100%;
height: 100%;
}
</style>