Full Code of mescroll/mescroll for AI

master 465652855e3b cached
223 files
894.5 KB
344.8k tokens
99 symbols
1 requests
Download .txt
Showing preview only (963K chars total). Download the full file or copy to clipboard to get everything.
Repository: mescroll/mescroll
Branch: master
Commit: 465652855e3b
Files: 223
Total size: 894.5 KB

Directory structure:
gitextract_6t70kfgo/

├── LICENSE
├── README.md
├── mescroll-uni/
│   ├── App.vue
│   ├── api/
│   │   ├── goods.js
│   │   └── mock.js
│   ├── components/
│   │   ├── good-list/
│   │   │   └── good-list.vue
│   │   ├── me-tabs/
│   │   │   └── me-tabs.vue
│   │   └── me-video/
│   │       └── me-video.vue
│   ├── main.js
│   ├── manifest.json
│   ├── package.json
│   ├── pages/
│   │   ├── base/
│   │   │   ├── list-msg.vue
│   │   │   ├── list-news.vue
│   │   │   ├── list-products.vue
│   │   │   ├── list-search.vue
│   │   │   ├── mescroll-body-part.vue
│   │   │   ├── mescroll-comp-center.vue
│   │   │   ├── mescroll-comp-item.vue
│   │   │   ├── mescroll-comp.vue
│   │   │   ├── mescroll-empty.vue
│   │   │   ├── mescroll-i18n.vue
│   │   │   ├── mescroll-more-item.vue
│   │   │   ├── mescroll-more.vue
│   │   │   ├── mescroll-native.vue
│   │   │   ├── mescroll-one.vue
│   │   │   ├── mescroll-options.vue
│   │   │   ├── mescroll-uni-part.vue
│   │   │   ├── mescroll-uni.vue
│   │   │   ├── sticky-data.vue
│   │   │   ├── sticky-scroll-data.vue
│   │   │   ├── sticky-scroll.vue
│   │   │   ├── sticky-uni.vue
│   │   │   └── sticky.vue
│   │   ├── index/
│   │   │   └── index.vue
│   │   └── intermediate/
│   │       ├── beibei.vue
│   │       ├── list-msg.vue
│   │       ├── mescroll-body-part.vue
│   │       ├── mescroll-swiper-item.vue
│   │       ├── mescroll-swiper-sticky-item.vue
│   │       ├── mescroll-swiper-sticky.vue
│   │       ├── mescroll-swiper.vue
│   │       ├── mescroll-uni-part.vue
│   │       ├── sticky-data.vue
│   │       ├── sticky-scroll-data.vue
│   │       ├── sticky-scroll.vue
│   │       ├── sticky-uni.vue
│   │       ├── sticky.vue
│   │       └── xinlang.vue
│   ├── pages.json
│   └── uni_modules/
│       └── mescroll-uni/
│           ├── changelog.md
│           ├── components/
│           │   ├── mescroll-body/
│           │   │   ├── mescroll-body.css
│           │   │   └── mescroll-body.vue
│           │   ├── mescroll-diy/
│           │   │   ├── beibei/
│           │   │   │   ├── components/
│           │   │   │   │   ├── mescroll-down.css
│           │   │   │   │   └── mescroll-down.vue
│           │   │   │   ├── mescroll-body.vue
│           │   │   │   ├── mescroll-uni-option.js
│           │   │   │   └── mescroll-uni.vue
│           │   │   └── xinlang/
│           │   │       ├── components/
│           │   │       │   ├── mescroll-down.css
│           │   │       │   ├── mescroll-down.vue
│           │   │       │   ├── mescroll-up.css
│           │   │       │   └── mescroll-up.vue
│           │   │       ├── mescroll-body.vue
│           │   │       ├── mescroll-uni-option.js
│           │   │       └── mescroll-uni.vue
│           │   ├── mescroll-empty/
│           │   │   └── mescroll-empty.vue
│           │   └── mescroll-uni/
│           │       ├── components/
│           │       │   ├── mescroll-down.css
│           │       │   ├── mescroll-down.vue
│           │       │   ├── mescroll-top.vue
│           │       │   ├── mescroll-up.css
│           │       │   └── mescroll-up.vue
│           │       ├── mescroll-i18n.js
│           │       ├── mescroll-mixins.js
│           │       ├── mescroll-uni-option.js
│           │       ├── mescroll-uni.css
│           │       ├── mescroll-uni.js
│           │       ├── mescroll-uni.vue
│           │       ├── mixins/
│           │       │   ├── mescroll-comp.js
│           │       │   ├── mescroll-more-item.js
│           │       │   └── mescroll-more.js
│           │       └── wxs/
│           │           ├── mixins.js
│           │           ├── renderjs.js
│           │           └── wxs.wxs
│           ├── hooks/
│           │   ├── useMescroll.js
│           │   ├── useMescrollComp.js
│           │   └── useMescrollMore.js
│           ├── package.json
│           └── readme.md
├── mescroll-uni-vue3/
│   ├── App.vue
│   ├── api/
│   │   ├── goods.js
│   │   └── mock.js
│   ├── components/
│   │   ├── good-list/
│   │   │   └── good-list.vue
│   │   ├── me-tabs/
│   │   │   └── me-tabs.vue
│   │   └── me-video/
│   │       └── me-video.vue
│   ├── index.html
│   ├── main.js
│   ├── manifest.json
│   ├── package.json
│   ├── pages/
│   │   ├── base/
│   │   │   ├── list-news.vue
│   │   │   ├── list-products.vue
│   │   │   ├── list-search.vue
│   │   │   ├── mescroll-comp-center.vue
│   │   │   ├── mescroll-comp-item.vue
│   │   │   ├── mescroll-comp.vue
│   │   │   ├── mescroll-empty.vue
│   │   │   ├── mescroll-i18n.vue
│   │   │   ├── mescroll-more-item.vue
│   │   │   ├── mescroll-more.vue
│   │   │   ├── mescroll-native.vue
│   │   │   ├── mescroll-one.vue
│   │   │   ├── mescroll-options.vue
│   │   │   └── mescroll-uni.vue
│   │   ├── index/
│   │   │   └── index.vue
│   │   └── intermediate/
│   │       ├── beibei.vue
│   │       ├── list-msg.vue
│   │       ├── mescroll-body-part.vue
│   │       ├── mescroll-swiper-item.vue
│   │       ├── mescroll-swiper-sticky-item.vue
│   │       ├── mescroll-swiper-sticky.vue
│   │       ├── mescroll-swiper.vue
│   │       ├── mescroll-uni-part.vue
│   │       ├── sticky-data.vue
│   │       ├── sticky-scroll-data.vue
│   │       ├── sticky-scroll.vue
│   │       ├── sticky-uni.vue
│   │       ├── sticky.vue
│   │       └── xinlang.vue
│   ├── pages.json
│   └── uni_modules/
│       └── mescroll-uni/
│           ├── changelog.md
│           ├── components/
│           │   ├── mescroll-body/
│           │   │   ├── mescroll-body.css
│           │   │   └── mescroll-body.vue
│           │   ├── mescroll-diy/
│           │   │   ├── beibei/
│           │   │   │   ├── components/
│           │   │   │   │   ├── mescroll-down.css
│           │   │   │   │   └── mescroll-down.vue
│           │   │   │   ├── mescroll-body.vue
│           │   │   │   ├── mescroll-uni-option.js
│           │   │   │   └── mescroll-uni.vue
│           │   │   └── xinlang/
│           │   │       ├── components/
│           │   │       │   ├── mescroll-down.css
│           │   │       │   ├── mescroll-down.vue
│           │   │       │   ├── mescroll-up.css
│           │   │       │   └── mescroll-up.vue
│           │   │       ├── mescroll-body.vue
│           │   │       ├── mescroll-uni-option.js
│           │   │       └── mescroll-uni.vue
│           │   ├── mescroll-empty/
│           │   │   └── mescroll-empty.vue
│           │   └── mescroll-uni/
│           │       ├── components/
│           │       │   ├── mescroll-down.css
│           │       │   ├── mescroll-down.vue
│           │       │   ├── mescroll-top.vue
│           │       │   ├── mescroll-up.css
│           │       │   └── mescroll-up.vue
│           │       ├── mescroll-i18n.js
│           │       ├── mescroll-mixins.js
│           │       ├── mescroll-uni-option.js
│           │       ├── mescroll-uni.css
│           │       ├── mescroll-uni.js
│           │       ├── mescroll-uni.vue
│           │       ├── mixins/
│           │       │   ├── mescroll-comp.js
│           │       │   ├── mescroll-more-item.js
│           │       │   └── mescroll-more.js
│           │       └── wxs/
│           │           ├── mixins.js
│           │           ├── renderjs.js
│           │           └── wxs.wxs
│           ├── hooks/
│           │   ├── useMescroll.js
│           │   ├── useMescrollComp.js
│           │   └── useMescrollMore.js
│           ├── package.json
│           └── readme.md
└── mescroll.js/
    ├── dist/
    │   ├── mescroll.css
    │   ├── mescroll.js
    │   └── mescroll.vue
    ├── html-demo/
    │   ├── base/
    │   │   ├── list-full-lock.html
    │   │   ├── list-mescroll-body.html
    │   │   ├── list-mescroll-lazy.html
    │   │   ├── list-mescroll-more.html
    │   │   ├── list-mescroll-one.html
    │   │   ├── list-msg.html
    │   │   ├── list-news.html
    │   │   ├── list-products-vue.html
    │   │   ├── list-products.html
    │   │   ├── mescroll-options.html
    │   │   └── vue-mescroll.html
    │   ├── beibei/
    │   │   ├── beibei.html
    │   │   └── option/
    │   │       ├── mescroll-option.css
    │   │       └── mescroll-option.js
    │   ├── dotJump/
    │   │   ├── dotJump.html
    │   │   └── option/
    │   │       ├── mescroll-option.css
    │   │       └── mescroll-option.js
    │   ├── index.html
    │   ├── res/
    │   │   ├── pdlist1.js
    │   │   ├── pdlist1.json
    │   │   ├── pdlist2.js
    │   │   └── pdlist2.json
    │   ├── search/
    │   │   └── mescroll-search.html
    │   ├── sticky/
    │   │   └── mescroll-sticky.html
    │   ├── swiper/
    │   │   ├── mescroll-swiper-nav.html
    │   │   ├── mescroll-swiper-sticky.html
    │   │   └── mescroll-swiper-tap.html
    │   ├── xinlang/
    │   │   ├── option/
    │   │   │   ├── mescroll-option.css
    │   │   │   └── mescroll-option.js
    │   │   └── xinlang.html
    │   ├── yabuli/
    │   │   ├── option/
    │   │   │   ├── mescroll-option.css
    │   │   │   └── mescroll-option.js
    │   │   └── yabuli.html
    │   └── zhihu/
    │       ├── option/
    │       │   ├── mescroll-option.css
    │       │   └── mescroll-option.js
    │       └── zhihu.html
    └── vue-demo/
        ├── .eslintrc.js
        ├── package.json
        ├── public/
        │   └── index.html
        ├── src/
        │   ├── App.vue
        │   ├── assets/
        │   │   ├── MescrollMixins.js
        │   │   └── css/
        │   │       ├── normalize.css
        │   │       └── reset.css
        │   ├── main.js
        │   ├── mock/
        │   │   ├── pdlist.js
        │   │   └── pdlistEdit.js
        │   ├── pages/
        │   │   ├── base/
        │   │   │   ├── list-news.vue
        │   │   │   ├── list-products.vue
        │   │   │   ├── mescroll-component.vue
        │   │   │   ├── mescroll-more.vue
        │   │   │   ├── mescroll-options.vue
        │   │   │   └── mescroll-swiper-nav.vue
        │   │   └── home.vue
        │   └── router/
        │       └── index.js
        └── vue-demo的运行方法.txt

================================================
FILE CONTENTS
================================================

================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2017-2018 wenju

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
# mescroll
## mescroll -- 精致的下拉刷新和上拉加载js框架 (JS framework for pull-refresh and pull-up-loading)
## http://www.mescroll.com

1. 主流APP案例, 丰富经典, 随心定制, 轻松拓展
2. 自由灵活的api, 超详细的注释, 可让您快速自定义真正属于自己的下拉上拉组件

## 功能亮点 :
1. 自动判断和提示列表无任何数据或无更多数据
2. 无需手动判断处理列表的页码,时间等变量
3. 支持监听列表滚动事件,可平滑滚动到任何位置
4. 一个界面可支持多个实例对象,互不干扰
5. 可临时锁定下拉刷新和上拉加载  
6. 支持图片懒加载,可配置各种占位图与显示动画,上手超简单

---
## mescroll.js :
1. mescroll.js是原生js写的下拉刷新和上拉加载. 支持vue, 不依赖jquery, zepto
2. 一套代码多端运行. 完美支持android, iOS, 各手机浏览器, 兼容PC主流浏览器
3. 快速入门, 经典案例, 接口文档, 请移步至官网 <a href="http://www.mescroll.com/api.html">http://www.mescroll.com/api.html</a>
4. mescroll的vue版本已整理, 但react和angular版本还没有, 期待哪位好心的神仙能pull requests~

---
## mescroll-uni :
1. mescroll-uni 是用在uni-app的下拉刷新和上拉加载的组件
2. 支持一套代码编译到iOS、Android、H5、小程序等多个平台
3. 采用uni官方推荐的自定义组件模式, 实现了更高性能及更多Vue语法支持
4. 继承了mescroll.js的实用功能: 自动处理分页, 自动控制无数据, 空布局提示, 回到顶部按钮 ..
5. 快速入门, 经典案例, 接口文档, 请移步至官网 <a href="http://www.mescroll.com/uni.html">http://www.mescroll.com/uni.html</a>

================================================
FILE: mescroll-uni/App.vue
================================================
<script>
	export default {
		onLaunch: function () {
			console.log('App Launch')
		},
		onShow: function () {
			console.log('App Show')
		},
		onHide: function () {
			console.log('App Hide')
		}
	}
</script>

<style>
	page{background-color: #fff}
	
	view,
	text,
	image,
	input,
	textarea {
		box-sizing: border-box;
	}
	
	image{will-change: transform;}
</style>


================================================
FILE: mescroll-uni/api/goods.js
================================================
const goods = [{
	"id": "1",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd1.jpg",
	"goodName": "【1】  六罐装荷兰美素佳儿金装2段900g",
	"goodPrice": 1149.00,
	"goodSold": 648
}, {
	"id": "2",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd2.jpg",
	"goodName": "【2】  韩国Amore爱茉莉红吕洗发水套装修复受损发质",
	"goodPrice": 89.00,
	"goodSold": 128
}, {
	"id": "3",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd3.jpg",
	"goodName": "【3】  Friso美素佳儿 金装婴儿配方奶粉3段900g",
	"goodPrice": 195.00,
	"goodSold": 968
}, {
	"id": "4",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd4.jpg",
	"goodName": "【4】  Fisher goodPrice费雪 费雪三轮儿童滑行车",
	"goodPrice": 299.00,
	"goodSold": 85
}, {
	"id": "5",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd5.jpg",
	"goodName": "【5】  Babylee巴布力 实木婴儿床 雷卡拉130*70cm",
	"goodPrice": 1889.00,
	"goodSold": 18
}, {
	"id": "6",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd6.jpg",
	"goodName": "【6】  Pigeon贝亲 独立三层奶粉盒 送小罐奶粉1段200g",
	"goodPrice": 70.00,
	"goodSold": 658
}, {
	"id": "7",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd7.jpg",
	"goodName": "【7】 TTBOO兔兔小布 肩纽扣套装",
	"goodPrice": 268.00,
	"goodSold": 128
}, {
	"id": "8",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd8.jpg",
	"goodName": "【8】  Nuna璐拉 婴儿布里奇果精纯嫩肤沐浴露婴儿精纯芦荟胶",
	"goodPrice": 140.00,
	"goodSold": 366
}, {
	"id": "9",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd9.jpg",
	"goodName": "【9】  illuma启赋 奶粉3段900g",
	"goodPrice": 252.00,
	"goodSold": 98
}, {
	"id": "10",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd10.jpg",
	"goodName": "【10】  Abbott雅培乳蛋白部分水解婴儿配方奶粉3段820g",
	"goodPrice": 89.00,
	"goodSold": 128
}, {
	"id": "11",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd11.jpg",
	"goodName": "【11】  韩蜜 酷炫唇蜜(礼盒套装)2.8g*4",
	"goodPrice": 179.00,
	"goodSold": 35
}, {
	"id": "12",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd12.jpg",
	"goodName": "【12】  保税区直发【3包装】日本Merries花王纸尿裤NB90",
	"goodPrice": 289.00,
	"goodSold": 1928
}, {
	"id": "13",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd13.jpg",
	"goodName": "【13】  Comotomo可么多么 硅胶奶瓶(0-3月奶嘴)150ml绿色",
	"goodPrice": 203.00,
	"goodSold": 87
}, {
	"id": "14",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd14.jpg",
	"goodName": "【14】  香港直邮德国瑞德露Rival de Loop芦荟精华安瓶",
	"goodPrice": 152.00,
	"goodSold": 61
}, {
	"id": "15",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd15.jpg",
	"goodName": "【15】  保税区直发药师堂尊马油香草味温和保湿无刺激面霜",
	"goodPrice": 269.00,
	"goodSold": 73
}, {
	"id": "16",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd16.jpg",
	"goodName": "【16】  香港直邮日本Spatreatment眼膜保湿去细纹法令纹",
	"goodPrice": 219.00,
	"goodSold": 13
}, {
	"id": "17",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd17.jpg",
	"goodName": "【17】  韩国MEDIHEALNMF可莱丝针剂睡眠面膜",
	"goodPrice": 81.00,
	"goodSold": 128
}, {
	"id": "18",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd18.jpg",
	"goodName": "【18】  DHC蝶翠诗橄榄蜂蜜滋养洗脸手工皂90g",
	"goodPrice": 123.00,
	"goodSold": 77
}, {
	"id": "19",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd19.jpg",
	"goodName": "【19】  日本资生堂CPB肌肤之钥新版隔离霜 清爽型 30ml",
	"goodPrice": 429.00,
	"goodSold": 36
}, {
	"id": "20",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd20.jpg",
	"goodName": "【20】 Heinz亨氏 婴儿面条优加面条全素套餐组合3口味3盒",
	"goodPrice": 39.00,
	"goodSold": 61
}, {
	"id": "21",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd21.jpg",
	"goodName": "【21】  Heinz亨氏 乐维滋果汁泥组合5口味15袋",
	"goodPrice": 69.00,
	"goodSold": 55
}, {
	"id": "22",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd22.jpg",
	"goodName": "【22】  保税区直发澳大利亚Swisse高浓度蔓越莓胶囊30粒",
	"goodPrice": 271.00,
	"goodSold": 19
}, {
	"id": "23",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd23.jpg",
	"goodName": "【23】  挪威Nordic Naturals小鱼婴幼儿鱼油DHA滴剂",
	"goodPrice": 102.00,
	"goodSold": 125
}, {
	"id": "24",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd24.jpg",
	"goodName": "【24】  澳大利亚Bio island DHA for Pregnancy海藻油DHA",
	"goodPrice": 289.00,
	"goodSold": 28
}, {
	"id": "25",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd25.jpg",
	"goodName": "【25】  澳大利亚Fatblaster Coconut Detox椰子水",
	"goodPrice": 152.00,
	"goodSold": 17
}, {
	"id": "26",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd26.jpg",
	"goodName": "【26】  Suitsky舒比奇 高护极薄舒爽纸尿片尿不湿XL60",
	"goodPrice": 99.00,
	"goodSold": 181
}, {
	"id": "27",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd27.jpg",
	"goodName": "【27】  英国JUST SOAP手工皂 玫瑰天竺葵蛋糕皂",
	"goodPrice": 72.00,
	"goodSold": 66
}, {
	"id": "28",
	"goodImg": "https://www.mescroll.com/demo/res/img/pd28.jpg",
	"goodName": "【28】  德国NUK 多色婴幼儿带盖学饮杯",
	"goodPrice": 92.00,
	"goodSold": 138
}]

export default goods;

================================================
FILE: mescroll-uni/api/mock.js
================================================
/*
本地模拟接口请求, 仅demo演示用.
实际项目以您服务器接口返回的数据为准,无需本地处理分页.
请参考官方写法: https://www.mescroll.com/uni.html?v=20200210#tagUpCallback
* */

// 模拟数据
import goods from "./goods.js";

// 获取新闻列表
export function apiNewList(pageNum, pageSize) {
	return new Promise((resolute, reject)=>{
		//延时一秒,模拟联网
		setTimeout(function() {
			try {
				let list = [];
				if (!pageNum) {
					//模拟下拉刷新返回的数据
					let id=new Date().getTime();
					let newObj = {
						id:id,
						title: "【新增新闻" + id + "】 标题",
						content: "新增新闻的内容"
					};
					list.push(newObj);
				} else {
					//模拟上拉加载返回的数据
					for (let i = 0; i < pageSize; i++) {
						let upIndex = (pageNum - 1) * pageSize + i + 1;
						let newObj = {
							id:upIndex,
							title: "【新闻" + upIndex + "】 标题标题标题标题标题",
							content: "内容内容内容内容内容内容内容内容内容"
						};
						list.push(newObj);
					}
					console.log("page.num=" + pageNum + ", page.size=" + pageSize + ", curPageData.length=" + list.length);
				}
				//模拟接口请求成功
				resolute(list);
			} catch (e) {
				//模拟接口请求失败
				reject(e);
			}
		}, 1000)
	})
}

// 搜索商品
export function apiGoods(pageNum, pageSize, keyword) {
	return new Promise((resolute, reject)=>{
		//延时一秒,模拟联网
		setTimeout(()=> {
			try{
				let data = {
					list: [], // 数据列表
					totalCount: 0, // 总数量
					totalPage: 0, // 总页数
					hasNext: false // 是否有下一页
				}
				
				// 符合关键词的记录
				let keywordList = [];
				if (!keyword || keyword == "全部") {
					// 搜索全部商品
					keywordList = goods;
				}else{
					// 关键词搜索
					if(keyword=="母婴") keyword="婴"; // 为这个关键词展示多几条数据
					for (let i = 0; i < goods.length; i++) {
						let good = goods[i]
						if (good.goodName.indexOf(keyword) !== -1) {
							keywordList.push(good)
						}
					}
				}
				
				// 分页
				for (let i = (pageNum - 1) * pageSize; i < pageNum * pageSize; i++) {
					if (i >= keywordList.length) break
					data.list.push(keywordList[i])
				}
				
				// 汇总数据
				data.totalCount = keywordList.length;
				data.totalPage = Math.ceil(data.totalCount/pageSize);
				data.hasNext = pageNum < data.totalPage
				
				//模拟接口请求成功
				console.log("pageNum=" + pageNum + ", pageSize=" + pageSize + ", data.list.length=" + data.list.length + ", totalCount=" + data.totalCount + ", totalPage=" + data.totalPage + ", hasNext=" + data.hasNext + (keyword ? ", keyword=" + keyword : ""));
				resolute(data);
			} catch (e) {
				//模拟接口请求失败
				reject(e);
			}
		},1000)
	})
}

// 获取微博列表
export function apiWeiboList(pageNum, pageSize) {
	return new Promise((resolute, reject)=>{
		//延时2秒,模拟联网
		setTimeout(function() {
			try {
				let list = [];
				if(!pageNum){
					//此处模拟下拉刷新返回的数据
					let id=new Date().getTime();
					let newObj={id:id, title:"【新增微博"+id+"】 新增微博", content:"新增微博的内容,新增微博的内容"};
					list.push(newObj);
				}else{
					//此处模拟上拉加载返回的数据
					for (let i = 0; i < pageSize; i++) {
						let upIndex=(pageNum-1)*pageSize+i+1;
						let newObj={id:upIndex, title:"【微博"+upIndex+"】 标题标题标题标题标题标题", content:"内容内容内容内容内容内容内容内容内容内容"};
						list.push(newObj);
					}
					console.log("page.num=" + pageNum + ", page.size=" + pageSize + ", curPageData.length=" + list.length);
				}
				//模拟接口请求成功
				resolute(list);
			} catch (e) {
				//模拟接口请求失败
				reject(e);
			}
		}, 2000)
	})
}


// 获取消息列表(共5页消息)
export function apiMsgList(pageNum, pageSize) {
	return new Promise((resolute, reject)=>{
		//延时一秒,模拟联网
		setTimeout(function() {
			try {
				let list = [];
				//模拟下拉加载更多记录
				for (let i = 0; i < pageSize; i++) {
					let msgId = (pageNum - 1) * pageSize + i + 1;
					let newObj = {
						id: msgId,
						title: "【消息" + msgId + "】",
						content: "内容: 下拉获取聊天记录"
					};
					// 此处模拟只有5页的消息 (第5页只有3条)
					if(pageNum>=5 && i>=3){}else{
						list.unshift(newObj);
					}
				}
				console.log("page.num=" + pageNum + ", page.size=" + pageSize + ", curPageData.length=" + list.length);
				//模拟接口请求成功
				resolute(list);
			} catch (e) {
				//模拟接口请求失败
				reject(e);
			}
		}, 1000)
	})
}

// 获取tabs类目
export function apiGetTabs() {
	return new Promise((resolute, reject)=>{
		//延时,模拟联网
		setTimeout(function() {
			try {
				let tabs = ['全部', '奶粉', '面膜', '图书', '果汁', '奶瓶', '美素', '花王', '韩蜜', '口红', '毛巾', '玩具', '衣服'];
				//模拟接口请求成功
				resolute(tabs);
			} catch (e) {
				//模拟接口请求失败
				reject(e);
			}
		}, 10)
	})
}

================================================
FILE: mescroll-uni/components/good-list/good-list.vue
================================================
<!-- 商品列表组件 <good-list :list="xx"></good-list> -->
<template>
	<view class="good-list">
		<view :id="'good'+good.id" class="good-li" v-for="good in list" :key="good.id">
			<image class="good-img" :src="good.goodImg" mode="widthFix"/>
			<view class="flex-item">
				<view class="good-name">{{good.goodName}}</view>
				<text class="good-price">{{good.goodPrice}} 元</text>
				<text class="good-sold">已售{{good.goodSold}}件</text>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		props:{
			list: {
				type: Array,
				default(){
					return []
				}
			}
		}
	}
</script>

<style lang="scss">
	.good-list{
		background-color: #fff;
		
		.good-li{
			display: flex;
			align-items: center;
			padding: 20upx;
			border-bottom: 1upx solid #eee;
			
			.good-img{
				width: 160upx;
				height: 160upx;
				margin-right: 20rpx;
			}
			
			.flex-item{
				flex: 1;
				
				.good-name{
					font-size: 26upx;
					line-height: 40upx;
					height: 80upx;
					margin-bottom: 20upx;
					overflow: hidden;
				}
				.good-price{
					font-size: 26upx;
					color: red;
				}
				.good-sold{
					font-size: 24upx;
					margin-left: 16upx;
					color: gray;
				}
				
			}
		}
	}
</style>


================================================
FILE: mescroll-uni/components/me-tabs/me-tabs.vue
================================================
<!-- tab组件: <me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs> -->
<template>
	<view class="me-tabs" :class="{'tabs-fixed': fixed}" :style="{height: tabHeightVal, top:topFixed, 'margin-top':topMargin}">
		<scroll-view v-if="tabs.length" :id="viewId" :scroll-left="scrollLeft" scroll-x scroll-with-animation :scroll-animation-duration="300">
			<view class="tabs-item" :class="{'tabs-flex':!isScroll, 'tabs-scroll':isScroll}">
				<!-- tab -->
				<view class="tab-item" :style="{width: tabWidthVal, height: tabHeightVal, 'line-height':tabHeightVal}" v-for="(tab, i) in tabs" :class="{'active': value===i}" :key="i" @click="tabClick(i)">
					{{getTabName(tab)}}
				</view>
				<!-- 下划线 -->
				<view class="tabs-line" :style="{left:lineLeft}"></view>
			</view>
		</scroll-view>
	</view>
</template>

<script>
	export default {
		props:{
			tabs: { // 支持格式: ['全部', '待付款'] 或 [{name:'全部'}, {name:'待付款'}]
				type: Array,
				default(){
					return []
				}
			},
			nameKey: { // 取name的字段
				type: String,
				default: 'name'
			},
			value: { // 当前显示的下标 (使用v-model语法糖: 1.props需为value; 2.需回调input事件)
				type: [String, Number],
				default: 0
			},
			fixed: Boolean, // 是否悬浮,默认false
			tabWidth: Number, // 每个tab的宽度,默认不设置值,为flex平均分配; 如果指定宽度,则不使用flex,每个tab居左,超过则水平滑动(单位默认rpx)
			height: { // 高度,单位rpx
				type: Number,
				default: 64
			},
			top: { // 顶部偏移的距离,默认单位rpx (当fixed=true时,已加上windowTop)
				type: Number,
				default: 0
			}
		},
		data() {
			return {
				viewId: 'id_' + Math.random().toString(36).substr(2,16),
				scrollLeft: 0,
				windowWidth: 0,
				windowTop: 0
			}
		},
		computed: {
			isScroll(){
				return this.tabWidth && this.tabs.length // 指定了tabWidth的宽度,则支持水平滑动
			},
			tabHeightPx(){
				return uni.upx2px(this.height)
			},
			tabHeightVal(){
				return this.tabHeightPx+'px'
			},
			tabWidthPx(){
				return uni.upx2px(this.tabWidth)
			},
			tabWidthVal(){
				return this.isScroll ? this.tabWidthPx+'px' : ''
			},
			lineLeft() {
				if (this.isScroll) {
					return this.tabWidthPx * this.value + this.tabWidthPx/2 + 'px' // 需转为px (用rpx的话iOS真机显示有误差)
				} else{
					return 100/this.tabs.length*(this.value + 1) - 100/(this.tabs.length*2) + '%'
				}
			},
			topFixed(){
				return this.fixed ? this.windowTop + uni.upx2px(this.top) + 'px' : 0
			},
			topMargin(){
				return this.fixed ? 0 : this.top + 'rpx'
			}
		},
		watch: {
			tabs() {
				// 水平滚动到中间
				this.initWarpRect(()=>{
					this.scrollCenter()
				})
			},
			value() {
				this.scrollCenter(); // 水平滚动到中间
			}
		},
		created() {
			let sys = uni.getSystemInfoSync();
			this.windowWidth = sys.windowWidth
			this.windowTop = sys.windowTop
		},
		mounted() {
			// 滚动到当前下标
			this.initWarpRect(()=>{
				this.scrollCenter()
			})
		},
		methods: {
			getTabName(tab){
				return typeof tab === "object" ? tab[this.nameKey] : tab
			},
			tabClick(i){
				if(this.value!=i){
					this.$emit("input",i);
					this.$emit("change",i);
				}
			},
			scrollCenter(){
				if(!this.isScroll) return;
				let tabLeft = this.tabWidthPx * this.value + this.tabWidthPx/2; // 当前tab中心点到左边的距离
				let diff = tabLeft - this.warpWidth/2 // 如果超过tabs容器的一半,则滚动差值
				this.scrollLeft = diff;
			},
			initWarpRect(success){
				setTimeout(()=>{ // 延时确保dom已渲染, 不使用$nextclick
					let query = uni.createSelectorQuery().in(this);
					query.select('#'+this.viewId).boundingClientRect(rect => {
						this.warpWidth = rect ? rect.width : this.windowWidth; // 某些情况下取不到宽度,暂时取屏幕宽度
						success()
					}).exec();
				},20)
			}
		}
	}
</script>

<style lang="scss">
	.me-tabs{
		position: relative;
		font-size: 24rpx;
		background-color: #fff;
		border-bottom: 1rpx solid #eee;
		box-sizing: border-box;
		overflow-y: hidden;
		background-color: #fff;
		&.tabs-fixed{
			z-index: 990;
			position: fixed;
			left: 0;
			width: 100%;
		}
		
		.tabs-item{
			position: relative;
			white-space: nowrap;
			padding-bottom: 30rpx; // 撑开高度,再配合me-tabs的overflow-y: hidden,以达到隐藏滚动条的目的
			box-sizing: border-box;
			.tab-item{
				position: relative;
				text-align: center;
				box-sizing: border-box;
				&.active{
					font-weight: bold;
					color: red;
				}
			}
		}
		
		// 平分的方式显示item
		.tabs-flex{
			display: flex;
			.tab-item{
				flex: 1;
			}
		}
		// 居左显示item,支持水平滑动
		.tabs-scroll{
			.tab-item{
				display: inline-block;
			}
		}
		
		// 选中tab的线
		.tabs-line{
			z-index: 1;
			position: absolute;
			bottom: 30rpx; // 至少与.tabs-item的padding-bottom一致,才能保证在底部边缘
			width: 50rpx;
			height: 6rpx;
			transform: translateX(-50%);
			border-radius: 4rpx;
			transition: left .3s;
			background: red;
		}
	}
</style>


================================================
FILE: mescroll-uni/components/me-video/me-video.vue
================================================
<!-- 视频组件: <me-video src="视频地址" poster="封面图"></me-video> 
video标签在APP端是原生组件, 真机APP端下拉时会渲染不及时, 出现悬浮错位现象;
me-video组件, 未播放时自动展示image封面, 播放时才显示video, 提高性能; 如果播放中执行下拉,会自动显示封面, 避免视频下拉悬浮错位;
-->
<template>
	<view class="me-video" :style="{width:width, height:height}">
		<!-- 播放的时候才渲染video标签 -->
		<video v-if="showVideo" ref="videoRef" class="video" :class="{'full-play': fullplay&&!autoplay, 'mescroll-dowload': mescrollDownLoad}" :src="src" autoplay :loop="loop" @click="videoClick" x5-playsinline="true" x5-video-player-type="h5" playsinline="true" webkit-playsinline="true" x5-video-player-fullscreen="false"></video>
		<!-- 播放按钮 -->
		<view v-else class="btn-play"> <view class="triangle"></view> </view>
		<!-- 封面 -->
		<image v-if="(!showVideo || mescrollDownLoad) && poster" class="poster" :src="poster" @click="play()" mode="aspectFit"></image>
	</view>
</template>

<script>
	export default {
		props: {
			src: String, // 视频地址
			poster: String, // 封面图
			autoplay: { // 是否自动播放
				type: Boolean,
				default(){
					return false
				}
			},
			fullplay: { // 是否全屏播放,默认不全屏
				type: Boolean,
				default(){
					return false
				}
			},
			loop: { // 是否循环播放
				type: Boolean,
				default(){
					return true // 循环播放可避免Android微信播放完毕显示广告
				}
			},
			width: { // 宽度 (需带单位,支持格式: '100%', '300px', '300rpx')
				type: String,
				default: "100%"
			},
			height: { // 高度 (需带单位,支持格式: '100%', '300px', '300rpx')
				type: String,
				default: "225px"
			},
			mescroll: { // mescroll对象,APP端下拉刷新时显示封面,隐藏视频.缓解APP端视频下拉悬浮错位问题
				type: Object,
				default(){
					return {}
				}
			}
		},
		data() {
			return {
				showVideo: this.autoplay // 是否播放视频
			}
		},
		computed: {
			// 是否下拉中 (下拉隐藏视频,显示封面, 仅APP端生效)
			mescrollDownLoad() {
				// #ifdef APP-PLUS
				return this.mescroll.downLoadType
				// #endif
				// #ifndef APP-PLUS
				return false
				// #endif
			}
		},
		watch: {
			autoplay(val) {
				if(val) this.play()
			}
		},
		methods: {
			// 播放
			play(){
				this.showVideo = true
				this.wxAutoPlay()
			},
			// 视频点击事件
			videoClick(){
				// 全屏播放时,点击视频退出
				if(this.fullplay) this.showVideo = false
			},
			// 解决微信端视频无法自动播放的问题
			wxAutoPlay(){
				// #ifdef H5
				// 微信端
				if(navigator.userAgent.toLowerCase().match(/MicroMessenger/i) == 'micromessenger'){
					// iOS
					let head = document.getElementsByTagName("head")[0]
					let wxscript = document.createElement("script");
					wxscript.type = "text/javascript"
					wxscript.src = "https://res.wx.qq.com/open/js/jweixin-1.6.0.js"
					head.appendChild(wxscript)
					let vm = this
					let doPlay = function(){
						vm.$refs.videoRef && vm.$refs.videoRef.play()
					}
					wxscript.onload = function(){
						window.wx.config({
							debug: !1,
							appId: "",
							timestamp: 1,
							nonceStr: "",
							signature: "",
							jsApiList: []
						})
						window.wx.ready(doPlay)
					}
					// Android
					document.addEventListener("WeixinJSBridgeReady", doPlay, false);
					// 先尝试播放
					setTimeout(()=>{
						doPlay()
					},20)
				}
				// #endif
			}
		}
	}
</script>

<style lang="scss">
	.me-video{
		position: relative;
		background-color: #000;
		overflow: hidden;
		// 播放按钮
		.btn-play{
			z-index: 9;
			position: absolute;
			left: 50%;
			top: 50%;
			transform: translate(-50%, -50%);
			width: 100rpx;
			height: 100rpx;
			border-radius: 50%;
			background-color: rgba(0,0,0,.75);
			pointer-events: none;
			.triangle{
				position: absolute;
				left: 50%;
				top: 50%;
				transform: translate(-25%, -50%);
				width: 0;
				height: 0;
				border-top: 16rpx solid transparent;
				border-left: 24rpx solid #fff;
				border-bottom: 16rpx solid transparent;
			}
		}
		// 封面图
		.poster{
			width: 100%;
			height: 100%;
			vertical-align: bottom;
		}
		// 视频 (默认非全屏播放)
		.video{
			z-index: 8;
			position: absolute;
			top: 0;
			left: 0;
			width: 100%;
			height: 100%;
			// 全屏播放
			&.full-play{
				z-index: 999;
				position: fixed;
			}
			// 下拉时隐藏视频
			&.mescroll-dowload{
				display: none;
			}
		}
	}
</style>


================================================
FILE: mescroll-uni/main.js
================================================
import Vue from 'vue'
import App from './App'

Vue.config.productionTip = false

App.mpType = 'app'

const app = new Vue({
    ...App
})
app.$mount()


================================================
FILE: mescroll-uni/manifest.json
================================================
{
    "name" : "mescroll_uni",
    "appid" : "",
    "description" : "mescroll的uni版本 -支持uni-app的下拉刷新上拉加载组件,支持原生页面和局部区域滚动",
    "versionName" : "1.0.0",
    "versionCode" : "100",
    "transformPx" : false,
    "app-plus" : {
        /* 5+App特有相关 */
        "usingComponents" : true,
        "modules" : {},
        /* 模块配置 */
        "distribute" : {
            /* 应用发布信息 */
            "android" : {
                /* android打包配置 */
                "permissions" : [
                    "<uses-permission android:name=\"android.permission.CHANGE_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.MOUNT_UNMOUNT_FILESYSTEMS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_CONTACTS\"/>",
                    "<uses-permission android:name=\"android.permission.VIBRATE\"/>",
                    "<uses-permission android:name=\"android.permission.READ_LOGS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_WIFI_STATE\"/>",
                    "<uses-feature android:name=\"android.hardware.camera.autofocus\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_CONTACTS\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_NETWORK_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CAMERA\"/>",
                    "<uses-permission android:name=\"android.permission.RECORD_AUDIO\"/>",
                    "<uses-permission android:name=\"android.permission.GET_ACCOUNTS\"/>",
                    "<uses-permission android:name=\"android.permission.MODIFY_AUDIO_SETTINGS\"/>",
                    "<uses-permission android:name=\"android.permission.READ_PHONE_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.CHANGE_WIFI_STATE\"/>",
                    "<uses-permission android:name=\"android.permission.WAKE_LOCK\"/>",
                    "<uses-permission android:name=\"android.permission.CALL_PHONE\"/>",
                    "<uses-permission android:name=\"android.permission.FLASHLIGHT\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_COARSE_LOCATION\"/>",
                    "<uses-feature android:name=\"android.hardware.camera\"/>",
                    "<uses-permission android:name=\"android.permission.ACCESS_FINE_LOCATION\"/>",
                    "<uses-permission android:name=\"android.permission.WRITE_SETTINGS\"/>"
                ]
            },
            "ios" : {},
            /* ios打包配置 */
            "sdkConfigs" : {}
        }
    },
    /* SDK配置 */
    "quickapp" : {},
    /* 快应用特有相关 */
    "mp-weixin" : {
        /* 小程序特有相关 */
        "appid" : "wxae53aa69d15c0f62",
        "setting" : {
            "urlCheck" : true
        },
        "usingComponents" : true
    },
    "mp-alipay" : {
        "usingComponents" : true
    },
    "mp-baidu" : {
        "usingComponents" : true
    },
    "mp-toutiao" : {
        "usingComponents" : true
    }
}


================================================
FILE: mescroll-uni/package.json
================================================
{
	"uni-app": {
		"scripts": {
			"mp-dingtalk": {
				"title": "钉钉小程序",
				"env": {
					"UNI_PLATFORM": "mp-alipay"
				},
				"define": {
					"MP-DINGTALK": true
				}
			},
			"mp-jjt": {
				"title": "交建通小程序",
				"env": {
					"UNI_PLATFORM": "mp-weixin"
				},
				"define": {
					"MP-JJT": true
				}
			}
		}
	}
}


================================================
FILE: mescroll-uni/pages/base/list-msg.vue
================================================
<template>
	<!-- 需配置bottom的偏移量, 用于底部留白 -->
	<mescroll-body ref="mescrollRef" bottom="50%" @init="mescrollInit" :down="downOption" @down="downCallback" :up="upOption">
		<!-- 无更多消息 -->
		<view v-if="isEnd" class="msg-end">没有更多消息了</view>
		
		<!-- 消息列表 (必须配置id,以便定位) -->
		<view class="msg" v-for="msg in msgList" :key="msg.id" :id="msg.VIEW_ID" :class="[msg.id%2==0 ? 'right' : 'left']">
			<view class="msg-warp">
				<view class="msg-title">{{msg.title}}</view>
				<view class="msg-content">{{msg.content}}</view>
			</view>
		</view>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiMsgList} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				downOption:{
					autoShowLoading: true, // 显示下拉刷新的进度条
					textColor: "#FF8095" // 下拉刷新的文本颜色
				},
				upOption: {
					use: false, // 禁止上拉
					toTop: {
						src: '' // 不显示回到顶部按钮
					}
				},
				pageNum: 1, // 页码
				pageSize: 10, // 页长
				isEnd: false, // 是否无消息
				msgList: []
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				//联网加载数据
				apiMsgList(this.pageNum, this.pageSize).then(data => {
					// 需自行维护页码
					this.pageNum ++;
					// 先隐藏下拉刷新的状态
					this.mescroll.endSuccess();
					// 不满一页,说明已经无更多消息 (建议根据您实际接口返回的总页码数,总消息量,是否有消息的字段来判断)
					if(data.length < this.pageSize){
						this.isEnd = true; // 标记已无更多消息
						this.mescroll.lockDownScroll(true); // 锁定下拉
					}
					// 生成VIEW_ID,大写,避免污染源数据
					data.forEach(val=>{
						val.VIEW_ID = "msg" + val.id // 不以数字开头
					})
					
					// 获取当前最顶部的VIEW_ID (注意是写在data.concat前面)
					let topMsg = this.msgList[0]
					
					//设置列表数据
					this.msgList = data.concat(this.msgList); // 注意不是this.msgList.concat
					
					this.$nextTick(()=>{
						if(this.pageNum <= 2){
							// 第一页直接滚动到底部 ( this.pageNum已在前面加1 )
							this.mescroll.scrollTo(99999, 0)
						}else if(topMsg){
							// 保持顶部消息的位置
							let view = uni.createSelectorQuery().select('#'+topMsg.VIEW_ID);
							view.boundingClientRect(v => {
								console.log("节点离页面顶部的距离=" + v.top);
								this.mescroll.scrollTo(v.top - 100, 0) // 减去上偏移量100
							}).exec();
						}
					})
					
				}).catch(()=>{
					this.pageNum --; // 联网失败,必须回减页码
					this.mescroll.endErr(); // 隐藏下拉刷新的状态
				})
			}
		}
	}
</script>

<style lang="scss">
	/* 无更多消息 */
	.msg-end{
		padding: 40rpx 0;
		font-size: 24rpx;
		text-align: center;
		color: #FF8095;
	}
	/*消息列表*/
	.msg{
		margin: 30rpx;
		&.right{
			text-align: right;
		}
		&.left{
			text-align: left;
		}
		.msg-warp{
			width: 50%;
			display: inline-block;
			padding: 30rpx;
			border-radius: 30rpx;
			background-color: #FF8095;
			color: #fff;
			.msg-title{
				margin-left: -12rpx;
				font-size: 32rpx;
				text-align: left;
			}
			.msg-content{
				font-size: 26rpx;
				margin-top: 10rpx;
				text-align: left;
			}
		}
	}
</style>


================================================
FILE: mescroll-uni/pages/base/list-news.vue
================================================
<template>
	<mescroll-body @init="mescrollInit" :down="downOption" @down="downCallback" @up="upCallback">
		<view class="notice">本Demo的下拉刷新: 添加新数据到列表顶部</view>
		<view class="news-li" v-for="news in dataList" :key="news.id">
			<view>{{news.title}}</view>
			<view class="new-content">{{news.content}}</view>
		</view>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiNewList} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				downOption: {
					auto: false //是否在初始化后,自动执行downCallback; 默认true
				},
				dataList: []
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				//联网加载数据
				apiNewList().then(data => {
					//联网成功的回调,隐藏下拉刷新的状态
					this.mescroll.endSuccess();
					//设置列表数据
					this.dataList.unshift(data[0]);
				}).catch(()=>{
					//联网失败的回调,隐藏下拉刷新的状态
					this.mescroll.endErr();
				})
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				apiNewList(page.num, page.size).then(curPageData=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					//mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;
					
					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
					//this.mescroll.endByPage(curPageData.length, totalPage); //必传参数(当前页的数据个数, 总页数)
					
					//方法二(推荐): 后台接口有返回列表的总数据量 totalSize
					//this.mescroll.endBySize(curPageData.length, totalSize); //必传参数(当前页的数据个数, 总数据量)
					
					//方法三(推荐): 您有其他方式知道是否有下一页 hasNext
					//this.mescroll.endSuccess(curPageData.length, hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)
					
					//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据.
					this.mescroll.endSuccess(curPageData.length);
					
					//设置列表数据
					this.dataList=this.dataList.concat(curPageData);
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			}
		}
	}
</script>

<style>
	/*说明*/
	.notice{
		font-size: 30upx;
		padding: 40upx 0;
		border-bottom: 1upx solid #eee;
		text-align: center;
	}
	/*展示上拉加载的数据列表*/
	.news-li{
		font-size: 32upx;
		padding: 32upx;
		border-bottom: 1upx solid #eee;
	}
	.news-li .new-content{
		font-size: 28upx;
		margin-top: 10upx;
		margin-left: 20upx;
		color: #666;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/list-products.vue
================================================
<template>
	 <mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback">
		<view class="notice">mescroll的极简示例,大部分情况就是这么用</view>
		<good-list :list="goods"></good-list>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [] // 数据列表
			}
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				// 此处可以继续请求其他接口
				// if(page.num == 1){
				// 	// 请求其他接口...
				// }
				
				// 如果希望先请求其他接口,再触发upCallback,可参考以下写法
				// if(!this.isInitxx){
				// 	apiGetxx().then(res=>{
				// 		this.isInitxx = true
				// 		this.mescroll.resetUpScroll() // 重新触发upCallback
				// 	}).catch(()=>{
				// 		this.mescroll.endErr()
				// 	})
				// 	return // 此处return,先获取xx
				// }
				
				//联网加载数据
				apiGoods(page.num, page.size).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					//mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;

					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
					//this.mescroll.endByPage(res.list.length, totalPage); //必传参数(当前页的数据个数, 总页数)

					//方法二(推荐): 后台接口有返回列表的总数据量 totalSize
					//this.mescroll.endBySize(res.list.length, totalSize); //必传参数(当前页的数据个数, 总数据量)

					//方法三(推荐): 您有其他方式知道是否有下一页 hasNext
					//this.mescroll.endSuccess(res.list.length, hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)

					//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据
					this.mescroll.endSuccess(res.list.length);

					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			}
		}
	}
</script>

<style>
	/*说明*/
	.notice{
		font-size: 26upx;
		padding: 40upx 0;
		border-bottom: 1upx solid #eee;
		text-align: center;
		color:#555;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/list-search.vue
================================================
<template>
	 <mescroll-body @init="mescrollInit" @down="downCallback" :up="upOption" @up="upCallback">
		<view class="item">
			<text class="tip">热门搜索:</text>
			<text class="hot-word" @click="doSearch('奶粉')">奶粉</text>
			<text class="hot-word" @click="doSearch('面霜')">面霜</text>
			<text class="hot-word" @click="doSearch('图书')">图书</text>
		</view>
		<view class="item">
			<text class="tip">关键词:</text>
			<input class="word-input" placeholder="请输入搜索关键词" v-model="curWord" @input="inputWord"/>
		</view>
		<good-list :list="goods"></good-list>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				upOption: {
					// auto: false, //是否在初始化后,自动执行上拉回调callback; 默认true
					// page: {
					// 	num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
					// 	size: 10 // 每页数据的数量
					// }
					noMoreSize: 3, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看
					empty: {
						tip: '~ 搜索无结果 ~' // 提示
					}
				},
				goods: [], // 数据列表
				curWord:"" //当前搜索关键词
			}
		},
		methods: {
			// 输入监听
			inputWord(e){
				// this.curWord = e.detail.value // 已使用v-model,无需再次赋值
				// 节流,避免输入过快多次请求
				this.searchTimer && clearTimeout(this.searchTimer)
				this.searchTimer = setTimeout(()=>{
					this.doSearch(this.curWord)
				},300)
			},
			// 搜索
			doSearch(word){
				this.curWord = word
				this.goods = []; // 先清空列表,显示加载进度
				this.mescroll.resetUpScroll();
				// this.mescroll.hideUpScroll() // 不显示进度条
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				apiGoods(page.num, page.size, this.curWord).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//如果是第一页需手动制空列表
					if(page.num == 1) this.goods = [];
					//追加新数据
					this.goods=this.goods.concat(res.list);
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			}
		}
	}
</script>

<style>
	/*关键词搜索*/
	.item{
		padding: 20rpx;
	}
	.tip{
		font-size: 30rpx;
		vertical-align: middle;
	}
	.hot-word{
		font-size: 24rpx;
		margin-left: 30rpx;
		padding: 6rpx 40rpx;
		border: 2rpx solid #FF6990;
		border-radius: 100rpx;
		vertical-align: middle;
		color: #FF6990;
	}
	.word-input{
		display: inline-block;
		width: 60%;
		height: 50rpx;
		line-height: 50rpx;
		font-size: 24rpx;
		margin-left: 30rpx;
		border: 2rpx solid #18B4FE;
		border-radius: 60rpx;
		text-align: center;
		background-color: #fff;
		vertical-align: middle;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/mescroll-body-part.vue
================================================
<template>
	<!-- mescroll-body本质是原生page的滚动,无法像mescroll-uni那样用flex布局嵌在某个view中使用局部区域滚动, 但是可以通过fixed定位其他元素来实现"局部区域滚动"-->
	<view>
		<!-- 顶部 fixed定位 -->
		<view class="top-warp"> 
			<view>顶部区域</view>
			<view style="font-size: 24rpx;">mescroll-body 通过fixed定位其他元素,实现"局部区域滚动"</view>
		</view>
		
		<!-- 左边 fixed定位 -->
		<scroll-view class="left-warp" :scroll-y="true">
			<view class="tab" :class="{active:i==tabIndex}" v-for="(tab,i) in tabs" :key="i" @click="tabChange(i)">{{tab}}</view>
		</scroll-view>
		
		<!-- mescroll-body跟随page滚动, 不可fixed定位, 可设置 top, bottom, topbar, bottombar, safearea的偏移量-->
		<mescroll-body ref="mescrollRef" top="88" bottom="100" @init="mescrollInit" @down="downCallback" @up="upCallback">
			<good-list :list="goods"></good-list>
		</mescroll-body>
		
		<!-- 底部 fixed定位 -->
		<view class="bottom-warp"> 底部区域 </view>
	</view>
</template>


<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods, apiGetTabs} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: [], // tabs异步获取
				// tabs: ['全部', '奶粉', '面膜', '图书', '果汁', '奶瓶', '美素', '花王', '韩蜜', '口红', '毛巾', '玩具', '衣服'],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			upCallback(page) {
				// tabs异步获取
				if(this.tabs.length == 0){
					apiGetTabs().then(res=>{
						this.tabs = res
						this.mescroll.resetUpScroll() // 重新触发upCallback
					}).catch(()=>{
						this.mescroll.endErr()
					})
					return // 此处return,先获取tabs
				}
				
				//联网加载数据
				let keyword = this.tabs[this.tabIndex]
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange(i){
				if(this.tabIndex != i){
					this.tabIndex = i
					this.goods = []; // 先置空列表,显示加载进度条
					this.mescroll.resetUpScroll(); // 重置列表数据
				}
			}
		}
	}
</script>


<style lang="scss">
	/* 顶部 fixed定位*/
	.top-warp{
		z-index: 200;
		position: fixed;
		top: var(--window-top);
		left: 0;
		width: 100%;
		height: 88rpx;
		padding-top: 10rpx;
		font-size: 28rpx;
		text-align: center;
		background-color: #CFE0DA;
	}
	
	/* 左边 fixed定位*/
	.left-warp{
		z-index: 100;
		position: fixed;
		top: var(--window-top);
		left: 0;
		bottom: 100rpx;
		width: 180rpx;
		padding-top: 88rpx;
		background-color: #eee;
		.tab{
			font-size: 28rpx;
			padding: 28rpx;
			&.active{
				background-color: #fff;
			}
		}
	}
	
	// 设置padding
	.mescroll-body,
	/deep/.mescroll-body{
		padding-left: 180rpx;
	}
	
	/* 底部 fixed定位*/
	.bottom-warp{
		z-index: 200;
		position: fixed;
		left: 0;
		bottom: 0;
		width: 100%;
		height: 100rpx;
		line-height: 100rpx;
		text-align: center;
		background-color: #FF6990;
	}
</style>

================================================
FILE: mescroll-uni/pages/base/mescroll-comp-center.vue
================================================
<template>
	<!-- 当mescroll-body写在子子..子组件时, 需每层子组件都引入mescroll-comp.js, 添加ref="mescrollItem" -->
	<view>
		<mescroll-item ref="mescrollItem"></mescroll-item>
	</view>
</template>

<script>
	import MescrollItem from "./mescroll-comp-item.vue"; // 一个mescroll-body写在多层子组件的情况
	// 第二步: 引入mescroll-comp.js
	import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js";
	export default {
		mixins: [MescrollCompMixin],
		components: {
			MescrollItem
		}
	}
</script>

<style>
</style>


================================================
FILE: mescroll-uni/pages/base/mescroll-comp-item.vue
================================================
<template>
	<!-- 当mescroll-body写在子组件时,父页面需引入mescroll-comp.js的mixins -->
	<mescroll-body top="100" @init="mescrollInit" @down="downCallback" @up="upCallback">
		<!-- 数据列表 -->
		<good-list :list="goods"></good-list>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: []
			}
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				apiGoods(page.num, page.size).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			}
		}
	}
</script>


================================================
FILE: mescroll-uni/pages/base/mescroll-comp.vue
================================================
<template>
	<!-- 
	 mescroll-body写在一层子组件时, 需引入mescroll-comp.js, 给子组件添加ref="mescrollItem",
	 当mescroll-body写在子子..子组件时, 需每层子组件都引入mescroll-comp.js, 添加ref="mescrollItem",
	 嵌套太多层,建议直接使用mescroll-uni最简单 
	 -->
	 <view>
		<view class="notice-warp">
			<view class="notice">mescroll-body是原生页面的滚动,子组件无页面生命周期</view>
			<view class="notice">需通过mescroll-comp.js给子组件补充页面生命周期</view>
		</view>
		
		<!-- 第一步: 给mescroll-body的组件添加: ref="mescrollItem" (固定的,不可改,与mescroll-comp.js对应)-->
		<mescroll-item ref="mescrollItem"></mescroll-item>
	</view>
</template>

<script>
	// import MescrollItem from "./mescroll-comp-item.vue"; // 一个mescroll-body写在一层子组件的情况
	import MescrollItem from "./mescroll-comp-center.vue"; // 一个mescroll-body写在多层子组件的情况
	// import MescrollItem from "./mescroll-more.vue"; // 多个mescroll-body写在子组件的情况
	
	// 第二步: 引入mescroll-comp.js
	import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js";
	export default {
		mixins: [MescrollCompMixin],
		components: {
			MescrollItem
		}
	}
</script>

<style>
	/*说明*/
	.notice-warp{
		z-index: 9;
		position: fixed;
		top: var(--window-top);
		left: 0;
		width: 100%;
		height: 100rpx;/*对应mescroll-body的top值*/
		font-size: 26upx;
		padding-top: 10upx;
		border-bottom: 1upx solid #eee;
		text-align: center;
		background-color: #fff;
	}
	.notice-warp .notice{
		color:#555;
	}
	.notice-warp .btn-change{
		display: inline-block;
		margin-top: 28upx;
		padding: 6upx 16upx;
		border: 1upx solid #FF6990;
		border-radius: 40upx;
		color: #FF6990;
	}
	.notice-warp .btn-change:active{
		opacity: .5;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/mescroll-empty.vue
================================================
<!-- mescroll-empty遵循easycom, 可直接单独使用 -->
<template>
	<view>
		<!-- 列表内容 -->
		<view v-if="list.length">
			<!-- ... -->
		</view>
		<!-- 空布局简单使用: 就这一行代码 -->
		<!-- <mescroll-empty v-else></mescroll-empty> -->
		
		<!-- 空布局完整配置 -->
		<mescroll-empty v-else :option="emptyOption" @emptyclick="emptyClick"></mescroll-empty>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				list: [],
				
				// 非国际化配置
				// emptyOption: {
				// 	icon: "https://www.mescroll.com/img/mescroll-empty.png", // 图标路径
				// 	tip: '~ 暂无相关数据 ~', // 提示
				// 	btnText: '去逛逛 >'// 按钮
				// },
				
				// 国际化配置
				emptyOption: {
					i18n: {
						zh: {
							icon: "https://www.mescroll.com/img/mescroll-empty.png", // 图标路径
							tip: '~ 暂无相关数据 ~', // 提示
							btnText: '去逛逛 >'// 按钮
						},
						en: {
							icon: "https://www.mescroll.com/img/mescroll-empty-en.png", // 图标路径
							tip: '~ empty ~',
							btnText: 'go shopping'
						}
					}
				}
			}
		},
		mounted() {
			// 支持动态修改
			// setTimeout(()=>{
			// 	this.emptyOption.tip = "空的"
			// 	this.emptyOption.btnText = ""
			// }, 1000)
		},
		methods:{
			emptyClick(){
				uni.showToast({title: "点击了去逛逛"})
			}
		}
	}
</script>

================================================
FILE: mescroll-uni/pages/base/mescroll-i18n.vue
================================================
<template>
	<view>
		<!-- 菜单 -->
		<view class="top-warp">
			<view class="tip" @click="i18nChange()">点击切换语言</view>
			<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
		</view>
		
		<!-- 列表 -->
		 <mescroll-body :i18n="i18n" @init="mescrollInit" top="120" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick">
			<good-list :list="goods"></good-list>
		</mescroll-body>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				upOption:{
					noMoreSize: 4
				},
				goods: [],
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'面膜',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0,
				i18n:{ // 具体页面的语言配置
					zh: {
						up:{
							empty:{ // 空布局的提示
								tip: '~ 搜索无数据 ~',
								btnText: '去商城逛逛'
							}
						}
					},
					en: {
						up:{
							empty: {
								tip: '~ Search for no data ~',
								btnText: 'go shopping >'
							}
						}
					}
				}
			}
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			//点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:'点击了按钮,具体逻辑自行实现'
				})
			},
			
			// 切换菜单
			tabChange() {
				this.goods = []// 先置空列表,显示加载进度
				this.mescroll.resetUpScroll() // 再刷新列表数据
			},
			
			// 动态设置全局配置 (i18n 国际化)
			i18nChange(){
				// 语言切换
				let i18nType = this.mescroll.i18n.type == 'zh' ? 'en' : 'zh';
				// 动态更新全局配置
				uni.$emit("setMescrollGlobalOption", {i18n: {type: i18nType}})
				// 提示
				let tip = i18nType == 'zh' ? "已切换为中文语言" : "switched to English"
				uni.showToast({icon: "none", title: tip})
			}
		}
	}
</script>

<style>
	.top-warp{
		z-index: 9990;
		position: fixed;
		top: --window-top; /* css变量 */
		left: 0;
		width: 100%;
		height: 120upx;
		background-color: white;
	}
	.top-warp .tip{
		font-size: 28upx;
		height: 60upx;
		line-height: 60upx;
		text-align: center;
		color: red;
	}
</style>

================================================
FILE: mescroll-uni/pages/base/mescroll-more-item.vue
================================================
<template>
	<!-- 不能用v-if (i: 每个tab页的专属下标;  index: 当前tab的下标; 申明在 MescrollMoreItemMixin )-->
	<view v-show="i === index">
		<!-- top="120"下拉布局往下偏移,防止被悬浮菜单遮住 -->
		<mescroll-body @init="mescrollInit" top="120" :down="downOption" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick">
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
	</view>
</template>

<script>
	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";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin,MescrollMoreItemMixin], // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面)
		props:{
			i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
			index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
				type: Number,
				default(){
					return 0
				}
			},
			tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传
				type: Array,
				default(){
					return []
				}
			}
		},
		data() {
			return {
				downOption:{
					auto:false // 不自动加载 (mixin已处理第一个tab触发downCallback)
				},
				upOption:{
					auto:false, // 不自动加载
					// page: {
					// 	num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
					// 	size: 10 // 每页数据的数量
					// },
					noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
					empty:{
						tip: '~ 空空如也 ~', // 提示
						btnText: '去看看'
					}
				},
				goods: [] //列表数据
			}
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				// this.i: 每个tab页的专属下标
				// this.index: 当前tab的下标
				let word = this.tabs[this.i].name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, word).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			//点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:'点击了按钮,具体逻辑自行实现'
				})
			}
		}
	}
</script>


================================================
FILE: mescroll-uni/pages/base/mescroll-more.vue
================================================
<template>
	<view>
		<!-- 菜单 -->
		<view class="top-warp">
			<view class="tip">每个菜单列表仅初始化一次,切换菜单缓存数据</view>
			<!-- 当设置tab-width,指定每个tab宽度时,则不使用flex布局,改用水平滑动 -->
			<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange" :tab-width="130"></me-tabs>
		</view>
		
		<!-- 子组件 (i: 每个tab页的专属下标;  index: 当前tab的下标) -->
		
		<!-- 如果每个子组件布局不一样, 可拆开写 (注意ref只能为 "mescrollItem下标" 的格式, 另外 :i="下标" :index="tabIndex"也是固定写法) : -->
		<!-- <home ref="mescrollItem0" :i="0" :index="tabIndex"></home>
		<shopcart ref="mescrollItem1" :i="1" :index="tabIndex"></shopcart>
		<user ref="mescrollItem2" :i="2" :index="tabIndex"></user> -->
		
		<mescroll-item ref="mescrollItem0" :i="0" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem1" :i="1" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem2" :i="2" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem3" :i="3" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem4" :i="4" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem5" :i="5" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem6" :i="6" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem7" :i="7" :index="tabIndex" :tabs="tabs"></mescroll-item>
		<mescroll-item ref="mescrollItem8" :i="8" :index="tabIndex" :tabs="tabs"></mescroll-item>
		
		<!-- 如果每个子组件布局一样, 则可使用v-for (注意v-for的ref="mescrollItem"必须是固定值)-->
		<!-- <mescroll-item ref="mescrollItem" v-for="(tab,i) in tabs" :key="i" :i="i" :index="tabIndex" :tabs="tabs"></mescroll-item> -->
	</view>
</template>

<script>
	import MescrollItem from "./mescroll-more-item.vue";
	import MescrollMoreMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js";
	
	export default {
		mixins: [MescrollMoreMixin], // 多个mescroll-body写在子组件时, 则使用mescroll-more.js补充子组件的页面生命周期
		components: {
			MescrollItem
		},
		data() {
			return {
				tabs: [{name:'全部'}, {name:'奶粉'}, {name:'面膜'}, {name:'图书'}, {name:'果汁'}, {name:'奶瓶'}, {name:'美素'}, {name:'花王'}, {name:'韩蜜'}],
				tabIndex: 0 // 当前tab下标,必须与mescroll-more.js对应,所以tabIndex是固定变量,不可以改为其他的名字
			}
		},
		onShow() {
			// 返回刷新: https://www.mescroll.com/uni.html#note 第二点
			// if(this.canReset){
			// 	let curMescroll = this.getMescroll(this.tabIndex)
			// 	curMescroll && curMescroll.resetUpScroll()
			// }
			// this.canReset = true
		}
	}
</script>

<style>
	.top-warp{
		z-index: 9990;
		position: fixed;
		top: --window-top; /* css变量 */
		left: 0;
		width: 100%;
		height: 120upx;
		background-color: white;
	}
	.top-warp .tip{
		font-size: 28upx;
		height: 60upx;
		line-height: 60upx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/mescroll-native.vue
================================================
<template>
	<!-- 系统自带的下拉刷新,只能配合mescroll-body使用, 在mescroll-uni中无效 -->
	<mescroll-body @init="mescrollInit" :down="downOption" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick">
		<view class="tip">系统自带的下拉刷新,性能最好,支持条件编译</view>
		<view class="tip">模拟器和真机效果可能不一样,请用真机测试</view>
		<view class="tip" @click="triggerDownScroll">点此主动触发下拉刷新</view>
		<!-- 菜单 -->
		<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
		<!-- 数据列表 -->
		<good-list :list="goods"></good-list>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件,内部已注册onPullDownRefresh)
		data() {
			return {
				downOption:{
					native: true // 必须配置此项,且需在pages.json配置"enablePullDownRefresh" : true
					
					// 支持条件编译,如您可以配置小程序端使用系统自带的,其他平台使用mescroll的下拉样式
					//ifdef MP
					// native: true
					//endif
					//可在mescroll-uni-option.js全局配置native的值
				},
				upOption:{
					noMoreSize: 4, 
					empty:{
						tip: '~ 搜索无数据 ~',
						btnText: '去看看'
					}
				},
				goods: [], //列表数据
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'面膜',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			//点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:'点击了按钮,具体逻辑自行实现'
				})
			},
			
			// 切换菜单
			tabChange() {
				this.goods = []// 先置空列表,显示加载进度
				this.mescroll.resetUpScroll() // 再刷新列表数据
			},
			
			// 主动触发下拉刷新
			triggerDownScroll(){
				this.mescroll.triggerDownScroll()
			}
		}
	}
</script>

<style>
	.tip{
		font-size: 28upx;
		height: 60upx;
		line-height: 60upx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/mescroll-one.vue
================================================
<template>
	<view>
		<!-- 菜单 -->
		<view class="top-warp">
			<view class="tip">每次切换菜单及时刷新列表,不缓存数据</view>
			<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
		</view>
		
		<!-- top="xxx"下拉布局往下偏移,防止被悬浮菜单遮住 -->
		 <mescroll-body @init="mescrollInit" top="120" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick">
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				upOption:{
					// page: {
					// 	num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
					// 	size: 10 // 每页数据的数量
					// },
					noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
					empty:{
						tip: '~ 搜索无数据 ~', // 提示
						btnText: '去看看'
					}
				},
				goods: [], //列表数据
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'面膜',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			//点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:'点击了按钮,具体逻辑自行实现'
				})
			},
			
			// 切换菜单
			tabChange() {
				this.goods = []// 先置空列表,显示加载进度
				this.mescroll.resetUpScroll() // 再刷新列表数据
			}
		}
	}
</script>

<style>
	.top-warp{
		z-index: 9990;
		position: fixed;
		top: --window-top; /* css变量 */
		left: 0;
		width: 100%;
		height: 120upx;
		background-color: white;
	}
	.top-warp .tip{
		font-size: 28upx;
		height: 60upx;
		line-height: 60upx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/mescroll-options.vue
================================================
<template>
	<mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback" 
	 :down="downOption" 
	 :up="upOption" 
	 :top="0" 
	 :bottom="0" 
	 :topbar="false" 
	 :bottombar="true" 
	 :fixed="true" 
	 height="100%" 
	 :safearea="false" 
	 :sticky="true"
	 @emptyclick="emptyClick" 
	 @topclick="topClick" 
	 @scroll="scroll">
	 
		<view class="tip">展示down和up的所有配置项</view>
		<view class="tip" @click="triggerDownScroll">点此主动触发下拉刷新</view>
		<view class="tip" @click="scrollToY(200)">点此测试滚动到指定位置 (如: 200px)</view>
		<!-- 滚动到本页元素,只需普通的id或class选择器即可 -->
		<view class="tip" @click="scrollIntoView('#anchorPoint')" id="anchorPoint">点此测试滚动到指定view (元素在本页)</view>
		<!-- 滚动到子组件,小程序必须用'跨自定义组件的后代选择器' -->
		<view class="tip" @click="scrollIntoView('.good-comp >>> #good2')">点此测试滚动到指定view (元素在子组件)</view>
		
		<!-- sticky吸顶悬浮的菜单 (父元素必须是 mescroll, 且mescroll配置:sticky="true") -->
		<view class="sticky-tabs">
			<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
		</view>
		
		<!-- 视频请尽量使用me-video组件 (video在APP中是原生组件, 真机APP端下拉渲染不及时.) -->
		<!-- 使用me-video组件, 未播放时自动展示image封面, 播放时才显示video, 提高性能; 当加上 :mescroll="mescroll"之后, 如果播放中执行下拉,会自动隐藏视频,显示封面,避免视频下拉悬浮错位(仅APP端这样处理) -->
		<me-video v-if="tabIndex==0" :mescroll="mescroll" poster="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-mescroll/2e3cd7a0-f31a-11ea-81ea-f115fe74321c.png" src="https://vkceyugu.cdn.bspapp.com/VKCEYUGU-mescroll/2ae5d090-f26e-11ea-81ea-f115fe74321c.mp4"></me-video>
		
		<!-- 商品组件 -->
		<good-list class="good-comp" :list="goods"></good-list>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				downOption: {
					use: true, // 是否启用下拉刷新; 默认true
					auto: true, // 是否在初始化完毕之后自动执行下拉刷新的回调; 默认true
					native: false, // 是否使用系统自带的下拉刷新; 默认false; 仅mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
					autoShowLoading: false, // 如果设置auto=true(在初始化完毕之后自动执行下拉刷新的回调),那么是否显示下拉刷新的进度; 默认false
					isLock: false, // 是否锁定下拉刷新,默认false;
					offset: 80, // 在列表顶部,下拉大于80upx,松手即可触发下拉刷新的回调
					inOffsetRate: 1, // 在列表顶部,下拉的距离小于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
					outOffsetRate: 0.2, // 在列表顶部,下拉的距离大于offset时,改变下拉区域高度比例;值小于1且越接近0,高度变化越小,表现为越往下越难拉
					bottomOffset: 20, // 当手指touchmove位置在距离body底部20upx范围内的时候结束上拉刷新,避免Webview嵌套导致touchend事件不执行
					minAngle: 45, // 向下滑动最少偏移的角度,取值区间  [0,90];默认45度,即向下滑动的角度大于45度则触发下拉;而小于45度,将不触发下拉,避免与左右滑动的轮播等组件冲突;
					beforeEndDelay: 0, // 延时结束的时长 (显示加载成功/失败的时长, android小程序设置此项结束下拉会卡顿, 配置后请注意测试)
					bgColor: "#E75A7C", // 背景颜色 (建议在pages.json中再设置一下backgroundColorTop)
					textColor: "#fff", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
					textInOffset: '下拉刷新', // 下拉的距离在offset范围内的提示文本
					textOutOffset: '释放更新', // 下拉的距离大于offset范围的提示文本
					textLoading: '加载中 ...' // 加载中的提示文本
				},
				upOption: {
					use: true, // 是否启用上拉加载; 默认true
					auto: true, // 是否在初始化完毕之后自动执行上拉加载的回调; 默认true
					isLock: false, // 是否锁定上拉加载,默认false;
					isBoth: true, // 上拉加载时,如果滑动到列表顶部是否可以同时触发下拉刷新;默认true,两者可同时触发;
					page: {
						num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
						size: 10, // 每页数据的数量
						time: null // 加载第一页数据服务器返回的时间; 防止用户翻页时,后台新增了数据从而导致下一页数据重复;
					},
					noMoreSize: 3, // 如果列表已无数据,可设置列表的总数量要大于等于5条才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看
					offset: 80, // 距底部多远时,触发upCallback(仅mescroll-uni生效, 对于mescroll-body则需在pages.json设置"onReachBottomDistance")
					bgColor: "transparent", // 背景颜色 (建议在pages.json中再设置一下backgroundColorTop)
					textColor: "gray", // 文本颜色 (当bgColor配置了颜色,而textColor未配置时,则textColor会默认为白色)
					textLoading: '加载中 ...', // 加载中的提示文本
					textNoMore: '-- END --', // 没有更多数据的提示文本
					toTop: {
						// 回到顶部按钮,需配置src才显示
						src: "https://www.mescroll.com/img/mescroll-totop.png", // 图片路径
						offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000
						duration: 300, // 回到顶部的动画时长,默认300ms (当值为0或300则使用系统自带回到顶部,更流畅; 其他值则通过step模拟,部分机型可能不够流畅,所以非特殊情况不建议修改此项)
						zIndex: 9990, // fixed定位z-index值
						left: null, // 到左边的距离, 默认null. 此项有值时,right不生效. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
						right: 20, // 到右边的距离, 默认20 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
						bottom: 120, // 到底部的距离, 默认120 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
						safearea: false, // bottom的偏移量是否加上底部安全区的距离, 默认false, 需要适配iPhoneX时使用 (具体的界面如果不配置此项,则取mescroll组件props的safearea值)
						width: 72, // 回到顶部图标的宽度, 默认72 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
						radius: "50%" // 圆角, 默认"50%" (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx)
					},
					empty: {
						use: true, // 是否显示空布局
						icon: "https://www.mescroll.com/img/mescroll-empty.png", // 图标路径
						tip: '~ 暂无相关数据 ~', // 提示
						btnText: '去逛逛 >', // 按钮
						fixed: false, // 是否使用fixed定位,默认false; 配置fixed为true,以下的top和zIndex才生效 (transform会使fixed失效,最终会降级为absolute)
						top: "100rpx", // fixed定位的top值 (完整的单位值,如 "10%"; "100rpx")
						zIndex: 99 // fixed定位z-index值
					},
					onScroll: true // 是否监听滚动事件, 默认false, 仅mescroll-uni生效; mescroll-body直接声明onPageScroll (配置为true时,可@scroll="scroll"获取到滚动条位置和方向; 注意监听列表滚动是非常耗性能的,很容易出现卡顿,非特殊情况不要配置此项)
				},
				goods: [], //列表数据
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					//mescroll会根据传的参数,自动判断列表如果无任何数据,则提示空;列表无下一页数据,则提示无更多数据;

					//方法一(推荐): 后台接口有返回列表的总页数 totalPage
					//this.mescroll.endByPage(res.list.length, res.totalPage); //必传参数(当前页的数据个数, 总页数)

					//方法二(推荐): 后台接口有返回列表的总数据量 totalSize
					//this.mescroll.endBySize(res.list.length, res.totalSize); //必传参数(当前页的数据个数, 总数据量)

					//方法三(推荐): 您有其他方式知道是否有下一页 hasNext
					//this.mescroll.endSuccess(res.list.length, res.hasNext); //必传参数(当前页的数据个数, 是否有下一页true/false)

					//方法四 (不推荐),会存在一个小问题:比如列表共有20条数据,每页加载10条,共2页.如果只根据当前页的数据个数判断,则需翻到第三页才会知道无更多数据
					this.mescroll.endSuccess(res.list.length);

					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
					
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:"点击了按钮"
				})
			},
			// 点击回到顶部按钮的回调
			topClick(){
				console.log('点击了回到顶部按钮');
			},
			// mescroll-uni滚动事件 (需在up配置onScroll:true才生效, mescroll-body直接声明onPageScroll)
			scroll(){
				console.log('mescroll元素id: '+this.mescroll.viewId+' , 滚动内容高度:'+this.mescroll.getScrollHeight() + ', mescroll高度:'+this.mescroll.getClientHeight() + ', 滚动条位置:'+this.mescroll.getScrollTop() + ', 距离底部:'+this.mescroll.getScrollBottom() + ', 是否向上滑:'+this.mescroll.isScrollUp)
			},
			// 切换菜单
			tabChange() {
				this.goods = []// 先置空列表,显示加载进度
				this.mescroll.resetUpScroll() // 再刷新列表数据
			},
			// 主动触发下拉刷新
			triggerDownScroll(){
				this.mescroll.triggerDownScroll()
			},
			// 滚动到指定位置,传数字 (单位px)
			scrollToY(y){
				// this.mescroll.scrollTo(y) // 过渡动画时长默认300ms
				this.mescroll.scrollTo(y, 0) // 无过渡动画
			},
			// 滚动到指定view,传view的id
			scrollIntoView(viewId){
				// this.mescroll.scrollTo(viewId) // 过渡动画时长默认300ms
				this.mescroll.scrollTo(viewId, 0) // 无过渡动画
			}
		},
		// mescroll-body的滚动事件是页面的滚动事件
		// onPageScroll(e){
		// 	console.log("mescroll-body的滚动事件e.scrollTop=" + e.scrollTop);
		// }
	}
</script>

<style>
	.tip{
		font-size: 28upx;
		height: 60upx;
		line-height: 60upx;
		text-align: center;
	}
	
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: var(--window-top);
		background-color: #fff;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/mescroll-uni-part.vue
================================================
<template>
	<!-- mescroll-uni本质是scroll-view,支持局部区域滚动,可使用flex布局灵活的嵌在某个view中, 而mescroll-body只能靠fixed定位其他元素变相实现'局部滚动' -->
	<view class="page-warp">
		
		<view class="top-warp">
			<view>顶部区域</view>
			<view style="font-size: 24rpx;">mescroll-uni 支持局部区域滚动,支持使用flex嵌在某个view</view>
		</view>
		
		<view class="center-warp">
			<!-- 左边 -->
			<scroll-view class="left-warp" :scroll-y="true">
				<view class="tab" :class="{active:i==tabIndex}" v-for="(tab,i) in tabs" :key="i" @click="tabChange(i)">{{tab}}</view>
			</scroll-view>
			
			<view class="right-warp">
				<!--右边 :fixed="false", 高度跟随父元素 (不在组件上定义class,避免部分小程序平台编译丢失, 如支付宝,钉钉小程序) -->
				<mescroll-uni :fixed="false" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
					<good-list :list="goods"></good-list>
				</mescroll-uni>
			</view>
		</view>
		
		<view class="bottom-warp"> 底部区域 </view>
		
	</view>
</template>


<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods, apiGetTabs} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: [], // tabs异步获取
				// tabs: ['全部', '奶粉', '面膜', '图书', '果汁', '奶瓶', '美素', '花王', '韩蜜', '口红', '毛巾', '玩具', '衣服'],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			upCallback(page) {
				// tabs异步获取
				if(this.tabs.length == 0){
					apiGetTabs().then(res=>{
						this.tabs = res
						this.mescroll.resetUpScroll() // 重新触发upCallback
					}).catch(()=>{
						this.mescroll.endErr()
					})
					return // 此处return,先获取tabs
				}
				
				//联网加载数据
				let keyword = this.tabs[this.tabIndex]
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange(i){
				if(this.tabIndex != i){
					this.tabIndex = i
					this.goods = []; // 先置空列表,显示加载进度条
					this.mescroll.resetUpScroll(); // 重置列表数据
				}
			}
		}
	}
</script>


<style lang="scss">
	/*根元素需要有固定的高度*/
	page{
		height: 100%;
		// 支付宝小程序,钉钉小程序需添加绝对定位,否则height:100%失效: https://opendocs.alipay.com/mini/framework/acss#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
		/* #ifdef MP-ALIPAY || MP-DINGTALK*/
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		/* #endif */
		
		/*需给父元素设置height:100%*/
		.page-warp{
			height: 100%;
			display: flex;
			flex-direction: column;
			
			/* 顶部区域 */
			.top-warp{
				font-size: 28rpx;
				padding: 20rpx;
				text-align: center;
				background-color: #CFE0DA;
			}
			
			/* 中间 */
			.center-warp{
				flex: 1;
				min-width: 0;
				min-height: 0;/* 需给flex:1的元素加上最小高,否则内容超过会溢出容器 (如:小程序Android真机) */
				border: 4px solid red;
				display: flex;
				
				// 左边
				.left-warp{
					width: 180rpx;
					height: 100%;
					background-color: #eee;
					.tab{
						font-size: 28rpx;
						padding: 28rpx;
						&.active{
							background-color: #fff;
						}
					}
				}
				
				// 右边
				.right-warp{
					flex: 1;
					min-width: 0;
				}
			}
			
			/* 底部区域 */
			.bottom-warp{
				padding: 20rpx;
				text-align: center;
				background-color: #FF6990;
			}
		}
	}
</style>

================================================
FILE: mescroll-uni/pages/base/mescroll-uni.vue
================================================
<template>
	<view>
		<!-- 菜单 -->
		<view class="top-warp">
			<view class="tip">基于scroll-view,常用在浮窗弹层等局部滚动区域</view>
			<view class="tip" @click="triggerDownScroll">点此主动触发下拉刷新</view>
			<view class="tip" @click="scrollToY(200)">点此测试滚动到指定位置 (如: 200px)</view>
			<!-- 滚动到本页元素,只需普通的id或class选择器即可 -->
			<view class="tip" @click="scrollIntoView('#anchorPoint')">点此测试滚动到指定view (元素在本页)</view>
			<!-- 滚动到子组件,小程序必须用'跨自定义组件的后代选择器' -->
			<view class="tip" @click="scrollIntoView('.good-comp >>> #good2')">点此测试滚动到指定view (元素在子组件)</view>
			<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
		</view>
		
		<!-- top="xxx"下拉布局往下偏移,防止被悬浮菜单遮住 -->
		 <mescroll-uni @init="mescrollInit" top="365" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick">
			<!-- 大海报 -->
			<image id="anchorPoint" v-if="tabIndex==0" src="https://www.mescroll.com/img/taobao/taobao3.jpg" mode="widthFix" style="width: 100%"/>
			 
			<!-- 数据列表 -->
			<good-list class="good-comp" :list="goods"></good-list>
		</mescroll-uni>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				upOption:{
					// page: {
					// 	size: 10 // 每页数据的数量
					// },
					noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
					empty:{
						tip: '~ 搜索无数据 ~', // 提示
						btnText: '去看看'
					}
				},
				goods: [], //列表数据
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'面膜',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			//点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:'点击了按钮,具体逻辑自行实现'
				})
			},
			
			// 切换菜单
			tabChange() {
				this.goods = []// 先置空列表,显示加载进度
				this.mescroll.resetUpScroll() // 再刷新列表数据
			},
			
			// 主动触发下拉刷新
			triggerDownScroll(){
				this.mescroll.scrollTo(0, 0)
				this.mescroll.triggerDownScroll()
			},
			// 滚动到指定位置,传数字 (单位px)
			scrollToY(y){
				// this.mescroll.scrollTo(y) // 过渡动画时长默认300ms
				this.mescroll.scrollTo(y, 0) // 无过渡动画
			},
			// 滚动到指定view,传view的id
			scrollIntoView(viewId){
				// this.mescroll.scrollTo(viewId) // 过渡动画时长默认300ms
				this.mescroll.scrollTo(viewId, 0) // 无过渡动画
			}
		}
	}
</script>

<style>
	.top-warp{
		z-index: 9990;
		position: fixed;
		top: --window-top; /* css变量 */
		left: 0;
		width: 100%;
		height: 365upx;
		background-color: white;
	}
	.top-warp .tip{
		font-size: 28upx;
		height: 60upx;
		line-height: 60upx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/sticky-data.vue
================================================
<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->
<template>
	<view>
		<!-- 对于mescroll-body: 需设置:sticky="true", 此应避免在mescroll-body标签前面加其他非定位的元素, 否则下拉区域会被挤出, 无法会隐藏.-->
		<!-- 对于mescroll-uni: 则无需设置:sticky="true", 无其他限制和要求 -->
		<mescroll-body :sticky="true" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
				</swiper-item>
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
				</swiper-item>
			</swiper>
			
			<view class="demo-tip">
				<view>列表只初始化一次,切换菜单缓存数据</view>
				<view>吸顶通过给菜单加position:sticky实现, 用法简单</view>
				<view>小程序,微信h5端: 低端机sticky也可生效, 可放心使用</view>
				<view>APP端: 仅部分低端机无效,若要兼容则参考sticky-scroll</view>
			</view>
			
			<!-- sticky吸顶悬浮的菜单, 父元素必须是 mescroll -->
			<view class="sticky-tabs">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
		
		<!-- 此处可以写其他fixed定位元素 -->
		<!-- <view></view> -->
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				tabs:[
					{name:'全部', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'母婴', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'图书', goods: null, num:1, y:0, curPageLen:0, hasNext:true}
					],
				tabIndex: 0 // 当前菜单下标
			}
		},
		computed: {
			// 列表数据
			goods() {
				return this.tabs[this.tabIndex].goods
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				let keyword = this.tabs[this.tabIndex].name;
				apiGoods(page.num, page.size, keyword).then(res=>{
					// 当前tab数据
					let curTab = this.tabs[this.tabIndex]
					
					// 设置列表数据
					if(page.num == 1) curTab.goods = []; //如果是第一页需手动制空列表
					curTab.goods = curTab.goods.concat(res.list); //追加新数据
					curTab.num = page.num; // 页码
					curTab.curPageLen = res.list.length; // 当前页长
					curTab.hasNext = this.mescroll.optUp.hasNext; // 是否还有下一页
					
					// 需先隐藏加载状态
					this.mescroll.endSuccess(res.list.length);
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange (index) {
				// 记录切换前滚动条的位置
				if(!this.preIndex) this.preIndex = 0
				let preTab = this.tabs[this.preIndex]
				preTab.y = this.mescroll.getScrollTop()
				this.preIndex = index;
				// 当前菜单的数据
				let curTab = this.tabs[index]
				if (!curTab.goods) {
					// 没有初始化,则初始化
					this.mescroll.resetUpScroll()
				} else{
					// 初始化过,则恢复之前的列表数据
					this.mescroll.setPageNum(curTab.num + 1); // 恢复当前页码
					this.mescroll.endSuccess(curTab.curPageLen, curTab.hasNext); // 恢复是否有下一页或显示空布局
					this.$nextTick(()=>{
						this.mescroll.scrollTo(curTab.y, 0) // 恢复滚动条的位置
					})
				}
			}
		}
	}
</script>

<style lang="scss">
	/*
	sticky生效条件:
	1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
	2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
	3、父元素的高度不能低于sticky元素的高度
	4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
	*/
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: var(--window-top);
		background-color: #fff;
	}
	
	// 使用mescroll-uni,则top为0
	.mescroll-uni,
	/deep/.mescroll-uni{
		.sticky-tabs{
			top: 0;
		}
	}
	
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/sticky-scroll-data.vue
================================================
<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->
<template>
	<view>
		<!-- 菜单 (悬浮,预先隐藏)-->
		<me-tabs v-if="isShowSticky" v-model="tabIndex" :fixed="true" :tabs="tabs" @change="tabChange"></me-tabs>
		
		 <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption" @scroll="scroll" @topclick="topClick">
			<!--轮播-->
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
		        <swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
		        </swiper-item>
				<swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
		        </swiper-item>
		    </swiper>
			
			<view class="demo-tip">
				<view>列表只初始化一次,切换菜单缓存数据</view>
				<view>吸顶通过监听滚动条实现, 比sticky复杂, 但APP端可兼容低端机</view>
			</view>
			
			<!-- 菜单 (在mescroll-uni中不能使用fixed,否则iOS滚动时会抖动, 所以需在mescroll-uni之外存在一个一样的菜单) -->
			<view id="tabInList">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				upOption: {
					// 如果用mescroll-uni 则需要onScroll: true, 且需要 @scroll="scroll"; 而mescroll-body最简单只需在onPageScroll处理即可
					// onScroll: true // 是否监听滚动事件, 默认false (配置为true时,可@scroll="scroll"获取到滚动条位置和方向)
				},
				tabs:[
					{name:'全部', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'母婴', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'图书', goods: null, num:1, y:0, curPageLen:0, hasNext:true}
					],
				tabIndex: 0, // 当前菜单下标
				preIndex: 0, // 前一个菜单下标
				navTop: null, // nav距离到顶部的距离 (如计算不准确,可直接写死某个值)
				isShowSticky: false // 是否悬浮
			}
		},
		computed: {
			// 列表数据
			goods() {
				return this.tabs[this.tabIndex].goods
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				if(this.isChangeTab){
					this.mescroll.hideUpScroll(); // 切换菜单,不显示mescroll进度, 显示系统进度条
					uni.showLoading();
				}
				let keyword = this.tabs[this.tabIndex].name;
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调
					
					// 当前tab数据
					let curTab = this.tabs[this.tabIndex]
					
					//设置列表数据
					if(page.num == 1) curTab.goods = []; //如果是第一页需手动制空列表
					curTab.goods=curTab.goods.concat(res.list); //追加新数据
					
					// 数据渲染完毕再隐藏加载状态 this.$nextTick在iOS真机不触发,需改成setTimeout
					// this.$nextTick(()=>{
					setTimeout(()=>{
						// 需先隐藏加载状态
						this.mescroll.endSuccess(res.list.length);
						// 再记录当前页的数据
						curTab.num = page.num; // 页码
						curTab.curPageLen = res.list.length; // 当前页长
						curTab.hasNext = this.mescroll.optUp.hasNext; // 是否还有下一页
						
						// 设置nav到顶部的距离 (需根据自身的情况获取navTop的值, 这里放到列表数据渲染完毕之后)
						// 也可以放到onReady里面,或者菜单顶部的数据(轮播等)加载完毕之后..
						if(!this.navTop) this.setNavTop()
						// 保持tab悬浮,列表数据显示第一条
						if(this.isChangeTab){
							this.isChangeTab = false;
							uni.hideLoading();
							if(this.isShowSticky) this.mescroll.scrollTo(this.navTop, 0)
						}
					},20)
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 设置nav到顶部的距离 (滚动条为0, 菜单顶部的数据加载完毕获取到的navTop数值是最精确的)
			setNavTop(){
				let view = uni.createSelectorQuery().select('#tabInList');
				view.boundingClientRect(data => {
					console.log('tabInList基本信息 = ' + JSON.stringify(data));
					this.navTop = data.top // 到屏幕顶部的距离
				}).exec();
			},
			// mescroll-uni的滚动事件 (需在up配置onScroll:true才生效)
			// 而mescroll-body最简单只需在onPageScroll处理即可
			scroll(){
				console.log('滚动条位置 = ' + this.mescroll.getScrollTop() + ', navTop = ' + this.navTop);
				// 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏
				if (this.mescroll.getScrollTop() >= this.navTop) {
					this.isShowSticky = true // 显示悬浮菜单
				} else {
					this.isShowSticky = false // 隐藏悬浮菜单
				}
			},
			// 点击回到顶部按钮时,先隐藏悬浮菜单,避免闪动
			topClick(){
				this.isShowSticky = false
			},
			// 切换菜单
			tabChange (index) {
				// 记录前一个菜单的数据
				let preTab = this.tabs[this.preIndex]
				preTab.y = this.mescroll.getScrollTop(); // 滚动条位置
				this.preIndex = index;
				// 当前菜单的数据
				let curTab = this.tabs[index]
				if (!curTab.goods) {
					// 没有初始化,则初始化
					this.isChangeTab = true;
					this.mescroll.resetUpScroll()
				} else{
					// 初始化过,则恢复之前的列表数据
					this.mescroll.setPageNum(curTab.num + 1); // 恢复当前页码
					this.mescroll.endSuccess(curTab.curPageLen, curTab.hasNext); // 恢复是否有下一页或显示空布局
					this.$nextTick(()=>{
						this.mescroll.scrollTo(curTab.y, 0) // 恢复滚动条的位置
					})
				}
			}
		},
		// 使用mescroll-body最简单只需在onPageScroll处理即可
		onPageScroll(e){
			console.log('滚动条位置 = ' + e.scrollTop + ', navTop = ' + this.navTop);
			if (e.scrollTop >= this.navTop) {
				this.isShowSticky = true // 显示悬浮菜单
			} else {
				this.isShowSticky = false // 隐藏悬浮菜单
			}
		}
	}
</script>

<style>
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/sticky-scroll.vue
================================================
<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->
<template>
	<view>
		<!-- 菜单 (悬浮,预先隐藏)-->
		<me-tabs v-if="isShowSticky" v-model="tabIndex" :fixed="true" :tabs="tabs" @change="tabChange"></me-tabs>
		
		 <mescroll-body ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption" @scroll="scroll" @topclick="topClick">
			<!--轮播-->
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
		        <swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
		        </swiper-item>
				<swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
		        </swiper-item>
		    </swiper>
			
			<view class="demo-tip">
				<view>每次切换菜单都刷新列表数据</view>
				<view>吸顶通过监听滚动条实现, 比sticky复杂, 但APP端可兼容低端机</view>
			</view>
			
			<!-- 菜单 (在mescroll-uni中不能使用fixed,否则iOS滚动时会抖动, 所以需在mescroll-uni之外存在一个一样的菜单) -->
			<view id="tabInList">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				upOption: {
					// 如果用mescroll-uni 则需要onScroll: true, 且需要 @scroll="scroll"; 而mescroll-body最简单只需在onPageScroll处理即可
					// onScroll: true // 是否监听滚动事件, 默认false (配置为true时,可@scroll="scroll"获取到滚动条位置和方向)
				},
				tabs: ['全部', '母婴', '图书'],
				tabIndex: 0, // tab下标
				navTop: null, // nav距离到顶部的距离 (如计算不准确,可直接写死某个值)
				isShowSticky: false // 是否悬浮
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				if(this.isChangeTab){
					this.mescroll.hideUpScroll(); // 切换菜单,不显示mescroll进度, 显示系统进度条
					uni.showLoading();
				}
				let keyword = this.tabs[this.tabIndex]
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调

					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
					
					// 数据渲染完毕再隐藏加载状态 this.$nextTick在iOS真机不触发,需改成setTimeout
					// this.$nextTick(()=>{
					setTimeout(()=>{
						this.mescroll.endSuccess(res.list.length);
						// 设置nav到顶部的距离 (需根据自身的情况获取navTop的值, 这里放到列表数据渲染完毕之后)
						// 也可以放到onReady里面,或者菜单顶部的数据(轮播等)加载完毕之后..
						if(!this.navTop) this.setNavTop()
						// 保持tab悬浮,列表数据显示第一条
						if(this.isChangeTab){
							this.isChangeTab = false;
							uni.hideLoading();
							if(this.isShowSticky) this.mescroll.scrollTo(this.navTop, 0)
						}
					},20)
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 设置nav到顶部的距离 (滚动条为0, 菜单顶部的数据加载完毕获取到的navTop数值是最精确的)
			setNavTop(){
				let view = uni.createSelectorQuery().select('#tabInList');
				view.boundingClientRect(data => {
					console.log('tabInList基本信息 = ' + JSON.stringify(data));
					this.navTop = data.top // 到屏幕顶部的距离
				}).exec();
			},
			// mescroll-uni的滚动事件 (需在up配置onScroll:true才生效)
			// 而mescroll-body最简单只需在onPageScroll处理即可
			scroll(){
				console.log('滚动条位置 = ' + this.mescroll.getScrollTop() + ', navTop = ' + this.navTop);
				// 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏
				if (this.mescroll.getScrollTop() >= this.navTop) {
					this.isShowSticky = true // 显示悬浮菜单
				} else {
					this.isShowSticky = false // 隐藏悬浮菜单
				}
			},
			// 点击回到顶部按钮时,先隐藏悬浮菜单,避免闪动
			topClick(){
				this.isShowSticky = false
			},
			// 切换菜单
			tabChange () {
				this.isChangeTab = true;
				this.mescroll.resetUpScroll()
			}
		},
		// 使用mescroll-body最简单只需在onPageScroll处理即可
		onPageScroll(e){
			console.log('滚动条位置 = ' + e.scrollTop + ', navTop = ' + this.navTop);
			if (e.scrollTop >= this.navTop) {
				this.isShowSticky = true // 显示悬浮菜单
			} else {
				this.isShowSticky = false // 隐藏悬浮菜单
			}
		}
	}
</script>

<style>
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/sticky-uni.vue
================================================
<template>
	<view>
		<mescroll-uni ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
				</swiper-item>
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
				</swiper-item>
			</swiper>
			
			<view class="demo-tip">
				<view>仅测试mescroll-uni使用sticky的情况</view>
				<view>与mescroll-body使用的区别:</view>
				<view>1. mescroll-uni 无需配置 :sticky="true"</view>
				<view>2. sticky的top 无需考虑var(--window-top)</view>
			</view>
			
			<!-- sticky吸顶悬浮的菜单, 父元素必须是 mescroll -->
			<view class="sticky-tabs">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-uni>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: ['全部', '母婴', '图书'],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				let keyword = this.tabs[this.tabIndex]
				apiGoods(page.num, page.size, keyword).then(res=>{
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
					this.mescroll.endSuccess(res.list.length); // 隐藏加载状态栏
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange () {
				this.goods = []; // 置空列表,显示加载进度条
				this.mescroll.resetUpScroll()
			}
		}
	}
</script>

<style lang="scss">
	/*
	sticky生效条件:
	1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
	2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
	3、父元素的高度不能低于sticky元素的高度
	4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
	*/
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: 0;
		background-color: #fff;
	}
	
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/base/sticky.vue
================================================
<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->
<template>
	<view>
		<!-- 对于mescroll-body: 需设置:sticky="true", 此应避免在mescroll-body标签前面加其他非定位的元素, 否则下拉区域会被挤出, 无法会隐藏.-->
		<!-- 对于mescroll-uni: 则无需设置:sticky="true", 无其他限制和要求 -->
		<mescroll-body :sticky="true" ref="mescrollRef" @init="mescrollInit" @down="downCallback" @up="upCallback">
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
				</swiper-item>
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
				</swiper-item>
			</swiper>
			
			<view class="demo-tip">
				<view>每次切换菜单,都刷新列表数据</view>
				<view>吸顶通过给菜单加position:sticky实现, 用法简单</view>
				<view>小程序和微信h5端: 低端机sticky也可生效, 可放心使用</view>
				<view>APP端: 仅部分低端机无效,若要兼容则参考sticky-scroll</view>
			</view>
			
			<!-- sticky吸顶悬浮的菜单, 父元素必须是 mescroll -->
			<view class="sticky-tabs">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
		
		<!-- 此处可以写其他fixed定位元素 -->
		<!-- <view></view> -->
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: ['全部', '母婴', '图书'],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				let keyword = this.tabs[this.tabIndex]
				apiGoods(page.num, page.size, keyword).then(res=>{
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
					this.mescroll.endSuccess(res.list.length); // 隐藏加载状态栏
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange () {
				this.goods = []; // 置空列表,显示加载进度条
				this.mescroll.resetUpScroll()
			}
		}
	}
</script>

<style lang="scss">
	/*
	sticky生效条件:
	1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
	2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
	3、父元素的高度不能低于sticky元素的高度
	4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
	*/
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: var(--window-top);
		background-color: #fff;
	}
	
	// 使用mescroll-uni,则top为0
	.mescroll-uni,
	/deep/.mescroll-uni{
		.sticky-tabs{
			top: 0;
		}
	}
	
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/index/index.vue
================================================
<template>
	<view>
		
		<view class="group-title">base demos 基础案例</view>
		
		<navigator url="/pages/base/list-products">
			<view class="demo-li">mescroll 极简示例 <text class="demo-tip">大部分情况就是这么用</text></view>
		</navigator>
		
		<navigator url="/pages/base/mescroll-options">
			<view class="demo-li">mescroll-options 所有配置项 <text class="demo-tip">快速熟悉mescroll</text></view>
		</navigator>
		
		<navigator url="/pages/base/mescroll-comp">
			<view class="demo-li">mescroll-body写在子组件中 <text class="demo-tip">需引mescroll-comp.js</text></view>
		</navigator>
		
		<navigator url="/pages/base/mescroll-one">
			<view class="demo-li">mescroll-one 单mescroll<text class="demo-tip">切换菜单,及时刷新数据</text></view>
		</navigator>
		
		<navigator url="/pages/base/mescroll-more">
			<view class="demo-li">mescroll-more 多mescroll<text class="demo-tip">列表仅初始化一次,缓存数据</text></view>
		</navigator>
		
		<navigator url="/pages/base/list-search">
			<view class="demo-li">list-search 商品搜索<text class="demo-tip">this.mescroll.resetUpScroll()的使用</text></view>
		</navigator>
		
		<navigator url="/pages/base/list-news">
			<view class="demo-li">list-news 新闻列表 <text class="demo-tip">下拉刷新添加数据到列表顶部</text></view>
		</navigator>
		
		
		<navigator url="/pages/base/mescroll-native">
			<view class="demo-li">mescroll-native<text class="demo-tip">系统自带的下拉刷新,性能最好</text></view>
		</navigator>
		
		<navigator url="/pages/base/mescroll-uni">
			<view class="demo-li">mescroll-uni<text class="demo-tip">基于scroll-view,常用在浮窗弹层等局部区域</text></view>
		</navigator>
		
		<navigator url="/pages/base/mescroll-empty">
			<view class="demo-li">mescroll-empty<text class="demo-tip">空布局的单独使用</text></view>
		</navigator>
		
		<navigator url="/pages/base/mescroll-i18n">
			<view class="demo-li">mescroll-i18n<text class="demo-tip">语言国际化</text></view>
		</navigator>
		
		<view class="group-title">intermediate demos 中级案例</view>
		
		<navigator url="/pages/intermediate/list-msg">
			<view class="demo-li">list-msg 聊天记录 <text class="demo-tip">保持当前内容的位置</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/mescroll-uni-part">
			<view class="demo-li">mescroll-uni-part<text class="demo-tip">mescroll-uni用flex实现局部区域滚动</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/mescroll-body-part">
			<view class="demo-li">mescroll-body-part<text class="demo-tip">mescroll-body实现"局部区域"滚动</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/sticky">
			<view class="demo-li">sticky吸顶悬浮<text class="demo-tip">切换菜单刷新列表, 原生css实现</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/sticky-data">
			<view class="demo-li">sticky-data吸顶悬浮<text class="demo-tip">切换菜单缓存数据, 原生css实现</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/sticky-scroll">
			<view class="demo-li">sticky-scroll吸顶悬浮<text class="demo-tip">切换tab刷新列表,监听滚动实现</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/sticky-scroll-data">
			<view class="demo-li">sticky-scroll-data吸顶悬浮<text class="demo-tip">切换tab缓存数据,监听滚动实现</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/sticky-uni">
			<view class="demo-li">sticky-uni吸顶悬浮<text class="demo-tip">测试mescroll-uni使用sticky</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/mescroll-swiper">
			<view class="demo-li">mescroll-swiper<text class="demo-tip">轮播菜单导航</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/mescroll-swiper-sticky">
			<view class="demo-li">mescroll-swiper-sticky<text class="demo-tip">吸顶轮播菜单导航</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/beibei">
			<view class="demo-li">仿【贝贝】下拉刷新上拉加载<text class="demo-tip">自定义mescroll组件</text></view>
		</navigator>
		
		<navigator url="/pages/intermediate/xinlang">
			<view class="demo-li">仿【新浪微博】下拉刷新上拉加载<text class="demo-tip">自定义mescroll组件</text></view>
		</navigator>
		
		
		<view class="group-title">senior demos 高级案例</view>
		<view class="demo-li disable">仿【美囤妈妈】下拉刷新上拉加载<text class="demo-tip">请到官网获取</text></view>
		<view class="demo-li disable">仿【美团】下拉刷新上拉加载<text class="demo-tip">请到官网获取</text></view>
		<view class="demo-li disable">仿【京东】下拉刷新上拉加载<text class="demo-tip">请到官网获取</text></view>
		<view class="demo-li disable">仿【淘宝】下拉刷新上拉加载<text class="demo-tip">请到官网获取</text></view>
	</view>
</template>

<script>
	export default {
		onLoad() {
			uni.setNavigationBarTitle({
				title: 'mescroll ('+ uni.getSystemInfoSync().platform + ')'
			})
		}
	}
</script>

<style>
	.group-title {
		font-size: 30upx;
		padding: 24upx;
		border-bottom: 1upx solid #eee;
		color: red;
	}

	.demo-li {
		font-size: 28upx;
		padding: 24upx;
		border-bottom: 1upx solid #eee;
		color: #18B4FE;
	}
	
	.demo-li.disable{
		color: gray;
	}
	
	.demo-li .demo-tip {
		float: right;
		margin-top: 4upx;
		font-size: 24upx;
		color: gray;
	}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/beibei.vue
================================================
<template>
	<view>
		<!-- 模拟的标题 -->
		<image class="header" src="https://www.mescroll.com/img/beibei/header.jpg" mode="aspectFit"/>
		
		<mescroll-body-diy @init="mescrollInit" top="180" bottom="100" @down="downCallback" @up="upCallback">
			<!-- 模拟的内容 -->
			<image src="https://www.mescroll.com/img/beibei/beibei1.jpg" mode="widthFix"/>
			<image src="https://www.mescroll.com/img/beibei/beibei2.jpg" mode="widthFix"/>
			<!-- 分页的数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body-diy>
		
		<!-- 模拟的底部 -->
		<image class="footer" src="https://www.mescroll.com/img/beibei/footer.jpg" mode="aspectFit"/>
	</view>
</template>

<script>
	import MescrollBodyDiy from "@/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-body.vue";
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		components: {
			MescrollBodyDiy // 避免与main.js注册的全局组件名称相同,否则注册组件失效(iOS真机 APP HBuilderX2.7.9)
		},
		data() {
			return {
				goods: [] // 数据列表
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				apiGoods(page.num, page.size).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);

					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			}
		}
	}
</script>

<style>
	image{width: 100%;vertical-align: bottom;height:auto}
	.header{z-index: 9900;position: fixed;top: --window-top;left: 0;height: 180upx;background: white;}
	.footer{z-index: 9900;position: fixed;bottom: 0;left: 0;height: 100upx;background: white;}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/list-msg.vue
================================================
<template>
	<!-- 需配置bottom的偏移量, 用于底部留白 -->
	<mescroll-body bottom="50%" @init="mescrollInit" :down="downOption" @down="downCallback" :up="upOption">
		<!-- 无更多消息 -->
		<view v-if="isEnd" class="msg-end">没有更多消息了</view>
		
		<!-- 消息列表 (必须配置id,以便定位) -->
		<view class="msg" v-for="msg in msgList" :key="msg.id" :id="msg.VIEW_ID" :class="[msg.id%2==0 ? 'right' : 'left']">
			<view class="msg-warp">
				<view class="msg-title">{{msg.title}}</view>
				<view class="msg-content">{{msg.content}}</view>
			</view>
		</view>
	</mescroll-body>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiMsgList} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				downOption:{
					autoShowLoading: true, // 显示下拉刷新的进度条
					textColor: "#FF8095" // 下拉刷新的文本颜色
				},
				upOption: {
					use: false, // 禁止上拉
					toTop: {
						src: '' // 不显示回到顶部按钮
					}
				},
				pageNum: 1, // 页码
				pageSize: 10, // 页长
				isEnd: false, // 是否无消息
				msgList: []
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				//联网加载数据
				apiMsgList(this.pageNum, this.pageSize).then(data => {
					// 需自行维护页码
					this.pageNum ++;
					// 先隐藏下拉刷新的状态
					this.mescroll.endSuccess();
					// 不满一页,说明已经无更多消息 (建议根据您实际接口返回的总页码数,总消息量,是否有消息的字段来判断)
					if(data.length < this.pageSize){
						this.isEnd = true; // 标记已无更多消息
						this.mescroll.lockDownScroll(true); // 锁定下拉
					}
					// 生成VIEW_ID,大写,避免污染源数据
					data.forEach(val=>{
						val.VIEW_ID = "msg" + val.id // 不以数字开头
					})
					
					// 获取当前最顶部的VIEW_ID (注意是写在data.concat前面)
					let topMsg = this.msgList[0]
					
					//设置列表数据
					this.msgList = data.concat(this.msgList); // 注意不是this.msgList.concat
					
					this.$nextTick(()=>{
						if(this.pageNum <= 2){
							// 第一页直接滚动到底部 ( this.pageNum已在前面加1 )
							this.mescroll.scrollTo(99999, 0)
						}else if(topMsg){
							// 保持顶部消息的位置
							let view = uni.createSelectorQuery().select('#'+topMsg.VIEW_ID);
							view.boundingClientRect(v => {
								console.log("节点离页面顶部的距离=" + v.top);
								this.mescroll.scrollTo(v.top - 100, 0) // 减去上偏移量100
							}).exec();
						}
					})
					
				}).catch(()=>{
					this.pageNum --; // 联网失败,必须回减页码
					this.mescroll.endErr(); // 隐藏下拉刷新的状态
				})
			}
		}
	}
</script>

<style lang="scss">
	/* 无更多消息 */
	.msg-end{
		padding: 40rpx 0;
		font-size: 24rpx;
		text-align: center;
		color: #FF8095;
	}
	/*消息列表*/
	.msg{
		margin: 30rpx;
		&.right{
			text-align: right;
		}
		&.left{
			text-align: left;
		}
		.msg-warp{
			width: 50%;
			display: inline-block;
			padding: 30rpx;
			border-radius: 30rpx;
			background-color: #FF8095;
			color: #fff;
			.msg-title{
				margin-left: -12rpx;
				font-size: 32rpx;
				text-align: left;
			}
			.msg-content{
				font-size: 26rpx;
				margin-top: 10rpx;
				text-align: left;
			}
		}
	}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/mescroll-body-part.vue
================================================
<template>
	<!-- mescroll-body本质是原生page的滚动,无法像mescroll-uni那样用flex布局嵌在某个view中使用局部区域滚动, 但是可以通过fixed定位其他元素来实现"局部区域滚动"-->
	<view>
		<!-- 顶部 fixed定位 -->
		<view class="top-warp"> 
			<view>顶部区域</view>
			<view style="font-size: 24rpx;">mescroll-body 通过fixed定位其他元素,实现"局部区域滚动"</view>
		</view>
		
		<!-- 左边 fixed定位 -->
		<scroll-view class="left-warp" :scroll-y="true">
			<view class="tab" :class="{active:i==tabIndex}" v-for="(tab,i) in tabs" :key="i" @click="tabChange(i)">{{tab}}</view>
		</scroll-view>
		
		<!-- mescroll-body跟随page滚动, 不可fixed定位, 可设置 top, bottom, topbar, bottombar, safearea的偏移量-->
		<mescroll-body top="88" bottom="100" @init="mescrollInit" @down="downCallback" @up="upCallback">
			<good-list :list="goods"></good-list>
		</mescroll-body>
		
		<!-- 底部 fixed定位 -->
		<view class="bottom-warp"> 底部区域 </view>
	</view>
</template>


<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods, apiGetTabs} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: [], // tabs异步获取
				// tabs: ['全部', '奶粉', '面膜', '图书', '果汁', '奶瓶', '美素', '花王', '韩蜜', '口红', '毛巾', '玩具', '衣服'],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			upCallback(page) {
				// tabs异步获取
				if(this.tabs.length == 0){
					apiGetTabs().then(res=>{
						this.tabs = res
						this.mescroll.resetUpScroll() // 重新触发upCallback
					}).catch(()=>{
						this.mescroll.endErr()
					})
					return // 此处return,先获取tabs
				}
				
				//联网加载数据
				let keyword = this.tabs[this.tabIndex]
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange(i){
				if(this.tabIndex != i){
					this.tabIndex = i
					this.goods = []; // 先置空列表,显示加载进度条
					this.mescroll.resetUpScroll(); // 重置列表数据
				}
			}
		}
	}
</script>


<style lang="scss">
	/* 顶部 fixed定位*/
	.top-warp{
		z-index: 200;
		position: fixed;
		top: var(--window-top);
		left: 0;
		width: 100%;
		height: 88rpx;
		padding-top: 10rpx;
		font-size: 28rpx;
		text-align: center;
		background-color: #CFE0DA;
	}
	
	/* 左边 fixed定位*/
	.left-warp{
		z-index: 100;
		position: fixed;
		top: var(--window-top);
		left: 0;
		bottom: 100rpx;
		width: 180rpx;
		padding-top: 88rpx;
		background-color: #eee;
		.tab{
			font-size: 28rpx;
			padding: 28rpx;
			&.active{
				background-color: #fff;
			}
		}
	}
	
	// 设置padding
	.mescroll-body,
	/deep/.mescroll-body{
		padding-left: 180rpx;
	}
	
	/* 底部 fixed定位*/
	.bottom-warp{
		z-index: 200;
		position: fixed;
		left: 0;
		bottom: 0;
		width: 100%;
		height: 100rpx;
		line-height: 100rpx;
		text-align: center;
		background-color: #FF6990;
	}
</style>

================================================
FILE: mescroll-uni/pages/intermediate/mescroll-swiper-item.vue
================================================
<template>
	<!-- 
	swiper中的transfrom会使fixed失效,此时用height固定高度; 
	swiper中无法触发mescroll-mixins.js的onPageScroll和onReachBottom方法,只能用mescroll-uni,不能用mescroll-body
	-->
	<!-- top的高度等于悬浮菜单tabs的高度 -->
	 <mescroll-uni @init="mescrollInit" :height="height" :down="downOption" @down="downCallback" :up="upOption" @up="upCallback" @emptyclick="emptyClick">
		<!-- 数据列表 -->
		<good-list :list="goods"></good-list>
	</mescroll-uni>
</template>

<script>
	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";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin,MescrollMoreItemMixin], // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面)
		data() {
			return {
				downOption:{
					auto:false // 不自动加载 (mixin已处理第一个tab触发downCallback)
				},
				upOption:{
					auto:false, // 不自动加载
					// page: {
					// 	num: 0, // 当前页码,默认0,回调之前会加1,即callback(page)会从1开始
					// 	size: 10 // 每页数据的数量
					// },
					noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
					empty:{
						tip: '~ 空空如也 ~', // 提示
						btnText: '去看看'
					}
				},
				goods: [] //列表数据
			}
		},
		props:{
			i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
			index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
				type: Number,
				default(){
					return 0
				}
			},
			tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传
				type: Array,
				default(){
					return []
				}
			},
			height: [Number,String] // mescroll的高度
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				let keyword = this.tabs[this.i].name
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			//点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:'点击了按钮,具体逻辑自行实现'
				})
			}
		}
	}
</script>


================================================
FILE: mescroll-uni/pages/intermediate/mescroll-swiper-sticky-item.vue
================================================
<template>
	<!-- 
	swiper中的transfrom会使fixed失效,此时用height固定高度; 
	swiper中无法触发mescroll-mixins.js的onPageScroll和onReachBottom方法,只能用mescroll-uni,不能用mescroll-body
	-->
	<!-- top的高度等于悬浮菜单tabs的高度 -->
	 <mescroll-uni @init="mescrollInit" :height="height" :disable-scroll="disableScroll" :down="downOption" :up="upOption" @up="upCallback" @emptyclick="emptyClick">
		<!-- 数据列表 -->
		<good-list :list="goods"></good-list>
	</mescroll-uni>
</template>

<script>
	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";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin,MescrollMoreItemMixin], // 注意此处还需使用MescrollMoreItemMixin (必须写在MescrollMixin后面)
		data() {
			return {
				downOption:{
					use:false // 禁用
				},
				upOption:{
					auto:false, // 不自动加载
					noMoreSize: 4, //如果列表已无数据,可设置列表的总数量要大于半页才显示无更多数据;避免列表数据过少(比如只有一条数据),显示无更多数据会不好看; 默认5
					empty:{
						tip: '~ 空空如也 ~', // 提示
						btnText: '去看看'
					}
				},
				goods: [] //列表数据
			}
		},
		props:{
			i: Number, // 每个tab页的专属下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
			index: { // 当前tab的下标 (除了支付宝小程序必须在这里定义, 其他平台都可不用写, 因为已在MescrollMoreItemMixin定义)
				type: Number,
				default(){
					return 0
				}
			},
			tabs: { // 为了请求数据,演示用,可根据自己的项目判断是否要传
				type: Array,
				default(){
					return []
				}
			},
			height: [Number,String], // mescroll的高度
			disableScroll: Boolean // 是否禁止滚动, 默认false
		},
		methods: {
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				let keyword = this.tabs[this.i].name
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			//点击空布局按钮的回调
			emptyClick(){
				uni.showToast({
					title:'点击了按钮,具体逻辑自行实现'
				})
			}
		}
	}
</script>


================================================
FILE: mescroll-uni/pages/intermediate/mescroll-swiper-sticky.vue
================================================
<!-- 吸顶轮播菜单导航 -->
<template>
	<view>
		<!-- 需设置:sticky="true", 此时应避免在mescroll-body标签前面加其他非定位的元素, 否则下拉区域会被挤出, 无法会隐藏.-->
		<mescroll-body :sticky="true" @init="mescrollInit" @down="downCallback" :up="upOption">
			<!-- 顶部内容 -->
			<view :style="{height: topHeight+'px', overflow:'hidden'}">
				<image style="width: 100%;height: 340rpx;" src="https://www.mescroll.com/img/swiper1.jpg"/>
				<image style="width: 100%;height: 245rpx;border-bottom: 15rpx solid #f2f2f2" src="https://www.mescroll.com/img/beibei/beibei2.jpg"/>
			</view>
			
			<!-- sticky吸顶悬浮的菜单, 父元素必须是 mescroll -->
			<view class="sticky-tabs">
				<!-- 当设置tab-width,指定每个tab宽度时,则不使用flex布局,改用水平滑动 -->
				<me-tabs v-model="tabIndex" :tabs="tabs" :tab-width="130"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<swiper :style="{height: swiperHeight}" :current="tabIndex" @change="swiperChange">
				<swiper-item v-for="(tab,i) in tabs" :key="i">
					<mescroll-item ref="mescrollItem" :i="i" :index="tabIndex" :tabs="tabs" :height="swiperHeight" :disable-scroll="disableScroll"></mescroll-item>
				</swiper-item>
			</swiper>
		</mescroll-body>
		
		<!-- 此处可以写其他fixed定位元素 -->
		<!-- <view></view> -->
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import MescrollItem from "./mescroll-swiper-sticky-item.vue";
	export default {
		mixins: [MescrollMixin], // 使用mixin
		components: {
			MescrollItem
		},
		data() {
			return {
				upOption:{
					use: false // 主体框架只启用下拉刷新
				},
				topHeight: uni.upx2px(600), // 顶部内容的高度 (单位px)
				swiperHeight: "", // 需要固定swiper的高度 (单位px)
				tabs: [{name:'全部'}, {name:'奶粉'}, {name:'面膜'}, {name:'图书'}, {name:'果汁'}, {name:'奶瓶'}, {name:'美素'}, {name:'花王'}, {name:'韩蜜'}],
				tabIndex: 0, // 当前菜单下标
				disableScroll: true // swiper列表是否禁止滚动
			}
		},
		watch: {
			tabIndex(i) {
				// 当列表禁止滚动时,需把列表滚动条置顶 (解决问题: "全部"tab翻到第二页,切换到其他tab,滚动到顶部,再切回"全部"tab,此时的列表数据应该重头开始)
				if(this.disableScroll){
					this.disableScroll = false // 当disableScroll=true时,scroll-view的scrollTo会失效,需先开启,再置顶
					this.$nextTick(()=>{
						let mescroll = this.getMescroll(i)
						mescroll && mescroll.scrollTo(0,0)
						setTimeout(()=>{ // 经测试android真机需延时300ms才能恢复禁止滚动,否则scrollTo有可能无效
							this.disableScroll = true
						},300)
					})
				}
			}
		},
		onLoad() {
			// 需要固定swiper的高度 (需减去悬浮tabs的高度64rpx)
			this.swiperHeight = uni.getSystemInfoSync().windowHeight - uni.upx2px(64) + 'px'
		},
		mounted() {
			// #ifdef H5
			uni.pageScrollTo({scrollTop: 0,duration: 0}) // 刷新浏览器,重置滚动条
			// #endif
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				this.mescroll.endSuccess()
			},
			// 轮播菜单
			swiperChange(e){
				this.tabIndex = e.detail.current
			},
			// 获取指定下标的mescroll对象
			getMescroll(i){
				let mescrollItems = this.$refs.mescrollItem;
				if(mescrollItems){
					let item = mescrollItems[i]
					if(item) return item.mescroll
				}
				return null
			},
			// 页面的滚动事件
			onPageScroll(e){
				this.disableScroll = Math.ceil(e.scrollTop) < this.topHeight
			}
		}
	}
</script>

<style lang="scss">
	/*
	sticky生效条件:
	1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
	2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
	3、父元素的高度不能低于sticky元素的高度
	4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
	*/
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: var(--window-top);
		background-color: #fff;
	}
</style>

================================================
FILE: mescroll-uni/pages/intermediate/mescroll-swiper.vue
================================================
<template>
	<view>
		<!-- 当设置tab-width,指定每个tab宽度时,则不使用flex布局,改用水平滑动 -->
		<me-tabs v-model="tabIndex" :tabs="tabs" :tab-width="130"></me-tabs>
		<swiper :style="{height: height}" :current="tabIndex" @change="swiperChange">
			<swiper-item v-for="(tab,i) in tabs" :key="i">
				<mescroll-item ref="mescrollItem" :i="i" :index="tabIndex" :tabs="tabs" :height="height"></mescroll-item>
			</swiper-item>
		</swiper>
	</view>
</template>

<script>
	import MescrollItem from "./mescroll-swiper-item.vue";
	
	export default {
		components: {
			MescrollItem
		},
		data() {
			return {
				height: "", // 需要固定swiper的高度
				tabs: [{name:'全部'}, {name:'奶粉'}, {name:'面膜'}, {name:'图书'}, {name:'果汁'}, {name:'奶瓶'}, {name:'美素'}, {name:'花王'}, {name:'韩蜜'}],
				tabIndex: 0 // 当前tab的下标
			}
		},
		onLoad() {
			// 需要固定swiper的高度 (需减去悬浮tabs的高度64rpx)
			this.height = uni.getSystemInfoSync().windowHeight - uni.upx2px(64) + 'px'
		},
		onShow() {
			// 返回刷新: https://www.mescroll.com/uni.html#note 第二点
			// if(this.canReset){
			// 	let curMescroll = this.getMescroll(this.tabIndex)
			// 	curMescroll && curMescroll.resetUpScroll()
			// }
			// this.canReset = true
		},
		methods: {
			// 轮播菜单
			swiperChange(e){
				this.tabIndex = e.detail.current
			},
			// 获取指定下标的mescroll对象
			// getMescroll(i){
			// 	let mescrollItems = this.$refs.mescrollItem;
			// 	if(mescrollItems){
			// 		let item = mescrollItems[i]
			// 		if(item) return item.mescroll
			// 	}
			// 	return null
			// }
		}
	}
</script>

<style>
</style>


================================================
FILE: mescroll-uni/pages/intermediate/mescroll-uni-part.vue
================================================
<template>
	<!-- mescroll-uni本质是scroll-view,支持局部区域滚动,可使用flex布局灵活的嵌在某个view中, 而mescroll-body只能靠fixed定位其他元素变相实现'局部滚动' -->
	<view class="page-warp">
		
		<view class="top-warp">
			<view>顶部区域</view>
			<view style="font-size: 24rpx;">mescroll-uni 支持局部区域滚动,支持使用flex嵌在某个view</view>
		</view>
		
		<view class="center-warp">
			<!-- 左边 -->
			<scroll-view class="left-warp" :scroll-y="true">
				<view class="tab" :class="{active:i==tabIndex}" v-for="(tab,i) in tabs" :key="i" @click="tabChange(i)">{{tab}}</view>
			</scroll-view>
			
			<view class="right-warp">
				<!--右边 :fixed="false", 高度跟随父元素 (不在组件上定义class,避免部分小程序平台编译丢失, 如支付宝,钉钉小程序) -->
				<mescroll-uni :fixed="false" @init="mescrollInit" @down="downCallback" @up="upCallback">
					<good-list :list="goods"></good-list>
				</mescroll-uni>
			</view>
		</view>
		
		<view class="bottom-warp"> 底部区域 </view>
		
	</view>
</template>


<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods, apiGetTabs} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: [], // tabs异步获取
				// tabs: ['全部', '奶粉', '面膜', '图书', '果汁', '奶瓶', '美素', '花王', '韩蜜', '口红', '毛巾', '玩具', '衣服'],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			upCallback(page) {
				// tabs异步获取
				if(this.tabs.length == 0){
					apiGetTabs().then(res=>{
						this.tabs = res
						this.mescroll.resetUpScroll() // 重新触发upCallback
					}).catch(()=>{
						this.mescroll.endErr()
					})
					return // 此处return,先获取tabs
				}
				
				//联网加载数据
				let keyword = this.tabs[this.tabIndex]
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(res.list.length);
					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange(i){
				if(this.tabIndex != i){
					this.tabIndex = i
					this.goods = []; // 先置空列表,显示加载进度条
					this.mescroll.resetUpScroll(); // 重置列表数据
				}
			}
		}
	}
</script>


<style lang="scss">
	/*根元素需要有固定的高度*/
	page{
		height: 100%;
		// 支付宝小程序,钉钉小程序需添加绝对定位,否则height:100%失效: https://opendocs.alipay.com/mini/framework/acss#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98
		/* #ifdef MP-ALIPAY || MP-DINGTALK*/
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		/* #endif */
		
		/*需给父元素设置height:100%*/
		.page-warp{
			height: 100%;
			display: flex;
			flex-direction: column;
			
			/* 顶部区域 */
			.top-warp{
				font-size: 28rpx;
				padding: 20rpx;
				text-align: center;
				background-color: #CFE0DA;
			}
			
			/* 中间 */
			.center-warp{
				flex: 1;
				min-width: 0;
				min-height: 0;/* 需给flex:1的元素加上最小高,否则内容超过会溢出容器 (如:小程序Android真机) */
				border: 4px solid red;
				display: flex;
				
				// 左边
				.left-warp{
					width: 180rpx;
					height: 100%;
					background-color: #eee;
					.tab{
						font-size: 28rpx;
						padding: 28rpx;
						&.active{
							background-color: #fff;
						}
					}
				}
				
				// 右边
				.right-warp{
					flex: 1;
					min-width: 0;
				}
			}
			
			/* 底部区域 */
			.bottom-warp{
				padding: 20rpx;
				text-align: center;
				background-color: #FF6990;
			}
		}
	}
</style>

================================================
FILE: mescroll-uni/pages/intermediate/sticky-data.vue
================================================
<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->
<template>
	<view>
		<!-- 对于mescroll-body: 需设置:sticky="true", 此应避免在mescroll-body标签前面加其他非定位的元素, 否则下拉区域会被挤出, 无法会隐藏.-->
		<!-- 对于mescroll-uni: 则无需设置:sticky="true", 无其他限制和要求 -->
		<mescroll-body :sticky="true" @init="mescrollInit" @down="downCallback" @up="upCallback">
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
				</swiper-item>
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
				</swiper-item>
			</swiper>
			
			<view class="demo-tip">
				<view>列表只初始化一次,切换菜单缓存数据</view>
				<view>吸顶通过给菜单加position:sticky实现, 用法简单</view>
				<view>小程序,微信h5端: 低端机sticky也可生效, 可放心使用</view>
				<view>APP端: 仅部分低端机无效,若要兼容则参考sticky-scroll</view>
			</view>
			
			<!-- sticky吸顶悬浮的菜单, 父元素必须是 mescroll -->
			<view class="sticky-tabs">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
		
		<!-- 此处可以写其他fixed定位元素 -->
		<!-- <view></view> -->
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				tabs:[
					{name:'全部', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'母婴', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'图书', goods: null, num:1, y:0, curPageLen:0, hasNext:true}
					],
				tabIndex: 0 // 当前菜单下标
			}
		},
		computed: {
			// 列表数据
			goods() {
				return this.tabs[this.tabIndex].goods
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				let keyword = this.tabs[this.tabIndex].name;
				apiGoods(page.num, page.size, keyword).then(res=>{
					// 需先隐藏加载状态
					this.mescroll.endSuccess(res.list.length);
					
					// 当前tab数据
					let curTab = this.tabs[this.tabIndex]
					
					// 设置列表数据
					if(page.num == 1) curTab.goods = []; //如果是第一页需手动制空列表
					curTab.goods = curTab.goods.concat(res.list); //追加新数据
					curTab.num = page.num; // 页码
					curTab.curPageLen = res.list.length; // 当前页长
					curTab.hasNext = this.mescroll.optUp.hasNext; // 是否还有下一页
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange (index) {
				// 记录切换前滚动条的位置
				if(!this.preIndex) this.preIndex = 0
				let preTab = this.tabs[this.preIndex]
				preTab.y = this.mescroll.getScrollTop()
				this.preIndex = index;
				// 当前菜单的数据
				let curTab = this.tabs[index]
				if (!curTab.goods) {
					// 没有初始化,则初始化
					this.mescroll.resetUpScroll()
				} else{
					// 初始化过,则恢复之前的列表数据
					this.mescroll.setPageNum(curTab.num + 1); // 恢复当前页码
					this.mescroll.endSuccess(curTab.curPageLen, curTab.hasNext); // 恢复是否有下一页或显示空布局
					this.$nextTick(()=>{
						this.mescroll.scrollTo(curTab.y, 0) // 恢复滚动条的位置
					})
				}
			}
		}
	}
</script>

<style lang="scss">
	/*
	sticky生效条件:
	1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
	2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
	3、父元素的高度不能低于sticky元素的高度
	4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
	*/
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: var(--window-top);
		background-color: #fff;
	}
	
	// 使用mescroll-uni,则top为0
	.mescroll-uni,
	/deep/.mescroll-uni{
		.sticky-tabs{
			top: 0;
		}
	}
	
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/sticky-scroll-data.vue
================================================
<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->
<template>
	<view>
		<!-- 菜单 (悬浮,预先隐藏)-->
		<me-tabs v-if="isShowSticky" v-model="tabIndex" :fixed="true" :tabs="tabs" @change="tabChange"></me-tabs>
		
		 <mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption" @scroll="scroll" @topclick="topClick">
			<!--轮播-->
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
		        <swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
		        </swiper-item>
				<swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
		        </swiper-item>
		    </swiper>
			
			<view class="demo-tip">
				<view>列表只初始化一次,切换菜单缓存数据</view>
				<view>吸顶通过监听滚动条实现, 比sticky复杂, 但APP端可兼容低端机</view>
			</view>
			
			<!-- 菜单 (在mescroll-uni中不能使用fixed,否则iOS滚动时会抖动, 所以需在mescroll-uni之外存在一个一样的菜单) -->
			<view id="tabInList">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				upOption: {
					// 如果用mescroll-uni 则需要onScroll: true, 且需要 @scroll="scroll"; 而mescroll-body最简单只需在onPageScroll处理即可
					// onScroll: true // 是否监听滚动事件, 默认false (配置为true时,可@scroll="scroll"获取到滚动条位置和方向)
				},
				tabs:[
					{name:'全部', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'母婴', goods: null, num:1, y:0, curPageLen:0, hasNext:true},
					{name:'图书', goods: null, num:1, y:0, curPageLen:0, hasNext:true}
					],
				tabIndex: 0, // 当前菜单下标
				preIndex: 0, // 前一个菜单下标
				navTop: null, // nav距离到顶部的距离 (如计算不准确,可直接写死某个值)
				isShowSticky: false // 是否悬浮
			}
		},
		computed: {
			// 列表数据
			goods() {
				return this.tabs[this.tabIndex].goods
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				if(this.isChangeTab){
					this.mescroll.hideUpScroll(); // 切换菜单,不显示mescroll进度, 显示系统进度条
					uni.showLoading();
				}
				let keyword = this.tabs[this.tabIndex].name;
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调
					
					// 当前tab数据
					let curTab = this.tabs[this.tabIndex]
					
					//设置列表数据
					if(page.num == 1) curTab.goods = []; //如果是第一页需手动制空列表
					curTab.goods=curTab.goods.concat(res.list); //追加新数据
					
					// 数据渲染完毕再隐藏加载状态 this.$nextTick在iOS真机不触发,需改成setTimeout
					// this.$nextTick(()=>{
					setTimeout(()=>{
						// 需先隐藏加载状态
						this.mescroll.endSuccess(res.list.length);
						
						// 再记录当前页的数据
						curTab.num = page.num; // 页码
						curTab.curPageLen = res.list.length; // 当前页长
						curTab.hasNext = this.mescroll.optUp.hasNext; // 是否还有下一页
						
						// 设置nav到顶部的距离 (需根据自身的情况获取navTop的值, 这里放到列表数据渲染完毕之后)
						// 也可以放到onReady里面,或者菜单顶部的数据(轮播等)加载完毕之后..
						if(!this.navTop) this.setNavTop()
						// 保持tab悬浮,列表数据显示第一条
						if(this.isChangeTab){
							this.isChangeTab = false;
							uni.hideLoading();
							if(this.isShowSticky) this.mescroll.scrollTo(this.navTop, 0)
						}
					},20)
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 设置nav到顶部的距离 (滚动条为0, 菜单顶部的数据加载完毕获取到的navTop数值是最精确的)
			setNavTop(){
				let view = uni.createSelectorQuery().select('#tabInList');
				view.boundingClientRect(data => {
					console.log('tabInList基本信息 = ' + JSON.stringify(data));
					this.navTop = data.top // 到屏幕顶部的距离
				}).exec();
			},
			// mescroll-uni的滚动事件 (需在up配置onScroll:true才生效)
			// 而mescroll-body最简单只需在onPageScroll处理即可
			scroll(){
				console.log('滚动条位置 = ' + this.mescroll.getScrollTop() + ', navTop = ' + this.navTop);
				// 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏
				if (this.mescroll.getScrollTop() >= this.navTop) {
					this.isShowSticky = true // 显示悬浮菜单
				} else {
					this.isShowSticky = false // 隐藏悬浮菜单
				}
			},
			// 点击回到顶部按钮时,先隐藏悬浮菜单,避免闪动
			topClick(){
				this.isShowSticky = false
			},
			// 切换菜单
			tabChange (index) {
				// 记录前一个菜单的数据
				let preTab = this.tabs[this.preIndex]
				preTab.y = this.mescroll.getScrollTop(); // 滚动条位置
				this.preIndex = index;
				// 当前菜单的数据
				let curTab = this.tabs[index]
				if (!curTab.goods) {
					// 没有初始化,则初始化
					this.isChangeTab = true;
					this.mescroll.resetUpScroll()
				} else{
					// 初始化过,则恢复之前的列表数据
					this.mescroll.setPageNum(curTab.num + 1); // 恢复当前页码
					this.mescroll.endSuccess(curTab.curPageLen, curTab.hasNext); // 恢复是否有下一页或显示空布局
					this.$nextTick(()=>{
						this.mescroll.scrollTo(curTab.y, 0) // 恢复滚动条的位置
					})
				}
			}
		},
		// 使用mescroll-body最简单只需在onPageScroll处理即可
		onPageScroll(e){
			console.log('滚动条位置 = ' + e.scrollTop + ', navTop = ' + this.navTop);
			if (e.scrollTop >= this.navTop) {
				this.isShowSticky = true // 显示悬浮菜单
			} else {
				this.isShowSticky = false // 隐藏悬浮菜单
			}
		}
	}
</script>

<style>
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/sticky-scroll.vue
================================================
<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->
<template>
	<view>
		<!-- 菜单 (悬浮,预先隐藏)-->
		<me-tabs v-if="isShowSticky" v-model="tabIndex" :fixed="true" :tabs="tabs" @change="tabChange"></me-tabs>
		
		 <mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback" :up="upOption" @scroll="scroll" @topclick="topClick">
			<!--轮播-->
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
		        <swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
		        </swiper-item>
				<swiper-item>
		            <image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
		        </swiper-item>
		    </swiper>
			
			<view class="demo-tip">
				<view>每次切换菜单都刷新列表数据</view>
				<view>吸顶通过监听滚动条实现, 比sticky复杂, 但APP端可兼容低端机</view>
			</view>
			
			<!-- 菜单 (在mescroll-uni中不能使用fixed,否则iOS滚动时会抖动, 所以需在mescroll-uni之外存在一个一样的菜单) -->
			<view id="tabInList">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				upOption: {
					// 如果用mescroll-uni 则需要onScroll: true, 且需要 @scroll="scroll"; 而mescroll-body最简单只需在onPageScroll处理即可
					// onScroll: true // 是否监听滚动事件, 默认false (配置为true时,可@scroll="scroll"获取到滚动条位置和方向)
				},
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0, // tab下标
				navTop: null, // nav距离到顶部的距离 (如计算不准确,可直接写死某个值)
				isShowSticky: false // 是否悬浮
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				if(this.isChangeTab){
					this.mescroll.hideUpScroll(); // 切换菜单,不显示mescroll进度, 显示系统进度条
					uni.showLoading();
				}
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					//联网成功的回调

					//设置列表数据
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
					
					// 数据渲染完毕再隐藏加载状态 this.$nextTick在iOS真机不触发,需改成setTimeout
					// this.$nextTick(()=>{
					setTimeout(()=>{
						this.mescroll.endSuccess(res.list.length);
						// 设置nav到顶部的距离 (需根据自身的情况获取navTop的值, 这里放到列表数据渲染完毕之后)
						// 也可以放到onReady里面,或者菜单顶部的数据(轮播等)加载完毕之后..
						if(!this.navTop) this.setNavTop()
						// 保持tab悬浮,列表数据显示第一条
						if(this.isChangeTab){
							this.isChangeTab = false;
							uni.hideLoading();
							if(this.isShowSticky) this.mescroll.scrollTo(this.navTop, 0)
						}
					},20)
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 设置nav到顶部的距离 (滚动条为0, 菜单顶部的数据加载完毕获取到的navTop数值是最精确的)
			setNavTop(){
				let view = uni.createSelectorQuery().select('#tabInList');
				view.boundingClientRect(data => {
					console.log('tabInList基本信息 = ' + JSON.stringify(data));
					this.navTop = data.top // 到屏幕顶部的距离
				}).exec();
			},
			// mescroll-uni的滚动事件 (需在up配置onScroll:true才生效)
			// 而mescroll-body最简单只需在onPageScroll处理即可
			scroll(){
				console.log('滚动条位置 = ' + this.mescroll.getScrollTop() + ', navTop = ' + this.navTop);
				// 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏
				if (this.mescroll.getScrollTop() >= this.navTop) {
					this.isShowSticky = true // 显示悬浮菜单
				} else {
					this.isShowSticky = false // 隐藏悬浮菜单
				}
			},
			// 点击回到顶部按钮时,先隐藏悬浮菜单,避免闪动
			topClick(){
				this.isShowSticky = false
			},
			// 切换菜单
			tabChange () {
				this.isChangeTab = true;
				this.mescroll.resetUpScroll()
			}
		},
		// 使用mescroll-body最简单只需在onPageScroll处理即可
		onPageScroll(e){
			console.log('滚动条位置 = ' + e.scrollTop + ', navTop = ' + this.navTop);
			if (e.scrollTop >= this.navTop) {
				this.isShowSticky = true // 显示悬浮菜单
			} else {
				this.isShowSticky = false // 隐藏悬浮菜单
			}
		}
	}
</script>

<style>
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/sticky-uni.vue
================================================
<template>
	<view>
		<mescroll-uni @init="mescrollInit" @down="downCallback" @up="upCallback">
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
				</swiper-item>
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
				</swiper-item>
			</swiper>
			
			<view class="demo-tip">
				<view>仅测试mescroll-uni使用sticky的情况</view>
				<view>与mescroll-body使用的区别:</view>
				<view>1. mescroll-uni 无需配置 :sticky="true"</view>
				<view>2. sticky的top 无需考虑var(--window-top)</view>
			</view>
			
			<!-- sticky吸顶悬浮的菜单, 父元素必须是 mescroll -->
			<view class="sticky-tabs">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-uni>
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
					this.mescroll.endSuccess(res.list.length); // 隐藏加载状态栏
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange () {
				this.goods = []; // 置空列表,显示加载进度条
				this.mescroll.resetUpScroll()
			}
		}
	}
</script>

<style lang="scss">
	/*
	sticky生效条件:
	1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
	2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
	3、父元素的高度不能低于sticky元素的高度
	4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
	*/
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: 0;
		background-color: #fff;
	}
	
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/sticky.vue
================================================
<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->
<template>
	<view>
		<!-- 对于mescroll-body: 需设置:sticky="true", 此应避免在mescroll-body标签前面加其他非定位的元素, 否则下拉区域会被挤出, 无法会隐藏.-->
		<!-- 对于mescroll-uni: 则无需设置:sticky="true", 无其他限制和要求 -->
		<mescroll-body :sticky="true" @init="mescrollInit" @down="downCallback" @up="upCallback">
			<swiper style="min-height: 300rpx" autoplay="true" interval="3000" duration="300" circular="true">
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper1.jpg" mode="widthFix"/>
				</swiper-item>
				<swiper-item>
					<image style="width: 100%;height: auto;" src="https://www.mescroll.com/img/swiper2.jpg" mode="widthFix"/>
				</swiper-item>
			</swiper>
			
			<view class="demo-tip">
				<view>每次切换菜单,都刷新列表数据</view>
				<view>吸顶通过给菜单加position:sticky实现, 用法简单</view>
				<view>小程序和微信h5端: 低端机sticky也可生效, 可放心使用</view>
				<view>APP端: 仅部分低端机无效,若要兼容则参考sticky-scroll</view>
			</view>
			
			<!-- sticky吸顶悬浮的菜单, 父元素必须是 mescroll -->
			<view class="sticky-tabs">
				<me-tabs v-model="tabIndex" :tabs="tabs" @change="tabChange"></me-tabs>
			</view>
			
			<!-- 数据列表 -->
			<good-list :list="goods"></good-list>
		</mescroll-body>
		
		<!-- 此处可以写其他fixed定位元素 -->
		<!-- <view></view> -->
	</view>
</template>

<script>
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiGoods} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		data() {
			return {
				goods: [], // 数据列表
				tabs: [{name:'全部',type:'xx'}, {name:'奶粉',type:'xx'}, {name:'图书',type:'xx'}],
				tabIndex: 0 // tab下标
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback() {
				// 这里加载你想下拉刷新的数据, 比如刷新轮播数据
				// loadSwiper();
				// 下拉刷新的回调,默认重置上拉加载列表为第一页 (自动执行 page.num=1, 再触发upCallback方法 )
				this.mescroll.resetUpScroll()
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				let curTab = this.tabs[this.tabIndex]
				let keyword = curTab.name // 具体项目中,您可能取的是tab中的type,status等字段
				apiGoods(page.num, page.size, keyword).then(res=>{
					if(page.num == 1) this.goods = []; //如果是第一页需手动制空列表
					this.goods=this.goods.concat(res.list); //追加新数据
					this.mescroll.endSuccess(res.list.length); // 隐藏加载状态栏
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			// 切换菜单
			tabChange () {
				this.goods = []; // 置空列表,显示加载进度条
				this.mescroll.resetUpScroll()
			}
		}
	}
</script>

<style lang="scss">
	/*
	sticky生效条件:
	1、父元素不能overflow:hidden或者overflow:auto属性。(mescroll-body设置:sticky="true"即可, mescroll-uni本身没有设置overflow)
	2、必须指定top、bottom、left、right4个值之一,否则只会处于相对定位
	3、父元素的高度不能低于sticky元素的高度
	4、sticky元素仅在其父元素内生效,所以父元素必须是 mescroll
	*/
	.sticky-tabs{
		z-index: 990;
		position: sticky;
		top: var(--window-top);
		background-color: #fff;
	}
	
	// 使用mescroll-uni,则top为0
	.mescroll-uni,
	/deep/.mescroll-uni{
		.sticky-tabs{
			top: 0;
		}
	}
	
	.demo-tip{
		padding: 18rpx;
		font-size: 24rpx;
		text-align: center;
	}
</style>


================================================
FILE: mescroll-uni/pages/intermediate/xinlang.vue
================================================
<template>
	<view>
		<!-- 模拟的标题 -->
		<image class="header" src="https://www.mescroll.com/img/xinlang/header.jpg" mode="aspectFit"/>
		<view :style="{'top':top}" class="download-tip">1条新微博</view>
		
		<mescroll-body-diy @init="mescrollInit" top="100" bottom="100" :down="downOption" @down="downCallback" @up="upCallback">
			<!-- 新增的微博 -->
			<view class="news-li" v-for="news in addList" :key="news.id">
				<view>{{news.title}}</view>
				<view class="new-content">{{news.content}}</view>
			</view>
			<!-- 模拟的内容 -->
			<image src="https://www.mescroll.com/img/xinlang/xinlang1.jpg" mode="widthFix"/>
			<!-- 分页的数据 -->
			<view class="news-li" v-for="news in dataList" :key="news.id">
				<view>{{news.title}}</view>
				<view class="new-content">{{news.content}}</view>
			</view>
		</mescroll-body-diy>
		
		<!-- 模拟的底部 -->
		<image class="footer" src="https://www.mescroll.com/img/xinlang/footer.jpg" mode="aspectFit"/>
	</view>
</template>

<script>
	import MescrollBodyDiy from "@/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/mescroll-body.vue";
	import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
	import {apiWeiboList} from "@/api/mock.js"
	
	export default {
		mixins: [MescrollMixin], // 使用mixin
		components: {
			MescrollBodyDiy, // 避免与main.js注册的全局组件名称相同,否则注册组件失效(iOS真机 APP HBuilderX2.7.9)
		},
		data() {
			return {
				downOption:{
					auto:false,//是否在初始化完毕之后自动执行下拉回调callback; 默认true
				},
				addList:[],//新增微博
				dataList: [], // 数据列表
				top: 0 //提示,到顶部的距离
			}
		},
		methods: {
			/*下拉刷新的回调 */
			downCallback(){
				//加载轮播数据..
				//...
				//加载列表数据
				apiWeiboList().then(curPageData=>{
					//联网成功的回调,隐藏下拉刷新的状态
					this.mescroll.endSuccess();
					//添加新数据到顶部
					this.addList.unshift(curPageData[0]);
					//显示提示
					// #ifdef H5
					this.top=uni.upx2px(100+88)+"px"; // H5的高度需加上 88的标题栏
					// #endif
					
					// #ifndef H5
					this.top=uni.upx2px(100)+"px"; // 非H5不必加
					// #endif
					setTimeout(()=> {
						this.top=0;
					},2000);
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			},
			/*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
			upCallback(page) {
				//联网加载数据
				apiWeiboList(page.num, page.size).then(curPageData=>{
					//联网成功的回调,隐藏下拉刷新和上拉加载的状态;
					this.mescroll.endSuccess(curPageData.length);

					//追加新数据
					this.dataList=this.dataList.concat(curPageData);
				}).catch(()=>{
					//联网失败, 结束加载
					this.mescroll.endErr();
				})
			}
		}
	}
</script>

<style>
	image{width: 100%;vertical-align: bottom;height:auto}
	.header{z-index: 9900;position: fixed;top: --window-top;left: 0;height: 100upx;background: #fff;}
	.footer{z-index: 9900;position: fixed;bottom: 0;left: 0;height: 100upx;background: white;}
	
	.download-tip{
		z-index: 900;
		position: fixed;
		top: calc(var(--window-top) + 20upx);
		left: 0;
		width: 100%;
		height: 60upx;
		line-height: 60upx;
		font-size: 24upx;
		text-align: center;
		background-color: rgba(255,130,1,.7);
		color: white;
		-webkit-transition: top 300ms;
		transition: top 300ms;
	}
	
	/*展示上拉加载的数据列表*/
	.news-li{
		padding: 32upx;
		border-bottom: 1upx solid #eee;
	}
	.news-li .new-content{
		font-size: 28upx;
		margin-top: 10upx;
		margin-left: 20upx;
		color: #666;
	}
</style>


================================================
FILE: mescroll-uni/pages.json
================================================
{
    "pages" : [
        //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages
        {
            "path" : "pages/index/index",
            "style" : {
                "navigationBarTitleText" : "mescroll"
            }
        },
		{
		    "path" : "pages/base/list-news",
		    "style" : {
				"navigationBarTitleText" : "list-news"
			}
		},
        {
            "path" : "pages/base/list-products",
            "style" : {
				"navigationBarTitleText" : "极简示例"
			}
        },
        {
            "path" : "pages/base/mescroll-options",
            "style" : {
				"navigationBarTitleText" : "mescroll-options",
				"backgroundColorTop": "#E75A7C" // iOS APP真机bounce回弹区域颜色
			}
        },
        {
            "path" : "pages/base/mescroll-comp",
            "style" : {
				"navigationBarTitleText" : "mescroll-body写在子组件"
			}
        },
		{
            "path" : "pages/base/mescroll-i18n",
            "style" : {
				"navigationBarTitleText" : "mescroll语言国际化"
			}
        },
		{
		    "path" : "pages/base/mescroll-one",
		    "style" : {
				"navigationBarTitleText" : "mescroll-one"
			}
		},
        {
            "path" : "pages/base/mescroll-more",
            "style" : {
				"navigationBarTitleText" : "mescroll-more"
			}
        },
        {
            "path" : "pages/base/list-search",
            "style" : {
				"navigationBarTitleText" : "list-search"
			}
        },
		{
		    "path" : "pages/base/mescroll-empty",
		    "style" : {
				"navigationBarTitleText" : "单独使用mescroll-empty"
			}
		},
		{
		    "path" : "pages/base/mescroll-native",
		    "style" : {
				"navigationBarTitleText" : "mescroll-native",
				"enablePullDownRefresh" : true, // 开启系统自带的下拉刷新
				//ifdef MP 支持条件编译,如您可以配置小程序端使用系统自带的,其他平台使用mescroll的下拉样式
				//"enablePullDownRefresh" : true
				//endif
				//ifndef MP
				//"enablePullDownRefresh" : false
				//endif
				"mp-alipay":{"allowsBounceVertical":"YES"} // 开启支付宝和钉钉小程序自带的回弹
			}
		},
        {
            "path" : "pages/base/mescroll-uni",
            "style" : {
				"navigationBarTitleText" : "mescroll-uni",
				"disableScroll": true, // mescroll-uni需禁止滚动, 解决scroll-view在Android小程序卡顿的问题
				"app-plus" : {
					"bounce" : "none" // mescroll-uni需取消iOS回弹和安卓顶部底部的半月形阴影
				},
				"mp-alipay":{"allowsBounceVertical":"NO"} // mescroll-uni需取消支付宝和钉钉小程序自带的回弹
			}
        },
		{
		    "path" : "pages/intermediate/list-msg",
		    "style" : {
				"navigationBarTitleText" : "list-msg"
			}
		},
		{
		    "path" : "pages/intermediate/sticky",
		    "style" : {
				"navigationBarTitleText" : "sticky吸顶悬浮 (切换刷新列表,原生css实现)"
			}
		},
		{
		    "path" : "pages/intermediate/sticky-data",
		    "style" : {
				"navigationBarTitleText" : "sticky吸顶悬浮 (缓存列表数据,原生css实现)"
			}
		},
		{
		    "path" : "pages/intermediate/sticky-scroll",
		    "style" : {
				"navigationBarTitleText" : "sticky吸顶悬浮 (切换刷新列表,监听滚动实现)"
			}
		},
		{
		    "path" : "pages/intermediate/sticky-scroll-data",
		    "style" : {
				"navigationBarTitleText" : "sticky吸顶悬浮 (缓存列表数据,监听滚动实现)"
			}
		},
		{
		    "path" : "pages/intermediate/sticky-uni",
		    "style" : {
				"navigationBarTitleText" : "sticky吸顶悬浮 (mescroll-uni使用sticky)"
			}
		},
		{
		    "path" : "pages/intermediate/mescroll-uni-part",
		    "style" : {
				"navigationBarTitleText" : "mescroll-uni-part",
				"disableScroll": true, // mescroll-uni需禁止滚动, 解决scroll-view在Android小程序卡顿的问题
				"app-plus" : {
					"bounce" : "none" // mescroll-uni需取消iOS回弹和安卓顶部底部的半月形阴影
				},
				"mp-alipay":{"allowsBounceVertical":"NO"} // mescroll-uni需取消支付宝和钉钉小程序自带的回弹
			}
		},
		{
		    "path" : "pages/intermediate/mescroll-body-part",
		    "style" : {
				"navigationBarTitleText" : "mescroll-body-part"
			}
		},
		{
		    "path" : "pages/intermediate/mescroll-swiper",
		    "style" : {
				"navigationBarTitleText" : "轮播菜单导航 mescroll-swiper.vue",
				"disableScroll": true, // mescroll-uni需禁止滚动, 解决scroll-view在Android小程序卡顿的问题
				"app-plus" : {
					"bounce" : "none" // mescroll-uni需取消iOS回弹和安卓顶部底部的半月形阴影
				},
				"mp-alipay":{"allowsBounceVertical":"NO"} // mescroll-uni需取消支付宝和钉钉小程序自带的回弹
			}
		},
		{
		    "path" : "pages/intermediate/mescroll-swiper-sticky",
		    "style" : {
				"navigationBarTitleText" : "吸顶轮播菜单导航",
				// "disableScroll": false, // 此处不可禁止滚动
				"app-plus" : {
					"bounce" : "none" // mescroll-uni需取消iOS回弹和安卓顶部底部的半月形阴影
				},
				"mp-alipay":{"allowsBounceVertical":"NO"} // mescroll-uni需取消支付宝和钉钉小程序自带的回弹
			}
		},
		{
            "path" : "pages/intermediate/beibei",
            "style" : {
				"navigationBarTitleText" : "贝贝 mescroll-beibei.vue"
			}
        },
        {
            "path" : "pages/intermediate/xinlang",
            "style" : {
				"navigationBarTitleText" : "新浪微博 mescroll-xinlang.vue"
			}
        }
    ],
    "globalStyle" : {
		"backgroundColorTop":"#FFFFFF", // iOS APP真机bounce回弹区域默认灰色,需重置为白色
		"mp-alipay":{"allowsBounceVertical":"NO"}, // 支付宝和钉钉小程序取消自带的回弹
        "navigationBarTextStyle" : "black",
        "navigationBarBackgroundColor" : "#fff"
    }
}


================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/changelog.md
================================================
## 1.3.8(2023-03-26)
1. 新增useMescroll的hook, 支持vue3 script setup的写法  
2. 新增vue3 script setup的示例 ( 根据vue2的示例,全部重写了一遍 )  
3. mescroll-body 和 mescroll-uni 无需再写 ref="mescrollRef"  
4. 解决mescroll-uni在页面渲染之后,无法动态设置height的问题  
5. 解决renderjs在h5返回有时候无法正常滑动的问题  
6. 修复小程序编辑器提示 Cannot read property 'nv_optDown' of undefined 的错误  
-by 小瑾同学


================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.css
================================================
.mescroll-body {
	position: relative; /* 下拉刷新区域相对自身定位 */
	height: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实现列表不满屏仍可下拉*/
	overflow: hidden; /* 当有元素写在mescroll-body标签前面时,可遮住下拉刷新区域 */
	box-sizing: border-box; /* 避免设置padding出现双滚动条的问题 */
}

/* 使sticky生效: 父元素不能overflow:hidden或者overflow:auto属性 */
.mescroll-body.mescorll-sticky{
	overflow: unset !important
}

/* 适配 iPhoneX */
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
	.mescroll-safearea {
		padding-bottom: constant(safe-area-inset-bottom);
		padding-bottom: env(safe-area-inset-bottom);
	}
}

================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.vue
================================================
<template>
	<view 
	class="mescroll-body mescroll-render-touch" 
	:class="{'mescorll-sticky': sticky}"
	:style="{'minHeight':minHeight, 'padding-top': padTop, 'padding-bottom': padBottom}" 
	@touchstart="wxsBiz.touchstartEvent" 
	@touchmove="wxsBiz.touchmoveEvent" 
	@touchend="wxsBiz.touchendEvent" 
	@touchcancel="wxsBiz.touchendEvent"
	:change:prop="wxsBiz.propObserver"
	:prop="wxsProp"
	>
		<!-- 状态栏 -->
		<view v-if="topbar&&statusBarHeight" class="mescroll-topbar" :style="{height: statusBarHeight+'px', background: topbar}"></view>
		
		<view class="mescroll-body-content mescroll-wxs-content" :style="{ transform: translateY, transition: transition }" :change:prop="wxsBiz.callObserver" :prop="callProp">
			<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)-->
			<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType" :rate="downRate"></mescroll-down> -->
			<view v-if="mescroll.optDown.use" class="mescroll-downwarp" :style="{'background':mescroll.optDown.bgColor,'color':mescroll.optDown.textColor}">
				<view class="downwarp-content">
					<view class="downwarp-progress mescroll-wxs-progress" :class="{'mescroll-rotate': isDownLoading}" :style="{'border-color':mescroll.optDown.textColor, 'transform': downRotate}"></view>
					<view class="downwarp-tip">{{downText}}</view>
				</view>
			</view>
	
			<!-- 列表内容 -->
			<slot></slot>

			<!-- 空布局 -->
			<mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty>

			<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)-->
			<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> -->
			<view v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" class="mescroll-upwarp" :style="{'background':mescroll.optUp.bgColor,'color':mescroll.optUp.textColor}">
				<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
				<view v-show="upLoadType===1">
					<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mescroll.optUp.textColor}"></view>
					<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view>
				</view>
				<!-- 无数据 -->
				<view v-if="upLoadType===2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view>
			</view>
		</view>
		
		<!-- 底部是否偏移TabBar的高度(默认仅在H5端的tab页生效) -->
		<!-- #ifdef H5 -->
		<view v-if="bottombar && windowBottom>0" class="mescroll-bottombar" :style="{height: windowBottom+'px'}"></view>
		<!-- #endif -->
		
		<!-- 适配iPhoneX -->
		<view v-if="safearea" class="mescroll-safearea"></view>
		
		<!-- 回到顶部按钮 (fixed元素需写在transform外面,防止降级为absolute)-->
		<mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick"></mescroll-top>
		
		<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
		<!-- renderjs的数据载体,不可写在mescroll-downwarp内部,避免use为false时,载体丢失,无法更新数据 -->
		<view :change:prop="renderBiz.propObserver" :prop="wxsProp"></view>
		<!-- #endif -->
	</view>
</template>

<!-- 微信小程序, QQ小程序, app, h5使用wxs -->
<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
<script src="../mescroll-uni/wxs/wxs.wxs" module="wxsBiz" lang="wxs"></script>
<!-- #endif -->

<!-- app, h5使用renderjs -->
<!-- #ifdef APP-PLUS || H5 -->
<script module="renderBiz" lang="renderjs">
	import renderBiz from "../mescroll-uni/wxs/renderjs.js";
	export default {
		mixins: [renderBiz]
	}
</script>
<!-- #endif -->

<script>
	// 引入mescroll-uni.js,处理核心逻辑
	import MeScroll from "../mescroll-uni/mescroll-uni.js";
	// 引入全局配置
	import GlobalOption from "../mescroll-uni/mescroll-uni-option.js";
	// 引入国际化工具类
	import mescrollI18n from '../mescroll-uni/mescroll-i18n.js';
	// 引入回到顶部组件
	import MescrollTop from "../mescroll-uni/components/mescroll-top.vue";
	// 引入兼容wxs(含renderjs)写法的mixins
	import WxsMixin from "../mescroll-uni/wxs/mixins.js";
	
	/**
	 * mescroll-body 基于page滚动的下拉刷新和上拉加载组件, 支持嵌套原生组件, 性能好
	 * @property {Object} down 下拉刷新的参数配置
	 * @property {Object} up 上拉加载的参数配置
	 * @property {Object} i18n 国际化的参数配置
	 * @property {String, Number} top 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
	 * @property {Boolean, String} topbar 偏移量top是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可留出状态栏的占位, 支持传入字符串背景,如色值,背景图,渐变)
	 * @property {String, Number} bottom 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
	 * @property {Boolean} safearea 偏移量bottom是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用)
	 * @property {Boolean} fixed 是否通过fixed固定mescroll的高度, 默认true
	 * @property {String, Number} height 指定mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉
	 * @property {Boolean} bottombar 底部是否偏移TabBar的高度 (仅在H5端的tab页生效)
	 * @property {Boolean} sticky 是否支持sticky,默认false; 当值配置true时,需避免在mescroll-body标签前面加非定位的元素,否则下拉区域无法隐藏
	 * @event {Function} init 初始化完成的回调 
	 * @event {Function} down 下拉刷新的回调
	 * @event {Function} up 上拉加载的回调 
	 * @event {Function} emptyclick 点击empty配置的btnText按钮回调
	 * @event {Function} topclick 点击回到顶部的按钮回调
	 * @event {Function} scroll 滚动监听 (需在 up 配置 onScroll:true 才生效)
	 * @example <mescroll-body @init="mescrollInit" @down="downCallback" @up="upCallback"> ... </mescroll-body>
	 */
	export default {
		name: 'mescroll-body',
		mixins: [WxsMixin],
		components: {
			MescrollTop
		},
		props: {
			down: Object,
			up: Object,
			i18n: Object,
			top: [String, Number],
			topbar: [Boolean, String],
			bottom: [String, Number],
			safearea: Boolean,
			height: [String, Number],
			bottombar:{
				type: Boolean,
				default: true
			},
			sticky: Boolean
		},
		data() {
			return {
				mescroll: {optDown:{},optUp:{}}, // mescroll实例
				downHight: 0, //下拉刷新: 容器高度
				downRate: 0, // 下拉比率(inOffset: rate<1; outOffset: rate>=1)
				downLoadType: 0, // 下拉刷新状态: 0(loading前), 1(inOffset), 2(outOffset), 3(showLoading), 4(endDownScroll)
				upLoadType: 0, // 上拉加载状态:0(loading前),1(loading中),2(没有更多了,显示END文本提示),3(没有更多了,不显示END文本提示)
				isShowEmpty: false, // 是否显示空布局
				isShowToTop: false, // 是否显示回到顶部按钮
				windowHeight: 0, // 可使用窗口的高度
				windowBottom: 0, // 可使用窗口的底部位置
				statusBarHeight: 0 // 状态栏高度
			};
		},
		computed: {
			// mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉
			minHeight(){
				return this.toPx(this.height || '100%') + 'px'
			},
			// 下拉布局往下偏移的距离 (px)
			numTop() {
				return this.toPx(this.top)
			},
			padTop() {
				return this.numTop + 'px';
			},
			// 上拉布局往上偏移 (px)
			numBottom() {
				return this.toPx(this.bottom);
			},
			padBottom() {
				return this.numBottom + 'px';
			},
			// 是否为重置下拉的状态
			isDownReset() {
				return this.downLoadType === 3 || this.downLoadType === 4;
			},
			// 过渡
			transition() {
				return this.isDownReset ? 'transform 300ms' : '';
			},
			translateY() {
				return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : ''; // transform会使fixed失效,需注意把fixed元素写在mescroll之外
			},
			// 是否在加载中
			isDownLoading(){
				return this.downLoadType === 3
			},
			// 旋转的角度
			downRotate(){
				return 'rotate(' + 360 * this.downRate + 'deg)'
			},
			// 文本提示
			downText(){
				if(!this.mescroll) return ""; // 避免头条小程序初始化时报错
				switch (this.downLoadType){
					case 1: return this.mescroll.optDown.textInOffset;
					case 2: return this.mescroll.optDown.textOutOffset;
					case 3: return this.mescroll.optDown.textLoading;
					case 4: return this.mescroll.isDownEndSuccess ? this.mescroll.optDown.textSuccess : this.mescroll.isDownEndSuccess==false ? this.mescroll.optDown.textErr : this.mescroll.optDown.textInOffset;
					default: return this.mescroll.optDown.textInOffset;
				}
			}
		},
		methods: {
			//number,rpx,upx,px,% --> px的数值
			toPx(num) {
				if (typeof num === 'string') {
					if (num.indexOf('px') !== -1) {
						if (num.indexOf('rpx') !== -1) {
							// "10rpx"
							num = num.replace('rpx', '');
						} else if (num.indexOf('upx') !== -1) {
							// "10upx"
							num = num.replace('upx', '');
						} else {
							// "10px"
							return Number(num.replace('px', ''));
						}
					} else if (num.indexOf('%') !== -1) {
						// 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10%
						let rate = Number(num.replace('%', '')) / 100;
						return this.windowHeight * rate;
					}
				}
				return num ? uni.upx2px(Number(num)) : 0;
			},
			// 点击空布局的按钮回调
			emptyClick() {
				this.$emit('emptyclick', this.mescroll);
			},
			// 点击回到顶部的按钮回调
			toTopClick() {
				this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部
				this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调
			}
		},
		// 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效
		created() {
			let vm = this;

			let diyOption = {
				// 下拉刷新的配置
				down: {
					inOffset() {
						vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删)
					},
					outOffset() {
						vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删)
					},
					onMoving(mescroll, rate, downHight) {
						// 下拉过程中的回调,滑动过程一直在执行;
						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
						vm.downRate = rate; //下拉比率 (inOffset: rate<1; outOffset: rate>=1)
					},
					showLoading(mescroll, downHight) {
						vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删)
						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
					},
					beforeEndDownScroll(mescroll){
						vm.downLoadType = 4; 
						return mescroll.optDown.beforeEndDelay // 延时结束的时长
					},
					endDownScroll() {
						vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删)
						vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
						if(vm.downResetTimer) {clearTimeout(vm.downResetTimer); vm.downResetTimer = null} // 移除重置倒计时
						vm.downResetTimer = setTimeout(()=>{ // 过渡动画执行完毕后,需重置为0的状态,避免下次inOffset不及时显示textInOffset
							if(vm.downLoadType === 4) vm.downLoadType = 0
						},300)
					},
					// 派发下拉刷新的回调
					callback: function(mescroll) {
						vm.$emit('down', mescroll);
					}
				},
				// 上拉加载的配置
				up: {
					// 显示加载中的回调
					showLoading() {
						vm.upLoadType = 1;
					},
					// 显示无更多数据的回调
					showNoMore() {
						vm.upLoadType = 2;
					},
					// 隐藏上拉加载的回调
					hideUpScroll(mescroll) {
						vm.upLoadType = mescroll.optUp.hasNext ? 0 : 3;
					},
					// 空布局
					empty: {
						onShow(isShow) {
							// 显示隐藏的回调
							vm.isShowEmpty = isShow;
						}
					},
					// 回到顶部
					toTop: {
						onShow(isShow) {
							// 显示隐藏的回调
							vm.isShowToTop = isShow;
						}
					},
					// 派发上拉加载的回调
					callback: function(mescroll) {
						vm.$emit('up', mescroll);
					}
				}
			};
			
			let i18nType = mescrollI18n.getType() // 当前语言类型
			let i18nOption = {type: i18nType} // 国际化配置
			MeScroll.extend(i18nOption, vm.i18n) // 具体页面的国际化配置
			MeScroll.extend(i18nOption, GlobalOption.i18n) // 全局的国际化配置
			MeScroll.extend(diyOption, i18nOption[i18nType]); // 混入国际化配置
			MeScroll.extend(diyOption, {down:GlobalOption.down, up:GlobalOption.up}); // 混入全局的配置
			let myOption = JSON.parse(JSON.stringify({down: vm.down,up: vm.up})); // 深拷贝,避免对props的影响
			MeScroll.extend(myOption, diyOption); // 混入具体界面的配置

			// 初始化MeScroll对象
			vm.mescroll = new MeScroll(myOption, true); // 传入true,标记body为滚动区域
			// 挂载语言包
			vm.mescroll.i18n = i18nOption;
			// init回调mescroll对象
			vm.$emit('init', vm.mescroll);

			// 设置高度
			const sys = uni.getSystemInfoSync();
			if (sys.windowHeight) vm.windowHeight = sys.windowHeight;
			if (sys.windowBottom) vm.windowBottom = sys.windowBottom;
			if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight;
			// 使down的bottomOffset生效
			vm.mescroll.setBodyHeight(sys.windowHeight);

			// 因为使用的是page的scroll,这里需自定义scrollTo
			vm.mescroll.resetScrollTo((y, t) => {
				if(typeof y === 'string'){
					// 滚动到指定view (y为css选择器)
					setTimeout(()=>{ // 延时确保view已渲染; 不使用$nextTick
						let selector;
						if(y.indexOf('#')==-1 && y.indexOf('.')==-1){
							selector = '#'+y // 不带#和. 则默认为id选择器
						}else{
							selector = y
							// #ifdef APP-PLUS || H5 || MP-ALIPAY || MP-DINGTALK
							if(y.indexOf('>>>')!=-1){ // 不支持跨自定义组件的后代选择器 (转为普通的选择器即可跨组件查询)
								selector = y.split('>>>')[1].trim()
							}
							// #endif
						}
						uni.createSelectorQuery().select(selector).boundingClientRect(function(rect){
							if (rect) {
								let top = rect.top
								top += vm.mescroll.getScrollTop()
								uni.pageScrollTo({
									scrollTop: top,
									duration: t
								})
							} else{
								console.error(selector + ' does not exist');
							}
						}).exec()
					},30)
				} else{
					// 滚动到指定位置 (y必须为数字)
					uni.pageScrollTo({
						scrollTop: y,
						duration: t
					})
				}
			});

			// 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值
			if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {} else {
				vm.mescroll.optUp.toTop.safearea = vm.safearea;
			}
			
			// 全局配置监听
			uni.$on("setMescrollGlobalOption", options=>{
				if(!options) return;
				let i18nType = options.i18n ? options.i18n.type : null
				if(i18nType && vm.mescroll.i18n.type != i18nType){
					vm.mescroll.i18n.type = i18nType
					mescrollI18n.setType(i18nType)
					MeScroll.extend(options, vm.mescroll.i18n[i18nType])
				}
				if(options.down){
					let down = MeScroll.extend({}, options.down)
					vm.mescroll.optDown = MeScroll.extend(down, vm.mescroll.optDown)
				}
				if(options.up){
					let up = MeScroll.extend({}, options.up)
					vm.mescroll.optUp = MeScroll.extend(up, vm.mescroll.optUp)
				}
			})
		},
		destroyed() {
			// 注销全局配置监听
			uni.$off("setMescrollGlobalOption")
		}
	};
</script>

<style>
	@import "../mescroll-body/mescroll-body.css";
	@import "../mescroll-uni/components/mescroll-down.css";
	@import "../mescroll-uni/components/mescroll-up.css";
</style>

================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/components/mescroll-down.css
================================================
/*下拉刷新--标语*/
.mescroll-downwarp .downwarp-slogan{
	display: block;
	width: 420rpx;
	height: 168rpx;
	margin: auto;
}
/*下拉刷新--向下进度动画*/
.mescroll-downwarp .downwarp-progress{
	display: inline-block;
	width: 40rpx;
	height: 40rpx;
	border: none;
	margin: auto;
	background-size: contain;
	background-repeat: no-repeat;
	background-position: center;
	background-image: url(https://www.mescroll.com/img/beibei/mescroll-progress.png);
	transition: all 300ms;
}
/*下拉刷新--进度条*/
.mescroll-downwarp .downwarp-loading{
	display: inline-block;
	width: 32rpx;
	height: 32rpx;
	border-radius: 50%;
	border: 2rpx solid #FF8095;
	border-bottom-color: transparent;
}
/*下拉刷新--吉祥物*/
.mescroll-downwarp .downwarp-mascot{
	position: absolute;
	right: 16rpx;
	bottom: 0;
	width: 100rpx;
	height: 100rpx;
	background-size: contain;
	background-repeat: no-repeat;
	animation: animMascot .6s steps(1,end) infinite;
}
@keyframes animMascot {
	0% {background-image: url(https://www.mescroll.com/img/beibei/mescroll-bb1.png)}
	25% {background-image: url(https://www.mescroll.com/img/beibei/mescroll-bb2.png)}
	50% {background-image: url(https://www.mescroll.com/img/beibei/mescroll-bb3.png)}
	75% {background-image: url(https://www.mescroll.com/img/beibei/mescroll-bb4.png)}
	100% {background-image: url(https://www.mescroll.com/img/beibei/mescroll-bb1.png)}
}

================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/components/mescroll-down.vue
================================================
<!-- 下拉刷新区域 -->
<template>
	<view v-if="mOption.use" class="mescroll-downwarp" :style="{'background':mOption.bgColor,'color':mOption.textColor}">
		<view class="downwarp-content">
			<image class="downwarp-slogan" src="https://www.mescroll.com/img/beibei/mescroll-slogan.jpg?v=1" mode="widthFix"/>
			<view v-if="isDownLoading" class="downwarp-loading mescroll-rotate"></view>
			<view v-else class="downwarp-progress" :style="{'transform':downRotate}"></view>
			<view class="downwarp-mascot"></view>
		</view>
	</view>
</template>

<script>
export default {
	props: {
		option: Object , // down的配置项
		type: Number // 下拉状态(inOffset:1, outOffset:2, showLoading:3, endDownScroll:4)
	},
	computed: {
		// 支付宝小程序需写成计算属性,prop定义default仍报错
		mOption(){
			return this.option || {}
		},
		// 是否在加载中
		isDownLoading(){
			return this.type === 3
		},
		// 旋转的角度
		downRotate(){
			return this.type === 2 ? 'rotate(180deg)' : 'rotate(0deg)'
		}
	}
};
</script>

<style>
@import "../../../mescroll-uni/components/mescroll-down.css";
@import "./mescroll-down.css";
</style>


================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-body.vue
================================================
<template>
	<view 
		class="mescroll-body mescroll-render-touch" 
		:style="{'minHeight':minHeight, 'padding-top': padTop, 'padding-bottom': padBottom}" 
		:class="{'mescorll-sticky': sticky}"
		@touchstart="wxsBiz.touchstartEvent" 
		@touchmove="wxsBiz.touchmoveEvent" 
		@touchend="wxsBiz.touchendEvent" 
		@touchcancel="wxsBiz.touchendEvent"
		:change:prop="wxsBiz.propObserver"
		:prop="wxsProp"
		>
		
		<!-- 状态栏 -->
		<view v-if="topbar&&statusBarHeight" class="mescroll-topbar" :style="{height: statusBarHeight+'px', background: topbar}"></view>

		<view class="mescroll-body-content mescroll-wxs-content" :style="{ transform: translateY, transition: transition }" :change:prop="wxsBiz.callObserver" :prop="callProp">
			<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)-->
			<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType"></mescroll-down> -->
			<view v-if="mescroll.optDown.use" class="mescroll-downwarp" :style="{'background':mescroll.optDown.bgColor,'color':mescroll.optDown.textColor}">
				<view class="downwarp-content">
					<image class="downwarp-slogan" src="https://www.mescroll.com/img/beibei/mescroll-slogan.jpg?v=1" mode="widthFix"/>
					<view v-if="isDownLoading" class="downwarp-loading mescroll-rotate"></view>
					<view v-else class="downwarp-progress" :style="{'transform':downRotate}"></view>
					<view class="downwarp-mascot"></view>
				</view>
			</view>
						
			<!-- 列表内容 -->
			<slot></slot>

			<!-- 空布局 -->
			<mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty>

			<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)-->
			<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> -->
			<view v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" class="mescroll-upwarp" :style="{'background':mescroll.optUp.bgColor,'color':mescroll.optUp.textColor}">
				<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
				<view v-show="upLoadType===1">
					<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mescroll.optUp.textColor}"></view>
					<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view>
				</view>
				<!-- 无数据 -->
				<view v-if="upLoadType===2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view>
			</view>
		</view>
		
		<!-- 底部是否偏移TabBar的高度(仅H5端生效) -->
		<!-- #ifdef H5 -->
		<view v-if="bottombar && windowBottom>0" class="mescroll-bottombar" :style="{height: windowBottom+'px'}"></view>
		<!-- #endif -->
		
		<!-- 适配iPhoneX -->
		<view v-if="safearea" class="mescroll-safearea"></view>
		
		<!-- 回到顶部按钮 (fixed元素需写在transform外面,防止降级为absolute)-->
		<mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick"></mescroll-top>

		<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
		<!-- renderjs的数据载体,不可写在mescroll-downwarp内部,避免use为false时,载体丢失,无法更新数据 -->
		<view :change:prop="renderBiz.propObserver" :prop="wxsProp"></view>
		<!-- #endif -->
	</view>
</template>

<!-- 微信小程序, QQ小程序, app, h5使用wxs -->
<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
<script src="../../mescroll-uni/wxs/wxs.wxs" module="wxsBiz" lang="wxs"></script>
<!-- #endif -->

<!-- app, h5使用renderjs -->
<!-- #ifdef APP-PLUS || H5 -->
<script module="renderBiz" lang="renderjs">
	import renderBiz from '../../mescroll-uni/wxs/renderjs.js';
	export default {
		mixins: [renderBiz]
	}
</script>
<!-- #endif -->

<script>
	import MeScroll from '../../mescroll-uni/mescroll-uni.js';
	import MescrollTop from '../../mescroll-uni/components/mescroll-top.vue';
	import WxsMixin from '../../mescroll-uni/wxs/mixins.js';
	import mescrollI18n from '../../mescroll-uni/mescroll-i18n.js';
	import GlobalOption from './mescroll-uni-option.js';
	
	export default {
		mixins: [WxsMixin],
		components: {
			MescrollTop
		},
		data() {
			return {
				mescroll: {optDown:{},optUp:{}}, // mescroll实例
				downHight: 0, //下拉刷新: 容器高度
				downLoadType: 0, // 下拉刷新状态: 0(loading前), 1(inOffset), 2(outOffset), 3(showLoading), 4(endDownScroll)
				upLoadType: 0, // 上拉加载状态:0(loading前),1(loading中),2(没有更多了,显示END文本提示),3(没有更多了,不显示END文本提示)
				isShowEmpty: false, // 是否显示空布局
				isShowToTop: false, // 是否显示回到顶部按钮
				windowHeight: 0, // 可使用窗口的高度
				windowBottom: 0, // 可使用窗口的底部位置
				statusBarHeight: 0 // 状态栏高度
			};
		},
		props: {
			down: Object, // 下拉刷新的参数配置
			up: Object, // 上拉加载的参数配置
			i18n: Object, // 国际化的参数配置
			top: [String, Number], // 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
			topbar: [Boolean, String], // top的偏移量是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可留出状态栏的占位, 支持传入字符串背景,如色值,背景图,渐变)
			bottom: [String, Number], // 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
			safearea: Boolean, // bottom的偏移量是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用)
			height: [String, Number], // 指定mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉
			bottombar:{ // 底部是否偏移TabBar的高度(默认仅在H5端的tab页生效)
				type: Boolean,
				default: true
			},
			sticky: Boolean // 是否支持sticky,默认false; 当值配置true时,需避免在mescroll-body标签前面加非定位的元素,否则下拉区域无法会隐藏
		},
		computed: {
			// mescroll最小高度,默认windowHeight,使列表不满屏仍可下拉
			minHeight(){
				return this.toPx(this.height || '100%') + 'px'
			},
			// 下拉布局往下偏移的距离 (px)
			numTop() {
				return this.toPx(this.top)
			},
			padTop() {
				return this.numTop + 'px';
			},
			// 上拉布局往上偏移 (px)
			numBottom() {
				return this.toPx(this.bottom);
			},
			padBottom() {
				return this.numBottom + 'px';
			},
			// 是否为重置下拉的状态
			isDownReset() {
				return this.downLoadType === 3 || this.downLoadType === 4;
			},
			// 过渡
			transition() {
				return this.isDownReset ? 'transform 300ms' : '';
			},
			translateY() {
				return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : ''; // transform会使fixed失效,需注意把fixed元素写在mescroll之外
			},
			// 是否在加载中
			isDownLoading(){
				return this.downLoadType === 3
			},
			// 旋转的角度
			downRotate(){
				return this.downLoadType === 2 ? 'rotate(180deg)' : 'rotate(0deg)'
			}
		},
		methods: {
			//number,rpx,upx,px,% --> px的数值
			toPx(num) {
				if (typeof num === 'string') {
					if (num.indexOf('px') !== -1) {
						if (num.indexOf('rpx') !== -1) {
							// "10rpx"
							num = num.replace('rpx', '');
						} else if (num.indexOf('upx') !== -1) {
							// "10upx"
							num = num.replace('upx', '');
						} else {
							// "10px"
							return Number(num.replace('px', ''));
						}
					} else if (num.indexOf('%') !== -1) {
						// 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10%
						let rate = Number(num.replace('%', '')) / 100;
						return this.windowHeight * rate;
					}
				}
				return num ? uni.upx2px(Number(num)) : 0;
			},
			// 点击空布局的按钮回调
			emptyClick() {
				this.$emit('emptyclick', this.mescroll);
			},
			// 点击回到顶部的按钮回调
			toTopClick() {
				this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部
				this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调
			}
		},
		// 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效
		created() {
			let vm = this;

			let diyOption = {
				// 下拉刷新的配置
				down: {
					inOffset() {
						vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删)
					},
					outOffset() {
						vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删)
					},
					onMoving(mescroll, rate, downHight) {
						// 下拉过程中的回调,滑动过程一直在执行;
						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
					},
					showLoading(mescroll, downHight) {
						vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删)
						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
					},
					endDownScroll() {
						vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删)
						vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
						if(vm.downResetTimer) {clearTimeout(vm.downResetTimer); vm.downResetTimer = null} // 移除重置倒计时
						vm.downResetTimer = setTimeout(()=>{ // 过渡动画执行完毕后,需重置为0的状态,避免下次inOffset不及时显示textInOffset
							if(vm.downLoadType === 4) vm.downLoadType = 0
						},300)
					},
					// 派发下拉刷新的回调
					callback: function(mescroll) {
						vm.$emit('down', mescroll);
					}
				},
				// 上拉加载的配置
				up: {
					// 显示加载中的回调
					showLoading() {
						vm.upLoadType = 1;
					},
					// 显示无更多数据的回调
					showNoMore() {
						vm.upLoadType = 2;
					},
					// 隐藏上拉加载的回调
					hideUpScroll(mescroll) {
						vm.upLoadType = mescroll.optUp.hasNext ? 0 : 3;
					},
					// 空布局
					empty: {
						onShow(isShow) {
							// 显示隐藏的回调
							vm.isShowEmpty = isShow;
						}
					},
					// 回到顶部
					toTop: {
						onShow(isShow) {
							// 显示隐藏的回调
							vm.isShowToTop = isShow;
						}
					},
					// 派发上拉加载的回调
					callback: function(mescroll) {
						vm.$emit('up', mescroll);
					}
				}
			};

			let i18nType = mescrollI18n.getType() // 当前语言类型
			let i18nOption = {type: i18nType} // 国际化配置
			MeScroll.extend(i18nOption, vm.i18n) // 具体页面的国际化配置
			MeScroll.extend(i18nOption, GlobalOption.i18n) // 全局的国际化配置
			MeScroll.extend(diyOption, i18nOption[i18nType]); // 混入国际化配置
			MeScroll.extend(diyOption, {down:GlobalOption.down, up:GlobalOption.up}); // 混入全局的配置
			let myOption = JSON.parse(JSON.stringify({down: vm.down,up: vm.up})); // 深拷贝,避免对props的影响
			MeScroll.extend(myOption, diyOption); // 混入具体界面的配置

			// 初始化MeScroll对象
			vm.mescroll = new MeScroll(myOption, true); // 传入true,标记body为滚动区域
			// 挂载语言包
			vm.mescroll.i18n = i18nOption;
			// init回调mescroll对象
			vm.$emit('init', vm.mescroll);

			// 设置高度
			const sys = uni.getSystemInfoSync();
			if (sys.windowHeight) vm.windowHeight = sys.windowHeight;
			if (sys.windowBottom) vm.windowBottom = sys.windowBottom;
			if (sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight;
			// 使down的bottomOffset生效
			vm.mescroll.setBodyHeight(sys.windowHeight);

			// 因为使用的是page的scroll,这里需自定义scrollTo
			vm.mescroll.resetScrollTo((y, t) => {
				if(typeof y === 'string'){
					// 滚动到指定view (y为css选择器)
					setTimeout(()=>{ // 延时确保view已渲染; 不使用$nextTick
						let selector;
						if(y.indexOf('#')==-1 && y.indexOf('.')==-1){
							selector = '#'+y // 不带#和. 则默认为id选择器
						}else{
							selector = y
							// #ifdef APP-PLUS || H5 || MP-ALIPAY || MP-DINGTALK
							if(y.indexOf('>>>')!=-1){ // 不支持跨自定义组件的后代选择器 (转为普通的选择器即可跨组件查询)
								selector = y.split('>>>')[1].trim()
							}
							// #endif
						}
						uni.createSelectorQuery().select(selector).boundingClientRect(function(rect){
							if (rect) {
								let top = rect.top
								top += vm.mescroll.getScrollTop()
								uni.pageScrollTo({
									scrollTop: top,
									duration: t
								})
							} else{
								console.error(selector + ' does not exist');
							}
						}).exec()
					},30)
				} else{
					// 滚动到指定位置 (y必须为数字)
					uni.pageScrollTo({
						scrollTop: y,
						duration: t
					})
				}
			});

			// 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值
			if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {} else {
				vm.mescroll.optUp.toTop.safearea = vm.safearea;
			}
			
			// 全局配置监听
			uni.$on("setMescrollGlobalOption", options=>{
				if(!options) return;
				let i18nType = options.i18n ? options.i18n.type : null
				if(i18nType && vm.mescroll.i18n.type != i18nType){
					vm.mescroll.i18n.type = i18nType
					mescrollI18n.setType(i18nType)
					MeScroll.extend(options, vm.mescroll.i18n[i18nType])
				}
				if(options.down){
					let down = MeScroll.extend({}, options.down)
					vm.mescroll.optDown = MeScroll.extend(down, vm.mescroll.optDown)
				}
				if(options.up){
					let up = MeScroll.extend({}, options.up)
					vm.mescroll.optUp = MeScroll.extend(up, vm.mescroll.optUp)
				}
			})
		},
		destroyed() {
			// 注销全局配置监听
			uni.$off("setMescrollGlobalOption")
		}
	};
</script>

<style>
	@import "../../mescroll-body/mescroll-body.css";
	@import "../../mescroll-uni/components/mescroll-down.css";
	@import "../../mescroll-uni/components/mescroll-up.css";
	@import "./components/mescroll-down.css";
</style>


================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-uni-option.js
================================================
// mescroll-uni和mescroll-body 的全局配置
const GlobalOption = {
	down: {
		// 其他down的配置参数也可以写,这里只展示了常用的配置:
		offset: uni.upx2px(140), // 在列表顶部,下拉大于140upx,松手即可触发下拉刷新的回调
		native: false // 是否使用系统自带的下拉刷新; 默认false; 仅在mescroll-body生效 (值为true时,还需在pages配置enablePullDownRefresh:true;详请参考mescroll-native的案例)
	},
	up: {
		// 其他up的配置参数也可以写,这里只展示了常用的配置:
		offset: 150, // 距底部多远时,触发upCallback
		toTop: {
			// 回到顶部按钮,需配置src才显示
			src: "https://www.mescroll.com/img/mescroll-totop.png", // 图片路径 (建议放入static目录, 如 /static/img/mescroll-totop.png )
			offset: 1000, // 列表滚动多少距离才显示回到顶部按钮,默认1000px
			right: 20, // 到右边的距离, 默认20 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
			bottom: 120, // 到底部的距离, 默认120 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
			width: 72 // 回到顶部图标的宽度, 默认72 (支持"20rpx", "20px", "20%"格式的值, 纯数字则默认单位rpx)
		},
		empty: {
			use: true, // 是否显示空布局
			icon: "https://www.mescroll.com/img/mescroll-empty.png" // 图标路径 (建议放入static目录, 如 /static/img/mescroll-empty.png )
		}
	},
	// 国际化配置
	i18n: {
		// 中文
		zh: {
			up: {
				textLoading: '加载中 ...', // 加载中的提示文本
				textNoMore: '-- END --', // 没有更多数据的提示文本
				empty: {
					tip: '~ 暂无相关数据 ~' // 空提示
				}
			}
		},
		// 英文
		en: {
			up: {
				textLoading: 'loading ...',
				textNoMore: '-- END --',
				empty: {
					tip: '~ absolutely empty ~'
				}
			}
		}
	}
}

export default GlobalOption

================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-uni.vue
================================================
<template>
	<view class="mescroll-uni-warp">
		<scroll-view :id="viewId" class="mescroll-uni" :class="{'mescroll-uni-fixed':isFixed}" :style="{'height':scrollHeight,'padding-top':padTop,'padding-bottom':padBottom,'top':fixedTop,'bottom':fixedBottom}" :scroll-top="scrollTop" :scroll-with-animation="scrollAnim" @scroll="scroll" :scroll-y='scrollable' :enable-back-to-top="true" :throttle="false">
			<view class="mescroll-uni-content mescroll-render-touch"
			@touchstart="wxsBiz.touchstartEvent" 
			@touchmove="wxsBiz.touchmoveEvent" 
			@touchend="wxsBiz.touchendEvent" 
			@touchcancel="wxsBiz.touchendEvent"
			:change:prop="wxsBiz.propObserver"
			:prop="wxsProp">
						
				<!-- 状态栏 -->
				<view v-if="topbar&&statusBarHeight" class="mescroll-topbar" :style="{height: statusBarHeight+'px', background: topbar}"></view>
							
				<view class="mescroll-wxs-content" :style="{'transform': translateY, 'transition': transition}" :change:prop="wxsBiz.callObserver" :prop="callProp">
					<!-- 下拉加载区域 (支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-down组件实现)-->
					<!-- <mescroll-down :option="mescroll.optDown" :type="downLoadType"></mescroll-down> -->
					<view v-if="mescroll.optDown.use" class="mescroll-downwarp" :style="{'background':mescroll.optDown.bgColor,'color':mescroll.optDown.textColor}">
						<view class="downwarp-content">
							<image class="downwarp-slogan" src="https://www.mescroll.com/img/beibei/mescroll-slogan.jpg?v=1" mode="widthFix"/>
							<view v-if="isDownLoading" class="downwarp-loading mescroll-rotate"></view>
							<view v-else class="downwarp-progress" :style="{'transform':downRotate}"></view>
							<view class="downwarp-mascot"></view>
						</view>
					</view>

					<!-- 列表内容 -->
					<slot></slot>

					<!-- 空布局 -->
					<mescroll-empty v-if="isShowEmpty" :option="mescroll.optUp.empty" @emptyclick="emptyClick"></mescroll-empty>

					<!-- 上拉加载区域 (下拉刷新时不显示, 支付宝小程序子组件传参给子子组件仍报单项数据流的异常,暂时不通过mescroll-up组件实现)-->
					<!-- <mescroll-up v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" :option="mescroll.optUp" :type="upLoadType"></mescroll-up> -->
					<view v-if="mescroll.optUp.use && !isDownLoading && upLoadType!==3" class="mescroll-upwarp" :style="{'background':mescroll.optUp.bgColor,'color':mescroll.optUp.textColor}">
						<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
						<view v-show="upLoadType===1">
							<view class="upwarp-progress mescroll-rotate" :style="{'border-color':mescroll.optUp.textColor}"></view>
							<view class="upwarp-tip">{{ mescroll.optUp.textLoading }}</view>
						</view>
						<!-- 无数据 -->
						<view v-if="upLoadType===2" class="upwarp-nodata">{{ mescroll.optUp.textNoMore }}</view>
					</view>
				</view>
				
				<!-- 底部是否偏移TabBar的高度(仅H5端生效) -->
				<!-- #ifdef H5 -->
				<view v-if="bottombar && windowBottom>0" class="mescroll-bottombar" :style="{height: windowBottom+'px'}"></view>
				<!-- #endif -->
				
				<!-- 适配iPhoneX -->
				<view v-if="safearea" class="mescroll-safearea"></view>
			</view>
		</scroll-view>

		<!-- 回到顶部按钮 (fixed元素,需写在scroll-view外面,防止滚动的时候抖动)-->
		<mescroll-top v-model="isShowToTop" :option="mescroll.optUp.toTop" @click="toTopClick"></mescroll-top>

		<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
		<!-- renderjs的数据载体,不可写在mescroll-downwarp内部,避免use为false时,载体丢失,无法更新数据 -->
		<view :change:prop="renderBiz.propObserver" :prop="wxsProp"></view>
		<!-- #endif -->
	</view>
</template>

<!-- 微信小程序, QQ小程序, app, h5使用wxs -->
<!-- #ifdef MP-WEIXIN || MP-QQ || APP-PLUS || H5 -->
<script src="../../mescroll-uni/wxs/wxs.wxs" module="wxsBiz" lang="wxs"></script>
<!-- #endif -->

<!-- app, h5使用renderjs -->
<!-- #ifdef APP-PLUS || H5 -->
<script module="renderBiz" lang="renderjs">
	import renderBiz from '../../mescroll-uni/wxs/renderjs.js';
	export default {
		mixins: [renderBiz]
	}
</script>
<!-- #endif -->

<script>
	import MeScroll from '../../mescroll-uni/mescroll-uni.js';
	import MescrollTop from '../../mescroll-uni/components/mescroll-top.vue';
	import WxsMixin from '../../mescroll-uni/wxs/mixins.js';
	import mescrollI18n from '../../mescroll-uni/mescroll-i18n.js';
	import GlobalOption from './mescroll-uni-option.js';
	
	export default {
		mixins: [WxsMixin],
		components: {
			MescrollTop
		},
		data() {
			return {
				mescroll: {optDown:{},optUp:{}}, // mescroll实例
				viewId: 'id_' + Math.random().toString(36).substr(2,16), // 随机生成mescroll的id(不能数字开头,否则找不到元素)
				downHight: 0, //下拉刷新: 容器高度
				downLoadType: 0, // 下拉刷新状态: 0(loading前), 1(inOffset), 2(outOffset), 3(showLoading), 4(endDownScroll)
				upLoadType: 0, // 上拉加载状态: 0(loading前), 1loading中, 2没有更多了,显示END文本提示, 3(没有更多了,不显示END文本提示)
				isShowEmpty: false, // 是否显示空布局
				isShowToTop: false, // 是否显示回到顶部按钮
				scrollTop: 0, // 滚动条的位置
				scrollAnim: false, // 是否开启滚动动画
				windowTop: 0, // 可使用窗口的顶部位置
				windowBottom: 0, // 可使用窗口的底部位置
				windowHeight: 0, // 可使用窗口的高度
				statusBarHeight: 0 // 状态栏高度
			}
		},
		props: {
			down: Object, // 下拉刷新的参数配置
			up: Object, // 上拉加载的参数配置
			i18n: Object, // 国际化的参数配置
			top: [String, Number], // 下拉布局往下的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
			topbar: [Boolean, String], // top的偏移量是否加上状态栏高度, 默认false (使用场景:取消原生导航栏时,配置此项可留出状态栏的占位, 支持传入字符串背景,如色值,背景图,渐变)
			bottom: [String, Number], // 上拉布局往上的偏移量 (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
			safearea: Boolean, // bottom的偏移量是否加上底部安全区的距离, 默认false (需要适配iPhoneX时使用)
			fixed: { // 是否通过fixed固定mescroll的高度, 默认true
				type: Boolean,
				default: true
			},
			height: [String, Number], // 指定mescroll的高度, 此项有值,则不使用fixed. (支持20, "20rpx", "20px", "20%"格式的值, 其中纯数字则默认单位rpx, 百分比则相对于windowHeight)
			bottombar:{ // 底部是否偏移TabBar的高度(默认仅在H5端的tab页生效)
				type: Boolean,
				default: true
			},
			disableScroll: Boolean // 是否禁止滚动
		},
		computed: {
			// 是否使用fixed定位 (当height有值,则不使用)
			isFixed(){
				return !this.height && this.fixed
			},
			// mescroll的高度
			scrollHeight(){
				if (this.isFixed) {
					return "auto"
				} else if(this.height){
					return this.toPx(this.height) + 'px'
				}else{
					return "100%"
				}
			},
			// 下拉布局往下偏移的距离 (px)
			numTop() {
				return this.toPx(this.top)
			},
			fixedTop() {
				return this.isFixed ? (this.numTop + this.windowTop) + 'px' : 0
			},
			padTop() {
				return !this.isFixed ? this.numTop + 'px' : 0
			},
			// 上拉布局往上偏移 (px)
			numBottom() {
				return this.toPx(this.bottom)
			},
			fixedBottom() {
				return this.isFixed ? (this.numBottom + this.windowBottom) + 'px' : 0
			},
			padBottom() {
				return !this.isFixed ? this.numBottom + 'px' : 0
			},
			// 是否为重置下拉的状态
			isDownReset(){
				return this.downLoadType===3 || this.downLoadType===4
			},
			// 过渡
			transition() {
				return this.isDownReset ? 'transform 300ms' : ''
			},
			translateY() {
				return this.downHight > 0 ? 'translateY(' + this.downHight + 'px)' : '' // transform会使fixed失效,需注意把fixed元素写在mescroll之外
			},
			// 列表是否可滑动
			scrollable(){
				if(this.disableScroll) return false
				return this.downLoadType===0 || this.isDownReset
			},
			// 是否在加载中
			isDownLoading(){
				return this.downLoadType === 3
			},
			// 旋转的角度
			downRotate(){
				return this.downLoadType === 2 ? 'rotate(180deg)' : 'rotate(0deg)'
			}
		},
		methods: {
			//number,rpx,upx,px,% --> px的数值
			toPx(num){
				if(typeof num === "string"){
					if (num.indexOf('px') !== -1) {
						if(num.indexOf('rpx') !== -1) { // "10rpx"
							num = num.replace('rpx', '');
						} else if(num.indexOf('upx') !== -1) { // "10upx"
							num = num.replace('upx', '');
						} else { // "10px"
							return Number(num.replace('px', ''))
						}
					}else if (num.indexOf('%') !== -1){
						// 传百分比,则相对于windowHeight,传"10%"则等于windowHeight的10%
						let rate = Number(num.replace("%","")) / 100
						return this.windowHeight * rate
					}
				}
				return num ? uni.upx2px(Number(num)) : 0
			},
			//注册列表滚动事件,用于下拉刷新和上拉加载
			scroll(e) {
				this.mescroll.scroll(e.detail, () => {
					this.$emit('scroll', this.mescroll) // 此时可直接通过 this.mescroll.scrollTop获取滚动条位置; this.mescroll.isScrollUp获取是否向上滑动
				})
			},
			// 点击空布局的按钮回调
			emptyClick() {
				this.$emit('emptyclick', this.mescroll)
			},
			// 点击回到顶部的按钮回调
			toTopClick() {
				this.mescroll.scrollTo(0, this.mescroll.optUp.toTop.duration); // 执行回到顶部
				this.$emit('topclick', this.mescroll); // 派发点击回到顶部按钮的回调
			},
			// 更新滚动区域的高度 (使内容不满屏和到底,都可继续翻页)
			setClientHeight() {
				if (this.mescroll.getClientHeight(true) === 0 && !this.isExec) {
					this.isExec = true; // 避免多次获取
					this.$nextTick(() => { // 确保dom已渲染
						this.getClientInfo(data=>{
							this.isExec = false;
							if (data) {
								this.mescroll.setClientHeight(data.height);
							} else if (this.clientNum != 3) { // 极少部分情况,可能dom还未渲染完毕,递归获取,最多重试3次
								this.clientNum = this.clientNum == null ? 1 : this.clientNum + 1;
								setTimeout(() => {
									this.setClientHeight()
								}, this.clientNum * 100)
							}
						})
					})
				}
			},
			// 获取滚动区域的信息
			getClientInfo(success){
				let query = uni.createSelectorQuery().in(this);
				let view = query.select('#' + this.viewId);
				view.boundingClientRect(data => {
					success(data)
				}).exec();
			}
		},
		// 使用created初始化mescroll对象; 如果用mounted部分css样式编译到H5会失效
		created() {
			let vm = this;

			let diyOption = {
				// 下拉刷新的配置
				down: {
					inOffset() {
						vm.downLoadType = 1; // 下拉的距离进入offset范围内那一刻的回调 (自定义mescroll组件时,此行不可删)
					},
					outOffset() {
						vm.downLoadType = 2; // 下拉的距离大于offset那一刻的回调 (自定义mescroll组件时,此行不可删)
					},
					onMoving(mescroll, rate, downHight) {
						// 下拉过程中的回调,滑动过程一直在执行;
						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
					},
					showLoading(mescroll, downHight) {
						vm.downLoadType = 3; // 显示下拉刷新进度的回调 (自定义mescroll组件时,此行不可删)
						vm.downHight = downHight; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
					},
					endDownScroll() {
						vm.downLoadType = 4; // 结束下拉 (自定义mescroll组件时,此行不可删)
						vm.downHight = 0; // 设置下拉区域的高度 (自定义mescroll组件时,此行不可删)
						vm.downResetTimer && clearTimeout(vm.downResetTimer)
						vm.downResetTimer = setTimeout(()=>{ // 过渡动画执行完毕后,需重置为0的状态,以便置空this.transition,避免iOS小程序列表渲染不完整
							if(vm.downLoadType===4) vm.downLoadType = 0
						},300)
					},
					// 派发下拉刷新的回调
					callback: function(mescroll) {
						vm.$emit('down', mescroll)
					}
				},
				// 上拉加载的配置
				up: {
					// 显示加载中的回调
					showLoading() {
						vm.upLoadType = 1;
					},
					// 显示无更多数据的回调
					showNoMore() {
						vm.upLoadType = 2;
					},
					// 隐藏上拉加载的回调
					hideUpScroll(mescroll) {
						vm.upLoadType = mescroll.optUp.hasNext ? 0 : 3;
					},
					// 空布局
					empty: {
						onShow(isShow) { // 显示隐藏的回调
							vm.isShowEmpty = isShow;
						}
					},
					// 回到顶部
					toTop: {
						onShow(isShow) { // 显示隐藏的回调
							vm.isShowToTop = isShow;
						}
					},
					// 派发上拉加载的回调
					callback: function(mescroll) {
						vm.$emit('up', mescroll);
						// 更新容器的高度 (多mescroll的情况)
						vm.setClientHeight()
					}
				}
			}

			let i18nType = mescrollI18n.getType() // 当前语言类型
			let i18nOption = {type: i18nType} // 国际化配置
			MeScroll.extend(i18nOption, vm.i18n) // 具体页面的国际化配置
			MeScroll.extend(i18nOption, GlobalOption.i18n) // 全局的国际化配置
			MeScroll.extend(diyOption, i18nOption[i18nType]); // 混入国际化配置
			MeScroll.extend(diyOption, {down:GlobalOption.down, up:GlobalOption.up}); // 混入全局的配置
			let myOption = JSON.parse(JSON.stringify({'down': vm.down,'up': vm.up})) // 深拷贝,避免对props的影响
			MeScroll.extend(myOption, diyOption); // 混入具体界面的配置

			// 初始化MeScroll对象
			vm.mescroll = new MeScroll(myOption);
			vm.mescroll.viewId = vm.viewId; // 附带id
			// 挂载语言包
			vm.mescroll.i18n = i18nOption;
			// init回调mescroll对象
			vm.$emit('init', vm.mescroll);
			
			// 设置高度
			const sys = uni.getSystemInfoSync();
			if(sys.windowTop) vm.windowTop = sys.windowTop;
			if(sys.windowBottom) vm.windowBottom = sys.windowBottom;
			if(sys.windowHeight) vm.windowHeight = sys.windowHeight;
			if(sys.statusBarHeight) vm.statusBarHeight = sys.statusBarHeight;
			// 使down的bottomOffset生效
			vm.mescroll.setBodyHeight(sys.windowHeight);

			// 因为使用的是scrollview,这里需自定义scrollTo
			vm.mescroll.resetScrollTo((y, t) => {
				vm.scrollAnim = (t !== 0); // t为0,则不使用动画过渡
				if(typeof y === 'string'){
					// 小程序不支持slot里面的scroll-into-view, 统一使用计算的方式实现
					vm.getClientInfo(function(rect){
						let mescrollTop = rect.top // mescroll到顶部的距离
						let selector;
						if(y.indexOf('#')==-1 && y.indexOf('.')==-1){
							selector = '#'+y // 不带#和. 则默认为id选择器
						}else{
							selector = y
							// #ifdef APP-PLUS || H5 || MP-ALIPAY || MP-DINGTALK
							if(y.indexOf('>>>')!=-1){ // 不支持跨自定义组件的后代选择器 (转为普通的选择器即可跨组件查询)
								selector = y.split('>>>')[1].trim()
							}
							// #endif
						}
						uni.createSelectorQuery().select(selector).boundingClientRect(function(rect){
							if (rect) {
								let curY = vm.mescroll.getScrollTop()
								let top = rect.top - mescrollTop
								top += curY
								if(!vm.isFixed) top -= vm.numTop
								vm.scrollTop = curY;
								vm.$nextTick(function() {
									vm.scrollTop = top
								})
							} else{
								console.error(selector + ' does not exist');
							}
						}).exec()
					})
					return;
				}
				let curY = vm.mescroll.getScrollTop()
				if (t === 0 || t === 300) { // 当t使用默认配置的300时,则使用系统自带的动画过渡
					vm.scrollTop = curY;
					vm.$nextTick(function() {
						vm.scrollTop = y
					})
				} else {
					vm.mescroll.getStep(curY, y, step => { // 此写法可支持配置t
						vm.scrollTop = step
					}, t)
				}
			})
			
			// 具体的界面如果不配置up.toTop.safearea,则取本vue的safearea值
			if (vm.up && vm.up.toTop && vm.up.toTop.safearea != null) {} else {
				vm.mescroll.optUp.toTop.safearea = vm.safearea;
			}
			// 全局配置监听
			uni.$on("setMescrollGlobalOption", options=>{
				if(!options) return;
				let i18nType = options.i18n ? options.i18n.type : null
				if(i18nType && vm.mescroll.i18n.type != i18nType){
					vm.mescroll.i18n.type = i18nType
					mescrollI18n.setType(i18nType)
					MeScroll.extend(options, vm.mescroll.i18n[i18nType])
				}
				if(options.down){
					let down = MeScroll.extend({}, options.down)
					vm.mescroll.optDown = MeScroll.extend(down, vm.mescroll.optDown)
				}
				if(options.up){
					let up = MeScroll.extend({}, options.up)
					vm.mescroll.optUp = MeScroll.extend(up, vm.mescroll.optUp)
				}
			})
		},
		mounted() {
			// 设置容器的高度
			this.setClientHeight()
		},
		destroyed() {
			// 注销全局配置监听
			uni.$off("setMescrollGlobalOption")
		}
	}
</script>

<style>
	@import "../../mescroll-uni/mescroll-uni.css";
	@import "../../mescroll-uni/components/mescroll-down.css";
	@import "../../mescroll-uni/components/mescroll-up.css";
	@import "./components/mescroll-down.css";
</style>


================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-down.css
================================================
/*下拉刷新--上下箭头*/
.mescroll-downwarp .downwarp-arrow {
	display: inline-block;
	width: 20px;
	height: 20px;
	margin: 10px;
	background-image: url(https://www.mescroll.com/img/xinlang/mescroll-arrow.png);
	background-size: contain;
	vertical-align: middle;
	transition: all 300ms;
}

/*下拉刷新--旋转进度条*/
.mescroll-downwarp .downwarp-progress{
	width: 36px;
	height: 36px;
	border: none;
	margin: auto;
	background-size: contain;
	animation: progressRotate 0.6s steps(6, start) infinite;
}
@keyframes progressRotate {
	0% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress1.png);
	}
	16% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress2.png);
	}
	32% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress3.png);
	}
	48% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress4.png);
	}
	64% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress5.png);
	}
	80% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress6.png);
	}
	100% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress1.png);
	}
}

================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-down.vue
================================================
<!-- 下拉刷新区域 -->
<template>
	<view v-if="mOption.use" class="mescroll-downwarp" :style="{'background':mOption.bgColor,'color':mOption.textColor}">
		<view class="downwarp-content">
			<view v-if="isDownLoading" class="downwarp-progress"></view>
			<view v-else class="downwarp-arrow" :style="{ transform: downRotate }"></view>
			<view class="downwarp-tip">{{ downText }}</view>
		</view>
	</view>
</template>

<script>
export default {
	props: {
		option: Object, // down的配置项
		type: Number // 下拉状态(inOffset:1, outOffset:2, showLoading:3, endDownScroll:4)
	},
	computed: {
		// 支付宝小程序需写成计算属性,prop定义default仍报错
		mOption() {
			return this.option || {};
		},
		// 是否在加载中
		isDownLoading() {
			return this.type === 3;
		},
		// 旋转的角度
		downRotate() {
			return this.type === 2 ? 'rotate(-180deg)' : 'rotate(0deg)';
		},
		// 文本提示
		downText() {
			switch (this.type) {
				case 1:
					return this.mOption.textInOffset;
				case 2:
					return this.mOption.textOutOffset;
				case 3:
					return this.mOption.textLoading;
				case 4:
					return this.mOption.textLoading;
				default:
					return this.mOption.textInOffset;
			}
		}
	}
};
</script>

<style>
@import '../../../mescroll-uni/components/mescroll-down.css';
@import './mescroll-down.css';
</style>


================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-up.css
================================================
/*上拉加载--旋转进度条*/
.mescroll-upwarp .upwarp-progress {
	width: 36px;
	height: 36px;
	border: none;
	margin: auto;
	background-size: contain;
	animation: progressRotate 0.6s steps(6, start) infinite;
}
@keyframes progressRotate {
	0% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress1.png);
	}
	16% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress2.png);
	}
	32% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress3.png);
	}
	48% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress4.png);
	}
	64% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress5.png);
	}
	80% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress6.png);
	}
	100% {
		background-image: url(https://www.mescroll.com/img/xinlang/mescroll-progress1.png);
	}
}

================================================
FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-up.vue
================================================
<!-- 上拉加载区域 -->
<template>
	<view class="mescroll-upwarp" :style="{'background':mOption.bgColor,'color':mOption.textColor}">
		<!-- 加载中 (此处不能用v-if,否则android小程序快速上拉可能会不断触发上拉回调) -->
		<view v-show="isUpLoading">
			<view class="upwarp-progress mescroll-rotate"></view>
			<view class="upwarp-tip">{{ mOption.textLoading }}</view>
		</view>
		<!-- 无数据 -->
		<view v-if="isUpNoMore" class="upwarp-nodata">{{ mOption.textNoMore }}</view>
	</view>
</template>

<script>
export default {
	props: {
		option: Object, // up的配置项
		type: Number // 上拉加载的状态:0(loading前),1(loading中),2(没有更多了,显示END文本提示),3(没有更多了,不显示END文本提示)
	},
	computed: {
		// 支付宝小程序需写成计算属性,prop定义default仍报错
		mOption() {
			return this.option || {};
		},
		// 加载中
		isUpLoading() {
			return this.type === 1;
		},
		// 没有更多了
		isUpNoMore() {
			return this.type === 2;
		}
	}
};
</script>

<style>
@impo
Download .txt
gitextract_6t70kfgo/

├── LICENSE
├── README.md
├── mescroll-uni/
│   ├── App.vue
│   ├── api/
│   │   ├── goods.js
│   │   └── mock.js
│   ├── components/
│   │   ├── good-list/
│   │   │   └── good-list.vue
│   │   ├── me-tabs/
│   │   │   └── me-tabs.vue
│   │   └── me-video/
│   │       └── me-video.vue
│   ├── main.js
│   ├── manifest.json
│   ├── package.json
│   ├── pages/
│   │   ├── base/
│   │   │   ├── list-msg.vue
│   │   │   ├── list-news.vue
│   │   │   ├── list-products.vue
│   │   │   ├── list-search.vue
│   │   │   ├── mescroll-body-part.vue
│   │   │   ├── mescroll-comp-center.vue
│   │   │   ├── mescroll-comp-item.vue
│   │   │   ├── mescroll-comp.vue
│   │   │   ├── mescroll-empty.vue
│   │   │   ├── mescroll-i18n.vue
│   │   │   ├── mescroll-more-item.vue
│   │   │   ├── mescroll-more.vue
│   │   │   ├── mescroll-native.vue
│   │   │   ├── mescroll-one.vue
│   │   │   ├── mescroll-options.vue
│   │   │   ├── mescroll-uni-part.vue
│   │   │   ├── mescroll-uni.vue
│   │   │   ├── sticky-data.vue
│   │   │   ├── sticky-scroll-data.vue
│   │   │   ├── sticky-scroll.vue
│   │   │   ├── sticky-uni.vue
│   │   │   └── sticky.vue
│   │   ├── index/
│   │   │   └── index.vue
│   │   └── intermediate/
│   │       ├── beibei.vue
│   │       ├── list-msg.vue
│   │       ├── mescroll-body-part.vue
│   │       ├── mescroll-swiper-item.vue
│   │       ├── mescroll-swiper-sticky-item.vue
│   │       ├── mescroll-swiper-sticky.vue
│   │       ├── mescroll-swiper.vue
│   │       ├── mescroll-uni-part.vue
│   │       ├── sticky-data.vue
│   │       ├── sticky-scroll-data.vue
│   │       ├── sticky-scroll.vue
│   │       ├── sticky-uni.vue
│   │       ├── sticky.vue
│   │       └── xinlang.vue
│   ├── pages.json
│   └── uni_modules/
│       └── mescroll-uni/
│           ├── changelog.md
│           ├── components/
│           │   ├── mescroll-body/
│           │   │   ├── mescroll-body.css
│           │   │   └── mescroll-body.vue
│           │   ├── mescroll-diy/
│           │   │   ├── beibei/
│           │   │   │   ├── components/
│           │   │   │   │   ├── mescroll-down.css
│           │   │   │   │   └── mescroll-down.vue
│           │   │   │   ├── mescroll-body.vue
│           │   │   │   ├── mescroll-uni-option.js
│           │   │   │   └── mescroll-uni.vue
│           │   │   └── xinlang/
│           │   │       ├── components/
│           │   │       │   ├── mescroll-down.css
│           │   │       │   ├── mescroll-down.vue
│           │   │       │   ├── mescroll-up.css
│           │   │       │   └── mescroll-up.vue
│           │   │       ├── mescroll-body.vue
│           │   │       ├── mescroll-uni-option.js
│           │   │       └── mescroll-uni.vue
│           │   ├── mescroll-empty/
│           │   │   └── mescroll-empty.vue
│           │   └── mescroll-uni/
│           │       ├── components/
│           │       │   ├── mescroll-down.css
│           │       │   ├── mescroll-down.vue
│           │       │   ├── mescroll-top.vue
│           │       │   ├── mescroll-up.css
│           │       │   └── mescroll-up.vue
│           │       ├── mescroll-i18n.js
│           │       ├── mescroll-mixins.js
│           │       ├── mescroll-uni-option.js
│           │       ├── mescroll-uni.css
│           │       ├── mescroll-uni.js
│           │       ├── mescroll-uni.vue
│           │       ├── mixins/
│           │       │   ├── mescroll-comp.js
│           │       │   ├── mescroll-more-item.js
│           │       │   └── mescroll-more.js
│           │       └── wxs/
│           │           ├── mixins.js
│           │           ├── renderjs.js
│           │           └── wxs.wxs
│           ├── hooks/
│           │   ├── useMescroll.js
│           │   ├── useMescrollComp.js
│           │   └── useMescrollMore.js
│           ├── package.json
│           └── readme.md
├── mescroll-uni-vue3/
│   ├── App.vue
│   ├── api/
│   │   ├── goods.js
│   │   └── mock.js
│   ├── components/
│   │   ├── good-list/
│   │   │   └── good-list.vue
│   │   ├── me-tabs/
│   │   │   └── me-tabs.vue
│   │   └── me-video/
│   │       └── me-video.vue
│   ├── index.html
│   ├── main.js
│   ├── manifest.json
│   ├── package.json
│   ├── pages/
│   │   ├── base/
│   │   │   ├── list-news.vue
│   │   │   ├── list-products.vue
│   │   │   ├── list-search.vue
│   │   │   ├── mescroll-comp-center.vue
│   │   │   ├── mescroll-comp-item.vue
│   │   │   ├── mescroll-comp.vue
│   │   │   ├── mescroll-empty.vue
│   │   │   ├── mescroll-i18n.vue
│   │   │   ├── mescroll-more-item.vue
│   │   │   ├── mescroll-more.vue
│   │   │   ├── mescroll-native.vue
│   │   │   ├── mescroll-one.vue
│   │   │   ├── mescroll-options.vue
│   │   │   └── mescroll-uni.vue
│   │   ├── index/
│   │   │   └── index.vue
│   │   └── intermediate/
│   │       ├── beibei.vue
│   │       ├── list-msg.vue
│   │       ├── mescroll-body-part.vue
│   │       ├── mescroll-swiper-item.vue
│   │       ├── mescroll-swiper-sticky-item.vue
│   │       ├── mescroll-swiper-sticky.vue
│   │       ├── mescroll-swiper.vue
│   │       ├── mescroll-uni-part.vue
│   │       ├── sticky-data.vue
│   │       ├── sticky-scroll-data.vue
│   │       ├── sticky-scroll.vue
│   │       ├── sticky-uni.vue
│   │       ├── sticky.vue
│   │       └── xinlang.vue
│   ├── pages.json
│   └── uni_modules/
│       └── mescroll-uni/
│           ├── changelog.md
│           ├── components/
│           │   ├── mescroll-body/
│           │   │   ├── mescroll-body.css
│           │   │   └── mescroll-body.vue
│           │   ├── mescroll-diy/
│           │   │   ├── beibei/
│           │   │   │   ├── components/
│           │   │   │   │   ├── mescroll-down.css
│           │   │   │   │   └── mescroll-down.vue
│           │   │   │   ├── mescroll-body.vue
│           │   │   │   ├── mescroll-uni-option.js
│           │   │   │   └── mescroll-uni.vue
│           │   │   └── xinlang/
│           │   │       ├── components/
│           │   │       │   ├── mescroll-down.css
│           │   │       │   ├── mescroll-down.vue
│           │   │       │   ├── mescroll-up.css
│           │   │       │   └── mescroll-up.vue
│           │   │       ├── mescroll-body.vue
│           │   │       ├── mescroll-uni-option.js
│           │   │       └── mescroll-uni.vue
│           │   ├── mescroll-empty/
│           │   │   └── mescroll-empty.vue
│           │   └── mescroll-uni/
│           │       ├── components/
│           │       │   ├── mescroll-down.css
│           │       │   ├── mescroll-down.vue
│           │       │   ├── mescroll-top.vue
│           │       │   ├── mescroll-up.css
│           │       │   └── mescroll-up.vue
│           │       ├── mescroll-i18n.js
│           │       ├── mescroll-mixins.js
│           │       ├── mescroll-uni-option.js
│           │       ├── mescroll-uni.css
│           │       ├── mescroll-uni.js
│           │       ├── mescroll-uni.vue
│           │       ├── mixins/
│           │       │   ├── mescroll-comp.js
│           │       │   ├── mescroll-more-item.js
│           │       │   └── mescroll-more.js
│           │       └── wxs/
│           │           ├── mixins.js
│           │           ├── renderjs.js
│           │           └── wxs.wxs
│           ├── hooks/
│           │   ├── useMescroll.js
│           │   ├── useMescrollComp.js
│           │   └── useMescrollMore.js
│           ├── package.json
│           └── readme.md
└── mescroll.js/
    ├── dist/
    │   ├── mescroll.css
    │   ├── mescroll.js
    │   └── mescroll.vue
    ├── html-demo/
    │   ├── base/
    │   │   ├── list-full-lock.html
    │   │   ├── list-mescroll-body.html
    │   │   ├── list-mescroll-lazy.html
    │   │   ├── list-mescroll-more.html
    │   │   ├── list-mescroll-one.html
    │   │   ├── list-msg.html
    │   │   ├── list-news.html
    │   │   ├── list-products-vue.html
    │   │   ├── list-products.html
    │   │   ├── mescroll-options.html
    │   │   └── vue-mescroll.html
    │   ├── beibei/
    │   │   ├── beibei.html
    │   │   └── option/
    │   │       ├── mescroll-option.css
    │   │       └── mescroll-option.js
    │   ├── dotJump/
    │   │   ├── dotJump.html
    │   │   └── option/
    │   │       ├── mescroll-option.css
    │   │       └── mescroll-option.js
    │   ├── index.html
    │   ├── res/
    │   │   ├── pdlist1.js
    │   │   ├── pdlist1.json
    │   │   ├── pdlist2.js
    │   │   └── pdlist2.json
    │   ├── search/
    │   │   └── mescroll-search.html
    │   ├── sticky/
    │   │   └── mescroll-sticky.html
    │   ├── swiper/
    │   │   ├── mescroll-swiper-nav.html
    │   │   ├── mescroll-swiper-sticky.html
    │   │   └── mescroll-swiper-tap.html
    │   ├── xinlang/
    │   │   ├── option/
    │   │   │   ├── mescroll-option.css
    │   │   │   └── mescroll-option.js
    │   │   └── xinlang.html
    │   ├── yabuli/
    │   │   ├── option/
    │   │   │   ├── mescroll-option.css
    │   │   │   └── mescroll-option.js
    │   │   └── yabuli.html
    │   └── zhihu/
    │       ├── option/
    │       │   ├── mescroll-option.css
    │       │   └── mescroll-option.js
    │       └── zhihu.html
    └── vue-demo/
        ├── .eslintrc.js
        ├── package.json
        ├── public/
        │   └── index.html
        ├── src/
        │   ├── App.vue
        │   ├── assets/
        │   │   ├── MescrollMixins.js
        │   │   └── css/
        │   │       ├── normalize.css
        │   │       └── reset.css
        │   ├── main.js
        │   ├── mock/
        │   │   ├── pdlist.js
        │   │   └── pdlistEdit.js
        │   ├── pages/
        │   │   ├── base/
        │   │   │   ├── list-news.vue
        │   │   │   ├── list-products.vue
        │   │   │   ├── mescroll-component.vue
        │   │   │   ├── mescroll-more.vue
        │   │   │   ├── mescroll-options.vue
        │   │   │   └── mescroll-swiper-nav.vue
        │   │   └── home.vue
        │   └── router/
        │       └── index.js
        └── vue-demo的运行方法.txt
Download .txt
SYMBOL INDEX (99 symbols across 31 files)

FILE: mescroll-uni-vue3/api/mock.js
  function apiNewList (line 13) | function apiNewList(pageNum, pageSize) {
  function apiGoods (line 55) | function apiGoods(pageNum, pageSize, keyword) {
  function apiWeiboList (line 109) | function apiWeiboList(pageNum, pageSize) {
  function apiMsgList (line 144) | function apiMsgList(pageNum, pageSize) {
  function apiGetTabs (line 178) | function apiGetTabs() {

FILE: mescroll-uni-vue3/main.js
  function isPromise (line 9) | function isPromise(obj) {
  method returnValue (line 19) | returnValue(res) {
  function createApp (line 44) | function createApp() {

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-i18n.js
  method getType (line 6) | getType(){
  method setType (line 10) | setType(type){

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js
  method data (line 3) | data() {
  method onPullDownRefresh (line 9) | onPullDownRefresh(){
  method onPageScroll (line 13) | onPageScroll(e) {
  method onReachBottom (line 17) | onReachBottom() {
  method mescrollInit (line 22) | mescrollInit(mescroll) {
  method downCallback (line 26) | downCallback() {
  method upCallback (line 36) | upCallback() {

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.js
  function MeScroll (line 7) | function MeScroll(options, isScrollBody) {

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js
  method onPageScroll (line 6) | onPageScroll(e) {
  method onReachBottom (line 9) | onReachBottom() {
  method onPullDownRefresh (line 13) | onPullDownRefresh(){
  method data (line 16) | data() {
  method handlePageScroll (line 32) | handlePageScroll(e){
  method handleReachBottom (line 36) | handleReachBottom(){
  method handlePullDownRefresh (line 40) | handlePullDownRefresh(){

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js
  method default (line 11) | default(){
  method data (line 17) | data() {
  method index (line 30) | index(val){
  method mescrollInit (line 36) | mescrollInit(mescroll) {
  method mescrollTrigger (line 44) | mescrollTrigger(){

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js
  method data (line 5) | data() {
  method onPageScroll (line 22) | onPageScroll(e) {
  method onReachBottom (line 25) | onReachBottom() {
  method onPullDownRefresh (line 29) | onPullDownRefresh(){
  method handlePageScroll (line 33) | handlePageScroll(e){
  method handleReachBottom (line 37) | handleReachBottom(){
  method handlePullDownRefresh (line 41) | handlePullDownRefresh(){
  method getMescroll (line 46) | getMescroll(i){
  method tabChange (line 62) | tabChange(i){

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/wxs/mixins.js
  method data (line 3) | data() {
  method wxsCall (line 53) | wxsCall(msg){
  method mounted (line 85) | mounted() {

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/wxs/renderjs.js
  function propObserver (line 75) | function propObserver(wxsProp) {
  method data (line 85) | data() {

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/hooks/useMescroll.js
  function useMescroll (line 10) | function useMescroll(onPageScroll, onReachBottom, onPullDownRefresh){

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/hooks/useMescrollComp.js
  function useMescrollComp (line 11) | function useMescrollComp(onPageScroll, onReachBottom, onPullDownRefresh){

FILE: mescroll-uni-vue3/uni_modules/mescroll-uni/hooks/useMescrollMore.js
  function useMescrollMore (line 7) | function useMescrollMore(mescrollItems, onPageScroll, onReachBottom, onP...

FILE: mescroll-uni/api/mock.js
  function apiNewList (line 11) | function apiNewList(pageNum, pageSize) {
  function apiGoods (line 50) | function apiGoods(pageNum, pageSize, keyword) {
  function apiWeiboList (line 101) | function apiWeiboList(pageNum, pageSize) {
  function apiMsgList (line 133) | function apiMsgList(pageNum, pageSize) {
  function apiGetTabs (line 164) | function apiGetTabs() {

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-i18n.js
  method getType (line 6) | getType(){
  method setType (line 10) | setType(type){

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js
  method data (line 3) | data() {
  method onPullDownRefresh (line 9) | onPullDownRefresh(){
  method onPageScroll (line 13) | onPageScroll(e) {
  method onReachBottom (line 17) | onReachBottom() {
  method mescrollInit (line 22) | mescrollInit(mescroll) {
  method downCallback (line 26) | downCallback() {
  method upCallback (line 36) | upCallback() {

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.js
  function MeScroll (line 7) | function MeScroll(options, isScrollBody) {

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js
  method onPageScroll (line 6) | onPageScroll(e) {
  method onReachBottom (line 9) | onReachBottom() {
  method onPullDownRefresh (line 13) | onPullDownRefresh(){
  method data (line 16) | data() {
  method handlePageScroll (line 32) | handlePageScroll(e){
  method handleReachBottom (line 36) | handleReachBottom(){
  method handlePullDownRefresh (line 40) | handlePullDownRefresh(){

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js
  method default (line 11) | default(){
  method data (line 17) | data() {
  method index (line 30) | index(val){
  method mescrollInit (line 36) | mescrollInit(mescroll) {
  method mescrollTrigger (line 44) | mescrollTrigger(){

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js
  method data (line 5) | data() {
  method onPageScroll (line 22) | onPageScroll(e) {
  method onReachBottom (line 25) | onReachBottom() {
  method onPullDownRefresh (line 29) | onPullDownRefresh(){
  method handlePageScroll (line 33) | handlePageScroll(e){
  method handleReachBottom (line 37) | handleReachBottom(){
  method handlePullDownRefresh (line 41) | handlePullDownRefresh(){
  method getMescroll (line 46) | getMescroll(i){
  method tabChange (line 62) | tabChange(i){

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/wxs/mixins.js
  method data (line 3) | data() {
  method wxsCall (line 53) | wxsCall(msg){
  method mounted (line 85) | mounted() {

FILE: mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/wxs/renderjs.js
  function propObserver (line 75) | function propObserver(wxsProp) {
  method data (line 85) | data() {

FILE: mescroll-uni/uni_modules/mescroll-uni/hooks/useMescroll.js
  function useMescroll (line 10) | function useMescroll(onPageScroll, onReachBottom, onPullDownRefresh){

FILE: mescroll-uni/uni_modules/mescroll-uni/hooks/useMescrollComp.js
  function useMescrollComp (line 11) | function useMescrollComp(onPageScroll, onReachBottom, onPullDownRefresh){

FILE: mescroll-uni/uni_modules/mescroll-uni/hooks/useMescrollMore.js
  function useMescrollMore (line 7) | function useMescrollMore(mescrollItems, onPageScroll, onReachBottom, onP...

FILE: mescroll.js/html-demo/beibei/option/mescroll-option.js
  function initMeScroll (line 56) | function initMeScroll(mescrollId, options) {

FILE: mescroll.js/html-demo/dotJump/option/mescroll-option.js
  function initMeScroll (line 54) | function initMeScroll(mescrollId, options) {

FILE: mescroll.js/html-demo/xinlang/option/mescroll-option.js
  function initMeScroll (line 56) | function initMeScroll(mescrollId, options) {

FILE: mescroll.js/html-demo/yabuli/option/mescroll-option.js
  function initMeScroll (line 56) | function initMeScroll(mescrollId, options) {

FILE: mescroll.js/html-demo/zhihu/option/mescroll-option.js
  function initMeScroll (line 56) | function initMeScroll(mescrollId, options) {

FILE: mescroll.js/vue-demo/src/assets/MescrollMixins.js
  method data (line 2) | data() {
  method beforeRouteEnter (line 5) | beforeRouteEnter(to, from, next) { // 如果没有配置回到顶部按钮或isBounce,则beforeRoute...
  method beforeRouteLeave (line 11) | beforeRouteLeave(to, from, next) { // 如果没有配置回到顶部按钮或isBounce,则beforeRoute...
Condensed preview — 223 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,055K chars).
[
  {
    "path": "LICENSE",
    "chars": 1067,
    "preview": "MIT License\n\nCopyright (c) 2017-2018 wenju\n\nPermission is hereby granted, free of charge, to any person obtaining a copy"
  },
  {
    "path": "README.md",
    "chars": 986,
    "preview": "# mescroll\r\n## mescroll -- 精致的下拉刷新和上拉加载js框架 (JS framework for pull-refresh and pull-up-loading)\r\n## http://www.mescroll."
  },
  {
    "path": "mescroll-uni/App.vue",
    "chars": 366,
    "preview": "<script>\n\texport default {\n\t\tonLaunch: function () {\n\t\t\tconsole.log('App Launch')\n\t\t},\n\t\tonShow: function () {\n\t\t\tconsol"
  },
  {
    "path": "mescroll-uni/api/goods.js",
    "chars": 4661,
    "preview": "const goods = [{\n\t\"id\": \"1\",\n\t\"goodImg\": \"https://www.mescroll.com/demo/res/img/pd1.jpg\",\n\t\"goodName\": \"【1】  六罐装荷兰美素佳儿金装"
  },
  {
    "path": "mescroll-uni/api/mock.js",
    "chars": 4253,
    "preview": "/*\n本地模拟接口请求, 仅demo演示用.\n实际项目以您服务器接口返回的数据为准,无需本地处理分页.\n请参考官方写法: https://www.mescroll.com/uni.html?v=20200210#tagUpCallback\n"
  },
  {
    "path": "mescroll-uni/components/good-list/good-list.vue",
    "chars": 1207,
    "preview": "<!-- 商品列表组件 <good-list :list=\"xx\"></good-list> -->\n<template>\n\t<view class=\"good-list\">\n\t\t<view :id=\"'good'+good.id\" cla"
  },
  {
    "path": "mescroll-uni/components/me-tabs/me-tabs.vue",
    "chars": 4622,
    "preview": "<!-- tab组件: <me-tabs v-model=\"tabIndex\" :tabs=\"tabs\" @change=\"tabChange\"></me-tabs> -->\n<template>\n\t<view class=\"me-tabs"
  },
  {
    "path": "mescroll-uni/components/me-video/me-video.vue",
    "chars": 4033,
    "preview": "<!-- 视频组件: <me-video src=\"视频地址\" poster=\"封面图\"></me-video> \nvideo标签在APP端是原生组件, 真机APP端下拉时会渲染不及时, 出现悬浮错位现象;\nme-video组件, 未播放时"
  },
  {
    "path": "mescroll-uni/main.js",
    "chars": 150,
    "preview": "import Vue from 'vue'\nimport App from './App'\n\nVue.config.productionTip = false\n\nApp.mpType = 'app'\n\nconst app = new Vue"
  },
  {
    "path": "mescroll-uni/manifest.json",
    "chars": 3064,
    "preview": "{\n    \"name\" : \"mescroll_uni\",\n    \"appid\" : \"\",\n    \"description\" : \"mescroll的uni版本 -支持uni-app的下拉刷新上拉加载组件,支持原生页面和局部区域滚动"
  },
  {
    "path": "mescroll-uni/package.json",
    "chars": 326,
    "preview": "{\n\t\"uni-app\": {\n\t\t\"scripts\": {\n\t\t\t\"mp-dingtalk\": {\n\t\t\t\t\"title\": \"钉钉小程序\",\n\t\t\t\t\"env\": {\n\t\t\t\t\t\"UNI_PLATFORM\": \"mp-alipay\"\n\t"
  },
  {
    "path": "mescroll-uni/pages/base/list-msg.vue",
    "chars": 2930,
    "preview": "<template>\n\t<!-- 需配置bottom的偏移量, 用于底部留白 -->\n\t<mescroll-body ref=\"mescrollRef\" bottom=\"50%\" @init=\"mescrollInit\" :down=\"do"
  },
  {
    "path": "mescroll-uni/pages/base/list-news.vue",
    "chars": 2276,
    "preview": "<template>\n\t<mescroll-body @init=\"mescrollInit\" :down=\"downOption\" @down=\"downCallback\" @up=\"upCallback\">\n\t\t<view class="
  },
  {
    "path": "mescroll-uni/pages/base/list-products.vue",
    "chars": 1984,
    "preview": "<template>\n\t <mescroll-body @init=\"mescrollInit\" @down=\"downCallback\" @up=\"upCallback\">\n\t\t<view class=\"notice\">mescroll的"
  },
  {
    "path": "mescroll-uni/pages/base/list-search.vue",
    "chars": 2638,
    "preview": "<template>\n\t <mescroll-body @init=\"mescrollInit\" @down=\"downCallback\" :up=\"upOption\" @up=\"upCallback\">\n\t\t<view class=\"it"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-body-part.vue",
    "chars": 2988,
    "preview": "<template>\n\t<!-- mescroll-body本质是原生page的滚动,无法像mescroll-uni那样用flex布局嵌在某个view中使用局部区域滚动, 但是可以通过fixed定位其他元素来实现\"局部区域滚动\"-->\n\t<"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-comp-center.vue",
    "chars": 523,
    "preview": "<template>\n\t<!-- 当mescroll-body写在子子..子组件时, 需每层子组件都引入mescroll-comp.js, 添加ref=\"mescrollItem\" -->\n\t<view>\n\t\t<mescroll-item "
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-comp-item.vue",
    "chars": 950,
    "preview": "<template>\n\t<!-- 当mescroll-body写在子组件时,父页面需引入mescroll-comp.js的mixins -->\n\t<mescroll-body top=\"100\" @init=\"mescrollInit\" @"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-comp.vue",
    "chars": 1596,
    "preview": "<template>\n\t<!-- \n\t mescroll-body写在一层子组件时, 需引入mescroll-comp.js, 给子组件添加ref=\"mescrollItem\",\n\t 当mescroll-body写在子子..子组件时, 需每"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-empty.vue",
    "chars": 1201,
    "preview": "<!-- mescroll-empty遵循easycom, 可直接单独使用 -->\n<template>\n\t<view>\n\t\t<!-- 列表内容 -->\n\t\t<view v-if=\"list.length\">\n\t\t\t<!-- ... -->"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-i18n.vue",
    "chars": 2549,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\" @click=\"i18nChange()\">点击切换语言</view>\n\t\t\t<"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-more-item.vue",
    "chars": 2258,
    "preview": "<template>\n\t<!-- 不能用v-if (i: 每个tab页的专属下标;  index: 当前tab的下标; 申明在 MescrollMoreItemMixin )-->\n\t<view v-show=\"i === index\">\n"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-more.vue",
    "chars": 2760,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\">每个菜单列表仅初始化一次,切换菜单缓存数据</view>\n\t\t\t<!-- 当设置"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-native.vue",
    "chars": 2306,
    "preview": "<template>\n\t<!-- 系统自带的下拉刷新,只能配合mescroll-body使用, 在mescroll-uni中无效 -->\n\t<mescroll-body @init=\"mescrollInit\" :down=\"downOpt"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-one.vue",
    "chars": 2201,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\">每次切换菜单及时刷新列表,不缓存数据</view>\n\t\t\t<me-tabs v-"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-options.vue",
    "chars": 8037,
    "preview": "<template>\n\t<mescroll-body @init=\"mescrollInit\" @down=\"downCallback\" @up=\"upCallback\" \n\t :down=\"downOption\" \n\t :up=\"upOp"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-uni-part.vue",
    "chars": 3344,
    "preview": "<template>\n\t<!-- mescroll-uni本质是scroll-view,支持局部区域滚动,可使用flex布局灵活的嵌在某个view中, 而mescroll-body只能靠fixed定位其他元素变相实现'局部滚动' -->\n\t"
  },
  {
    "path": "mescroll-uni/pages/base/mescroll-uni.vue",
    "chars": 3158,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\">基于scroll-view,常用在浮窗弹层等局部滚动区域</view>\n\t\t\t<"
  },
  {
    "path": "mescroll-uni/pages/base/sticky-data.vue",
    "chars": 3994,
    "preview": "<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->\n<template>\n\t<view>\n"
  },
  {
    "path": "mescroll-uni/pages/base/sticky-scroll-data.vue",
    "chars": 5469,
    "preview": "<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->\n<template>\n\t<view>\n\t\t<!-- 菜单 (悬浮,预先隐藏)-->\n\t\t<me-"
  },
  {
    "path": "mescroll-uni/pages/base/sticky-scroll.vue",
    "chars": 4381,
    "preview": "<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->\n<template>\n\t<view>\n\t\t<!-- 菜单 (悬浮,预先隐藏)-->\n\t\t<me-"
  },
  {
    "path": "mescroll-uni/pages/base/sticky-uni.vue",
    "chars": 2524,
    "preview": "<template>\n\t<view>\n\t\t<mescroll-uni ref=\"mescrollRef\" @init=\"mescrollInit\" @down=\"downCallback\" @up=\"upCallback\">\n\t\t\t<swi"
  },
  {
    "path": "mescroll-uni/pages/base/sticky.vue",
    "chars": 2964,
    "preview": "<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->\n<template>\n\t<view>\n"
  },
  {
    "path": "mescroll-uni/pages/index/index.vue",
    "chars": 4837,
    "preview": "<template>\n\t<view>\n\t\t\n\t\t<view class=\"group-title\">base demos 基础案例</view>\n\t\t\n\t\t<navigator url=\"/pages/base/list-products\""
  },
  {
    "path": "mescroll-uni/pages/intermediate/beibei.vue",
    "chars": 2024,
    "preview": "<template>\n\t<view>\n\t\t<!-- 模拟的标题 -->\n\t\t<image class=\"header\" src=\"https://www.mescroll.com/img/beibei/header.jpg\" mode=\"a"
  },
  {
    "path": "mescroll-uni/pages/intermediate/list-msg.vue",
    "chars": 2912,
    "preview": "<template>\n\t<!-- 需配置bottom的偏移量, 用于底部留白 -->\n\t<mescroll-body bottom=\"50%\" @init=\"mescrollInit\" :down=\"downOption\" @down=\"d"
  },
  {
    "path": "mescroll-uni/pages/intermediate/mescroll-body-part.vue",
    "chars": 2970,
    "preview": "<template>\n\t<!-- mescroll-body本质是原生page的滚动,无法像mescroll-uni那样用flex布局嵌在某个view中使用局部区域滚动, 但是可以通过fixed定位其他元素来实现\"局部区域滚动\"-->\n\t<"
  },
  {
    "path": "mescroll-uni/pages/intermediate/mescroll-swiper-item.vue",
    "chars": 2448,
    "preview": "<template>\n\t<!-- \n\tswiper中的transfrom会使fixed失效,此时用height固定高度; \n\tswiper中无法触发mescroll-mixins.js的onPageScroll和onReachBottom方"
  },
  {
    "path": "mescroll-uni/pages/intermediate/mescroll-swiper-sticky-item.vue",
    "chars": 2162,
    "preview": "<template>\n\t<!-- \n\tswiper中的transfrom会使fixed失效,此时用height固定高度; \n\tswiper中无法触发mescroll-mixins.js的onPageScroll和onReachBottom方"
  },
  {
    "path": "mescroll-uni/pages/intermediate/mescroll-swiper-sticky.vue",
    "chars": 3477,
    "preview": "<!-- 吸顶轮播菜单导航 -->\n<template>\n\t<view>\n\t\t<!-- 需设置:sticky=\"true\", 此时应避免在mescroll-body标签前面加其他非定位的元素, 否则下拉区域会被挤出, 无法会隐藏.-->\n\t"
  },
  {
    "path": "mescroll-uni/pages/intermediate/mescroll-swiper.vue",
    "chars": 1512,
    "preview": "<template>\n\t<view>\n\t\t<!-- 当设置tab-width,指定每个tab宽度时,则不使用flex布局,改用水平滑动 -->\n\t\t<me-tabs v-model=\"tabIndex\" :tabs=\"tabs\" :tab-"
  },
  {
    "path": "mescroll-uni/pages/intermediate/mescroll-uni-part.vue",
    "chars": 3326,
    "preview": "<template>\n\t<!-- mescroll-uni本质是scroll-view,支持局部区域滚动,可使用flex布局灵活的嵌在某个view中, 而mescroll-body只能靠fixed定位其他元素变相实现'局部滚动' -->\n\t"
  },
  {
    "path": "mescroll-uni/pages/intermediate/sticky-data.vue",
    "chars": 3976,
    "preview": "<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->\n<template>\n\t<view>\n"
  },
  {
    "path": "mescroll-uni/pages/intermediate/sticky-scroll-data.vue",
    "chars": 5458,
    "preview": "<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->\n<template>\n\t<view>\n\t\t<!-- 菜单 (悬浮,预先隐藏)-->\n\t\t<me-"
  },
  {
    "path": "mescroll-uni/pages/intermediate/sticky-scroll.vue",
    "chars": 4478,
    "preview": "<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->\n<template>\n\t<view>\n\t\t<!-- 菜单 (悬浮,预先隐藏)-->\n\t\t<me-"
  },
  {
    "path": "mescroll-uni/pages/intermediate/sticky-uni.vue",
    "chars": 2621,
    "preview": "<template>\n\t<view>\n\t\t<mescroll-uni @init=\"mescrollInit\" @down=\"downCallback\" @up=\"upCallback\">\n\t\t\t<swiper style=\"min-hei"
  },
  {
    "path": "mescroll-uni/pages/intermediate/sticky.vue",
    "chars": 3061,
    "preview": "<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->\n<template>\n\t<view>\n"
  },
  {
    "path": "mescroll-uni/pages/intermediate/xinlang.vue",
    "chars": 3283,
    "preview": "<template>\n\t<view>\n\t\t<!-- 模拟的标题 -->\n\t\t<image class=\"header\" src=\"https://www.mescroll.com/img/xinlang/header.jpg\" mode=\""
  },
  {
    "path": "mescroll-uni/pages.json",
    "chars": 5013,
    "preview": "{\n    \"pages\" : [\n        //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages\n        {\n            \"path"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/changelog.md",
    "chars": 328,
    "preview": "## 1.3.8(2023-03-26)\n1. 新增useMescroll的hook, 支持vue3 script setup的写法  \n2. 新增vue3 script setup的示例 ( 根据vue2的示例,全部重写了一遍 )  \n3"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.css",
    "chars": 604,
    "preview": ".mescroll-body {\n\tposition: relative; /* 下拉刷新区域相对自身定位 */\n\theight: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.vue",
    "chars": 13575,
    "preview": "<template>\n\t<view \n\tclass=\"mescroll-body mescroll-render-touch\" \n\t:class=\"{'mescorll-sticky': sticky}\"\n\t:style=\"{'minHei"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/components/mescroll-down.css",
    "chars": 1331,
    "preview": "/*下拉刷新--标语*/\n.mescroll-downwarp .downwarp-slogan{\n\tdisplay: block;\n\twidth: 420rpx;\n\theight: 168rpx;\n\tmargin: auto;\n}\n/*下"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/components/mescroll-down.vue",
    "chars": 1062,
    "preview": "<!-- 下拉刷新区域 -->\n<template>\n\t<view v-if=\"mOption.use\" class=\"mescroll-downwarp\" :style=\"{'background':mOption.bgColor,'co"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-body.vue",
    "chars": 12000,
    "preview": "<template>\n\t<view \n\t\tclass=\"mescroll-body mescroll-render-touch\" \n\t\t:style=\"{'minHeight':minHeight, 'padding-top': padTo"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-uni-option.js",
    "chars": 1333,
    "preview": "// mescroll-uni和mescroll-body 的全局配置\nconst GlobalOption = {\n\tdown: {\n\t\t// 其他down的配置参数也可以写,这里只展示了常用的配置:\n\t\toffset: uni.upx2"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-uni.vue",
    "chars": 14704,
    "preview": "<template>\n\t<view class=\"mescroll-uni-warp\">\n\t\t<scroll-view :id=\"viewId\" class=\"mescroll-uni\" :class=\"{'mescroll-uni-fix"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-down.css",
    "chars": 1182,
    "preview": "/*下拉刷新--上下箭头*/\n.mescroll-downwarp .downwarp-arrow {\n\tdisplay: inline-block;\n\twidth: 20px;\n\theight: 20px;\n\tmargin: 10px;\n"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-down.vue",
    "chars": 1258,
    "preview": "<!-- 下拉刷新区域 -->\n<template>\n\t<view v-if=\"mOption.use\" class=\"mescroll-downwarp\" :style=\"{'background':mOption.bgColor,'co"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-up.css",
    "chars": 899,
    "preview": "/*上拉加载--旋转进度条*/\n.mescroll-upwarp .upwarp-progress {\n\twidth: 36px;\n\theight: 36px;\n\tborder: none;\n\tmargin: auto;\n\tbackgrou"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-up.vue",
    "chars": 950,
    "preview": "<!-- 上拉加载区域 -->\n<template>\n\t<view class=\"mescroll-upwarp\" :style=\"{'background':mOption.bgColor,'color':mOption.textColo"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/mescroll-body.vue",
    "chars": 12482,
    "preview": "<template>\n\t<view \n\t\tclass=\"mescroll-body mescroll-render-touch\" \n\t\t:style=\"{'minHeight':minHeight, 'padding-top': padTo"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/mescroll-uni-option.js",
    "chars": 1817,
    "preview": "// 全局配置\n// mescroll-body 和 mescroll-uni 通用\nconst GlobalOption = {\n\tdown: {\n\t\t// 其他down的配置参数也可以写,这里只展示了常用的配置:\n\t\toffset: 8"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/mescroll-uni.vue",
    "chars": 15199,
    "preview": "<template>\n\t<view class=\"mescroll-uni-warp\">\n\t\t<scroll-view :id=\"viewId\" class=\"mescroll-uni\" :class=\"{'mescroll-uni-fix"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-empty/mescroll-empty.vue",
    "chars": 2544,
    "preview": "<!--空布局:\n遵循easycom规范, 可作为独立的组件, 不使用mescroll的页面也能使用:\n<mescroll-empty v-if=\"isShowEmpty\" :option=\"optEmpty\" @emptyclick=\"e"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-down.css",
    "chars": 988,
    "preview": "/* 下拉刷新区域 */\n.mescroll-downwarp {\n\tposition: absolute;\n\ttop: -100%;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\ttext-align: "
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-down.vue",
    "chars": 1224,
    "preview": "<!-- 下拉刷新区域 -->\n<template>\n\t<view v-if=\"mOption.use\" class=\"mescroll-downwarp\" :style=\"{'background-color':mOption.bgCol"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-top.vue",
    "chars": 2136,
    "preview": "<!-- 回到顶部的按钮 -->\n<template>\n\t<image\n\t\tv-if=\"option.src\"\n\t\tclass=\"mescroll-totop\"\n\t\t:class=\"[isShow ? 'mescroll-totop-in'"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-up.css",
    "chars": 848,
    "preview": "/* 上拉加载区域 */\n.mescroll-upwarp {\n\tbox-sizing: border-box;\n\tmin-height: 110rpx;\n\tpadding: 30rpx 0;\n\ttext-align: center;\n\tc"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-up.vue",
    "chars": 910,
    "preview": "<!-- 上拉加载区域 -->\n<template>\n\t<view class=\"mescroll-upwarp\" :style=\"{'background-color':mOption.bgColor,'color':mOption.te"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-i18n.js",
    "chars": 247,
    "preview": "// 国际化工具类\nconst mescrollI18n = {\n\t// 默认语言\n\tdef: \"zh\",\n\t// 获取当前语言类型\n\tgetType(){\n\t\treturn uni.getStorageSync(\"mescroll-i18"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js",
    "chars": 1070,
    "preview": "// mescroll-body 和 mescroll-uni 通用\nconst MescrollMixin = {\n\tdata() {\n\t\treturn {\n\t\t\tmescroll: null //mescroll实例对象\n\t\t}\n\t},"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni-option.js",
    "chars": 1817,
    "preview": "// 全局配置\n// mescroll-body 和 mescroll-uni 通用\nconst GlobalOption = {\n\tdown: {\n\t\t// 其他down的配置参数也可以写,这里只展示了常用的配置:\n\t\toffset: 8"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.css",
    "chars": 652,
    "preview": ".mescroll-uni-warp{\n\theight: 100%;\n}\n\n.mescroll-uni-content{\n\theight: 100%;\n}\n\n.mescroll-uni {\n\tposition: relative;\n\twid"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.js",
    "chars": 24340,
    "preview": "/* mescroll\n * version 1.3.7\n * 2021-04-12 wenju\n * https://www.mescroll.com\n */\n\nexport default function MeScroll(optio"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.vue",
    "chars": 16155,
    "preview": "<template>\n\t<view class=\"mescroll-uni-warp\">\n\t\t<scroll-view :id=\"viewId\" class=\"mescroll-uni\" :class=\"{'mescroll-uni-fix"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js",
    "chars": 1069,
    "preview": "/**\n * mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期\n */\nconst MescrollCompMixin = {\n\t// 因为子组件无onPageScroll和onReach"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js",
    "chars": 1093,
    "preview": "/**\n * mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例)\n */\nconst MescrollMoreItemMixin = {\n"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js",
    "chars": 1768,
    "preview": "/**\n * mescroll-body写在子组件时, 需通过mescroll的mixins补充子组件缺少的生命周期\n */\nconst MescrollMoreMixin = {\n\tdata() {\n\t\treturn {\n\t\t\ttabIn"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/wxs/mixins.js",
    "chars": 3203,
    "preview": "// 定义在wxs (含renderjs) 逻辑层的数据和方法, 与视图层相互通信\nconst WxsMixin = {\n\tdata() {\n\t\treturn {\n\t\t\t// 传入wxs视图层的数据 (响应式)\n\t\t\twxsProp: {\n"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/wxs/renderjs.js",
    "chars": 2334,
    "preview": "// 使用renderjs直接操作window对象,实现动态控制app和h5的bounce\n// bounce: iOS橡皮筋,Android半月弧,h5浏览器下拉背景等效果 (下拉刷新时禁止)\n// https://uniapp.dclo"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/components/mescroll-uni/wxs/wxs.wxs",
    "chars": 8000,
    "preview": "// 使用wxs处理交互动画, 提高性能, 同时避免小程序bounce对下拉刷新的影响\n// https://uniapp.dcloud.io/frame?id=wxs\n// https://developers.weixin.qq.com"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/hooks/useMescroll.js",
    "chars": 1620,
    "preview": "// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173\n// import { onPageScroll, onReachBottom, onPul"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/hooks/useMescrollComp.js",
    "chars": 1305,
    "preview": "import { ref } from 'vue';\n\n// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173\n// import { onPage"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/hooks/useMescrollMore.js",
    "chars": 1636,
    "preview": "import { ref  } from 'vue';\n\n// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173\n// import { onPag"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/package.json",
    "chars": 1522,
    "preview": "{\n  \"id\": \"mescroll-uni\",\n  \"displayName\": \"【wxs+renderjs实现】高性能的下拉刷新上拉加载组件,支持vue3 setup\",\n  \"version\": \"1.3.8\",\n  \"descr"
  },
  {
    "path": "mescroll-uni/uni_modules/mescroll-uni/readme.md",
    "chars": 1980,
    "preview": "## mescroll --【wxs+renderjs实现】高性能的下拉刷新上拉加载组件\n1. mescroll的uni版本 是专门用在uni-app的下拉刷新和上拉加载的组件  \n\n2. mescroll的uni版本 继承了mescrol"
  },
  {
    "path": "mescroll-uni-vue3/App.vue",
    "chars": 242,
    "preview": "<script>\n\texport default {\n\t\tonLaunch: function() {\n\t\t\tconsole.log('App Launch')\n\t\t},\n\t\tonShow: function() {\n\t\t\tconsole."
  },
  {
    "path": "mescroll-uni-vue3/api/goods.js",
    "chars": 4661,
    "preview": "const goods = [{\n\t\"id\": \"1\",\n\t\"goodImg\": \"https://www.mescroll.com/demo/res/img/pd1.jpg\",\n\t\"goodName\": \"【1】  六罐装荷兰美素佳儿金装"
  },
  {
    "path": "mescroll-uni-vue3/api/mock.js",
    "chars": 4682,
    "preview": "/*\n本地模拟接口请求, 仅demo演示用.\n实际项目以您服务器接口返回的数据为准,无需本地处理分页.\n请参考官方写法: https://www.mescroll.com/uni.html?v=20200210#tagUpCallback\n"
  },
  {
    "path": "mescroll-uni-vue3/components/good-list/good-list.vue",
    "chars": 1207,
    "preview": "<!-- 商品列表组件 <good-list :list=\"xx\"></good-list> -->\n<template>\n\t<view class=\"good-list\">\n\t\t<view :id=\"'good'+good.id\" cla"
  },
  {
    "path": "mescroll-uni-vue3/components/me-tabs/me-tabs.vue",
    "chars": 4707,
    "preview": "<!-- tab组件: <me-tabs v-model=\"tabIndex\" :tabs=\"tabs\" @change=\"tabChange\"></me-tabs> -->\n<template>\n\t<view class=\"me-tabs"
  },
  {
    "path": "mescroll-uni-vue3/components/me-video/me-video.vue",
    "chars": 4033,
    "preview": "<!-- 视频组件: <me-video src=\"视频地址\" poster=\"封面图\"></me-video> \nvideo标签在APP端是原生组件, 真机APP端下拉时会渲染不及时, 出现悬浮错位现象;\nme-video组件, 未播放时"
  },
  {
    "path": "mescroll-uni-vue3/index.html",
    "chars": 672,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <script>\n      var coverSupport = 'CSS' in wi"
  },
  {
    "path": "mescroll-uni-vue3/main.js",
    "chars": 884,
    "preview": "import App from './App'\n\n// #ifndef VUE3\nimport Vue from 'vue'\nVue.config.productionTip = false\nApp.mpType = 'app'\n\ntry "
  },
  {
    "path": "mescroll-uni-vue3/manifest.json",
    "chars": 2718,
    "preview": "{\n    \"name\" : \"mescrollVue3\",\n    \"appid\" : \"\",\n    \"description\" : \"mescroll uni-app vue3\",\n    \"versionName\" : \"1.0.0"
  },
  {
    "path": "mescroll-uni-vue3/package.json",
    "chars": 326,
    "preview": "{\n\t\"uni-app\": {\n\t\t\"scripts\": {\n\t\t\t\"mp-dingtalk\": {\n\t\t\t\t\"title\": \"钉钉小程序\",\n\t\t\t\t\"env\": {\n\t\t\t\t\t\"UNI_PLATFORM\": \"mp-alipay\"\n\t"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/list-news.vue",
    "chars": 1746,
    "preview": "<template>\n\t<mescroll-body @init=\"mescrollInit\" :down=\"downOption\" @down=\"downCallback\" @up=\"upCallback\">\n\t\t<view class="
  },
  {
    "path": "mescroll-uni-vue3/pages/base/list-products.vue",
    "chars": 1685,
    "preview": "<template>\n\t <mescroll-body @init=\"mescrollInit\" @down=\"downCallback\" @up=\"upCallback\">\n\t\t<view class=\"notice\">mescroll的"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/list-search.vue",
    "chars": 2649,
    "preview": "<template>\n\t <mescroll-body @init=\"mescrollInit\" @down=\"downCallback\" :up=\"upOption\" @up=\"upCallback\">\n\t\t<view class=\"it"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-comp-center.vue",
    "chars": 577,
    "preview": "<template>\n\t<!-- 当mescroll-body写在子子..子组件时, 需每层子组件都引入useMescrollComp, 添加ref=\"mescrollItem\" -->\n\t<view>\n\t\t<mescroll-item r"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-comp-item.vue",
    "chars": 1061,
    "preview": "<template>\n\t<!-- 当mescroll-body写在子组件时,父页面需引入useMescrollComp.js -->\n\t<mescroll-body top=\"100\" @init=\"mescrollInit\" @down="
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-comp.vue",
    "chars": 1621,
    "preview": "<template>\n\t<!-- \n\t\tmescroll-body写在一层子组件时, 需引入useMescrollComp, 给子组件添加ref=\"mescrollItem\",\n\t\t当mescroll-body写在子子..子组件时, 需每层"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-empty.vue",
    "chars": 1264,
    "preview": "<!-- mescroll-empty遵循easycom, 可直接单独使用 -->\n<template>\n\t<view>\n\t\t<!-- 列表内容 -->\n\t\t<view v-if=\"list.length\">\n\t\t\t<!-- ... -->"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-i18n.vue",
    "chars": 2579,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\" @click=\"i18nChange()\">点击切换语言</view>\n\t\t\t<"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-more-item.vue",
    "chars": 2342,
    "preview": "<template>\n\t<!-- 不能用v-if (i: 每个tab页的专属下标;  index: 当前tab的下标 )-->\n\t<view v-show=\"i === index\">\n\t\t<!-- top=\"120\"下拉布局往下偏移,防止"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-more.vue",
    "chars": 3101,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\">每个菜单列表仅初始化一次,切换菜单缓存数据</view>\n\t\t\t<!-- 当设置"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-native.vue",
    "chars": 2330,
    "preview": "<template>\n\t<!-- 系统自带的下拉刷新,只能配合mescroll-body使用, 在mescroll-uni中无效 -->\n\t<mescroll-body @init=\"mescrollInit\" :down=\"downOpt"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-one.vue",
    "chars": 2240,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\">每次切换菜单及时刷新列表,不缓存数据</view>\n\t\t\t<me-tabs v-"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-options.vue",
    "chars": 7327,
    "preview": "<template>\n\t<mescroll-body @init=\"mescrollInit\" @down=\"downCallback\" @up=\"upCallback\" \n\t :down=\"downOption\" \n\t :up=\"upOp"
  },
  {
    "path": "mescroll-uni-vue3/pages/base/mescroll-uni.vue",
    "chars": 3159,
    "preview": "<template>\n\t<view>\n\t\t<!-- 菜单 -->\n\t\t<view class=\"top-warp\">\n\t\t\t<view class=\"tip\">基于scroll-view,常用在浮窗弹层等局部滚动区域</view>\n\t\t\t<"
  },
  {
    "path": "mescroll-uni-vue3/pages/index/index.vue",
    "chars": 4834,
    "preview": "<template>\n\t<view>\n\t\t\n\t\t<view class=\"group-title\">base demos 基础案例</view>\n\t\t\n\t\t<navigator url=\"/pages/base/list-products\""
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/beibei.vue",
    "chars": 1805,
    "preview": "<template>\n\t<view>\n\t\t<!-- 模拟的标题 -->\n\t\t<image class=\"header\" src=\"https://www.mescroll.com/img/beibei/header.jpg\" mode=\"a"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/list-msg.vue",
    "chars": 2937,
    "preview": "<template>\n\t<!-- 需配置bottom的偏移量, 用于底部留白 -->\n\t<mescroll-body bottom=\"50%\" @init=\"mescrollInit\" :down=\"downOption\" @down=\"d"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/mescroll-body-part.vue",
    "chars": 3097,
    "preview": "<template>\n\t<!-- mescroll-body本质是原生page的滚动,无法像mescroll-uni那样用flex布局嵌在某个view中使用局部区域滚动, 但是可以通过fixed定位其他元素来实现\"局部区域滚动\"-->\n\t<"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/mescroll-swiper-item.vue",
    "chars": 2429,
    "preview": "<template>\n\t<!-- \n\tswiper中的transfrom会使fixed失效,此时用height固定高度; \n\tswiper中无法触发mescroll-mixins.js的onPageScroll和onReachBottom方"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/mescroll-swiper-sticky-item.vue",
    "chars": 2472,
    "preview": "<template>\n\t<!-- \n\tswiper中的transfrom会使fixed失效,此时用height固定高度; \n\tswiper中无法触发mescroll-mixins.js的onPageScroll和onReachBottom方"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/mescroll-swiper-sticky.vue",
    "chars": 3437,
    "preview": "<!-- 吸顶轮播菜单导航 -->\n<template>\n\t<view>\n\t\t<!-- 需设置:sticky=\"true\", 此时应避免在mescroll-body标签前面加其他非定位的元素, 否则下拉区域会被挤出, 无法会隐藏.-->\n\t"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/mescroll-swiper.vue",
    "chars": 1479,
    "preview": "<template>\n\t<view>\n\t\t<!-- 当设置tab-width,指定每个tab宽度时,则不使用flex布局,改用水平滑动 -->\n\t\t<me-tabs v-model=\"tabIndex\" :tabs=\"tabs\" :tab-"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/mescroll-uni-part.vue",
    "chars": 3459,
    "preview": "<template>\n\t<!-- mescroll-uni本质是scroll-view,支持局部区域滚动,可使用flex布局灵活的嵌在某个view中, 而mescroll-body只能靠fixed定位其他元素变相实现'局部滚动' -->\n\t"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/sticky-data.vue",
    "chars": 3805,
    "preview": "<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->\n<template>\n\t<view>\n"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/sticky-scroll-data.vue",
    "chars": 5115,
    "preview": "<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->\n<template>\n\t<view>\n\t\t<!-- 菜单 (悬浮,预先隐藏)-->\n\t\t<me-"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/sticky-scroll.vue",
    "chars": 4448,
    "preview": "<!-- 菜单悬浮的原理: 监听滚动条的位置大于某个值时,控制顶部菜单的显示和隐藏, 用法比sticky复杂, 但APP端可兼容低端机 -->\n<template>\n\t<view>\n\t\t<!-- 菜单 (悬浮,预先隐藏)-->\n\t\t<me-"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/sticky-uni.vue",
    "chars": 2502,
    "preview": "<template>\n\t<view>\n\t\t<mescroll-uni @init=\"mescrollInit\" @down=\"downCallback\" @up=\"upCallback\">\n\t\t\t<swiper style=\"height:"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/sticky.vue",
    "chars": 2968,
    "preview": "<!-- 菜单悬浮的原理: 通过给菜单添加position:sticky实现, 用法超简单, 仅APP端的低端机不兼容 https://caniuse.com/#feat=css-sticky -->\n<template>\n\t<view>\n"
  },
  {
    "path": "mescroll-uni-vue3/pages/intermediate/xinlang.vue",
    "chars": 3283,
    "preview": "<template>\n\t<view>\n\t\t<!-- 模拟的标题 -->\n\t\t<image class=\"header\" src=\"https://www.mescroll.com/img/xinlang/header.jpg\" mode=\""
  },
  {
    "path": "mescroll-uni-vue3/pages.json",
    "chars": 5013,
    "preview": "{\n    \"pages\" : [\n        //pages数组中第一项表示应用启动页,参考:https://uniapp.dcloud.io/collocation/pages\n        {\n            \"path"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/changelog.md",
    "chars": 328,
    "preview": "## 1.3.8(2023-03-26)\n1. 新增useMescroll的hook, 支持vue3 script setup的写法  \n2. 新增vue3 script setup的示例 ( 根据vue2的示例,全部重写了一遍 )  \n3"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.css",
    "chars": 604,
    "preview": ".mescroll-body {\n\tposition: relative; /* 下拉刷新区域相对自身定位 */\n\theight: auto; /* 不可固定高度,否则overflow:hidden导致无法滑动; 同时使设置的最小高生效,实"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-body/mescroll-body.vue",
    "chars": 13575,
    "preview": "<template>\n\t<view \n\tclass=\"mescroll-body mescroll-render-touch\" \n\t:class=\"{'mescorll-sticky': sticky}\"\n\t:style=\"{'minHei"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/beibei/components/mescroll-down.css",
    "chars": 1331,
    "preview": "/*下拉刷新--标语*/\n.mescroll-downwarp .downwarp-slogan{\n\tdisplay: block;\n\twidth: 420rpx;\n\theight: 168rpx;\n\tmargin: auto;\n}\n/*下"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/beibei/components/mescroll-down.vue",
    "chars": 1062,
    "preview": "<!-- 下拉刷新区域 -->\n<template>\n\t<view v-if=\"mOption.use\" class=\"mescroll-downwarp\" :style=\"{'background':mOption.bgColor,'co"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-body.vue",
    "chars": 12000,
    "preview": "<template>\n\t<view \n\t\tclass=\"mescroll-body mescroll-render-touch\" \n\t\t:style=\"{'minHeight':minHeight, 'padding-top': padTo"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-uni-option.js",
    "chars": 1333,
    "preview": "// mescroll-uni和mescroll-body 的全局配置\nconst GlobalOption = {\n\tdown: {\n\t\t// 其他down的配置参数也可以写,这里只展示了常用的配置:\n\t\toffset: uni.upx2"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/beibei/mescroll-uni.vue",
    "chars": 14704,
    "preview": "<template>\n\t<view class=\"mescroll-uni-warp\">\n\t\t<scroll-view :id=\"viewId\" class=\"mescroll-uni\" :class=\"{'mescroll-uni-fix"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-down.css",
    "chars": 1182,
    "preview": "/*下拉刷新--上下箭头*/\n.mescroll-downwarp .downwarp-arrow {\n\tdisplay: inline-block;\n\twidth: 20px;\n\theight: 20px;\n\tmargin: 10px;\n"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-down.vue",
    "chars": 1258,
    "preview": "<!-- 下拉刷新区域 -->\n<template>\n\t<view v-if=\"mOption.use\" class=\"mescroll-downwarp\" :style=\"{'background':mOption.bgColor,'co"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-up.css",
    "chars": 899,
    "preview": "/*上拉加载--旋转进度条*/\n.mescroll-upwarp .upwarp-progress {\n\twidth: 36px;\n\theight: 36px;\n\tborder: none;\n\tmargin: auto;\n\tbackgrou"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/components/mescroll-up.vue",
    "chars": 950,
    "preview": "<!-- 上拉加载区域 -->\n<template>\n\t<view class=\"mescroll-upwarp\" :style=\"{'background':mOption.bgColor,'color':mOption.textColo"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/mescroll-body.vue",
    "chars": 12482,
    "preview": "<template>\n\t<view \n\t\tclass=\"mescroll-body mescroll-render-touch\" \n\t\t:style=\"{'minHeight':minHeight, 'padding-top': padTo"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/mescroll-uni-option.js",
    "chars": 1817,
    "preview": "// 全局配置\n// mescroll-body 和 mescroll-uni 通用\nconst GlobalOption = {\n\tdown: {\n\t\t// 其他down的配置参数也可以写,这里只展示了常用的配置:\n\t\toffset: 8"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-diy/xinlang/mescroll-uni.vue",
    "chars": 15199,
    "preview": "<template>\n\t<view class=\"mescroll-uni-warp\">\n\t\t<scroll-view :id=\"viewId\" class=\"mescroll-uni\" :class=\"{'mescroll-uni-fix"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-empty/mescroll-empty.vue",
    "chars": 2544,
    "preview": "<!--空布局:\n遵循easycom规范, 可作为独立的组件, 不使用mescroll的页面也能使用:\n<mescroll-empty v-if=\"isShowEmpty\" :option=\"optEmpty\" @emptyclick=\"e"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-down.css",
    "chars": 988,
    "preview": "/* 下拉刷新区域 */\n.mescroll-downwarp {\n\tposition: absolute;\n\ttop: -100%;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\ttext-align: "
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-down.vue",
    "chars": 1224,
    "preview": "<!-- 下拉刷新区域 -->\n<template>\n\t<view v-if=\"mOption.use\" class=\"mescroll-downwarp\" :style=\"{'background-color':mOption.bgCol"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-top.vue",
    "chars": 2136,
    "preview": "<!-- 回到顶部的按钮 -->\n<template>\n\t<image\n\t\tv-if=\"option.src\"\n\t\tclass=\"mescroll-totop\"\n\t\t:class=\"[isShow ? 'mescroll-totop-in'"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-up.css",
    "chars": 848,
    "preview": "/* 上拉加载区域 */\n.mescroll-upwarp {\n\tbox-sizing: border-box;\n\tmin-height: 110rpx;\n\tpadding: 30rpx 0;\n\ttext-align: center;\n\tc"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/components/mescroll-up.vue",
    "chars": 910,
    "preview": "<!-- 上拉加载区域 -->\n<template>\n\t<view class=\"mescroll-upwarp\" :style=\"{'background-color':mOption.bgColor,'color':mOption.te"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-i18n.js",
    "chars": 247,
    "preview": "// 国际化工具类\nconst mescrollI18n = {\n\t// 默认语言\n\tdef: \"zh\",\n\t// 获取当前语言类型\n\tgetType(){\n\t\treturn uni.getStorageSync(\"mescroll-i18"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js",
    "chars": 1070,
    "preview": "// mescroll-body 和 mescroll-uni 通用\nconst MescrollMixin = {\n\tdata() {\n\t\treturn {\n\t\t\tmescroll: null //mescroll实例对象\n\t\t}\n\t},"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni-option.js",
    "chars": 1817,
    "preview": "// 全局配置\n// mescroll-body 和 mescroll-uni 通用\nconst GlobalOption = {\n\tdown: {\n\t\t// 其他down的配置参数也可以写,这里只展示了常用的配置:\n\t\toffset: 8"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.css",
    "chars": 652,
    "preview": ".mescroll-uni-warp{\n\theight: 100%;\n}\n\n.mescroll-uni-content{\n\theight: 100%;\n}\n\n.mescroll-uni {\n\tposition: relative;\n\twid"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.js",
    "chars": 24340,
    "preview": "/* mescroll\n * version 1.3.7\n * 2021-04-12 wenju\n * https://www.mescroll.com\n */\n\nexport default function MeScroll(optio"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-uni.vue",
    "chars": 16155,
    "preview": "<template>\n\t<view class=\"mescroll-uni-warp\">\n\t\t<scroll-view :id=\"viewId\" class=\"mescroll-uni\" :class=\"{'mescroll-uni-fix"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js",
    "chars": 1069,
    "preview": "/**\n * mescroll-body写在子组件时,需通过mescroll的mixins补充子组件缺少的生命周期\n */\nconst MescrollCompMixin = {\n\t// 因为子组件无onPageScroll和onReach"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more-item.js",
    "chars": 1093,
    "preview": "/**\n * mescroll-more-item的mixins, 仅在多个 mescroll-body 写在子组件时使用 (参考 mescroll-more 案例)\n */\nconst MescrollMoreItemMixin = {\n"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-more.js",
    "chars": 1768,
    "preview": "/**\n * mescroll-body写在子组件时, 需通过mescroll的mixins补充子组件缺少的生命周期\n */\nconst MescrollMoreMixin = {\n\tdata() {\n\t\treturn {\n\t\t\ttabIn"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/wxs/mixins.js",
    "chars": 3203,
    "preview": "// 定义在wxs (含renderjs) 逻辑层的数据和方法, 与视图层相互通信\nconst WxsMixin = {\n\tdata() {\n\t\treturn {\n\t\t\t// 传入wxs视图层的数据 (响应式)\n\t\t\twxsProp: {\n"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/wxs/renderjs.js",
    "chars": 2334,
    "preview": "// 使用renderjs直接操作window对象,实现动态控制app和h5的bounce\n// bounce: iOS橡皮筋,Android半月弧,h5浏览器下拉背景等效果 (下拉刷新时禁止)\n// https://uniapp.dclo"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/components/mescroll-uni/wxs/wxs.wxs",
    "chars": 8000,
    "preview": "// 使用wxs处理交互动画, 提高性能, 同时避免小程序bounce对下拉刷新的影响\n// https://uniapp.dcloud.io/frame?id=wxs\n// https://developers.weixin.qq.com"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/hooks/useMescroll.js",
    "chars": 1620,
    "preview": "// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173\n// import { onPageScroll, onReachBottom, onPul"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/hooks/useMescrollComp.js",
    "chars": 1305,
    "preview": "import { ref } from 'vue';\n\n// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173\n// import { onPage"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/hooks/useMescrollMore.js",
    "chars": 1636,
    "preview": "import { ref  } from 'vue';\n\n// 小程序无法在hook中使用页面级别生命周期,需单独传入: https://ask.dcloud.net.cn/question/161173\n// import { onPag"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/package.json",
    "chars": 1522,
    "preview": "{\n  \"id\": \"mescroll-uni\",\n  \"displayName\": \"【wxs+renderjs实现】高性能的下拉刷新上拉加载组件,支持vue3 setup\",\n  \"version\": \"1.3.8\",\n  \"descr"
  },
  {
    "path": "mescroll-uni-vue3/uni_modules/mescroll-uni/readme.md",
    "chars": 1980,
    "preview": "## mescroll --【wxs+renderjs实现】高性能的下拉刷新上拉加载组件\n1. mescroll的uni版本 是专门用在uni-app的下拉刷新和上拉加载的组件  \n\n2. mescroll的uni版本 继承了mescrol"
  },
  {
    "path": "mescroll.js/dist/mescroll.css",
    "chars": 4972,
    "preview": "/* mescroll\n * version 1.4.2\n * 2019-08-01 wenju\n * http://www.mescroll.com\n *\n * 温馨提示: mescroll唯一的全局样式: html,body{heigh"
  },
  {
    "path": "mescroll.js/dist/mescroll.js",
    "chars": 42837,
    "preview": "/* mescroll\n * version 1.4.2\n * 2019-08-01 wenju\n * http://www.mescroll.com\n */\n(function (name, definition) {\n  if (typ"
  },
  {
    "path": "mescroll.js/dist/mescroll.vue",
    "chars": 1489,
    "preview": "<template>\n  <div ref=\"mescroll\" class=\"mescroll\">\n    <div>\n      <slot></slot>\n    </div>\n  </div>\n</template>\n\n<scrip"
  },
  {
    "path": "mescroll.js/html-demo/base/list-full-lock.html",
    "chars": 6970,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-mescroll-body.html",
    "chars": 8304,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-mescroll-lazy.html",
    "chars": 8219,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-mescroll-more.html",
    "chars": 9685,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-mescroll-one.html",
    "chars": 8202,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-msg.html",
    "chars": 5473,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-news.html",
    "chars": 6186,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-products-vue.html",
    "chars": 6241,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/list-products.html",
    "chars": 6748,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/mescroll-options.html",
    "chars": 14252,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/base/vue-mescroll.html",
    "chars": 5361,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/beibei/beibei.html",
    "chars": 7563,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/beibei/option/mescroll-option.css",
    "chars": 1718,
    "preview": "/*\n * 自定义下拉刷新\n * \n\t//下拉刷新区域\n\t<div class=\"mescroll-downwarp\">\n\t\t<div class=\"downwarp-content\">\n\t\t\t<img class=\"downwarp-sl"
  },
  {
    "path": "mescroll.js/html-demo/beibei/option/mescroll-option.js",
    "chars": 3416,
    "preview": "/*\n *下拉刷新和上拉加载js\n * \n1.引用mescroll.css和mescroll.js; 引用自定义的mescroll-option.css和mescroll-option.js,并检查相关图片路径是否引用正确;\n\n2.拷贝以下"
  },
  {
    "path": "mescroll.js/html-demo/dotJump/dotJump.html",
    "chars": 8062,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/dotJump/option/mescroll-option.css",
    "chars": 1896,
    "preview": "/*\n * 自定义下拉刷新和上拉加载的结构\n * \n\t//下拉刷新区域\n\t<div class=\"mescroll-downwarp\">\n\t\t//可自定义内容\n\t\t<p class=\"downwarp-circle\"></p>\n\t\t<img"
  },
  {
    "path": "mescroll.js/html-demo/dotJump/option/mescroll-option.js",
    "chars": 4082,
    "preview": "/*\n *下拉刷新和上拉加载js\n * \n1.引用mescroll.css和mescroll.js; 引用自定义的mescroll-option.css和mescroll-option.js,并检查相关图片路径是否引用正确;\n\n2.拷贝以下"
  },
  {
    "path": "mescroll.js/html-demo/index.html",
    "chars": 3428,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/res/pdlist1.js",
    "chars": 3443,
    "preview": "var pdlist1=[\n\t{\n\t\t\"pdImg\": \"../res/img/pd1.jpg\",\n\t\t\"pdName\": \"【1】  六罐装荷兰美素佳儿金装2段900g\",\n\t\t\"pdPrice\": 1149.00,\n\t\t\"pdSold\""
  },
  {
    "path": "mescroll.js/html-demo/res/pdlist1.json",
    "chars": 3430,
    "preview": "[\n\t{\n\t\t\"pdImg\": \"../res/img/pd1.jpg\",\n\t\t\"pdName\": \"【1】  六罐装荷兰美素佳儿金装2段900g\",\n\t\t\"pdPrice\": 1149.00,\n\t\t\"pdSold\": 648\n\t}, {\n"
  },
  {
    "path": "mescroll.js/html-demo/res/pdlist2.js",
    "chars": 3138,
    "preview": "var pdlist2=[\n\t{\n\t\t\"pdImg\": \"../res/img/pd3.jpg\",\n\t\t\"pdName\": \"【3】 美素佳儿Friso婴儿配方奶粉3段 ( 商品【1】【2】 已删除 )\",\n\t\t\"pdPrice\": 177"
  },
  {
    "path": "mescroll.js/html-demo/res/pdlist2.json",
    "chars": 3125,
    "preview": "[\n\t{\n\t\t\"pdImg\": \"../res/img/pd3.jpg\",\n\t\t\"pdName\": \"【3】 美素佳儿Friso婴儿配方奶粉3段 ( 商品【1】【2】 已删除 )\",\n\t\t\"pdPrice\": 177.00,\n\t\t\"pdSo"
  },
  {
    "path": "mescroll.js/html-demo/search/mescroll-search.html",
    "chars": 8459,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/sticky/mescroll-sticky.html",
    "chars": 8947,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/swiper/mescroll-swiper-nav.html",
    "chars": 11818,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/swiper/mescroll-swiper-sticky.html",
    "chars": 13211,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/swiper/mescroll-swiper-tap.html",
    "chars": 10081,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/xinlang/option/mescroll-option.css",
    "chars": 1865,
    "preview": "/*\n * 自定义下拉刷新和上拉加载的结构\n * \n\t//下拉刷新区域\n\t<div class=\"mescroll-downwarp\">\n\t\t<div class=\"downwarp-onload\"><p class=\"downwarp-p"
  },
  {
    "path": "mescroll.js/html-demo/xinlang/option/mescroll-option.js",
    "chars": 3652,
    "preview": "/*\n *下拉刷新和上拉加载js\n * \n1.引用mescroll.css和mescroll.js; 引用自定义的mescroll-option.css和mescroll-option.js,并检查相关图片路径是否引用正确;\n\n2.拷贝以下"
  },
  {
    "path": "mescroll.js/html-demo/xinlang/xinlang.html",
    "chars": 7393,
    "preview": "<!DOCTYPE html>\n<html>\n\n\t<head>\n\t\t<meta charset=\"utf-8\">\n\t\t<meta name=\"viewport\" content=\"width=device-width, initial-sc"
  },
  {
    "path": "mescroll.js/html-demo/yabuli/option/mescroll-option.css",
    "chars": 999,
    "preview": "/*\n * 自定义下拉刷新和上拉加载的结构\n * \n\t//下拉刷新区域\n\t<div class=\"mescroll-downwarp\">\n\t\t//可自定义内容\n\t\t<p class=\"downwarp-tip\">↓ 下拉刷新 ↓</p>\n\t"
  },
  {
    "path": "mescroll.js/html-demo/yabuli/option/mescroll-option.js",
    "chars": 4165,
    "preview": "/*\n *下拉刷新和上拉加载js\n * \n1.引用mescroll.css和mescroll.js; 引用自定义的mescroll-option.css和mescroll-option.js,并检查相关图片路径是否引用正确;\n\n2.拷贝以下"
  }
]

// ... and 23 more files (download for full content)

About this extraction

This page contains the full source code of the mescroll/mescroll GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 223 files (894.5 KB), approximately 344.8k tokens, and a symbol index with 99 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!