uni_app组件实现tags 小说标签筛选,支持多级筛选,支持默认选中,vue3+ts+setup

效果图:

主要能力:选中的tab会自动移动到组件的中间位置,支持默认选中第几个tab,支持多级联动筛选,然后发送数据请求。

参考文章:uni_app组件实现tab选项卡滑动切换,支持默认选中,vue3+ts+setup_平谷一勺的博客-CSDN博客
 废话不多说上菜了,

tags.vue组件

<template>
	<view class="nav">
		<scroll-view class="tabs" scroll-x="true" scroll-with-animation :scroll-left="scrollLeft">
			<view class="tabs-scroll">
				<view class="tabs-scroll_item" v-for=" (item,index) in itemList" :key="index"
					:class="{'active':selectIndex==index}" @click="chenked(index)">
					{{item.title}}
				</view>
			</view>
		</scroll-view>
	</view>
</template>

<script setup lang="ts">
	import { getCurrentInstance, onMounted, ref, watch } from "vue";
	const scrollLeft = ref<number>(0)
	const selectIndex = ref<number>(0)
 	const itemList = ref<Array<ItabItem>>()
	interface ItabItem {
		title : string
		width ?: number
		left ?: number
		id : number
		type:number
	}
	interface Iprops {
		tablist : Array<ItabItem>
		defaultSelectIndex ?: number
	}
    
	const props = withDefaults(defineProps<Iprops>(), {
		tablist: () => [],
		defaultSelectIndex: 6
	})
	const emits=defineEmits<{
		(e : 'select',value : ItabItem,index:number) : void
	}>()
	const chenked = (index:number) => {
		selectIndex.value = index
		scrollLeft.value = 0
		for (let i = 0; i < index - 2; i++) {
			scrollLeft.value = scrollLeft.value + itemList.value[i]?.width
		}
		emits('select',props.tablist[index],index)
	}
	onMounted(() => {
		const query = uni.createSelectorQuery().in(getCurrentInstance());
		 
		query.selectAll('.tabs-scroll_item').boundingClientRect((data:Array<UniApp.NodeInfo>) => {
			let dataLen = data.length;
			for (let i = 0; i < dataLen; i++) {
				//  scroll-view 子元素组件距离左边栏的距离
				itemList.value[i].left = data[i].left;
				//  scroll-view 子元素组件宽度
				itemList.value[i].width = data[i].width
			}
		}).exec()


	})
	watch(() => [props.tablist, props.defaultSelectIndex], () => {
		itemList.value = props.tablist
		selectIndex.value = props.defaultSelectIndex
		
		 // if (props.defaultSelectIndex !== 0) {
		 	setTimeout(() => {
		 		chenked(props.defaultSelectIndex)
		 	}, 50)
		 // }
		 
	}, {
		immediate: true
	})
</script>
<style lang="scss" scoped>
	.nav {
	    margin-top: 10rpx;
		z-index: 99;
		width: 100%;
		align-items: center;

		.tabs {
			flex: 1;
			overflow: hidden;
			box-sizing: border-box;
			padding-left: 30rpx;
			padding-right: 30rpx;

			.tabs-scroll {
				display: flex;
				align-items: center;
				flex-wrap: nowrap;
				box-sizing: border-box;

				.tabs-scroll_item {
					// line-height: 60rpx;
					margin-right: 35rpx;
					flex-shrink: 0;
					 padding: 6rpx 12rpx;
					display: flex;
					justify-content: center;
					font-size: 16px;
					 
				}
			}
		}
	}


	.active {
		position: relative;
		color: #fff;
		font-weight: 800;
		border-radius: 20rpx;
		background-color: #ffbb00;
	}

 

	/* 隐藏滚动条,但依旧具备可以滚动的功能 */
	::v-deep.uni-scroll-view::-webkit-scrollbar {
		display: none
	}
</style>

代码实现

<template>
	<view>
		<tags :tablist='category[0].list' :defaultSelectIndex='defaultSelectIndex0' @select='change'></tags>
		<tags :tablist='category[1].list' :defaultSelectIndex='defaultSelectIndex1' @select='change'></tags>
		<tags :tablist='category[2].list' :defaultSelectIndex='defaultSelectIndex2' @select='change'></tags>
        <view class="">{{content}}</view>
		
	</view>

</template>

<script lang="ts" setup>
	import { ref, watch } from "vue";
	const defaultSelectIndex0 = ref(0)
	const defaultSelectIndex1 = ref(0)
	const defaultSelectIndex2 = ref(0)
	const content = ref<string>()

	const category = ref([
		{
			list: [
				{
					id: 1,
					title: '全部',
					type: 0
				},
				{
					id: 2,
					title: '悬疑',
					type: 0
				},
				{
					id: 3,
					title: '玄幻',
					type: 0
				},
				{
					id: 4,
					title: '都市',
					type: 0
				},
				{
					id: 5,
					title: '科幻',
					type: 0
				},
				{
					id: 6,
					title: '历史',
					type: 0
				},
				{
					id: 7,
					title: '同人',
					type: 0
				},
				{
					id: 8,
					title: '仙侠',
					type: 0
				}
			]
		},
		{
			list: [
				{
					id: 1,
					title: '全部',
					type: 1
				},
				{
					id: 2,
					title: '连载',
					type: 1
				},
				{
					id: 3,
					title: '完结',
					type: 1
				},
				{
					id: 4,
					title: '今日更新',
					type: 1
				}
			]
		},
		{
			list: [
				{
					id: 1,
					title: '全部',
					type: 2
				},
				{
					id: 2,
					title: '10万字一下',
					type: 2
				},
				{
					id: 3,
					title: '10万~20万',
					type: 2
				},
				{
					id: 4,
					title: '20万~30万',
					type: 2
				},
				{
					id: 5,
					title: '30万~40万',
					type: 2
				},
				{
					id: 6,
					title: '40万字以上',
					type: 2
				}
			]
		},

	])
	const change = (value, index) => {
		if (value.type === 0) {
			defaultSelectIndex0.value = index
			defaultSelectIndex1.value = 0
			defaultSelectIndex2.value = 0
		} else if (value.type === 1) {
			defaultSelectIndex1.value = index
			defaultSelectIndex2.value = 0
		} else if (value.type === 2) {
			defaultSelectIndex2.value = index
		}
	}
	 
	watch(() => [ defaultSelectIndex0.value, defaultSelectIndex1.value, defaultSelectIndex2.value], () => {
		 
		 content.value ='发送网络请求:'+category.value[0].list[defaultSelectIndex0.value].title
		 + category.value[1].list[defaultSelectIndex1.value].title
		 + category.value[2].list[defaultSelectIndex2.value].title
		 console.log(12121);
	}, {
		immediate: true
	})
</script>

<style>

</style>

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
根据提供的引用内容,我们可以使用uni-app的canvas组件实现电子签名。以下是实现步骤: 1. 在uni-app项目中安装canvas组件:`npm install --save uni-canvas` 2. 在需要使用电子签名的页面中引入canvas组件: ```vue <template> <view> <canvas :canvas-id="canvasId" @touchstart="handleTouchStart" @touchmove="handleTouchMove" @touchend="handleTouchEnd"></canvas> <button @click="clearCanvas">清除</button> <button @click="saveCanvas">保存</button> </view> </template> <script> import uniCanvas from 'uni-canvas'; export default { components: { uniCanvas }, data() { return { canvasId: 'myCanvas', ctx: null, isDrawing: false, lastX: 0, lastY: 0 } }, mounted() { this.ctx = uni.createCanvasContext(this.canvasId, this); }, methods: { handleTouchStart(e) { this.isDrawing = true; this.lastX = e.touches[0].x; this.lastY = e.touches[0].y; }, handleTouchMove(e) { if (!this.isDrawing) return; this.ctx.beginPath(); this.ctx.moveTo(this.lastX, this.lastY); this.ctx.lineTo(e.touches[0].x, e.touches[0].y); this.ctx.stroke(); this.lastX = e.touches[0].x; this.lastY = e.touches[0].y; }, handleTouchEnd() { this.isDrawing = false; }, clearCanvas() { this.ctx.clearRect(0, 0, uni.upx2px(375), uni.upx2px(500)); }, saveCanvas() { uni.canvasToTempFilePath({ canvasId: this.canvasId, success: function(res) { uni.saveImageToPhotosAlbum({ filePath: res.tempFilePath, success: function() { uni.showToast({ title: '保存成功' }); } }); } }, this); } } } ``` 在模板中,我们使用canvas组件来绘制电子签名,同时添加了两个按钮,一个用于清除画布,一个用于保存签名。在脚本中,我们使用uni.createCanvasContext方法获取canvas上下文,然后监听touch事件来绘制签名。最后,我们使用uni.canvasToTempFilePath方法将canvas转换为图片,并使用uni.saveImageToPhotosAlbum方法将图片保存到相册中。 3. 在tsconfig.json文件中添加以下配置: ```json { "compilerOptions": { "target": "es6", "module": "esnext", "moduleResolution": "node", "strict": true, "jsx": "preserve", "sourceMap": true, "resolveJsonModule": true, "esModuleInterop": true, "lib": [ "esnext", "dom", "dom.iterable", "scripthost" ] }, "include": [ "src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx" ], "exclude": [ "node_modules" ] } ``` 在tsconfig.json文件中,我们将target设置为es6,module设置为esnext,同时开启了strict模式。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值