展示热门精选
1. 发送请求
2. 分类数据存入Store中
3. 页面渲染(布局处理)
下面分别是组件v9和v3代码
//component/house-item-v9 <template> <div class="house-item-v9"> <div class="item-inner"> <div class="cover"> <img :src="itemData.image.url"> </div> <div class="info"> <div class="summary">{{itemData.summaryText}}</div> <div class="name">{{itemData.houseName}}</div> <div class="price"> <van-rate :model-value="itemScore" color="#fff" :size="15" readonly allow-half /> <div class="new">¥ {{itemData.finalPrice}}</div> </div> </div> </div> </div> </template> <script setup> import { computed } from "@vue/runtime-core" const props = defineProps({ itemData: { type: Object, default: () => ({}) } }) const itemScore = computed(() => { return Number(props.itemData.commentScore) }) </script> <style lang="less" scoped> .house-item-v9 { width: 50%; .item-inner { position: relative; margin: 5px; background-color: #fff; border-radius: 6px; overflow: hidden; .cover { img { width: 100%; } } .info { position: absolute; bottom: 0; padding: 8px 10px; color: #fff; .summary { font-size: 12px; } .name { margin: 5px 0; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .price { display: flex; justify-content: space-between; margin-top: 10px; } } } } </style>
//component/house-item-v3 <template> <div class="house-item-v3"> <div class="item-inner"> <div class="cover"> <img :src="itemData?.image?.url" alt="" > </div> <div class="info"> <div class="location"> <img src="@/assets/img/home/location.png" alt="" > <span>{{ itemData.location }}</span> </div> <div class="name">{{ itemData.houseName }}</div> <div class="summary">{{ itemData.summaryText }}</div> <div class="price"> <div class="new"> ¥ {{ itemData.finalPrice }}</div> <div class="old"> ¥ {{ itemData.productPrice }}</div> <div class="tip" v-if="itemData.priceTipBadge" > {{ itemData.priceTipBadge.text }} </div> </div> </div> </div> </div> </template> <script setup> defineProps({ itemData: { type: Object, default: () => ({}) } }) </script> <style lang="less" scoped> .house-item-v3 { width: 50%; .item-inner { margin: 5px; background: #fff; border-radius: 6px; overflow: hidden; .cover { img { width: 100%; } } .info { padding: 8px 10px; color: #666; font-size: 12px; } .location { display: flex; align-items: center; img { width: 12px; height: 12px; } .text { margin-left: 2px; font-size: 12px; color: #666; } } .name { margin: 5px 0; font-size: 14px; color: #333; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; } .price { display: flex; align-items: flex-start; margin: 8px 0; .new { color: #ff9645; font-size: 14px; } .old { margin: 0 3px; color: #999; font-size: 12px; text-decoration: line-through; } .tip { background-image: linear-gradient(270deg, #f66, #ff9f9f); color: #fff; padding: 0 6px; border-radius: 8px; } } } } </style>
效果:
5. 滚动到底部 加载更多(再次请求数据)
监听页面的滚动,当滚动到底部的时候,发送请求数据,渲染页面,离开页面时,需要移除监听
这里我们封装一个 hooks
因为监听页面滚动,滚动频率过高会频繁触发hooks,这里引入 underscore 库中的节流函数
安装underscore
npm install underscore
相关概念
scrollTop 属性可以获取或设置一个元素的内容垂直滚动的像素数
clientHeight 属性(只读)元素的像素高度
- 如果当前元素没有滚动条,那么 clinetHeight = scrollHeight
- 如果当前元素存在滚动条,那么scrollHeight > clientHeight
scrollHeight = scrollTop + clientHeight
// hooks/useScroll.js import { onMounted, onUnmounted, ref } from "vue" import { throttle } from "underscore" export default function useScroll() { // 用变量判断是否到达底部 const isReachBottom = ref(false) // scrollHeight = scrollTop + clientHeight const scrollHeight = ref(0) const clientHeight = ref(0) const scrolltop = ref(0) // 节流处理 const scrollListenerHandler = throttle(() => { clientHeight.value = document.documentElement.clientHeight scrillTop.value = document.documentElement.scrollTop scrollHeight.value = document.documentElement.scrollHeight if (clientHeight.value + scrollTop.value >= scrollHeight.value) { // 已经滚到底部了 console.log("滚动到底部了") isReachBottom.value = true } }, 100) onMounted(() => { window.addEventListener("scroll", scrollListenerHandler) }) onUnmounted(() => { window.removeEventListener("scroll", scrollListenerHandler) }) return { isReachBottom, scrollHeight, clientHeight, scrolltop } }
存储日期信息
1. 将日期信息存入 mainStore
2. 修改之前展示的日期信息
搜索框展示
1. 控制搜索框显示
2. 搜索框布局
<template> <div class="search"> <div class="select-time"> <div class="item start"> <div class="name">住</div> <div class="date">{{ startDateStr }}</div> </div> <div class="item end"> <div class="name">离</div> <div class="date">{{ endDateStr }}</div> </div> </div> <div class="content"> <div class="keyword">关键字/位置/民宿</div> </div> <div class="right"> <i class="icon-search"></i> </div> </div> </template> <script setup> import { storeToRefs } from "pinia"; import { computed } from "@vue/runtime-core"; import { formatMonthDay } from "@/utils/format-time"; import { useMainStore } from "@/stores/modules/main"; const mainStore = useMainStore() const { startDate, endDate } = storeToRefs(mainStore) const startDateStr = computed(() => formatMonthDay(startDate.value, "MM.DD")) const endDateStr = computed(() => formatMonthDay(endDate.value, "MM.DD")) </script> <style lang="less" scoped> .search { display: flex; flex-direction: row; align-items: center; height: 45px; line-height: 45px; padding: 0 10px; font-size: 14px; color: #999; border-radius: 6px; background-color: #f2f4f6; .select-time { display: flex; flex-direction: column; .item { display: flex; flex-direction: row; align-items: center; line-height: normal; font-size: 10px; .name { font-size: 10px; } .date { position: relative; color: #333; margin: 0 10px 0 3px; } } } .end .date::after { content: ' '; width: 0; height: 0; border: 4px solid #666; border-color: rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) rgba(0, 0, 0, 0) #666; -webkit-border-radius: 3px; border-radius: 3px; -webkit-transform: rotate(45deg); -ms-transform: rotate(45deg); transform: rotate(45deg); position: absolute; bottom: 0px; right: -12px; } } .content { position: relative; flex: 1; padding: 0 6px; text-align: left; border-left: 1px solid #fff; .keyword { max-width: 155px; font-size: 12px; } } .right { display: flex; align-items: center; .icon-search { width: 24px; height: 24px; display: inline-block; background-image: url(../../assets/img/home/home-sprite.png); background-position: -29px -151px; background-size: 207px 192px; } } </style>
效果:
Git 管理和代码托管(github)
1.添加到暂存区
git add .
2.添加到仓库
git commit -m "home02分支"
3.推送代码
git push -u origin home02
4.将本地的tabbar 分支 合并到主分支上master (注意要先切换在主分支上)
git checkout mater
5.分支合并
git merge home02
6.更新远程仓库 master 分支
git push
7.删除tabbar分支
git branch -d home02