uniapp 收藏功能实现及组件封装

前言

一、uniapp小程序收藏功能

思路分析:

  1. 父组件引入子组件.并且父组件通过属性绑定向子组件传递数据
  2. 子组件利用props来接收父组件传来的值,并且进行数据数据初始化赋值
  3. 子组件利用属性绑定,根据当前的type值来显示已收藏还是未收藏
  4. 点击收藏,切换状态,并且调用更新数据接口
  5. 在更新数据接口里面,通过 uni.showLoading() uni.hideLoading() uni.showToast({
    title:this.like?‘收藏成功’:‘取消收藏’,
    icon:‘none’
    })
    来切换状态
1 父组件向子组件传值
<likes :item="item"></likes>
2 子组件接收到值,将数据初始化
props: {
			item: {
				type: Object,
				default () {
					return {}
				}
			}
		},
		data() {
			return {
				like: false
			};
		},
		watch: {
			item(newVal) {
				this.like = this.item.is_like
			}
		},
		created() {
			this.like = this.item.is_like
		},
子组件利用属性绑定,根据当前的type值来显示已收藏还是未收藏
<uni-icons size="20" color="#f07373" :type="like?'heart-filled':'heart'"></uni-icons>
点击收藏,切换状态,并且调用更新数据接口
methods: {
			likeTap() {
				this.like = !this.like
				this.setUpdateLikes()
				console.log('收藏成功');
			},
			setUpdateLikes() {
				uni.showLoading()
				console.log(111)
				this.$api.update_like({
					user_id: '5e76254858d922004d6c9cdc',
					article_id: this.item._id
				}).then(res => {
					console.log(111)
					uni.hideLoading()
					console.log('是否', this.like)
					uni.showToast({
						title:this.like?'收藏成功':'取消收藏',
						icon:'none'
					})
					console.log(res);
					
				}).catch(()=>{
					uni.hideLoading()
				})
			}

完整收藏组件

<template>
	<view class="icons" @click.stop="likeTap">
		<uni-icons size="20" color="#f07373" :type="like?'heart-filled':'heart'"></uni-icons>
	</view>
</template>

<script>
	export default {
		props: {
			item: {
				type: Object,
				default () {
					return {}
				}
			}
		},
		data() {
			return {
				like: false
			};
		},
		watch: {
			item(newVal) {
				this.like = this.item.is_like
			}
		},
		created() {
			this.like = this.item.is_like
		},
		methods: {
			likeTap() {
				this.like = !this.like
				this.setUpdateLikes()
				console.log('收藏成功');
			},
			setUpdateLikes() {
				uni.showLoading()
				console.log(111)
				this.$api.update_like({
					user_id: '5e76254858d922004d6c9cdc',
					article_id: this.item._id
				}).then(res => {
					console.log(111)
					uni.hideLoading()
					console.log('是否', this.like)
					uni.showToast({
						title:this.like?'收藏成功':'取消收藏',
						icon:'none'
					})
					console.log(res);
					
				}).catch(()=>{
					uni.hideLoading()
				})
			}
		}
	}
</script>

<style>
	.icons {
		position: absolute;
		right: 0;
		top: 0;
		display: flex;
		justify-content: center;
		align-items: center;
		width: 20px;
		height: 20px;
	}
</style>

使用步骤

引入uniapp中的icons

下载icons插件 https://ext.dcloud.net.cn/plugin?id=2183

代码如下(示例):

在这里插入图片描述

在这里插入图片描述
在项目里新建一个icons 文件,将icons.js 和 icons.vue导入文件(原因是文件名和文件一致符合easyCom规范,不用导入,注册组件,直接用即可).我这里是都改成了uni-icons

UniApp虚拟列表瀑布流组件封装通常是为了提高性能并减少渲染成本,特别是在数据量大、界面滚动频繁的情况下。以下是一个简单的例子,展示了如何使用Vue.js来封装一个基础的虚拟列表瀑布流组件: ```javascript <template> <view class="waterfall"> <transition-group name="fade" v-for="(item, index) in items" :key="index" ref="list" > <uni-list-item v-if="shouldRender(item, index)" :key="item.id" slot-scope="{ item }" :scroll-y="isScrolling" @scroll="onScroll" ></uni-list-item> </transition-group> </view> </template> <script> export default { props: { data: { type: Array, required: true }, // 数据源 renderItem: { // 渲染单个元素的回调函数 type: Function, required: true }, itemHeight: { // 每个元素的高度 type: Number, default: 100 }, isInfinite: { // 是否有无限滚动 type: Boolean, default: false } }, data() { return { items: [], // 已渲染的元素 isScrolling: false, // 判断是否正在滚动 lastRenderedIndex: 0, // 上次渲染结束的索引 visibleItemCount: 10 // 显示的可见元素数量 }; }, computed: { shouldRender(item, index) { let start = this.lastRenderedIndex; if (this.isInfinite) start = Math.max(0, start - this.visibleItemCount); return start <= index && index < start + this.visibleItemCount; } }, methods: { onScroll(e) { this.isScrolling = e.detail.scrollTop > 0; // 更新滚动状态可能导致重新计算shouldRender,所以在这里处理下拉刷新 if (e.detail.scrollHeight - e.detail.scrollTop === this.$refs.list.offsetHeight) { this.loadMore(); } }, loadMore() { // 在这里添加加载更多数据的逻辑,例如向服务器请求新的数据 // 当新数据加载完成后更新items和lastRenderedIndex } }, mounted() { // 初始化可视区域内的元素 for (let i = 0; i < this.visibleItemCount; i++) { this.items.push(this.data[i]); } } }; </script> <style scoped> .fade-enter-active, .fade-leave-active { transition: opacity .3s ease; } .fade-enter, .fade-leave-to { opacity: 0; } </style> 在这个示例中,我们首先定义了一个`transition-group`包裹`uni-list-item`,然后通过`shouldRender`计算哪些元素应该显示。`loadMore`方法用于加载更多数据,而`mounted`生命周期钩子初始化了初始可见元素。当你需要调整瀑布流效果或修改组件行为时,可以在此基础上进行扩展。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值