uni-app实战项目,跟着做完你就可以独立作战了(二)

实现内容切换

实现内容左右滑动

我们新建list组件

里面使用swiper基础组件
我们将首页这一部分剪切过来
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
这样就可以正常内容左右滑动切换了
但是有一个问题,不能上下滚动
在这里插入图片描述
我们将list组件放到容器中,然后设置一下样式
但我们还需要在组件中设置样式来撑起高度
在这里插入图片描述
这样就可以上下滚动了
暂时代码

<template>
	<swiper class="home-swiper">
		<swiper-item class="swiper-item">
			<list-scrool class="list-scrool">
				<list-card mode="base" ></list-card>
				<list-card mode="image" ></list-card>
				<list-card mode="column" ></list-card>
				<list-card mode="base" ></list-card>
				<list-card mode="image" ></list-card>
				<list-card mode="column" ></list-card>
			</list-scrool>
		</swiper-item>
		<swiper-item class="swiper-item">
			<list-scrool class="list-scrool">
				<list-card mode="base" ></list-card>
				<list-card mode="image" ></list-card>
				<list-card mode="column" ></list-card>
				<list-card mode="base" ></list-card>
				<list-card mode="image" ></list-card>
				<list-card mode="column" ></list-card>
			</list-scrool>
		</swiper-item>
	</swiper>
</template>

<script>
	export default {
		data() {
			return {

			};
		}
	}
</script>

<style lang="scss">
	.home-swiper {
		height: 100%;
		.swiper-item{
			height: 100%;
			overflow: hidden;
			.list-scrool{
				height: 100%;
			}
		}
	}
</style>

改造:
我们在list组件下新建list-item.vue文件
在这里插入图片描述
我们要设置高度哦

	.list-scrool{
		height: 100%;
	}

list.vue组件中
在这里插入图片描述
我们给子组件传值
在这里插入图片描述
子组件接收并循环
在这里插入图片描述
这样我们的内容区域和选项卡区域可以对的上了 都是6块

实现内容与选项卡关联

实现左右滑动内容,选项卡对应高亮

我们在list组件中写一个change事件来监听变化
再用$emit传给首页index.vue
在这里插入图片描述
在首页中
我们接收事件 并且定义一个变量 传给选项卡
在这里插入图片描述
在tab选项卡中
我们接收值,并且在watch事件中监听变化赋值给activeIndex即可
在这里插入图片描述

实现选项卡与内容关联

实现点击选项卡,内容区域变化
之前我们在tab选项卡组件中定义了点击事件及传值给父组件
在这里插入图片描述
在首页父组件中

点击选项卡传值过来后将值赋给变量activeIndex,然后在传给内容组件
在这里插入图片描述
在list组件中我们接收传递过来的activeIndex值
swiper有一个属性current可以指定调整到索引为多少的内容区域,所以我们将activeIndex赋值过去
在这里插入图片描述

数据初始化

我们将静态内容从数据库获取放到页面中

新建云函数

在这里插入图片描述

get_list中编写
获取到内容之后,我们要过滤掉content字段(使用field),然后返回给客户端
在这里插入图片描述
我们在如下地方写
在这里插入图片描述
然后我们在list组件中写调用函数,在created中调用
在这里插入图片描述
获取到值以后,我们赋值给list 然后在传递给子组件list-item
在这里插入图片描述
list-item在接收到值以后循环一下,然后将mode类赋值给mode属性
然后在传递item过去,将内容替换
在这里插入图片描述

我们在list-card组件中接收传递过来的值item
在这里插入图片描述
我们在上面做一个更改
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
完整代码在下方

<template>
	<view class="list">
		<!-- 基础卡片 -->
		<view v-if="mode==='base'" class="listcard">
			<view class="listcard-image">
				<image :src="item.cover[0]" mode="aspectFill"></image>
			</view>
			<view class="listcard-content">
				<view class="listcard-content_title">
					<text>{{item.title}}</text>
				</view>
				<view class="listcard-content_des">
					<view class="listcard-content_des-label">
						<view class="listcard-content_des-label-item">
							{{item.classify}}
						</view>
					</view>
					<view class="listcard-content_des-browe">
						{{item.browse_count}}浏览
					</view>
				</view>
			</view>
		</view>
		
		<!-- 多图模式 -->
		<view v-if="mode==='image'" class="listcard mode-column">
			<view class="listcard-content">
				<view class="listcard-content_title">
					<text>{{item.title}}</text>
				</view>
				<view class="listcard-image">
					<view v-if="index<3" v-for="(item,index) in item.cover" :key="index" class="listcard-image_item">
						<image :src="item" mode="aspectFill"></image>
					</view>
				</view>
				<view class="listcard-content_des">
					<view class="listcard-content_des-label">
						<view class="listcard-content_des-label-item">
							{{item.classify}}
						</view>
					</view>
					<view class="listcard-content_des-browe">
						{{item.browse_count}}浏览
					</view>
				</view>
			</view>
		</view>
		<!-- 大图模式 -->
		<view v-if="mode==='column'" class="listcard mode-image">
			<view class="listcard-content">
				<view class="listcard-image">
					<image :src="item.cover[0]" mode="aspectFill"></image>
				</view>
				<view class="listcard-content_title">
					<text>{{item.title}}</text>
				</view>
				<view class="listcard-content_des">
					<view class="listcard-content_des-label">
						<view class="listcard-content_des-label-item">
							{{item.classify}}
						</view>
					</view>
					<view class="listcard-content_des-browe">
						{{item.browse_count}}浏览
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props:{
			mode:{
				type:String,
				default:'base'
			},
			item:{
				type:Object,
				default(){
					return {}
				}
			}
		},
		data() {
			return {

			};
		}
	}
</script>

<style lang="scss">
	.list{
		.listcard {
			display: flex;
			padding: 10px;
			margin: 10px;
			border-radius: 5px;
			box-shadow: 0 0 5px 1px rgba($color: #000000, $alpha: 0.1);
			box-sizing: border-box;
		
			.listcard-image {
				flex-shrink: 0;
				width: 60px;
				height: 60px;
				border-radius: 5px;
				overflow: hidden;
		
				image {
					width: 100%;
					height: 100%;
				}
			}
		
			.listcard-content {
				display: flex;
				flex-direction: column;
				justify-content: space-between;
				padding-left: 10px;
				width: 100%;
		
				.listcard-content_title {
					position: relative;
					padding-right: 30px;
					font-size: 14px;
					color: #333;
					font-weight: 400;
					line-height: 1.2;
		
					text {
						overflow: hidden;
						text-overflow: ellipsis;
						display: -webkit-box;
						-webkit-line-clamp: 2;
						-webkit-box-orient: vertical;
					}
		
				}
		
				.listcard-content_des {
					display: flex;
					justify-content: space-between;
					font-size: 12px;
		
					.listcard-content_des-label {
						display: flex;
		
						.listcard-content_des-label-item {
							padding: 0 5px;
							margin-right: 5px;
							border-radius: 15px;
							color: $mk-base-color;
							border: 1px $mk-base-color solid;
						}
					}
		
					.listcard-content_des-browe {
						color: #999;
						line-height: 1.5;
					}
				}
			}
		
			&.mode-column {
				.listcard-content {
					width: 100%;
					padding-left: 0;
				}
		
				.listcard-image {
					display: flex;
					margin-top: 10px;
					width: 100%;
					height: 70px;
		
					.listcard-image_item {
						margin-left: 10px;
						width: 100%;
						border-radius: 5px;
						overflow: hidden;
		
						&:first-child {
							margin-left: 0;
						}
		
						image {
							width: 100%;
							height: 100%;
						}
					}
				}
		
				.listcard-content_des {
					margin-top: 10px;
				}
			}
		
			&.mode-image {
				flex-direction: column;
				.listcard-image {
					width: 100%;
					height: 100px;
				}
		
				.listcard-content {
					padding-left: 0;
					margin-top: 10px;
		
					.listcard-content_des {
						display: flex;
						align-items: center;
						margin-top: 10px;
					}
				}
			}
		}
	}
</style>

在这里插入图片描述
页面暂时是这样了 有的图片可能因为地址过期获取没有权限展示不出,没有问题的

页面内容展示与选项卡相同

我们在首先执行的时候传递第一个需要展示的内容
在改变选项卡高亮和内容区域时再次调用将获取到的tab数组中的name值传递过去

在这里插入图片描述
在这里插入图片描述
效果
在这里插入图片描述
但是此时有一个弊端,他不是及时更新,而是启用之前的缓存
我们要做如下更改
在这里插入图片描述
list传值也做下更改,将listCatchData[index]传过去
在这里插入图片描述
这样就不会出现如上问题了
在这里插入图片描述

list.vue完整代码

<template>
	<swiper class="home-swiper" :current="activeIndex" @change="change">
		<swiper-item v-for="(item,index) in tab" class="swiper-item" :key="index">
			<list-item :list="listCatchData[index]"></list-item>
		</swiper-item>
	</swiper>
</template>

<script>
	import listItem from './list-item.vue'
	export default {
		components:{
			listItem
		},
		props:{
			tab:{
				type:Array,
				default(){
					return []
				}
			},
			activeIndex:{
				type:Number,
				default:0
			}
		},
		data() {
			return {
				list:[],
				listCatchData:{}
			};
		},
		created() {
			// this.get_list(0)
		},
		watch:{
			tab(newVal){
				if(newVal.length===0) return
				this.get_list(this.activeIndex)
			}
		},
		methods:{
			change(e){
				const {current}=e.detail
				this.$emit('change',current)
				this.get_list(current)
			},
			get_list(current){
				this.$api.get_list({
					name:this.tab[current].name
				})
				.then(res=>{
					// this.list=res.data.data
					// this.listCatchData[current]=res.data.data
					this.$set(this.listCatchData,current,res.data.data)
				})
			}
		}
	}
</script>

<style lang="scss">
	.home-swiper {
		height: 100%;
		.swiper-item{
			height: 100%;
			overflow: hidden;
			.list-scrool{
				height: 100%;
			}
		}
	}
</style>

我们将tab选项卡添加一个数据’全部’
pages/index.vue/index.vue
在这里插入图片描述
云函数get_list
在这里插入图片描述
在这里插入图片描述

我们在list组件的change事件中添加如下代码
否则会多次请求数据库,会造成服务器压力
在这里插入图片描述

引入加载插件

插件市场导入
在这里插入图片描述
list-item中使用
在这里插入图片描述

这里会有一个问题,在最下面会一直存在加载中,所以我们要做判断
我们在获取列表数据里面加入俩个条件
在这里插入图片描述
在get_list中加入下面代码
在这里插入图片描述

这样就可以获取每页多少条,我们后面去做判断,划到最后是显示正在加载还是没有更多数据提升
我们用的list-scrool组件
在这里插入图片描述
在list-scrool组件中添加上划到底事件
在这里插入图片描述
我们从组件一级一级传出事件到list组件中
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们在这几处加入代码,为了下滑到底加载更多数据
在这里插入图片描述
这时有一个问题,如果我们在全部页下滑加载完全部数据,划到单独分栏不会加载数据的

我们将page变量删除改为load:{} 即可完美解决
在这里插入图片描述
加入如下代码在list组件
在这里插入图片描述
然后在list-item组件中接收即可
在这里插入图片描述
再往下划会报错
在这里插入图片描述
加入如下代码,就完美解决了
在这里插入图片描述
在这里插入图片描述
最后这样如果数据库没有新数据就不会再次发起请求了
别的页面也能正常运行了
在这里插入图片描述
我们做一个小小修改,加入一行代码在index.vue
在这里插入图片描述
加入一行代码在list-item.vue中
在这里插入图片描述
这样我们就完美解决了

收藏功能

新建likes组件
在这里插入图片描述
然后再list-card中每个模式标题下面引入
在这里插入图片描述
再likes中做点击事件
在这里插入图片描述
编写新的云函数
在这里插入图片描述
api中加入
在这里插入图片描述
likes组件中加入传值
在这里插入图片描述
然后我们在likes.vue组件中进行接收

在点击收藏时我们直接调用我们的函数,我们也写了一个变量like,为了让收藏按钮是显示收藏还是为收藏
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
但是我们收藏状态在刷新后是不存储的
我们要做一下修改
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
改变文章收藏状态
在这里插入图片描述
加个收藏提示,是收藏还是取消
在这里插入图片描述
到此我们的收藏就完成了


结束语

到现在我们首页就完成了
敬请期待下一篇: 搜索功能的实现

  • 32
    点赞
  • 58
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 50
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 50
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

David凉宸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值