多一些不为什么的坚持🤳
贤蛋 🥚大眼萌 ,一名很普通但不想普通的程序媛🙊
📝本文章收录于专栏:Vue3.0移动端项目-旅游网
第二篇:【Vue3.0移动端项目–旅游网】–配置tabBar &首页搭建
通过 Git 管理项目,养成良好的开发习惯,可以创建分支。最后开发完可以合并分支。
git checkout -b home02
git branch



效果:


这里封装一个单独的组件
home-categories下面是组件完整代码:
<template>
<div class="categories">
<template
v-for="(item,index) in categories"
:key="index"
>
<div class="item">
<img :src="item.pictureUrl" />
<div class="text">{{item.title}}</div>
</div>
</template>
</div>
</template>
<script setup>
import { useHomeStore } from '@/stores/modules/home';
import { storeToRefs } from 'pinia';
const homeStore = useHomeStore()
const { categories } = storeToRefs(homeStore)
</script>
<style lang="less" scoped>
.categories {
display: flex;
overflow-x: auto;
height: 88px;
padding: 0 10px;
margin-top: 8px;
&::-webkit-scrollbar {
display: none;
}
.item {
flex-shrink: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
width: 70px;
text-align: center;
img {
width: 44px;
height: 44px;
}
.text {
font-size: 12px;
margin-top: 8px;
}
}
}
</style>
效果:

下面分别是组件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>
效果:
监听页面的滚动,当滚动到底部的时候,发送请求数据,渲染页面,离开页面时,需要移除监听
这里我们封装一个 hooks
因为监听页面滚动,滚动频率过高会频繁触发hooks,这里引入 underscore 库中的节流函数
安装underscore
npm install underscore
- 1
相关概念
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
}
}

<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 add .
git commit -m "home02分支"
git push -u origin home02
git checkout mater
git merge home02
git push
git branch -d home02
补充:
网络数据请求地址数据
项目github 地址:https://github.com/fdfd-0313/cz-trip.git
