首页IT科技uniapp下拉框(【uniapp】页面下拉刷新)

uniapp下拉框(【uniapp】页面下拉刷新)

时间2025-05-01 12:13:21分类IT科技浏览3119
导读:目录...

目录

一           、全局

二                 、局部

1     、一个页面一个下拉刷新

2      、一个页面多个下拉刷新(切换时滚动条回到顶部)

3                 、一个页面多个下拉刷新(切换时恢复滚动条位置)

一           、全局

修改pages.json的"enablePullDownRefresh": true,

{     "pages": [          {             "path": "pages/tabBar/dashboard/index",             "style": {                 "navigationBarTitleText": "项目管理",                 "enablePullDownRefresh": true,                 "navigationBarTextStyle": "white",                 "navigationBarBackgroundColor": "#374449"             }         },     ],     "globalStyle": {         "navigationBarTextStyle": "black",         "navigationBarTitleText": "管理平台",         "navigationBarBackgroundColor": "#F8F8F8",         "backgroundColor": "#F8F8F8"     }, }

页面中(onPullDownRefresh 处理函数和onLoad等生命周期函数同级 )

export default {     data() {             return {                 productList: [], //列表                 query: {                     keyword: , //搜索框                     pagesize: 10,                     page: 1,                 },                 total: 0, //总条数                 showTotal: true, //是否显示“下拉加载更多~            ”             }         },         // 下拉刷新         onPullDownRefresh() {             var allTotal = this.query.page * this.query.pagesize             //this.page为加载次数           ,this.pageSize为每一次加载的数据条数             if (allTotal < this.total) {                 //this.total为请求数据的总条数            。只要现有条数小于总条数就执行一下代码                 this.showTotal = true;                 this.query.page++;                 //加载次数递加                 this.getlist() //请求更多数据列表             } else {                 this.showTotal = false;             }             uni.stopPullDownRefresh();//停止刷新         }, }

二      、局部

我使用的是插件https://ext.dcloud.net.cn/plugin?id=343

插件文档https://www.mescroll.com/uni.html 

这个插件的还有相对应的案例我已经下载下来了                 ,到时候直接放到编辑器打开即可 链接:https://pan.baidu.com/s/1q6IB-mCdCQqcvKaZmzJtcg 提取码:e66j

我的需求是顶部内容固定不动     ,列表下拉刷新(没有页码      ,数据一次性展示) 

1                 、一个页面一个下拉刷新

页面使用

<template> <view class="details-container"> <view class="example-body"> <view v-for="(item,index) in tags" :key="index" :class="whichSelected===index?stateBtnSelected:stateBtnNoselect" :circle="true" @click="selectState(index)">{{item}}</view> </view> <view class="center" v-show="tabs===0"> <!-- 第一步:参数一个都不能少                 ,三个事件是固定的 --> <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption"> <Tree :list="list" :local=local></Tree> </mescroll-body> </view> </view> </template> <script> import Tree from ../../components/Tree/index.vue //第二步:引入 import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"; export default { mixins: [MescrollMixin],//第二步:引入 name: Details, components: { Tree, }, data() { return { tags: [], whichSelected: 0, //标签 tabs: 0, //标签对应页面 list: [], //列表 content: {}, //上一页数据 local: , //第三步:数据 //downOption和upOption的参数配置在mescroll-uni.js中查看 downOption: { auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback) }, upOption: { use: false, // 是否启用上拉加载; 默认true auto: false } }; }, onLoad(e) { let that = this this.local = uni.getLocale() this.content = JSON.parse(e.item) if (this.local === zh-Hans) { uni.setNavigationBarTitle({ title: that.content.Name, }) } else { uni.setNavigationBarTitle({ title: that.content.Name_EN, }) } this.GetFileListById() this.tags.push(this.$t(word.whole)) }, methods: { //第三步:事件 /*下拉刷新的回调 */ downCallback() { let that = this this.api.GetFileListById({ //调用接口 datagramsid: that.content.Id }).then(res => { that.list = res.data.Data this.$nextTick(() => { this.mescroll.endSuccess(this.list.length) }) }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) }, /*上拉 */ upCallback() { let that = this this.api.GetFileListById({ //调用接口 datagramsid: that.content.Id }).then(res => { that.list = res.data.Data let curPageLen = this.list.length; // 接口返回的是否有下一页 (true/false) let hasNext = false; setTimeout(() => { this.mescroll.endSuccess(curPageLen, hasNext) }, 20) }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) }, GetFileListById() { let that = this this.api.GetFileListById({ datagramsid: that.content.Id }).then(res => { that.list = res.data.Data }) }, } } </script>

2           、一个页面多个下拉刷新(切换时滚动条回到顶部)

多页tabs切换           ,实现下拉刷新(没有页码      ,数据一次性展示)                  ,每个tab页面内容都不相同

插件上说不能使用v-if           ,是因为使用了v-if就不能实现切换tabs恢复滚动条位置(v-if是创建和销毁,v-show是隐藏和显示)                。

但是我使用官方示例的代码重新加载列表数据或其他的方法都不行

// 详情返回列表,重新加载列表数据 onShow() { this.canReset && this.mescroll.resetUpScroll() // 重置列表数据为第一页 this.canReset && this.mescroll.scrollTo(0,0) // 重置列表数据为第一页时,建议把滚动条也重置到顶部,避免无法再次翻页的问题 this.canReset = true // 过滤第一次的onShow事件,避免初始化界面时重复触发upCallback, 无需配置auto:false // 注意: 子组件没有 onShow 的生命周期, 所以 // 对于 mescroll-more.vue 和 mescroll-swiper.vue 的返回刷新, 需更新 1.3.3 版本, 且参考对应示例的onShow写法 }

若是换成mescroll-body                 ,并且使用v-show会出现切换tabs滚动条位置一致                 ,也就是上一页滚动条在哪,下一页的滚动条就在哪     。找了好久也不知道问题出在哪里           ,最后我只能写成组件使用mescroll-uni+v-if的方法            。

但是你们使用还是要先根据官网来做                 ,如果出现我这样的问题再安装我的方法做 

第一步:创建组件放置tabs所对应的页面(这里我就只写一个子组件的格式)

pages/word/components/all.vue

注意:子组件使用onShow、onLoad无效     ,需要写在created中才行 

<template> <!-- 不能用v-if (i: 每个tab页的专属下标; index: 当前tab的下标; 申明在 MescrollMoreItemMixin )--> <view v-if="i === index"> <mescroll-uni ref="mescrollRef0" top="92" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption"> <!-- 数据列表 --> <Tree :list="list" :local=local></Tree> </mescroll-uni> </view> </template> <script> import Tree from @/components/Tree/index.vue import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"; import MescrollMoreItemMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js"; export default { mixins: [MescrollMixin, MescrollMoreItemMixin], // 使用mixin (在main.js注册全局组件) components: { Tree, }, props: { i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) type: Number, default () { return 0 } }, tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传 type: Array, default () { return [] } } }, data() { return { list: [], //下载列表 local: , downOption: { auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback) }, upOption: { use: false, // 是否启用上拉加载; 默认true auto: false } } }, created() { this.local = uni.getLocale() }, methods: { /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */ downCallback() { this.mescroll.resetUpScroll() }, upCallback(page) { let pageNum = page.num this.api.GetFileTreeJson().then(res => { // console.log(res.data.Data) this.list = res.data.Data this.mescroll.endByPage(this.list.length, 1); //设置列表数据 if (page.num == 1) this.list = []; //如果是第一页需手动制空列表 this.list = this.list.concat(res.data.Data); //追加新数据 }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) }, } } </script>

pages/word/components/downitem.vue和上一个组件一致           ,只不过数据组件不一致                 ,多了一个获取列表的方法给父组件使用

<template> <!-- 不能用v-if (i: 每个tab页的专属下标; index: 当前tab的下标; 申明在 MescrollMoreItemMixin )--> <view v-if="i === index"> <mescroll-uni ref="mescrollRef1" @init="mescrollInit" top="92" :down="downOption" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick"> <DownTree :records="records" :local=local></DownTree> </mescroll-uni> </view> </template> <script> import DownTree from @/components/DownTree/index.vue import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"; import MescrollMoreItemMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js"; export default { mixins: [MescrollMixin, MescrollMoreItemMixin], components: { DownTree }, props: { i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) type: Number, default () { return 0 } }, tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传 type: Array, default () { return [] } } }, data() { return { records: [], //下载列表 local: , downOption: { auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback) }, upOption: { use: false, // 是否启用上拉加载; 默认true auto: false } } }, created() { this.local = uni.getLocale() }, methods: { /*下拉刷新的回调 */ downCallback() { this.mescroll.resetUpScroll() }, upCallback(page) { let pageNum = page.num this.api.GetWxUserDownloadList().then(res => { this.records = res.data.Data this.mescroll.endByPage(this.records.length, 1); //设置列表数据 if (page.num == 1) this.records = []; //如果是第一页需手动制空列表 this.records = this.records.concat(res.data.Data); //追加新数据 }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) }, getrecords() { this.api.GetWxUserDownloadList().then(res => { this.records = res.data.Data this.mescroll.endByPage(this.records.length, 1); //设置列表数据 if (page.num == 1) this.records = []; //如果是第一页需手动制空列表 this.records = this.records.concat(res.data.Data); //追加新数据 }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) }, } } </script>

第三步:在页面中使用pages/word/components/index.vue

<template> <view class="word-container"> <view class="example-body"> <view v-for="(item,index) in tags" :key="index" :class="tabIndex===index?stateBtnSelected:stateBtnNoselect" :circle="true" @click="tabChange(index)" @input="changeload" v-model="tabIndex">{{item}}</view> </view> <!-- 全部 --> <mescroll-all ref="mescrollItem0" :i="0" :index="tabIndex" :tabs="tags"> </mescroll-all> <!-- 下载记录 --> <MescrollDown ref="mescrollItem1" :i="1" :index="tabIndex" :tabs="tags"> </MescrollDown> </view> </template> <script> import MescrollAll from "./components/all.vue"; import MescrollDown from "./components/downitem.vue"; import MescrollMoreMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js"; export default { mixins: [MescrollMoreMixin], name: Word, components: { MescrollDown, MescrollAll, }, data() { return { tags: [], local: , tabIndex: 0,//标签对应页面 }; }, onLoad() { this.tags.push(this.$t(word.whole), this.$t(word.download)) uni.setNavigationBarTitle({ title: this.$t(pages.word), }) }, onShow() { this.tabIndex = this.$store.state.tabs this.local = uni.getLocale() if (this.whichSelected === 1) { const Token = uni.getStorageSync(GetPhone_Token) if (Token) { //点击下载列表tab的时候要判断有没有token     ,没有就要跳转到登录页      ,我登录成功后返回到这一页 //若是我不调用子组件的方法也就是获取列表数据                 ,会出现一直显示加载中           ,所以我这里调用了方法      ,下面的标签切换同理 this.$refs.mescrollItem1.getrecords() } else { uni.navigateTo({ url: /pages/login/index }); } } }, methods: { // 标签切换 tabChange(index) { this.whichSelected = index this.tabIndex = index this.$store.commit(SET_TABS, index) if (this.tabIndex === 1) { const Token = uni.getStorageSync(GetPhone_Token) if (Token) { this.$refs.mescrollItem1.getrecords() } else { uni.navigateTo({ url: /pages/login/index }); } } }, } } </script> <style lang="scss"> .vue-ref { padding: 0 !important; } .word { &container { position: relative; } } .left { display: flex; margin: 10px; } .example-body { display: flex; padding: 10px 20px; background-color: #fff; width: 100%; position: fixed; z-index: 2; } .center { position: absolute; top: 45px; width: 100%; // height: 100%; border-top: 1px solid #e5e5e5; } .stateBtnSelected { background-color: #bbe5ff; color: #1480cd !important; border-radius: 20px; font-size: 14px; height: 25px; line-height: 25px; // width: 60px; margin: 0 5px; padding: 0 15px; text-align: center; } .stateBtnNoselect { background-color: transparent; color: #8f939c !important; border: none !important; font-size: 14px; height: 25px; line-height: 25px; // width: 60px; margin: 0 5px; padding: 0 15px; text-align: center; } .slot-image { width: 30px; height: 30px; } .slot-box { margin-right: 10px; } .uni-list-item__container { align-items: center !important; line-height: 20px; } </style>

3                 、一个页面多个下拉刷新(切换时恢复滚动条位置)

如果tabs对应内容分别封装成各自组件                 ,子组件封装的时候使用mescroll-uni           ,并且使用v-show会出现当列表数据多页时切换tabs,恢复滚动条位置不准确并且会触发上拉这样的问题                 。但是如果我把他放在一个组件里就不会产生这样的问题

 第一步:组件pages/word/components/all.vue

Tree和DownTree组件使用的是uni-list的自定义插槽                 ,不知道为啥我使用uni-list-item就会触发一次上拉                 ,之后就不会了,但是不使用就不会触发

<template> <view class="word-container"> <!-- 使用这个切换tabs的时候           ,会触发上拉一次                 ,之后就不会再触发了 --> <!-- <uni-list> <uni-list-item v-for="(item,index) in records" :key=index :title="local===zh-Hans?item.filename:item.filename_EN" thumb-size="lg" :rightText="item.DownloadTime"> <template v-slot:header> <view class="slot-box"> <image v-if="item.fileExt===.mp4" class="slot-image" src="/static/shipin_lvhangyingxiang.png" mode="widthFix"> </image> <image v-else-if="item.fileExt===.pdf" class="slot-image" src="/static/pdfwenjian.png" mode="widthFix"> </image> <image v-else class="slot-image" src="/static/a-wenjianjiawenjian.png" mode="widthFix"> </image> </view> </template> </uni-list-item> </uni-list> --> <uni-list v-for="(item,j) in records" :key=j> <view :border="none" :padding="0" :spacing="0" style="padding:0" :is-shadow="false" :isFull="true"> <view class="card-title" style="display: flex;justify-content: space-between;"> <view> <image v-if="item.fileExt===.mp4" class="slot-image" src="/static/shipin_lvhangyingxiang.png" mode="widthFix"> </image> <image v-else-if="item.fileExt===.pdf" class="slot-image" src="/static/pdfwenjian.png" mode="widthFix"> </image> <image v-else class="slot-image" src="/static/a-wenjianjiawenjian.png" mode="widthFix"> </image> </view> <view class="title-box" style="display: flex;justify-content: space-between;width: 100%;align-items: center;"> <view class="">{{local===zh-Hans?item.filename:item.filename_EN}} </view> <view class="">{{item.DownloadTime}}</view> </view> </view> </view> </uni-list> </view> </template> <template> <!-- 不能用v-if (i: 每个tab页的专属下标; index: 当前tab的下标; 申明在 MescrollMoreItemMixin )--> <view v-show="i === index"> <mescroll-uni :ref="mescrollRef+i" top="92" @init="mescrollInit" @down="downCallback" @up="upCallback" :down="downOption" :up="upOption"> <!-- 数据列表 --> <!-- tab为0的时候 --> <Tree v-if="index===0" :list="list" :local=local></Tree> <!-- tab为1的时候 --> <DownTree v-else :records="records" :local=local></DownTree> </mescroll-uni> </view> </template> <script> import DownTree from @/components/DownTree/index.vue import Tree from @/components/Tree/index.vue import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"; import MescrollMoreItemMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js"; export default { mixins: [MescrollMixin, MescrollMoreItemMixin], // 使用mixin (在main.js注册全局组件) components: { Tree, DownTree }, props: { i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义) type: Number, default () { return 0 } }, tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传 type: Array, default () { return [] } } }, data() { return { list: [], //下载列表 local: , records: [], //下载列表 downOption: { auto: false // 不自动加载 (mixin已处理第一个tab触发downCallback) }, upOption: { use: false, // 是否启用上拉加载; 默认true auto: false } } }, created() { this.local = uni.getLocale() }, methods: { /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */ downCallback() { this.mescroll.resetUpScroll() }, upCallback(page) { if (this.index === 0) { let pageNum = page.num this.api.GetFileTreeJson().then(res => { // console.log(res.data.Data) this.list = res.data.Data this.mescroll.endByPage(this.list.length, 1); //设置列表数据 if (page.num == 1) this.list = []; //如果是第一页需手动制空列表 this.list = this.list.concat(res.data.Data); //追加新数据 }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) } else { this.api.GetWxUserDownloadList().then(res => { // console.log(res.data.Data) this.records = res.data.Data this.mescroll.endByPage(this.records.length, 1); //设置列表数据 if (page.num == 1) this.records = []; //如果是第一页需手动制空列表 this.records = this.records.concat(res.data.Data); //追加新数据 }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) } }, // 文件列表 GetFileTreeJson() { this.api.GetFileTreeJson().then(res => { // console.log(res.data.Data) this.list = res.data.Data this.mescroll.endByPage(this.list.length, 1); //设置列表数据 if (page.num == 1) this.list = []; //如果是第一页需手动制空列表 this.list = this.list.concat(res.data.Data); //追加新数据 }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) }, getrecords() { this.api.GetWxUserDownloadList().then(res => { // console.log(res.data.Data) this.records = res.data.Data this.mescroll.endByPage(this.records.length, 1); //设置列表数据 if (page.num == 1) this.records = []; //如果是第一页需手动制空列表 this.records = this.records.concat(res.data.Data); //追加新数据 }).catch(() => { //联网失败, 结束加载 this.mescroll.endErr(); }) }, } } </script>

第二步:页面使用pages/word/components/index.vue

<template> <view class="word-container"> <view class="example-body"> <view v-for="(item,index) in tags" :key="index" :class="tabIndex===index?stateBtnSelected:stateBtnNoselect" :circle="true" @click="tabChange(index)" @input="changeload" v-model="tabIndex">{{item}}</view> </view> <mescrollItem0 ref="mescrollItem0" :i="0" :index="tabIndex" :tabs="tags"> </mescrollItem0> <mescrollItem0 ref="mescrollItem1" :i="1" :index="tabIndex" :tabs="tags"> </mescrollItem0> </view> </template> <script> import mescrollItem0 from "./components/all.vue"; import mescrollItem1 from "./components/downitem.vue"; // import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js"; import MescrollMoreMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js"; export default { mixins: [MescrollMixin], name: Word, components: { mescrollItem0, mescrollItem1, }, data() { return { tags: [], list: [], records: [], //下载列表 local: , tabIndex: 0,//标签对应页面 }; }, onLoad() { this.tags.push(this.$t(word.whole), this.$t(word.download)) uni.setNavigationBarTitle({ title: this.$t(pages.word), }) }, onShow() { this.whichSelected = this.$store.state.tabs this.tabIndex = this.$store.state.tabs this.local = uni.getLocale() if (this.whichSelected === 1) { const Token = uni.getStorageSync(GetPhone_Token) if (Token) { this.$refs.mescrollItem1.getrecords() } else { uni.navigateTo({ url: /pages/login/index }); } } }, methods: { // 标签切换 tabChange(index) { this.whichSelected = index this.tabIndex = index this.$store.commit(SET_TABS, index) if (this.tabIndex === 1) { const Token = uni.getStorageSync(GetPhone_Token) if (Token) { this.$refs.mescrollItem1.getrecords() } else { uni.navigateTo({ url: /pages/login/index }); } } }, } } </script> <style lang="scss"> .vue-ref { padding: 0 !important; } .word { &container { position: relative; } } .left { display: flex; margin: 10px; } .example-body { display: flex; padding: 10px 20px; background-color: #fff; width: 100%; position: fixed; z-index: 2; } .center { position: absolute; top: 45px; width: 100%; // height: 100%; border-top: 1px solid #e5e5e5; } .stateBtnSelected { background-color: #bbe5ff; color: #1480cd !important; border-radius: 20px; font-size: 14px; height: 25px; line-height: 25px; // width: 60px; margin: 0 5px; padding: 0 15px; text-align: center; } .stateBtnNoselect { background-color: transparent; color: #8f939c !important; border: none !important; font-size: 14px; height: 25px; line-height: 25px; // width: 60px; margin: 0 5px; padding: 0 15px; text-align: center; } .slot-image { width: 30px; height: 30px; } .slot-box { margin-right: 10px; } .uni-list-item__container { align-items: center !important; line-height: 20px; } </style>

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
vue的组件通信有哪些(vue组件间通信全面讲解) 新网站优化方案怎么写(新网站优化方案有哪些)