|
|
楼主 |
发表于 2026-7-22 22:30:19
|
显示全部楼层
六、模板与插槽
1. 普通 item 模板
通过 type 属性区分不同类型的 item,数据项的 type 字段与之匹配:
[code=vue]<qt-grid-view :list-data="listData" :spanCount="4">
<!-- type=1:标准卡片 -->
<qt-view type="1" :focusable="true" eventClick eventFocus>
<qt-image src="${cover}" style="width: 260px; height: 360px;" />
<qt-text text="${title}" :lines="1" :ellipsizeMode="3" />
</qt-view>
<!-- type=2:带角标的卡片 -->
<qt-view type="2" :focusable="true" eventClick>
<qt-image src="${cover}" />
<qt-view showIf="${isVip}" class="vip-badge">
<qt-text text="VIP" />
</qt-view>
</qt-view>
</qt-grid-view>[/code]
对应数据:
[code=ts]listData.value = [
{ type: 1, cover: '...', title: '普通卡片' },
{ type: 2, cover: '...', isVip: true }
][/code]
2. 内置 type(重要)
| type 值 | 用途 | 设置方式 | | 1002 | 加载更多 loading | 通过 v-slot:loading 插槽 | | 1003 | 分页结束提示语 | 直接在组件内放置带 type="1003" 的元素 |
[code=vue]<qt-grid-view penPage="true" :loadMore="loadMore" :pageSize="30">
<!-- 普通 item -->
<qt-view type="1" :focusable="true" eventClick>...</qt-view>
<!-- loading 模板(type 必须是 1002) -->
<template v-slot:loading>
<qt-loading-view :type="1002" name="loading" color="#409eff"
style="height: 40px; width: 40px;" :focusable="false" />
</template>
<!-- 分页结束提示(type 必须是 1003) -->
<qt-text :type="1003" text="已经到底啦"
style="width: 1920px; height: 100px;" gravity="center" :focusable="false" />
</qt-grid-view>[/code]
3. header / footer 插槽
[code=vue]<qt-grid-view :list-data="listData" :spanCount="5">
<template v-slot:header>
<qt-view type="1003" name="type0" :focusable="false">
<qt-text text="${assetTitle}" />
</qt-view>
</template>
<!-- 普通 item -->
<qt-view type="1" :focusable="true" eventClick>...</qt-view>
<template v-slot:footer>
<!-- 底部固定内容 -->
</template>
<template v-slot:loading>
<!-- loading -->
</template>
</qt-grid-view>[/code]
七、分页加载
1. 配置分页
[code=vue]<qt-grid-view
ref="gridViewRef"
:list-data="listData"
:spanCount="6"
penPage="true"
:pageSize="30"
:preloadNo="5"
:listenBoundEvent="true"
:loadMore="loadMore"
:loadingDecoration="{ left: 950, top: 20, bottom: 20 }"
>
<qt-view type="1" :focusable="true" eventClick>
<qt-text text="${text}" />
</qt-view>
<template v-slot:loading>
<qt-loading-view :type="1002" name="loading" color="rgba(255,255,255,0.3)" />
</template>
<qt-text :type="1003" text="已经到底啦" gravity="center" :focusable="false" />
</qt-grid-view>[/code]
2. loadMore 回调
[code=ts]const loadMore = async (pageNo: number) => {
const res = await fetchMoreData(pageNo)
if (res.length > 0) {
// 拼接到现有数据
listData.value = listData.value.concat(res)
} else {
// 数据加载完毕,结束分页
gridViewRef.value.stopPage(true) // true: 显示 "已经到底啦" 提示
// gridViewRef.value.stopPage() // 不带提示
}
}[/code]
3. 预加载触发时机
当 openPage=true 且 listenBoundEvent=true 时,组件在 item-bind 事件中判断:当绑定到倒数第 preloadNo 条数据时,自动调用 loadMore(pageNo+1)。
八、组件方法
通过 ref 调用:
| 方法 | 说明 | | init(data, isInit?) | 旧版数据初始化方式,返回响应式数组引用(推荐用 listData 替代) | | stopPage(isTip?) | 结束分页,isTip=true 显示 "已经到底啦" | | restartPage() | 重置分页,重新从第 1 页加载(仅 init 模式生效) | | setItemFocused(pos) | 让指定位置 item 获取焦点 | | scrollToFocused(pos) | 滚动到并聚焦指定位置 | | setItemSelected(pos, bool) | 设置选中状态 | | scrollToSelected(pos, bool) | 滚动到并选中 | | setInitPosition(pos) | 设置初始位置 | | updateItemProps(pos, name, data) | 局部更新某个 item 的某个属性 | | insertItem(pos, data) | 在指定位置插入数据 | | scrollToPosition(pos) | 滚动到指定位置 | | scrollToTop() | 滚动到顶部 |
通过 qt 全局 API 调用(基于 sid)
[code=ts]// 给组件加 sid
<qt-grid-view sid="my_grid" ... />
// 通过 sid 调用
qt.gridView.scrollToIndex('my_grid', 0, 0)
qt.gridView.scrollToPosition('my_grid', 0, 0)[/code]
九、两种数据驱动方式对比
方式一:listData(推荐)
[code=ts]import { qtRef } from '@quicktvui/quicktvui3'
const listData = qtRef<QTListViewItem[]>()
// 初始化
listData.value = getData()
// 追加
listData.value = listData.value.concat(newData)
// 清空
listData.value = []
// 重置
listData.value = newData[/code]
特点:声明式、自动监听数组变化(push/splice/concat/pop 均可)。
方式二:init 函数(兼容旧版)
[code=ts]const gridViewRef = ref()
let listDataRec: Array<QTGridViewItem> = []
defineExpose({
onESCreate() {
const arr = getData()
listDataRec = gridViewRef.value.init(arr)
}
})
// 后续操作直接操作 listDataRec
listDataRec.push(newItem)
listDataRec.splice(0, 2)
listDataRec[0].title.text = '修改标题' // 修改 item 字段[/code]
特点:命令式、返回响应式数组引用,需自行管理。适合需要精细控制单个 item 字段的场景。
十、数据操作示例
[code=ts]// push 单条
listDataRec.push(item)
// push 多条
listDataRec.push(...items)
// splice 删除
listDataRec.splice(2, 1) // 从索引 2 开始删 1 条
listDataRec.splice(0) // 清空
// splice 替换
listDataRec.splice(4, 2, ...newItems)
// splice 插入
listDataRec.splice(4, 0, ...newItems)
// concat 拼接
listDataRec = listDataRec.concat(newItems)
// pop 删除末尾
listDataRec.pop()[/code]
|
|