2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】

1、获取景点详情的请求【my_api.js】

javascript 复制代码
// 引入公共的请求封装
import http from './my_http.js'

// 登录接口(适配服务端返回 Token)
export const login = async (code, avatar) => {
		const res = await http('/login/getWXSessionKey', {code,avatar});
};


// 获取bannner列表
export const getBannerList = () => {
	return http('/banner/list')
}

// 获取景点类型列表(支持传入typeId参数)
export const getTypeList = () => {
	return http('/type/list')
}

// 获取景点列表
export const getAttractionList = (typeId) => {
	// 如果有typeId就拼接到URL,没有就不加
	const url = typeId ? `/attraction/list?typeId=${typeId}` : '/attraction/list'
	return http(url)
}
// 获取景点详情
export const getAttractionInfo = (attractionId) => {
	return http(`/attraction/getInfo/${attractionId}`)
}

// 获取收藏列表
export const getFavouriteList = () => {
	// 如果有typeId就拼接到URL,没有就不加
	return http('/favourite/list')
}

2、页面源码【attraction_details.vue】

html 复制代码
 <template>
 	<view class="container"><!-- 导航栏 -->
 		<up-navbar class="up-navbar-title" bg-color="#00000000" title="" :auto-back="true" left-icon-color="#fff" />

 		<!-- 景点主图 -->
 		<view class="attraction-box">
 			<image class="attraction-image" :src="attraction.cover" mode="aspectFill"></image>
 			<view class="image-overlay"></view>
 			<view class="attraction-header">
 				<view class="attraction-title">{{ attraction.title }}</view>
 				<view class="attraction-subtitle">{{ attraction.address }}</view>
 			</view>
 		</view>

 		<!-- 景点内容区域 -->
 		<view class="content-box">
 			<!-- 景点简介 -->
 			<view class="section" v-if="attraction.introduction">
 				<view class="section-title">
 					<up-icon name="info-circle" color="#3c9cff" size="18"></up-icon>
 					<text class="title-text">景点简介</text>
 				</view>
 				<view class="section-content">{{ attraction.introduction }}</view>
 			</view>


 			<!-- 开放时间 -->
 			<view class="section" v-if="attraction.inbusinessTime1 || attraction.inbusinessTime2">
 				<view class="section-title">
 					<up-icon name="clock" color="#3c9cff" size="18"></up-icon>
 					<text class="title-text">开放时间</text>
 				</view>
 				<view class="section-content">
 					{{ attraction.inbusinessTime1 ? attraction.inbusinessTime1.slice(0,5) : '未设置' }} -
 					{{ attraction.inbusinessTime2 ? attraction.inbusinessTime2.slice(0,5) : '未设置' }}
 				</view>
 			</view>

 			<!-- 详细描述 -->
 			<view class="section" v-if="attraction.description">
 				<view class="section-title">
 					<up-icon name="map" color="#3c9cff" size="18"></up-icon>
 					<text class="title-text">景点介绍</text>
 				</view>
 				<view class="section-content">{{ attraction.description }}</view>
 			</view>
 		

 			<!-- 联系方式 -->
 			<view class="section" v-if="attraction.tel">
 				<view class="section-title">
 					<up-icon name="phone" color="#3c9cff" size="18"></up-icon>
 					<text class="title-text">联系方式</text>
 				</view>
 				<view class="section-content">{{ attraction.tel }}</view>
 			</view>
 		</view>

 		
 	</view>
 </template>

 <script setup>
 	import {
 		onLoad
 	} from '@dcloudio/uni-app'
 	import {
 		ref,
 		reactive
 	} from 'vue'
 	import {
 		getAttractionInfo
 	} from '../../api/my_api.js'
	
	// 景点对象
 	const attraction = ref({})
	
	//接受传递过来的id
 	onLoad((opt) => {
 		const attractionId = opt.attractionId
		//重新获取景点详情
 		getInfo(attractionId)
 	})
	
	// 景点详情
 	const getInfo = (attractionId) => {
 		getAttractionInfo(attractionId).then(res => {
 			attraction.value = res
 		})
 	}
 </script>


<style lang="scss" scoped>
  .container {
    position: relative;
    min-height: 100vh;
    background-color: #f5f5f5;
    
    // 景点盒子
    .attraction-box {
      position: relative;
      height: 500rpx;
      overflow: hidden;
      
      .attraction-image {
        width: 100%;
        height: 100%;
      }
      
      .image-overlay {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        height: 200rpx;
        background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);
      }
      
      .attraction-header {
        position: absolute;
        bottom: 40rpx;
        left: 30rpx;
        right: 30rpx;
        color: #fff;
        
        .attraction-title {
          font-size: 42rpx;
          font-weight: bold;
          margin-bottom: 10rpx;
        }
        
        .attraction-subtitle {
          font-size: 28rpx;
          opacity: 0.9;
        }
      }
    }
    
    // 内容区域
    .content-box {
      padding: 30rpx;
      margin-top: 0rpx;
      background-color: #fff;
      border-radius: 30rpx 30rpx 0 0;
      box-shadow: 0 -5rpx 10rpx rgba(0,0,0,0.05);
      
      .section {
        margin-bottom: 40rpx;
        
        .section-title {
          display: flex;
          align-items: center;
          margin-bottom: 20rpx;
          font-size: 32rpx;
          font-weight: bold;
          color: #333;
          
          .title-text {
            margin-left: 10rpx;
          }
        }
        
        .section-content {
          font-size: 28rpx;
          color: #666;
          line-height: 1.6;
          text-align: justify;
        }
      }
    }
    
   
  }
</style>

3、后端返回的数据结构

javascript 复制代码
{
	"id": 2,
	"title": "石家庄动物园",
	"cover": "http://localhost:9001/attraction/8.png",
	"introduction": "与萌宠零距离,开启奇妙动物之旅!",
	"start": null,
	"browse": null,
	"img": null,
	"description": "石家庄动物园位于河北省石家庄市,是一座大型的综合性动物园,旨在饲养、繁殖、研究和保护各种动物,同时为公众提供观赏和教育的机会。动物园内环境优美,设施齐全,旨在为动物提供一个接近自然的生活环境,同时也为游客创造一个舒适、安全的观赏体验。\n园内分为多个区域,包括猛兽区、食草动物区、鸟语林、爬行馆等,每个区域都根据动物的习性进行了精心设计。在这里,游客可以近距离观察到狮子、老虎、大象、长颈鹿、熊猫等众多珍稀动物。此外,动物园还定期举办各种教育活动和互动体验,如动物喂食、科普讲座等,旨在提高公众的生态保护意识。\n石家庄动物园不仅是家庭休闲的好去处,也是学校组织学生进行生物多样性教育的理想场所。通过实地观察和学习,动物园激发人们对自然的兴趣和对动物的同情心,促进社会公众的生态保护意识。\n总之,石家庄动物园以其丰富的动物种类、优美的环境和丰富的教育活动,为游客提供了一个寓教于乐的场所,是石家庄市重要的旅游景点之一。\n",
	"inbusinessTime1": "06:00:00",
	"inbusinessTime2": "18:00:00",
	"address": "河北省石家庄市鹿泉区观景大街与山前大道交叉口西南处",
	"province": null,
	"city": null,
	"area": null,
	"longitude": "114.30 \r\n",
	"latitude": "38.06\r\n",
	"location": null,
	"enableType": "false",
	"typeId": "1",
	"enableAppointment": "false",
	"enablePay": "false",
	"tel": null
}

4、效果图

相关推荐
月忆3649 分钟前
等待组(waitgroup)
前端·爬虫·python
令狐寻欢12 分钟前
HTML中 的 meta 标签常用属性及其作用
前端·html
SynthWriter17 分钟前
Trae 帮我生成了一个贪吃蛇的游戏,好玩儿
前端
用户214118326360230 分钟前
dify案例分享-Dify+RSS 聚合 8 大平台实时热点,新闻获取效率飙升 300%
前端
百锦再32 分钟前
Razor编程中@Html的方法使用大全
前端·html
啪叽35 分钟前
JavaScript可选链操作符(?.)的实用指南
前端·javascript
Ian在掘金35 分钟前
bat+python实现easy connect自动连接
前端·python
代码搬运媛38 分钟前
【react实战】如何实现监听窗口大小变化
前端·javascript·react.js
小桥风满袖40 分钟前
Three.js-硬要自学系列30之专项学习环境光
前端·css·three.js
Luckyfif43 分钟前
🤯由 性能指标 散发开来的 Performance API 被问爆了呀
前端·面试·性能优化