uni-app 实现nvue中list相互嵌套,子list的滚动效果。结构为list_swiper_list或list_swiper_waterfall
场景uni-app平台的nvue。不是vue,vue的话很容易。不过vue性能不如nvue需求页面高度>屏幕高度时,页面会滚动。但是页面的最底部是一个可以左右切换的长列表。左右切换的元素一般用 swiper长列表的话,也只能用 list 或 waterfall那么结构就是<template><view><view>我是页面的其中内容</view>
场景
uni-app平台的nvue。不是vue。
vue的长列表,优化的好,性能也不差的。如何优化 请看我的其他文字
关于官方给的实例
https://github.com/dcloudio/hello-uniapp/tree/master/pages/template/swiper-list-nvue
上方就是官方给的案例,但是代码很多,特别难以理解。
而且存在两个bug。一个是ios中子list无法滚动。另一个是下面提到的scrollToElement问题。不过这两个问题,本demo已经修复了
需求
页面高度>屏幕高度时,页面会滚动。但是页面的最底部是一个可以左右切换的长列表。
左右切换的元素肯定用 swiper
长列表的话,也只能用 list 或 waterfall
那么结构就是
<template><view>
<view>我是页面的其中内容</view>
<swiper>
<swiper-item v-for="(value, key) in new Array(4)" :index="key">
<waterfall ref="waterfall">
<cell v-for="(item, index) in new Array(30)" :index="index">
我是可以左右切换,和垂直滚动的内容
左右切换由swiper 实现
垂直滚动由waterfall 实现
</cell>
</waterfall>
</swiper-item>
</swiper>
</view></template>
但这样子肯定是不行的。当你下滑到页面底部时,会发现waterfallfu是无法实现垂直滚动的。
必须把页面的根目录改为list
<template><list id="pageId">
<cell style="height: 500px;">
<view>我是页面的其中内容</view>
</cell>
<cell>
<swiper>
<swiper-item v-for="(value, key) in new Array(4)" :index="key">
<waterfall ref="waterfall">
<cell v-for="(item, index) in new Array(30)" :index="index">
我是可以左右切换,和垂直滚动的内容
左右切换由swiper 实现
垂直滚动由waterfall 实现
</cell>
</waterfall>
</swiper-item>
</swiper>
</cell>
</list></template>
但其实还是不行的,因为还需要js的配合
this.$refs.waterfall[this.activeIndex].setSpecialEffects({
id: 'pageId',
headerHeight: 500//这里的高度等于waterfall上面的所有元素的高度
});
并且每次swiper切换都需要执行这个js逻辑
============================
还有一个问题,如果列表1已经滚动了一段距离了,再从列表1切换到列表2,就会产生一个bug,具体看下面视频文件
https://vkceyugu.cdn.bspapp.com/VKCEYUGU-bf16ecad-1cbc-421f-9785-8a609ca4eb52/66a22f8b-de5b-42c8-b041-55b169efffc2.mp4
所以切换完成之后,切换前的列表需要回到顶部,用的是scrollToElement,
但是scrollToElement只能实现最外围的list滚动到某个位置。不能实现子list滚动到某个位置。
想实现这个功能,只能让子list以组件的方式引入,然后在组件中使用scrollToElement,就可以操控子list回到顶部了
============================
下面是demo
demo.nvue
<template><list id="pageId" bounce="false" show-scrollbar="false" fixFreezing="true">
<cell>
<view class="" ref="header">
<text style="line-height: 500px;background-color grey;">head</text>
<scroll-view class="nav" scroll-x="true" show-scrollbar="false" @scroll="scrollLeft = $event.detail.scrollLeft">
<text ref="navItem" :class="['text', {active: index === activeIndex}]" v-for="(value, index) in navList" @click="activeIndex = index">列表{{index}}</text>
<view class="xian" :style="{left: navXianLeft+'px',width: navXianWidth+'px'}"></view>
</scroll-view>
</view>
<swiper class="swiper" :current="activeIndex" :style="{height: swiperHeight+'px'}" @change="change">
<swiper-item class="swiperItem" v-for="(value, index) in navList" :key="index">
<demoList ref="demoList" :height="swiperHeight" :index="index" :dataList="dataList"></demoList>
</swiper-item>
</swiper>
</cell>
</list></template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom')
// #endif
import demoList from '@/components/demoList.nvue'
export default {
components: {demoList},
data(){
return {
activeIndex: 0,
swiperHeight: 100,
navList: [],
dataList: [],
navXianLeft: 0,
navXianWidth: 0,
scrollLeft: 0
}
},
methods: {
change: function(event){
this.activeIndex = event.detail.current;
this.xian()
},
xian: function(){//nav下面的那条线的水平位置调整
dom.getComponentRect(this.$refs.navItem[this.activeIndex], (option) => {
this.navXianLeft = option.size.left + this.scrollLeft
this.navXianWidth = option.size.width
})
},
xiding: function(index){//吸顶
dom.getComponentRect(this.$refs.header, (option) => {
this.$refs.demoList[index].qiehuan(option.size.height)
})
}
},
onLoad(){
this.navList = new Array(4)
this.dataList = new Array(30)
},
onReady(){
this.swiperHeight = this.$store.state.htmlHeight
this.xian()
this.xiding(0)
},
watch: {
'activeIndex': function(newValue, oldValue){
this.$refs.demoList[oldValue].goTop()
this.xiding(newValue)
}
}
}
</script>
<style lang="scss">
.nav{
flex-direction: row;
background-color: #FFF;
.text{
width: 300rpx;
text-align: center;
font-size: 30rpx;
color: rgba(0,0,0,0.5);
line-height: 64rpx;
&.active{
color: #000;
}
}
.xian{
position: absolute;
bottom: 0;
height: 4rpx;
background-color: blue;
}
}
</style>
demoList.nvue
<template><waterfall ref="list" bounce="true" show-scrollbar="false" column-count="2" fixFreezing="true">
<!-- waterfall 属性说明
bounce = 回弹效果,ios中list嵌套的list(或waterfall),必须设置bounce为true。否则子list无法滚动
fixFreezing = ios才需要配置的,具体作用不详。官方说要配置
show-scrollbar = 显示滚动条
-->
<cell v-for="(value, key) in dataList" :key="key">
<view v-if="key === 0" ref="goTop"></view>
<text class="text">{{index}}=>{{key}}</text>
</cell>
</waterfall></template>
<script>
// #ifdef APP-NVUE
const dom = weex.requireModule('dom')
// #endif
export default {
props:{swiperHeight: Number,index: Number,dataList: Array},
data(){return {}},
methods: {
qiehuan: function(height){
this.$refs.list.setSpecialEffects({
id: 'pageId',
headerHeight: height
});
},
goTop: function(){
dom.scrollToElement(this.$refs.goTop[0], {
animated: false//无动画
})
}
}
}
</script>
<style lang="scss">
.text{
background-color: #ebebeb;
margin-left: 12px;
margin-right: 12px;
margin-top: 12px;
padding: 20px;
background-color: #fff;
border-radius: 5px;
}
</style>
更多推荐
所有评论(0)