Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Accustomed_
hello uni-app x
提交
2c9ba045
H
hello uni-app x
项目概览
Accustomed_
/
hello uni-app x
与 Fork 源项目一致
Fork自
DCloud / hello uni-app x
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
H
hello uni-app x
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
2c9ba045
编写于
8月 22, 2023
作者:
H
hdx
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
long-list: 调整为 swiper-list 结构
上级
1cdd1c58
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
369 addition
and
137 deletion
+369
-137
pages/template/long-list/long-list-page.uvue
pages/template/long-list/long-list-page.uvue
+213
-0
pages/template/long-list/long-list.uvue
pages/template/long-list/long-list.uvue
+156
-137
static/fonts/icon-star.ttf
static/fonts/icon-star.ttf
+0
-0
未找到文件。
pages/template/long-list/long-list-page.uvue
0 → 100644
浏览文件 @
2c9ba045
<template>
<list-view class="list" ref="listView" @scrolltolower="loadData">
<list-item class="list-item" v-for="(item, index) in dataList" :key="index">
<view class="list-item-icon">
<image class="list-item-icon-image" :src="item.plugin_img_link"></image>
</view>
<view class="list-item-fill">
<view class="flex-row">
<text class="title">{{item.plugin_name}}</text>
</view>
<view class="description">
<text class="description-text">{{item.plugin_intro}}</text>
</view>
<text class="icon-star star">{{getStarUnicode(item.score)}}</text>
<view class="tag-list">
<text class="tag-item" v-for="(item2, index2) in item.tags" :key="index2">{{item2}}</text>
</view>
<view class="flex-row update-date">
<text class="update-date-text">更新日期</text>
<text class="update-date-value">{{item.update_date}}</text>
<text class="author">{{item.author_name}}</text>
</view>
</view>
</list-item>
</list-view>
</template>
<script>
const SERVER_URL = "https://ext.dcloud.net.cn/plugin/uniappx-plugin-list"
const PAGE_SIZE = 10; // 最大值 10
type ListItem = {
plugin_id : number,
plugin_img_link : string,
plugin_name : string,
plugin_intro : string,
score : number,
tags : Array<string>,
update_date : string,
author_name : string,
}
type ResponseDataType = {
code : number,
data : ListItem[]
}
export default {
props: {
type: {
type: String,
default: ''
}
},
data() {
return {
loading: false,
dataList: [] as ListItem[],
isEnded: false,
$currentPage: 0
}
},
mounted() {
uni.loadFontFace({
global: false,
family: 'UtsIconsFontFamily',
source: '/static/fonts/icon-star.ttf'
})
this.loadData()
},
methods: {
loadData() {
if (this.loading || this.isEnded) {
return
}
this.loading = true
// TODO request data 没有拼接到 url 中,暂时手动拼接
uni.request({
url: `${SERVER_URL}?type=${this.type}&page=${this.$currentPage}&page_size=${PAGE_SIZE}`,
data: {
type: this.type,
page: this.$currentPage,
page_size: PAGE_SIZE
},
dataType: '',
success: (res) => {
const responseData = JSON.parse<ResponseDataType>(res.data as string)
if (responseData == null) {
return
}
responseData.data.forEach((item) => {
this.dataList.push(item)
})
if (responseData.data.length <= 0) {
this.isEnded = true
} else {
this.$currentPage++
}
},
fail: (err) => {
console.log(err)
},
complete: () => {
this.loading = false
}
})
},
// score 0 ~ 50
getStarUnicode(score : Number) : string {
const fill_code = '\ue879'
const half_code = '\ue87a'
const null_code = '\ue87b'
const fillStarCount = parseInt(score / 10 % 10 + '')
const halfStarCount = score % 10 >= 5 ? 1 : 0
const nullStarCount = 5 - fillStarCount - halfStarCount
let result = ''
if (fillStarCount > 0) { result += fill_code.repeat(fillStarCount) }
if (halfStarCount > 0) { result += half_code.repeat(halfStarCount) }
if (nullStarCount > 0) { result += null_code.repeat(nullStarCount) }
return result
},
// onScroll(e : ScrollEvent) {
// console.log(e.detail.deltaY);
// }
}
}
</script>
<style>
.list {
flex: 1;
background-color: #ffffff;
}
.list-item {
flex-direction: row;
margin-top: 10px;
padding: 10px;
}
.list-item-icon {
position: relative;
}
.list-item-icon-image {
width: 80px;
height: 80px;
}
.list-item-fill {
flex: 1;
margin-left: 15px;
}
.description {
line-height: 14px;
}
.description-text {
font-size: 13px;
color: #666;
line-height: 19px;
}
.icon-star {
font-family: "UtsIconsFontFamily" !important;
font-size: 16px;
font-style: normal;
color: #ffca3e;
letter-spacing: 3px;
}
.tag-list {
flex-direction: row;
margin-top: 5px;
}
.tag-item {
font-size: 14px;
background-color: #EFF9F0;
color: #639069;
border-radius: 20px;
margin-right: 5px;
padding: 2px 5px;
}
.update-date {
margin-top: 10px;
}
.update-date-text {
font-size: 12px;
color: #888888;
}
.update-date-value {
font-size: 12px;
color: #777777;
margin-left: 5px;
}
.author {
font-size: 12px;
color: #008000;
margin-left: auto;
}
</style>
\ No newline at end of file
pages/template/long-list/long-list.uvue
浏览文件 @
2c9ba045
<template>
<template>
<list-view class="list" @scrolltolower="loadData">
<scroll-view class="page" :scroll-top="pageScrollTop">
<list-item class="list-item" v-for="(item, index) in dataList" :key="index">
<view class="search-bar">
<view class="list-item-icon">
<input placeholder="搜索..." />
<image class="list-item-icon-image" :src="item.author_avatar_link"></image>
</view>
</view>
<view class="swiper-list">
<view class="list-item-fill">
<scroll-view class="swiper-tabs" :scroll-left="tabsScrollLeft" :scroll-x="true" :show-scrollbar="false">
<view class="flex-row">
<view>
<text class="title">{{item.plugin_name}}</text>
<view class="flex-row">
<view class="swiper-tabs-item" v-for="(item, index) in swiperList" :id="'swipertab' + index" ref="swipertab"
:key="index" @click="onTabClick(index)">
<text class="swiper-tabs-item-text"
:class="swiperIndex==index ? 'uni-tab-item-title-active' : ''">{{item.name}}</text>
</view>
</view>
<view class="swiper-tabs-indicator">
<view class="swiper-tabs-underline"
:style="{left: swiperIndicatorLineLeft + 'px', width: swiperIndicatorLineWidth + 'px'}"></view>
</view>
</view>
</view>
<view class="description">
</scroll-view>
<text class="description-text">{{item.plugin_intro}}</text>
<swiper class="swiper-view" ref="swiper" :current="swiperIndex" @change="onSwiperChange"
</view>
@transition="onSwiperTransition" @animationfinish="onSwiperAnimationfinish">
<view class="tag-list">
<swiper-item class="swiper-item" v-for="(item, index) in swiperList" :key="index">
<text class="tag-item" v-for="(item2, index2) in item.tags" :key="index2">{{item2}}</text>
<long-page :type="item.type"></long-page>
</view>
</swiper-item>
<!-- <uts-rate></uts-rate> -->
</swiper>
<view class="flex-row update-date">
</view>
<text class="update-date-text">更新日期</text>
</scroll-view>
<text class="update-date-value">{{item.update_date}}</text>
<text class="author">{{item.author_name}}</text>
</view>
</view>
</list-item>
</list-view>
</template>
</template>
<script>
<script>
const SERVER_URL = "https://ext.dcloud.net.cn/plugin/uniappx-plugin-list"
import longPage from './long-list-page.uvue';
const PAGE_SIZE = 10; // 最大值 10
type SwiperTabsItem = {
type ListItem = {
left : number,
plugin_id : number,
width : number
author_avatar_link : string,
}
plugin_name : string,
plugin_intro : string,
type SwiperViewItem = {
tags : Array<string>,
type : string,
update_date : string,
name : string
author_name : string,
}
}
// 测试数据
type ResponseDataType = {
const CategoryData = [
code : number,
{
data : ListItem[]
type: 'UpdatedDate',
}
name: '最新上架'
} as SwiperViewItem,
{
type: 'FreeHot',
name: '免费热榜'
} as SwiperViewItem,
{
type: 'PaymentHot',
name: '付费热榜'
} as SwiperViewItem,
{
type: 'HotList',
name: '热门总榜'
} as SwiperViewItem
]
export default {
export default {
components: {
longPage
},
data() {
data() {
return {
return {
loading: false,
pageScrollTop: 0,
dataList: [] as ListItem[],
swiperList: [] as SwiperViewItem[],
isEnded: false,
swiperIndex: -1,
$currentPage: 0
tabsScrollLeft: 0,
swiperIndicatorLineLeft: 0,
swiperIndicatorLineWidth: 0,
$lastSwiperIndex: 0,
$swiperWidth: 0,
$swiperTabsRect: [] as SwiperTabsItem[],
$isTap: false
}
}
},
},
onLoad() {
onLoad() {
this.loadData()
CategoryData.forEach((item) => {
this.swiperList.push(item)
})
},
onReady() {
this.$swiperWidth = (this.$refs["swiper"] as INode)?.offsetWidth as number
this.queryTabItemsSize()
this.setSwiperIndex(0, true)
},
},
methods: {
methods: {
loadData() {
onTabClick(index : number) {
if (this.loading || this.isEnded) {
this.setSwiperIndex(index, false)
},
onSwiperChange(e : SwiperChangeEvent) {
this.setSwiperIndex(e.detail.current, false)
},
onSwiperTransition(e : SwiperTransitionEvent) {
const offsetX = e.detail.dx;
let moveToIndex = offsetX > 0 ? this.$lastSwiperIndex + 1 : this.$lastSwiperIndex - 1
if (moveToIndex < 0) { moveToIndex = 0 }
if (moveToIndex > this.$swiperTabsRect.length - 1) { moveToIndex = this.$swiperTabsRect.length - 1 }
const percentage = Math.abs(offsetX) / this.$swiperWidth;
const currentSize = this.$swiperTabsRect[this.$lastSwiperIndex];
const moveToSize = this.$swiperTabsRect[moveToIndex];
const indicatorlineL = currentSize.left + (moveToSize.left - currentSize.left) * percentage;
const indicatorlineW = currentSize.width + (moveToSize.width - currentSize.width) * percentage;
this.updateTabIndicator(indicatorlineL, indicatorlineW);
//console.log(this.$lastSwiperIndex, moveToIndex, offsetX, this.$swiperWidth, percentage);
},
onSwiperAnimationfinish(e : SwiperAnimationFinishEvent) {
this.$lastSwiperIndex = e.detail.current;
// console.log("onSwiperAnimationfinish", e.detail.current);
// this.setSwiperIndex(e.detail.current, true);
},
queryTabItemsSize() {
this.$swiperTabsRect.length = 0;
const tabs = this.$refs["swipertab"] as INode[]
tabs.forEach((node) => {
this.$swiperTabsRect.push({
left: node.offsetLeft as number,
width: node.offsetWidth as number
} as SwiperTabsItem)
})
},
setSwiperIndex(index : Number, updateIndicator : Boolean) {
if (this.swiperIndex === index) {
return
return
}
}
this.swiperIndex = index
this.loading = true;
if (updateIndicator) {
this.updateTabIndicator(this.$swiperTabsRect[index].left, this.$swiperTabsRect[index].width)
// TODO request data 没有拼接到 url 中,暂时手动拼接
}
uni.request({
},
url: `${SERVER_URL}?page=${this.$currentPage}&page_size=${PAGE_SIZE}`,
updateTabIndicator(left : Number, width : Number) {
data: {
this.swiperIndicatorLineLeft = left
page: this.$currentPage,
this.swiperIndicatorLineWidth = width
page_size: PAGE_SIZE
const offset = left + width / 2
},
if (offset > this.$swiperWidth / 2) {
dataType: '',
this.tabsScrollLeft = offset - this.$swiperWidth / 2
success: (res) => {
}
const responseData = JSON.parse<ResponseDataType>(res.data as string)
if (responseData == null) {
return
}
responseData.data.forEach((item) => {
this.dataList.push(item)
})
this.isEnded = responseData.data.length <= 0;
this.$currentPage++
},
fail: (err) => {
console.log(err);
},
complete: () => {
this.loading = false;
}
})
}
}
}
}
}
}
...
@@ -103,86 +155,53 @@
...
@@ -103,86 +155,53 @@
flex-direction: row;
flex-direction: row;
}
}
.
list
{
.
page
{
flex: 1;
flex: 1;
background-color: #ffffff;
}
}
.list-item {
.search-bar {
flex-direction: row;
margin-top: 10px;
padding: 10px;
padding: 10px;
}
}
.
list-item-icon
{
.
swiper-list
{
position: relative
;
height: 100%
;
}
}
.list-item-icon-image {
.swiper-tabs {
width: 80px;
background-color: #ffffff;
height: 80px;
}
.list-item-icon-index {
font-size: 12px;
color: #cccccc;
position: absolute;
left: 2px;
bottom: 2px;
}
.list-item-fill {
flex: 1;
margin-left: 15px;
}
.index {
margin-left: 10px;
}
.description {
margin-top: 3px;
}
}
.description-text {
.swiper-tabs-item {
font-size: 13px;
padding: 12px 25px;
color: #666;
margin-top: 5px;
}
}
.
tag-lis
t {
.
swiper-tabs-item-tex
t {
flex-direction: row
;
color: #555
;
margin-top: 5
px;
font-size: 16
px;
}
}
.tag-item {
.swiper-tabs-item-text-active {
font-size: 14px;
color: #007AFF;
font-weight: bold;
background-color: #EFF9F0;
color: #639069;
border-radius: 20px;
margin-right: 5px;
padding: 2px 5px;
}
}
.update-date {
.swiper-tabs-indicator {
margin-top: 10px;
position: relative;
height: 2px;
}
}
.update-date-text {
.swiper-tabs-underline {
font-size: 12px;
position: absolute;
color: #888888;
top: 0;
bottom: 0;
width: 0;
background-color: #007AFF;
}
}
.update-date-value {
.swiper-view {
font-size: 12px;
flex: 1;
color: #777777;
margin-left: 5px;
}
}
.author {
.swiper-item {
font-size: 12px;
flex: 1;
color: #005000;
margin-left: auto;
}
}
</style>
</style>
\ No newline at end of file
static/fonts/icon-star.ttf
0 → 100644
浏览文件 @
2c9ba045
文件已添加
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录