户籍信息录入
27
app.js
@ -1,17 +1,20 @@
|
||||
//app.js
|
||||
var restAjax = require('utils/restAjax.js');
|
||||
var dialog = require('utils/dialog.js');
|
||||
var dics = require('utils/dic.js')
|
||||
App({
|
||||
loginUrl: 'https://www.tenlion.com.cn/usercenter/',
|
||||
// loginUrl: 'http://192.168.0.103:7001/usercenter/',
|
||||
// requestUrl: 'http://192.168.0.120:8083/servicecity/',
|
||||
requestUrl: 'https://www.tenlion.com.cn/servicecity/',
|
||||
restAjax: restAjax,
|
||||
dialog: dialog,
|
||||
onLaunch: function () {
|
||||
|
||||
},
|
||||
globalData: {
|
||||
userInfo: null
|
||||
}
|
||||
// loginUrl: 'https://www.tenlion.com.cn/usercenter/',
|
||||
loginUrl: 'http://219.147.99.164:8082/usercenter/',
|
||||
requestUrl: 'http://219.147.99.164:8082/servicecity/',
|
||||
personUrl: 'http://219.147.99.164:8082/population/',
|
||||
// requestUrl: 'https://www.tenlion.com.cn/servicecity/',
|
||||
restAjax: restAjax,
|
||||
dialog: dialog,
|
||||
dics: dics,
|
||||
onLaunch: function () {
|
||||
|
||||
},
|
||||
globalData: {
|
||||
userInfo: null
|
||||
}
|
||||
})
|
50
app.json
@ -1,17 +1,22 @@
|
||||
{
|
||||
"pages":[
|
||||
"pages": [
|
||||
"pages/index/index",
|
||||
"pages/caseCheck/caseCheck",
|
||||
"pages/caseReport/caseReport",
|
||||
"pages/caseDetail/caseDetail",
|
||||
"pages/process/process",
|
||||
"pages/waitCheck/waitCheck"
|
||||
"pages/waitCheck/waitCheck",
|
||||
"pages/census/census",
|
||||
"pages/mine/mine",
|
||||
"pages/censusinput/censusinput",
|
||||
"pages/chooseArea/chooseArea",
|
||||
"pages/censusDetail/censusDetail"
|
||||
],
|
||||
"window":{
|
||||
"backgroundTextStyle":"light",
|
||||
"navigationBarBackgroundColor": "#008cff",
|
||||
"navigationBarTitleText": "片长制城市管理服务平台",
|
||||
"navigationBarTextStyle":"white"
|
||||
"window": {
|
||||
"backgroundTextStyle": "light",
|
||||
"navigationBarBackgroundColor": "#4583FE",
|
||||
"navigationBarTitleText": "包头高新网格化",
|
||||
"navigationBarTextStyle": "white"
|
||||
},
|
||||
"style": "v2",
|
||||
"sitemapLocation": "sitemap.json",
|
||||
@ -20,30 +25,27 @@
|
||||
"desc": "你的位置信息将用于小程序位置接口的效果展示"
|
||||
}
|
||||
},
|
||||
"usingComponents": {
|
||||
"scroller": "components/coolui-scroller/scroller/index"
|
||||
},
|
||||
"tabBar": {
|
||||
"color": "#000",
|
||||
"borderStyle": "black",
|
||||
"selectedColor": "#fff",
|
||||
"backgroundColor": "#1089f2",
|
||||
"borderStyle": "white",
|
||||
"selectedColor": "#4583FE",
|
||||
"backgroundColor": "#F8F8F8",
|
||||
"list": [
|
||||
{
|
||||
"pagePath": "pages/caseReport/caseReport",
|
||||
"iconPath": "images/report.png",
|
||||
"text": "案件上报",
|
||||
"selectedIconPath": "images/report-on.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/index/index",
|
||||
"iconPath": "images/history.png",
|
||||
"text": "上报历史",
|
||||
"selectedIconPath": "images/history-on.png"
|
||||
"iconPath": "images/ic_home_nomarl_icon.png",
|
||||
"text": "首页",
|
||||
"selectedIconPath": "images/ic_home_sel_icon.png"
|
||||
},
|
||||
{
|
||||
"pagePath": "pages/waitCheck/waitCheck",
|
||||
"iconPath": "images/check.png",
|
||||
"text": "待检查",
|
||||
"selectedIconPath": "images/check-on.png"
|
||||
"pagePath": "pages/mine/mine",
|
||||
"iconPath": "images/ic_mine_nomarl_icon.png",
|
||||
"text": "我的",
|
||||
"selectedIconPath": "images/ic_mine_sel_icon.png"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
49
app.wxss
@ -1,10 +1,43 @@
|
||||
/**app.wxss**/
|
||||
@import "/styles/iconfont.wxss";
|
||||
|
||||
.container {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 200rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
height: 100%;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
padding: 200rpx 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.empty-data {
|
||||
font-size: 16px;
|
||||
color: #5f5f5f;
|
||||
text-align: center;
|
||||
justify-self: center;
|
||||
align-self: center;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
|
||||
.wx-switch-input {
|
||||
width: 90rpx !important;
|
||||
height: 48rpx !important;
|
||||
}
|
||||
|
||||
/* false的样式 */
|
||||
.wx-switch-input::before {
|
||||
width: 100rpx !important;
|
||||
height: 40rpx !important;
|
||||
}
|
||||
|
||||
/* true的样式 */
|
||||
.wx-switch-input::after {
|
||||
width: 40rpx !important;
|
||||
height: 40rpx !important;
|
||||
}
|
21
components/coolui-scroller/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 缘℃Style
|
||||
|
||||
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.
|
178
components/coolui-scroller/README.md
Normal file
@ -0,0 +1,178 @@
|
||||
# coolui-scroller
|
||||
|
||||
<a href="https://www.npmjs.com/package/coolui-scroller"><img src="https://img.shields.io/npm/v/coolui-scroller.svg" alt="Version"></a>
|
||||
<a href="https://www.npmjs.com/package/coolui-scroller"><img src="https://img.shields.io/npm/l/coolui-scroller.svg" alt="License"></a>
|
||||
<a href="https://www.npmjs.com/package/coolui-scroller"><img src="https://img.shields.io/npm/dt/coolui-scroller" alt="Download"></a>
|
||||
<a href="https://github.com/wzs28150/coolui-scroller"><img src="https://img.shields.io/github/stars/wzs28150/coolui-scroller?style=social" alt="Stars"></a>
|
||||
|
||||
## 前言
|
||||
|
||||
### 初衷
|
||||
|
||||
本来写这个组件的初衷,是在我写了一个小程序之后,发现小程序如果要实现下拉刷新、上拉加载有两种方式:
|
||||
|
||||
1. 页面级的:利用页面 Page 里提供的方法。下拉虽说是那个东西但是它只有下拉三个点的动画效果而且只能显示在头部就很尴尬。很多时候一个列表的头部往往会有一些组件比如搜索、分类导航等等。所以往往列表都是局部的非页面级的。这时候下拉时动画出现在最顶部就显得很突兀。
|
||||
|
||||
```javascript
|
||||
Page({
|
||||
onPullDownRefresh: function () {
|
||||
// 监听用户下拉刷新事件。
|
||||
},
|
||||
onReachBottom: function () {
|
||||
// 监听用户上拉触底事件。
|
||||
},
|
||||
onPageScroll: function () {
|
||||
// 监听用户滑动页面事件。
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
2. 组件级的:利用 scroll-view。 但是当你打开 scroll-view 官方文档时,映入眼帘的是一列列的参数属性方法。要完全弄懂里面的内容,恐怕你得上手写写,挨个试试里面的参数和方法才行。而对于下拉刷新这个效果文档上有个简易的 demo 可寻。上拉加载也只有 bindscrolltolower 这么个方法和 lower-threshold 阈值。所以要实现起来完全还得靠自己。
|
||||
|
||||
所以在写项目的最后我把页面的列表下拉刷新,上拉加载进行了初步的封装。单独拿出来方便之后重复使用。所以有了起初的 1.0 版。
|
||||
|
||||
### 发展
|
||||
|
||||
#### V2.0
|
||||
|
||||
scroll-view 组件初期并没有那么多配置,所以 1.0 实现的效果很有限。
|
||||
后来随着官方 scroll-view 组件的不断的更新。增加了很多新的属性和事件使得下拉可以自定义起来。虽然也有很多地方不尽人意,但是可玩度还是有很多的。所以又升级了 2.0 版增加了很多下拉的自定义动画效果和上拉加载的效果。
|
||||
|
||||
2.0 版组件还是围绕着 scroll-view,写法上只有一个封装好的 scroller 组件。内置了一个基础的下拉效果。提供下拉的插槽位置。并给出了几个有趣的下拉效果 demo(如:天猫效果、京东小人效果)让下拉又有了更多的可能性;配置上也考虑了很多增加了列表为空时的设置上拉加载的配置。整个配置就是一个 Obj,细化到文字、背景。
|
||||
|
||||
V2.0 配置:
|
||||
|
||||
```js
|
||||
// data 中配置
|
||||
scroll: {
|
||||
// 设置分页信息
|
||||
pagination: {
|
||||
page: 1,
|
||||
totalPage: 10,
|
||||
limit: 10,
|
||||
length: 100
|
||||
},
|
||||
// 设置数据为空时的图片
|
||||
empty: {
|
||||
img: 'http://coolui.coolwl.cn/assets/mescroll-empty.png'
|
||||
},
|
||||
// 设置下拉刷新
|
||||
refresh: {
|
||||
type: 'default',
|
||||
style: 'black',
|
||||
background: "#000"
|
||||
},
|
||||
// 设置上拉加载
|
||||
loadmore: {
|
||||
type: 'default',
|
||||
icon: 'http://upload-images.jianshu.io/upload_images/5726812-95bd7570a25bd4ee.gif',
|
||||
background: '#f2f2f2',
|
||||
// backgroundImage: 'http://coolui.coolwl.cn/assets/bg.jpg',
|
||||
title: {
|
||||
show: true,
|
||||
text: '加载中',
|
||||
color: "#999",
|
||||
shadow: 5
|
||||
}
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
之后由于疫情及个人原因这个组件搁置了一阵子。当我再次打开它时便有了重构的想法。
|
||||
|
||||
#### V3.0
|
||||
|
||||
3.0 版打算把之前各个部分的插槽进行细化及拆分。并新增空列表插槽及组件、初次进入程序时的手势提示组件、顶部插槽及顶部插槽可用的组件(如:搜索组件、分类组件、下拉筛选组件)。
|
||||
|
||||
除了组件的变化外,核心列表准备加入长列表处理,解决数据量大时列表会出现的问题(如:setData 加载大数据的耗时高、列表渲染出来的 Dom 结构多、占用的内存高,造成页面被系统回收的概率变大等)。起初想以官方给出的 recycle-view 组件进行扩展。但是使用中,遇到很多坑及不方便之处。最让我接受不了的是需要设置 itemSize 这个方法。当我在不确定列表元素宽高的时候就很难设置。后来经过大量的思考和查资料及尝试。决定采用知乎上 daisy 提出的长列表解决方案。
|
||||
|
||||
该组件还在开发中各组件陆续上线~
|
||||
|
||||
### v3.0 版
|
||||
|
||||
1. 基于小程序原生组件 scroll-view 的扩展与封装,实现简单的上拉加载下拉刷新
|
||||
2. 扩展下拉刷新动画,有灵感的朋友可以丰富更多下拉动画
|
||||
3. 上传至 npm 包可安装下载并 npm 构建
|
||||
4. 修改参数配置使组件使用更便捷
|
||||
5. 增加加载插槽可以自定义加载更多样式
|
||||
6. 增加多组件配合使列表功能更丰富
|
||||
|
||||
### 开发进度
|
||||
|
||||
1. ~~调整为虚拟长列表模式~~
|
||||
2. ~~支持多组件搭配,使插件更灵活~~
|
||||
3. ~~新增组件 coolui-scroller-item(列表项组件)~~
|
||||
4. ~~新增组件 coolui-scroller-page(长列表分页组件)~~
|
||||
5. ~~新增组件 coolui-scroller-empty(空列表组件)~~
|
||||
6. ~~新增组件 coolui-scroller-handtip(手势提示组件)~~
|
||||
7. ~~新增组件 coolui-scroller-loadmore(加载更多组件)~~
|
||||
8. ~~新增组件 coolui-scroller-nav(分类导航组件)~~
|
||||
9. ~~新增组件 coolui-scroller-refresh(下拉刷新组件)~~
|
||||
10. ~~新增组件 coolui-scroller-parallax(下拉刷新视差位移组件)~~
|
||||
11. ~~新增组件 coolui-scroller-search(搜索组件)~~
|
||||
12. ~~新增组件 coolui-scroller-sort(分类筛选及排序组件)~~
|
||||
|
||||
### 支持 coolui-scroller
|
||||
|
||||
做一个组件库是一个繁琐且长期的事情,接下来我将花费业余时间进行多版本的完善。
|
||||
如果 coolui-scroller 对您的工作或者学习有所帮助,您可以捐赠 coolui-scroller 的研发工作,捐赠无门槛,哪怕是一瓶肥宅快乐水,也可以帮助我多敲半小时代码。
|
||||
|
||||
| 微信 | 支付宝 |
|
||||
| ------------------------------------------ | ------ |
|
||||
|  |  |
|
||||
|
||||
## 示例 demo
|
||||
|
||||
请微信扫码打开小程序查看
|
||||
|
||||

|
||||
|
||||
|
||||
示例代码: [https://github.com/wzs28150/coolui-scroller/tree/demo](https://github.com/wzs28150/coolui-scroller/tree/demo)
|
||||
|
||||
请 clone 下载到本地使用微信开发者工具查看
|
||||
|
||||
```
|
||||
git clone -b demo https://github.com/wzs28150/coolui-scroller.git
|
||||
```
|
||||
|
||||
## 安装
|
||||
|
||||
### npm 安装
|
||||
|
||||
```
|
||||
npm i coolui-scroller --production
|
||||
```
|
||||
|
||||
### npm 构建
|
||||
|
||||
安装之后开发者工具点击 npm 构建:<br/>
|
||||
<br/>
|
||||
当看到站点里面出现 miniprogram_npm 文件夹就算安装完成了<br/>
|
||||

|
||||
|
||||
## 引入
|
||||
|
||||
### 1.调用组件
|
||||
|
||||
在`app.json`或`index.json`中引入组件
|
||||
|
||||
```json
|
||||
"usingComponents": {
|
||||
"scroller": "coolui-scroller/scroller/index"
|
||||
}
|
||||
```
|
||||
|
||||
### 2.页面结构
|
||||
|
||||
```html
|
||||
<scroller class="my-scroller" > </scroller>
|
||||
```
|
||||
|
||||
### 3.配置
|
||||
|
||||
在 js 的 data 中进行配置参数设置,v3.0 版将功能细化到各个组件中具体配置详见([组件](https://wzs28150.github.io/coolui-scroller/v3/components/scroller.html))
|
||||
|
||||
### 4.组件
|
||||
|
||||
根据自己的业务场景选用组件,也可以在对应的插槽中自定义
|
19
components/coolui-scroller/empty/index.js
Normal file
@ -0,0 +1,19 @@
|
||||
Component({
|
||||
relations: {
|
||||
'../scroller/index': {
|
||||
type: 'parent',
|
||||
linked() {}
|
||||
}
|
||||
},
|
||||
externalClasses: ['img-class', 'text-class'],
|
||||
properties: {
|
||||
emptyImg: {
|
||||
type: String,
|
||||
value: ''
|
||||
},
|
||||
emptyText: {
|
||||
type: String,
|
||||
value: '暂无内容'
|
||||
}
|
||||
}
|
||||
})
|
4
components/coolui-scroller/empty/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
6
components/coolui-scroller/empty/index.wxml
Normal file
@ -0,0 +1,6 @@
|
||||
<view class="coolui-scroller-empty">
|
||||
<view class="coolui-scroller-empty-inner">
|
||||
<image src="{{emptyImg}}" mode="aspectFill" wx:if="{{emptyImg}}" class="empty-img img-class"></image>
|
||||
<view class="empty-text text-class">{{emptyText}}</view>
|
||||
</view>
|
||||
</view>
|
25
components/coolui-scroller/empty/index.wxss
Normal file
@ -0,0 +1,25 @@
|
||||
/* components/coolui-scroller-item/coolui-scroller-item.wxss */
|
||||
:host {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
.coolui-scroller-empty {
|
||||
height: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.empty-img{
|
||||
width: 30vw;
|
||||
height: 30vw;
|
||||
display: block;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.empty-text{
|
||||
text-align: center;
|
||||
font-size: 28rpx;
|
||||
color: #999;
|
||||
margin: 50rpx auto;
|
||||
}
|
BIN
components/coolui-scroller/handtip/icons/arrow_down.png
Normal file
After Width: | Height: | Size: 265 B |
BIN
components/coolui-scroller/handtip/icons/arrow_left.png
Normal file
After Width: | Height: | Size: 249 B |
BIN
components/coolui-scroller/handtip/icons/arrow_right.png
Normal file
After Width: | Height: | Size: 208 B |
BIN
components/coolui-scroller/handtip/icons/arrow_top.png
Normal file
After Width: | Height: | Size: 251 B |
BIN
components/coolui-scroller/handtip/icons/close.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
components/coolui-scroller/handtip/icons/tap.png
Normal file
After Width: | Height: | Size: 4.4 KiB |
BIN
components/coolui-scroller/handtip/icons/tap2.png
Normal file
After Width: | Height: | Size: 5.0 KiB |
BIN
components/coolui-scroller/handtip/icons/tap3.png
Normal file
After Width: | Height: | Size: 5.1 KiB |
55
components/coolui-scroller/handtip/index.js
Normal file
@ -0,0 +1,55 @@
|
||||
Component({
|
||||
properties: {
|
||||
top: {
|
||||
type: String,
|
||||
value: 0
|
||||
},
|
||||
bottom: {
|
||||
type: String,
|
||||
value: 0
|
||||
},
|
||||
left: {
|
||||
type: String,
|
||||
value: 0
|
||||
},
|
||||
right: {
|
||||
type: String,
|
||||
value: 0
|
||||
},
|
||||
key: {
|
||||
type: String,
|
||||
value: 'isTipShow'
|
||||
},
|
||||
opacity: {
|
||||
type: Number,
|
||||
value: 0.5
|
||||
}
|
||||
},
|
||||
data: {
|
||||
isTipShow: true
|
||||
},
|
||||
methods: {
|
||||
close: function () {
|
||||
try {
|
||||
wx.setStorageSync(this.data.key, 'true')
|
||||
this.setData({
|
||||
isTipShow: true
|
||||
})
|
||||
} catch (e) {
|
||||
|
||||
}
|
||||
}
|
||||
},
|
||||
ready() {
|
||||
try {
|
||||
var isKey = wx.getStorageSync(this.data.key)
|
||||
if (!isKey) {
|
||||
this.setData({
|
||||
isTipShow: false
|
||||
})
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(1);
|
||||
}
|
||||
}
|
||||
})
|
4
components/coolui-scroller/handtip/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
39
components/coolui-scroller/handtip/index.wxml
Normal file
@ -0,0 +1,39 @@
|
||||
<view class="hand" style="background-color: rgba(0, 0, 0, {{opacity}});" hidden="{{isTipShow}}" >
|
||||
<image src="./icons/close.png" mode="aspectFill" class="close" bindtap="close"></image>
|
||||
<view class="top" wx:if="{{top}}">
|
||||
<view>{{top}}</view>
|
||||
<view class="">
|
||||
<image src="./icons/tap3.png" mode="aspectFill" class="tap"></image>
|
||||
</view>
|
||||
<view class="arrow_down">
|
||||
<image src="./icons/arrow_down.png" mode="aspectFill" class="arrow"></image>
|
||||
</view>
|
||||
</view>
|
||||
<view class="bottom" wx:if="{{bottom}}">
|
||||
<view class="arrow_top">
|
||||
<image src="./icons/arrow_top.png" mode="aspectFill" class="arrow"></image>
|
||||
</view>
|
||||
<view class="">
|
||||
<image src="./icons/tap.png" mode="aspectFill" class="tap"></image>
|
||||
</view>
|
||||
<view>{{bottom}}</view>
|
||||
</view>
|
||||
<view class="left" wx:if="{{left}}">
|
||||
<view class="">
|
||||
<image src="./icons/arrow_right.png" mode="aspectFill" class="arrow"></image>
|
||||
</view>
|
||||
<view class="">
|
||||
<image src="./icons/tap.png" mode="aspectFill" class="tap"></image>
|
||||
</view>
|
||||
<view>{{left}}</view>
|
||||
</view>
|
||||
<view class="right" wx:if="{{right}}">
|
||||
<view>
|
||||
<image src="./icons/arrow_left.png" mode="aspectFill" class="arrow"></image>
|
||||
</view>
|
||||
<view>
|
||||
<image src="./icons/tap2.png" mode="aspectFill" class="tap"></image>
|
||||
</view>
|
||||
<view>{{right}}</view>
|
||||
</view>
|
||||
</view>
|
154
components/coolui-scroller/handtip/index.wxss
Normal file
@ -0,0 +1,154 @@
|
||||
.hand {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 90;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.hand .close {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 15px;
|
||||
width: 80rpx;
|
||||
height: 80rpx;
|
||||
}
|
||||
|
||||
.hand .tap {
|
||||
width: 90rpx;
|
||||
height: 131rpx;
|
||||
}
|
||||
|
||||
.hand .top {
|
||||
position: absolute;
|
||||
top: 15px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hand .top .arrow {
|
||||
width: 22rpx;
|
||||
height: 50rpx;
|
||||
transform: translateX(50rpx);
|
||||
}
|
||||
|
||||
.hand .top .tap {
|
||||
animation: movetop 3s infinite;
|
||||
}
|
||||
|
||||
.hand .bottom {
|
||||
position: absolute;
|
||||
bottom: 15px;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
color: #fff;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.hand .bottom .arrow {
|
||||
width: 22rpx;
|
||||
height: 50rpx;
|
||||
transform: translateX(-50rpx);
|
||||
}
|
||||
|
||||
.hand .bottom .tap {
|
||||
animation: movebottom 3s infinite;
|
||||
}
|
||||
|
||||
.hand .left {
|
||||
position: absolute;
|
||||
left: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #fff;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.hand .left .arrow {
|
||||
width: 50rpx;
|
||||
height: 22rpx;
|
||||
display: block;
|
||||
}
|
||||
|
||||
.hand .left .tap {
|
||||
animation: moveleft 3s infinite;
|
||||
}
|
||||
|
||||
.hand .right {
|
||||
position: absolute;
|
||||
right: 15px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
color: #fff;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.hand .right .arrow {
|
||||
width: 50rpx;
|
||||
height: 22rpx;
|
||||
}
|
||||
|
||||
.hand .right .tap {
|
||||
animation: moveright 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes moveleft {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(80rpx);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes moveright {
|
||||
0% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateX(-80rpx);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes movetop {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(80rpx);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes movebottom {
|
||||
0% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
50% {
|
||||
transform: translateY(-80rpx);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
53
components/coolui-scroller/index.js
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* coolui-scroller组件的api使用
|
||||
* 提供wx.createScrollContext进行管理功能
|
||||
*/
|
||||
function observePage(pageIndex, that) {
|
||||
wx.getSystemInfoAsync({
|
||||
success: (res) => {
|
||||
const { windowHeight } = res
|
||||
// this.windowHeight = windowHeight
|
||||
const observerObj = wx
|
||||
.createIntersectionObserver(that)
|
||||
.relativeToViewport({
|
||||
top: 2 * windowHeight,
|
||||
bottom: 2 * windowHeight,
|
||||
})
|
||||
observerObj.observe(`#wrp_${pageIndex}`, (res) => {
|
||||
if (res.intersectionRatio <= 0) {
|
||||
try {
|
||||
that.setData({
|
||||
['list[' + pageIndex + ']']: [
|
||||
{
|
||||
height: that.pageHeightArr[pageIndex],
|
||||
},
|
||||
],
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
that.setData({
|
||||
['list[' + pageIndex + ']']: that.wholeList[pageIndex],
|
||||
})
|
||||
} catch (error) {
|
||||
console.log(error)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
function setHeight(that) {
|
||||
const page = that.param.page
|
||||
this.query = wx.createSelectorQuery()
|
||||
this.query.select(`#wrp_${page}`).boundingClientRect()
|
||||
this.query.exec(function (res) {
|
||||
that.pageHeightArr[page] = res[0] && res[0].height
|
||||
})
|
||||
observePage(page, that)
|
||||
}
|
||||
|
||||
module.exports.setHeight = setHeight
|
33
components/coolui-scroller/item/index.js
Normal file
@ -0,0 +1,33 @@
|
||||
Component({
|
||||
relations: {
|
||||
"../scroller/index": {
|
||||
type: "parent",
|
||||
linked() {},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
ripple: {
|
||||
type: Boolean,
|
||||
value: false
|
||||
},
|
||||
},
|
||||
data: {
|
||||
rippleStyle: "",
|
||||
},
|
||||
methods: {
|
||||
itemTap(e) {
|
||||
if (this.data.ripple) {
|
||||
var x = e.changedTouches[0].pageX;
|
||||
var y = e.currentTarget.offsetTop;
|
||||
this.setData({
|
||||
rippleStyle: "left:" + x + "px;animation: ripple 0.5s linear;",
|
||||
});
|
||||
setTimeout((res) => {
|
||||
this.setData({
|
||||
rippleStyle: "",
|
||||
});
|
||||
}, 500);
|
||||
}
|
||||
},
|
||||
},
|
||||
});
|
4
components/coolui-scroller/item/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
4
components/coolui-scroller/item/index.wxml
Normal file
@ -0,0 +1,4 @@
|
||||
<view class="wx-coolui-scroller-item" bind:touchstart="itemTap">
|
||||
<slot></slot>
|
||||
<view class="ripple" style="{{rippleStyle}}"></view>
|
||||
</view>
|
25
components/coolui-scroller/item/index.wxss
Normal file
@ -0,0 +1,25 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
.wx-coolui-scroller-item {
|
||||
height: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ripple {
|
||||
background-color: rgba(0,0,0, 0.2);
|
||||
border-radius: 100%;
|
||||
height:10px;
|
||||
width:10px;
|
||||
position: absolute;
|
||||
transform: scale(0);
|
||||
top: 50%;
|
||||
}
|
||||
@keyframes ripple {
|
||||
100% {
|
||||
transform: scale(80);
|
||||
transform: scale(80);
|
||||
background-color: transparent;
|
||||
}
|
||||
}
|
49
components/coolui-scroller/loadmore/index.js
Normal file
@ -0,0 +1,49 @@
|
||||
Component({
|
||||
options: {
|
||||
addGlobalClass: true,
|
||||
},
|
||||
relations: {
|
||||
"../scroller/index": {
|
||||
type: "parent"
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
noMoreTextStyle: {
|
||||
type: String,
|
||||
value: "",
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
value: "more",
|
||||
},
|
||||
loading: {
|
||||
type: Object,
|
||||
value: {
|
||||
text: "\u52A0\u8F7D\u4E2D",
|
||||
color: "#999999"
|
||||
}
|
||||
},
|
||||
more: {
|
||||
type: Object,
|
||||
value: {
|
||||
text: "\u67E5\u770B\u66F4\u591A",
|
||||
color: "#333333"
|
||||
}
|
||||
},
|
||||
noMore: {
|
||||
type: Object,
|
||||
value: {
|
||||
text: "\u6CA1\u6709\u66F4\u591A",
|
||||
color: "#999999"
|
||||
},
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
value: "#999999",
|
||||
},
|
||||
shake: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
}
|
||||
});
|
4
components/coolui-scroller/loadmore/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
96
components/coolui-scroller/loadmore/index.scss
Normal file
@ -0,0 +1,96 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform : rotate(0deg);
|
||||
}
|
||||
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform : rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore {
|
||||
width : 100%;
|
||||
height : 100rpx;
|
||||
font-size : 28rpx;
|
||||
display : flex;
|
||||
justify-content: center;
|
||||
align-items : center;
|
||||
|
||||
.cool-indicator {
|
||||
display : -webkit-flex;
|
||||
display : -ms-flexbox;
|
||||
display : flex;
|
||||
line-height : 1;
|
||||
visibility : hidden;
|
||||
opacity : 0;
|
||||
-webkit-transition: all 0.3s cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
-o-transition : all 0.3s cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
transition : all 0.3s cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
|
||||
&.cool-indicator--isopened {
|
||||
opacity : 1;
|
||||
visibility: initial;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.cool-indicator__body,
|
||||
.cool-indicator__content {
|
||||
-webkit-flex : 0 0 auto;
|
||||
-ms-flex : 0 0 auto;
|
||||
flex : 0 0 auto;
|
||||
-webkit-box-flex: 0;
|
||||
}
|
||||
|
||||
.at-indicator__content {
|
||||
-webkit-align-self : center;
|
||||
-ms-flex-item-align: center;
|
||||
align-self : center;
|
||||
margin-left : 24rpx;
|
||||
color : #999;
|
||||
font-size : 28rpx;
|
||||
}
|
||||
|
||||
.cool-loading,
|
||||
.cool-loading__ring {
|
||||
display : inline-block;
|
||||
position: relative;
|
||||
width : 36rpx;
|
||||
height : 36rpx;
|
||||
}
|
||||
|
||||
.cool-loading__ring {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
position : absolute;
|
||||
margin : 2px;
|
||||
border-width : 2px;
|
||||
border-style : solid;
|
||||
border-color : #6190e8 transparent transparent;
|
||||
border-radius : 50%;
|
||||
-webkit-animation : loading 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
animation : loading 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
|
||||
&:nth-child(1) {
|
||||
-webkit-animation-delay: -.45s;
|
||||
animation-delay : -0.45s;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
-webkit-animation-delay: -.3s;
|
||||
animation-delay : -0.3s;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
-webkit-animation-delay: -.15s;
|
||||
animation-delay : -0.15s;
|
||||
}
|
||||
}
|
||||
}
|
16
components/coolui-scroller/loadmore/index.wxml
Normal file
@ -0,0 +1,16 @@
|
||||
<view class="coolui-scroller-loadmore">
|
||||
<block wx:if="{{status === 'more'}}" style="color: {{more.color}}">{{more.text}}</block>
|
||||
<block wx:elif="{{status === 'loading'}}">
|
||||
<view class="cool-indicator cool-indicator--isopened">
|
||||
<view class="cool-indicator__body">
|
||||
<view class="cool-loading">
|
||||
<view class="cool-loading__ring" style="border-color:{{loading.color}} transparent transparent;"></view>
|
||||
<view class="cool-loading__ring" style="border-color:{{loading.color}} transparent transparent;"></view>
|
||||
<view class="cool-loading__ring" style="border-color:{{loading.color}} transparent transparent;"></view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<text class="at-indicator__content" style="color: {{loading.color}}">{{loading.text}}</text>
|
||||
</block>
|
||||
<block wx:elif="{{status === 'noMore'}}" style="color: {{noMore.color}}">{{noMore.text}}</block>
|
||||
</view>
|
94
components/coolui-scroller/loadmore/index.wxss
Normal file
@ -0,0 +1,94 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
-webkit-transform: rotate(0deg);
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
to {
|
||||
-webkit-transform: rotate(360deg);
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore {
|
||||
width: 100%;
|
||||
height: 100rpx;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-indicator {
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
line-height: 1;
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
-webkit-transition: all 0.3s cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
-o-transition: all 0.3s cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
transition: all 0.3s cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-indicator.cool-indicator--isopened {
|
||||
opacity: 1;
|
||||
visibility: initial;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-indicator__body,
|
||||
.coolui-scroller-loadmore .cool-indicator__content {
|
||||
-webkit-flex: 0 0 auto;
|
||||
-ms-flex: 0 0 auto;
|
||||
flex: 0 0 auto;
|
||||
-webkit-box-flex: 0;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .at-indicator__content {
|
||||
-webkit-align-self: center;
|
||||
-ms-flex-item-align: center;
|
||||
align-self: center;
|
||||
margin-left: 24rpx;
|
||||
color: #999;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-loading,
|
||||
.coolui-scroller-loadmore .cool-loading__ring {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-loading__ring {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: absolute;
|
||||
margin: 2px;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-color: #6190e8 transparent transparent;
|
||||
border-radius: 50%;
|
||||
-webkit-animation: loading 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
animation: loading 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-loading__ring:nth-child(1) {
|
||||
-webkit-animation-delay: -.45s;
|
||||
animation-delay: -0.45s;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-loading__ring:nth-child(2) {
|
||||
-webkit-animation-delay: -.3s;
|
||||
animation-delay: -0.3s;
|
||||
}
|
||||
|
||||
.coolui-scroller-loadmore .cool-loading__ring:nth-child(3) {
|
||||
-webkit-animation-delay: -.15s;
|
||||
animation-delay: -0.15s;
|
||||
}
|
80
components/coolui-scroller/nav-bar/index.js
Normal file
@ -0,0 +1,80 @@
|
||||
// pages/second-floor/circle/index.js
|
||||
Component({
|
||||
externalClasses: ['nav-bar-class'],
|
||||
relations: {
|
||||
'../second-floor/index': {
|
||||
type: 'parent',
|
||||
linked(target) {
|
||||
this.setData({
|
||||
target,
|
||||
})
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
type: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
value: {
|
||||
back: {
|
||||
show: true,
|
||||
},
|
||||
background: {
|
||||
color: '#ffffff',
|
||||
},
|
||||
text: {
|
||||
color: '#000000',
|
||||
shadow: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
StatusBar: null,
|
||||
statusBarHeight: 0,
|
||||
Custom: null,
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
BackPage() {
|
||||
if (this.data.config.back.click) {
|
||||
this.data.config.back.click()
|
||||
} else {
|
||||
wx.navigateBack({
|
||||
delta: 1,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
ready() {
|
||||
const that = this
|
||||
wx.getSystemInfoAsync({
|
||||
success: (e) => {
|
||||
that.setData({
|
||||
StatusBar: e.statusBarHeight,
|
||||
})
|
||||
let capsule = wx.getMenuButtonBoundingClientRect()
|
||||
if (capsule) {
|
||||
that.setData({
|
||||
Custom: capsule,
|
||||
statusBarHeight: capsule.bottom + capsule.top - e.statusBarHeight,
|
||||
})
|
||||
} else {
|
||||
that.setData({
|
||||
statusBarHeight: e.statusBarHeight + 50,
|
||||
})
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
})
|
4
components/coolui-scroller/nav-bar/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
43
components/coolui-scroller/nav-bar/index.scss
Normal file
@ -0,0 +1,43 @@
|
||||
.nav-bar {
|
||||
position: relative;
|
||||
|
||||
.nav-bar-inner {
|
||||
display : flex;
|
||||
align-items: center;
|
||||
box-sizing : border-box;
|
||||
position : relative;
|
||||
}
|
||||
|
||||
.action {
|
||||
position : absolute;
|
||||
width : 40rpx;
|
||||
height : 40rpx;
|
||||
margin-left: 24rpx;
|
||||
|
||||
|
||||
.line {
|
||||
width : 24rpx;
|
||||
height : 4rpx;
|
||||
background-color : #fff;
|
||||
position : absolute;
|
||||
left : 50%;
|
||||
top : 50%;
|
||||
transform-origin : 0 center;
|
||||
// border-radius : 0 50px 50px 0;
|
||||
margin-top : 0rpx;
|
||||
transform : translate(-40%, -50%) rotate(45deg);
|
||||
|
||||
&+.line {
|
||||
margin-top: 0.5rpx;
|
||||
transform : translate(-40%, -50%) rotate(-45deg);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.content {
|
||||
text-align: center;
|
||||
width : 100%;
|
||||
font-size : 34rpx;
|
||||
}
|
||||
}
|
18
components/coolui-scroller/nav-bar/index.wxml
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- pages/second-floor/circle/index.wxml -->
|
||||
<!-- <text>{{p}}</text> -->
|
||||
<view class="nav-bar" style="height:{{statusBarHeight}}px;background-color:{{config.background.color}}">
|
||||
<view class="nav-bar-inner" style="height:{{statusBarHeight}}px;padding-top:{{StatusBar}}px;{{config.background.img?'background-image:url(' + config.background.img+')':''}}">
|
||||
<block wx:if="{{type === 'default'}}">
|
||||
<view class="action" bindtap="BackPage" wx:if="{{config.back}}">
|
||||
<view class="line" style="background-color:{{config.text.color}}"></view>
|
||||
<view class="line" style="background-color:{{config.text.color}}"></view>
|
||||
</view>
|
||||
<view class="content" style="top:{{StatusBar}}px; color: {{config.text.color}}">
|
||||
<slot />
|
||||
</view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<slot />
|
||||
</block>
|
||||
</view>
|
||||
</view>
|
40
components/coolui-scroller/nav-bar/index.wxss
Normal file
@ -0,0 +1,40 @@
|
||||
.nav-bar {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-bar .nav-bar-inner {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.nav-bar .action {
|
||||
position: absolute;
|
||||
width: 40rpx;
|
||||
height: 40rpx;
|
||||
margin-left: 24rpx;
|
||||
}
|
||||
|
||||
.nav-bar .action .line {
|
||||
width: 24rpx;
|
||||
height: 4rpx;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform-origin: 0 center;
|
||||
margin-top: 0rpx;
|
||||
transform: translate(-40%, -50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.nav-bar .action .line + .line {
|
||||
margin-top: 0.5rpx;
|
||||
transform: translate(-40%, -50%) rotate(-45deg);
|
||||
}
|
||||
|
||||
.nav-bar .content {
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-size: 34rpx;
|
||||
}
|
78
components/coolui-scroller/nav-pannel/index.js
Normal file
@ -0,0 +1,78 @@
|
||||
// miniprogram_npm/coolui-scroller/nav-pannel/index.js
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true,
|
||||
},
|
||||
relations: {
|
||||
'../scroller/index': {
|
||||
type: 'child',
|
||||
linked: function (target) {
|
||||
// console.log(target)
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
active: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
animation: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
value: 'side',
|
||||
},
|
||||
},
|
||||
observers: {
|
||||
active: function (val) {
|
||||
// console.log(val)
|
||||
// this.scrollNodes =
|
||||
// this.scrollNodes ?? this.getRelationNodes('../scroller/index')
|
||||
// if (this.scrollNodes[val]) {
|
||||
// console.log(this.scrollNodes[val])
|
||||
// }
|
||||
},
|
||||
},
|
||||
data: {
|
||||
width: 0,
|
||||
height: 0,
|
||||
scrollerLength: 0,
|
||||
},
|
||||
lifetimes: {
|
||||
attached: function () {
|
||||
// 计算宽高
|
||||
let that = this
|
||||
wx.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.wx-coolui-nav-pannel')
|
||||
.boundingClientRect()
|
||||
.exec(function (res) {
|
||||
if (res.length > 0 && res[0]) {
|
||||
that.setData({
|
||||
width: res[0].width,
|
||||
height: res[0].height,
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
detached: function () {
|
||||
// 在组件实例被从页面节点树移除时执行
|
||||
},
|
||||
},
|
||||
ready() {
|
||||
this.init()
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
// 计算子元素个数
|
||||
let that = this
|
||||
this.scrollNodes = this.getRelationNodes('../scroller/index')
|
||||
that.setData({
|
||||
scrollerLength: that.scrollNodes.length,
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
4
components/coolui-scroller/nav-pannel/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
48
components/coolui-scroller/nav-pannel/index.scss
Normal file
@ -0,0 +1,48 @@
|
||||
:host {
|
||||
display: block;
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
}
|
||||
|
||||
$active: var(--active);
|
||||
|
||||
.wx-coolui-nav-pannel {
|
||||
height : 100%;
|
||||
overflow: hidden;
|
||||
|
||||
// flex : 1;
|
||||
&-inner {
|
||||
height: 100%;
|
||||
|
||||
&.side {
|
||||
display : flex;
|
||||
transform: translateX(var(--left));
|
||||
|
||||
|
||||
scroller {
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.fade {
|
||||
position: relative;
|
||||
|
||||
scroller {
|
||||
position: absolute;
|
||||
width : 100%;
|
||||
height : 100%;
|
||||
left : 0;
|
||||
top : 0;
|
||||
z-index : 0;
|
||||
|
||||
&:first-child {
|
||||
position: relative;
|
||||
z-index : 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
5
components/coolui-scroller/nav-pannel/index.wxml
Normal file
@ -0,0 +1,5 @@
|
||||
<view class="wx-coolui-nav-pannel">
|
||||
<view class="wx-coolui-nav-pannel-inner {{type}}" style="width:{{type === 'side' ? width * scrollerLength : width}}px;--left:{{-width * active}}px; {{animation?'transition: transform 0.4s;':''}}--active:{{active}}">
|
||||
<slot />
|
||||
</view>
|
||||
</view>
|
41
components/coolui-scroller/nav-pannel/index.wxss
Normal file
@ -0,0 +1,41 @@
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wx-coolui-nav-pannel {
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wx-coolui-nav-pannel-inner {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.wx-coolui-nav-pannel-inner.side {
|
||||
display: flex;
|
||||
transform: translateX(var(--left));
|
||||
}
|
||||
|
||||
.wx-coolui-nav-pannel-inner.side scroller {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.wx-coolui-nav-pannel-inner.fade {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wx-coolui-nav-pannel-inner.fade scroller {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.wx-coolui-nav-pannel-inner.fade scroller:first-child {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
116
components/coolui-scroller/nav/index.js
Normal file
@ -0,0 +1,116 @@
|
||||
Component({
|
||||
relations: {
|
||||
'../scroller/index': {
|
||||
type: 'parent',
|
||||
linked() {},
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 组件的属性列表
|
||||
*/
|
||||
properties: {
|
||||
list: Array,
|
||||
border: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
text: {
|
||||
type: Object,
|
||||
value: {
|
||||
color: '#333333',
|
||||
activeColor: '#d13435',
|
||||
},
|
||||
},
|
||||
background: {
|
||||
type: Object,
|
||||
value: {
|
||||
color: '#333333',
|
||||
activeColor: '#d13435',
|
||||
},
|
||||
},
|
||||
navPerView: {
|
||||
type: [Number, String],
|
||||
value: 4.5,
|
||||
observer: function (newVal) {
|
||||
this._changeNavPerView(newVal)
|
||||
},
|
||||
},
|
||||
spaceBetween: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
value: 'line', //可选 line,round,plain
|
||||
},
|
||||
active: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
observer: function (newVal) {
|
||||
this.setData({
|
||||
toView: 'item' + (newVal - 1),
|
||||
})
|
||||
// console.log(this);
|
||||
this._change(newVal)
|
||||
},
|
||||
},
|
||||
},
|
||||
data: {
|
||||
toView: 'item0',
|
||||
navWidth: 0,
|
||||
scroll: false,
|
||||
index: 0,
|
||||
},
|
||||
lifetimes: {
|
||||
attached: function () {
|
||||
// 在组件实例进入页面节点树时执行
|
||||
let that = this
|
||||
that._changeNavPerView(that.data.navPerView)
|
||||
},
|
||||
detached: function () {
|
||||
// 在组件实例被从页面节点树移除时执行
|
||||
},
|
||||
},
|
||||
pageLifetimes: {
|
||||
// 组件所在页面的生命周期函数
|
||||
show: function () {},
|
||||
hide: function () {},
|
||||
resize: function () {},
|
||||
},
|
||||
methods: {
|
||||
_changeNav(e) {
|
||||
this.setData({
|
||||
active: e.currentTarget.dataset.index,
|
||||
})
|
||||
},
|
||||
_change(index) {
|
||||
this.triggerEvent('change', {
|
||||
id: this.data.list[index].id,
|
||||
})
|
||||
},
|
||||
_catchTouchMove() {
|
||||
return false
|
||||
},
|
||||
_changeNavPerView(navPerView) {
|
||||
let that = this
|
||||
wx.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.wx-coolui-nav')
|
||||
.boundingClientRect()
|
||||
.exec(function (res) {
|
||||
// console.log(res)
|
||||
if (res.length > 0 && res[0]) {
|
||||
// console.log(that.data.navPerView)
|
||||
that.setData({
|
||||
navWidth:
|
||||
navPerView === 'auto'
|
||||
? 'auto'
|
||||
: (res[0].width - that.data.spaceBetween * (navPerView - 1)) /
|
||||
navPerView +
|
||||
'px',
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
4
components/coolui-scroller/nav/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
112
components/coolui-scroller/nav/index.scss
Normal file
@ -0,0 +1,112 @@
|
||||
.wx-coolui-nav {
|
||||
border-bottom: 1px solid transparent;
|
||||
height : 83rpx;
|
||||
|
||||
&.border {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.nav-inner {
|
||||
white-space: nowrap;
|
||||
|
||||
.item {
|
||||
display : inline-block;
|
||||
text-align : center;
|
||||
height : 84rpx;
|
||||
font-size : 0;
|
||||
line-height: 0;
|
||||
color : #333;
|
||||
transition : color 0.4s;
|
||||
|
||||
.text {
|
||||
position : relative;
|
||||
display : inline-block;
|
||||
line-height: 84rpx;
|
||||
font-size : 28rpx;
|
||||
width : 100%;
|
||||
|
||||
&>view:first-child {
|
||||
position : relative;
|
||||
z-index : 1;
|
||||
overflow : hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space : nowrap;
|
||||
}
|
||||
}
|
||||
|
||||
&.round {
|
||||
.text {
|
||||
padding: 0 20px;
|
||||
width : calc(100% - 40px);
|
||||
}
|
||||
|
||||
.line {
|
||||
display : block;
|
||||
position : absolute;
|
||||
left : 50%;
|
||||
transform : translateX(-50%) translateY(50%);
|
||||
bottom : 50%;
|
||||
width : 100%;
|
||||
height : 60%;
|
||||
background-color: #ccc;
|
||||
transition : width 0.4s;
|
||||
border-radius : 50px;
|
||||
z-index : 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.plain {
|
||||
.text {
|
||||
padding: 0 20px;
|
||||
width : calc(100% - 40px);
|
||||
}
|
||||
|
||||
.line {
|
||||
display : block;
|
||||
position : absolute;
|
||||
left : 50%;
|
||||
transform : translateX(-50%) translateY(50%);
|
||||
bottom : 50%;
|
||||
width : calc(100% - 2px);
|
||||
height : 60%;
|
||||
background-color: transparent !important;
|
||||
border : 1px solid #ccc;
|
||||
transition : width 0.4s;
|
||||
border-radius : 50px;
|
||||
z-index : 0;
|
||||
}
|
||||
}
|
||||
|
||||
&.line {
|
||||
.text {
|
||||
.line {
|
||||
display : block;
|
||||
position : absolute;
|
||||
left : 50%;
|
||||
transform : translateX(-50%);
|
||||
bottom : 0;
|
||||
width : 0;
|
||||
height : 4rpx;
|
||||
background-color: transparent;
|
||||
transition : width 0.4s;
|
||||
}
|
||||
}
|
||||
|
||||
&.on {
|
||||
color: #0cba70;
|
||||
|
||||
.text {
|
||||
.line {
|
||||
|
||||
width : 100%;
|
||||
// transition: width 0.4s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
10
components/coolui-scroller/nav/index.wxml
Normal file
@ -0,0 +1,10 @@
|
||||
<view class="wx-coolui-nav {{border ? 'border' : ''}}">
|
||||
<scroll-view scroll-x scroll-with-animation enhanced show-scrollbar="{{false}}" scroll-animation-duration="{{500}}" scroll-into-view="{{toView}}" class="nav-inner">
|
||||
<view class="item {{type}} {{active == index?'on':'' }}" style="width: {{navWidth}}; margin-right: {{index == list.length - 1 ? 0 : spaceBetween}}px; {{active == index?'color:'+text.activeColor:'color:' + text.color}}" id="item{{index}}" wx:for="{{list}}" data-index="{{index}}" bind:tap="_changeNav" wx:key="id" catchtouchmove='_catchTouchMove'>
|
||||
<view class="text">
|
||||
<view>{{item.title}}</view>
|
||||
<view class="line" style="{{active == index?'background-color:'+background.activeColor:'background-color:' + (type === 'line' ?'transparent' : background.color)}};{{type === 'plain' ? (active == index ? ('border-color:' + background.activeColor): ('border-color:' + background.color)): ''}}"></view>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
</view>
|
97
components/coolui-scroller/nav/index.wxss
Normal file
@ -0,0 +1,97 @@
|
||||
.wx-coolui-nav {
|
||||
border-bottom: 1px solid transparent;
|
||||
height: 83rpx;
|
||||
}
|
||||
|
||||
.wx-coolui-nav.border {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item {
|
||||
display: inline-block;
|
||||
text-align: center;
|
||||
height: 84rpx;
|
||||
font-size: 0;
|
||||
line-height: 0;
|
||||
color: #333;
|
||||
transition: color 0.4s;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item .text {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
line-height: 84rpx;
|
||||
font-size: 28rpx;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item .text > view:first-child {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item.round .text {
|
||||
padding: 0 20px;
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item.round .line {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(50%);
|
||||
bottom: 50%;
|
||||
width: 100%;
|
||||
height: 60%;
|
||||
background-color: #ccc;
|
||||
transition: width 0.4s;
|
||||
border-radius: 50px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item.plain .text {
|
||||
padding: 0 20px;
|
||||
width: calc(100% - 40px);
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item.plain .line {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(50%);
|
||||
bottom: 50%;
|
||||
width: calc(100% - 2px);
|
||||
height: 60%;
|
||||
background-color: transparent !important;
|
||||
border: 1px solid #ccc;
|
||||
transition: width 0.4s;
|
||||
border-radius: 50px;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item.line .text .line {
|
||||
display: block;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 0;
|
||||
width: 0;
|
||||
height: 4rpx;
|
||||
background-color: transparent;
|
||||
transition: width 0.4s;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item.line.on {
|
||||
color: #0cba70;
|
||||
}
|
||||
|
||||
.wx-coolui-nav .nav-inner .item.line.on .text .line {
|
||||
width: 100%;
|
||||
}
|
31
components/coolui-scroller/package.json
Normal file
@ -0,0 +1,31 @@
|
||||
{
|
||||
"name": "coolui-scroller",
|
||||
"version": "3.3.2",
|
||||
"description": "微信小程序Scroll 上拉加载下拉刷新组件 ",
|
||||
"main": "./index.js",
|
||||
"scripts": {
|
||||
"push": "npm publish",
|
||||
"build-doc": "cd ../doc && pnpm docs:build",
|
||||
"prepublish": "pnpm build-doc"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git@github.com:wzs28150/coolui-scroller.git"
|
||||
},
|
||||
"publishConfig": {
|
||||
"@wzs28150:registry": "https://npm.pkg.github.com"
|
||||
},
|
||||
"keywords": [
|
||||
"weapp",
|
||||
"scroller",
|
||||
"pull-to-refresh",
|
||||
"push-to-loadmore"
|
||||
],
|
||||
"miniprogram": "./",
|
||||
"author": "wzs",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/wzs28150/coolui-scroller/issues"
|
||||
},
|
||||
"homepage": "https://github.com/wzs28150/coolui-scroller#readme"
|
||||
}
|
32
components/coolui-scroller/parallax/index.js
Normal file
@ -0,0 +1,32 @@
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true
|
||||
},
|
||||
externalClasses: ['parallax-class'],
|
||||
relations: {
|
||||
'../refresh/index': {
|
||||
type: 'parent',
|
||||
linked(target) {
|
||||
this.setData({
|
||||
...target.data
|
||||
})
|
||||
}
|
||||
}
|
||||
},
|
||||
properties: {
|
||||
parallax: {
|
||||
type: Number,
|
||||
value: 0
|
||||
},
|
||||
direction: {
|
||||
type: String,
|
||||
value: 'to bottom'
|
||||
}
|
||||
},
|
||||
data: {
|
||||
threshold: 0,
|
||||
triggered: true,
|
||||
config: {}
|
||||
}
|
||||
})
|
4
components/coolui-scroller/parallax/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
5
components/coolui-scroller/parallax/index.scss
Normal file
@ -0,0 +1,5 @@
|
||||
.wx-coolui-scroller-parallax {
|
||||
position : absolute;
|
||||
transform : translate3d(0, 0, 0);
|
||||
transition: all 0.01s;
|
||||
}
|
20
components/coolui-scroller/parallax/index.wxml
Normal file
@ -0,0 +1,20 @@
|
||||
<block wx:if="{{direction == 'to top'}}">
|
||||
<view class="wx-coolui-scroller-parallax parallax-class" style="transform: translate3d(0, {{-(parallax * threshold * config.height / 100)}}px, 0); ">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:if="{{direction == 'to bottom'}}">
|
||||
<view class="wx-coolui-scroller-parallax parallax-class" style="transform: translate3d(0, {{(parallax * threshold * config.height / 100)}}px, 0);">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:if="{{direction == 'to left'}}">
|
||||
<view class="wx-coolui-scroller-parallax parallax-class" style="transform: translate3d({{-(parallax * threshold * config.height / 100)}}px, 0, 0);">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</block>
|
||||
<block wx:if="{{direction == 'to right'}}">
|
||||
<view class="wx-coolui-scroller-parallax parallax-class" style="transform: translate3d({{(parallax * threshold * config.height / 100)}}px, 0, 0); ">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</block>
|
5
components/coolui-scroller/parallax/index.wxss
Normal file
@ -0,0 +1,5 @@
|
||||
.wx-coolui-scroller-parallax {
|
||||
position: absolute;
|
||||
transform: translate3d(0, 0, 0);
|
||||
transition: all 0.01s;
|
||||
}
|
110
components/coolui-scroller/refresh/index.js
Normal file
@ -0,0 +1,110 @@
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true,
|
||||
},
|
||||
externalClasses: ['refresh-class'],
|
||||
relations: {
|
||||
'../scroller/index': {
|
||||
type: 'parent',
|
||||
linked(target) {},
|
||||
},
|
||||
'../parallax/index': {
|
||||
type: 'child',
|
||||
linked(target) {
|
||||
// console.log(target);
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
type: {
|
||||
type: String,
|
||||
value: 'default',
|
||||
},
|
||||
threshold: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
isloading: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
refreshstate: {
|
||||
type: String,
|
||||
value: 'pulldown', // pulldown loosen loading
|
||||
},
|
||||
config: {
|
||||
type: Object,
|
||||
value: {
|
||||
shake: false,
|
||||
height: 50,
|
||||
isAutoTriggered: true,
|
||||
text: {
|
||||
color: '#000000', // 文字颜色
|
||||
shadow: 0, // 是否开启shadow阴影,0为不开启,数值越大阴影范围越大
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
data: {
|
||||
triggered: false,
|
||||
textWidth: null,
|
||||
scrollOption: {},
|
||||
},
|
||||
ready() {
|
||||
this.parallaxNodes = this.getRelationNodes('../parallax/index')
|
||||
let that = this
|
||||
wx.createSelectorQuery()
|
||||
.in(this)
|
||||
.select('.has-bg')
|
||||
.boundingClientRect()
|
||||
.exec(function (res) {
|
||||
if (res.length > 0 && res[0]) {
|
||||
that.setData({
|
||||
textWidth: res[0].width,
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
changeThreshold({ threshold }) {
|
||||
const that = this
|
||||
return new Promise((resolve) => {
|
||||
let refreshstate = 'pulldown'
|
||||
if (that.data.triggered && !that.data.isloading) {
|
||||
refreshstate = 'loosen'
|
||||
}
|
||||
that.setData(
|
||||
{
|
||||
threshold: threshold,
|
||||
refreshstate: refreshstate,
|
||||
},
|
||||
() => {
|
||||
resolve()
|
||||
if (that.parallaxNodes.length > 0) {
|
||||
that.parallaxNodes.forEach((elem, index) => {
|
||||
elem.setData({
|
||||
threshold: threshold,
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
setLoading({ isloading }) {
|
||||
const that = this
|
||||
return new Promise((resolve) => {
|
||||
that.setData(
|
||||
{
|
||||
isloading: isloading,
|
||||
refreshstate: isloading ? 'loading' : 'pulldown',
|
||||
},
|
||||
() => {
|
||||
resolve()
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
4
components/coolui-scroller/refresh/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
148
components/coolui-scroller/refresh/index.scss
Normal file
@ -0,0 +1,148 @@
|
||||
.wx-coolui-scroller-refresh {
|
||||
width : 100%;
|
||||
background-size : cover;
|
||||
background-position: center bottom;
|
||||
background-repeat : no-repeat;
|
||||
position : relative;
|
||||
overflow : hidden;
|
||||
|
||||
.refresh-inner {
|
||||
position : absolute;
|
||||
text-align : center;
|
||||
width : 100%;
|
||||
font-size : 28rpx;
|
||||
display : flex;
|
||||
justify-content: center;
|
||||
align-items : center;
|
||||
|
||||
|
||||
.down {
|
||||
width : 12px;
|
||||
height : 12px;
|
||||
margin-right : 20rpx;
|
||||
// background-color: #000;
|
||||
position : relative;
|
||||
|
||||
.line {
|
||||
&:nth-child(1) {
|
||||
display : block;
|
||||
width : 2px;
|
||||
height : 18px;
|
||||
background-color: #000;
|
||||
position : absolute;
|
||||
top : 50%;
|
||||
left : 50%;
|
||||
transform : translate(-50%, -50%);
|
||||
border-radius : 2px;
|
||||
opacity : 1;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width : 8px;
|
||||
height : 2px;
|
||||
background-color: #000;
|
||||
display : block;
|
||||
position : absolute;
|
||||
bottom : -3px;
|
||||
left : 50%;
|
||||
transform : rotate(-45deg);
|
||||
transform-origin: 0 50%;
|
||||
border-radius : 2px;
|
||||
opacity : 1;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width : 8px;
|
||||
height : 2px;
|
||||
background-color: #000;
|
||||
display : block;
|
||||
position : absolute;
|
||||
bottom : -3px;
|
||||
right : 50%;
|
||||
transform : rotate(45deg);
|
||||
transform-origin: 100% 50%;
|
||||
border-radius : 2px;
|
||||
opacity : 1;
|
||||
}
|
||||
}
|
||||
|
||||
&.loading {
|
||||
display : inline-block;
|
||||
position: relative;
|
||||
width : 36rpx;
|
||||
height : 36rpx;
|
||||
|
||||
.line {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing : border-box;
|
||||
display : block;
|
||||
position : absolute;
|
||||
margin : -18rpx 2px 2px -18rpx;
|
||||
border-width : 2px;
|
||||
border-style : solid;
|
||||
border-color : #6190e8 transparent transparent;
|
||||
border-radius : 50%;
|
||||
-webkit-animation : circle 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
animation : circle 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
width : 36rpx;
|
||||
height : 36rpx;
|
||||
left : 50%;
|
||||
top : 50%;
|
||||
transform-origin : 50% 50%;
|
||||
background-color : transparent;
|
||||
transform : translate(-50%, -50%);
|
||||
|
||||
&:nth-child(1) {
|
||||
-webkit-animation-delay: -.45s;
|
||||
animation-delay : -0.45s;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
-webkit-animation-delay: -.3s;
|
||||
animation-delay : -0.3s;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
-webkit-animation-delay: -.15s;
|
||||
animation-delay : -0.15s;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.has-bg {
|
||||
font-weight : bold;
|
||||
background-clip : text;
|
||||
-webkit-background-clip : text;
|
||||
color : transparent !important;
|
||||
background-size : 100% auto;
|
||||
// transition : all .4s;
|
||||
background-position : -100% -100%;
|
||||
background-repeat : no-repeat;
|
||||
|
||||
&.loading {
|
||||
animation: play 0.5s line infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes circle {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes play {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
to {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
19
components/coolui-scroller/refresh/index.wxml
Normal file
@ -0,0 +1,19 @@
|
||||
<view class="wx-coolui-scroller-refresh refresh-class" style="height:{{config.height}}px;{{config.background.img?'background-image:url('+config.background.img+');':''}}padding-top:{{config.background.height? config.background.height - config.height : 0}}px;">
|
||||
<view class="refresh-inner" wx:if="{{type == 'base'}}" style="height:{{config.height}}px;color:{{config.text.color}};{{config.text.shadow?'text-shadow:0 0 '+config.text.shadow+'rpx '+config.text.color+' outset;':''}}">
|
||||
<view class="down {{triggered && isloading?'loading':''}}" style="transform: rotate({{threshold*180}}deg);">
|
||||
<view class="line" style="border-color:{{config.text.color}} transparent transparent;{{triggered && isloading?'background-color:transparent':'background-color:' + config.text.color}}"></view>
|
||||
<view class="line" style="border-color:{{config.text.color}} transparent transparent;{{triggered && isloading?'background-color:transparent':'background-color:' + config.text.color}}"></view>
|
||||
<view class="line" style="border-color:{{config.text.color}} transparent transparent;{{triggered && isloading?'background-color:transparent':'background-color:' + config.text.color}}"></view>
|
||||
</view>
|
||||
<block wx:if="{{refreshstate == 'pulldown'}}">下拉刷新</block>
|
||||
<block wx:elif="{{refreshstate == 'loosen'}}">松手刷新</block>
|
||||
<block wx:elif="{{refreshstate == 'loading'}}">刷新中...</block>
|
||||
</view>
|
||||
<view class="refresh-inner" wx:if="{{type == 'logoText'}}">
|
||||
<text class="{{config.text.img ? 'has-bg' : ''}} {{triggered && isloading?'loading':''}}" style="font-size: {{config.text.size}}rpx; line-height: {{config.text.size}}rpx; color: {{config.text.color}}; background-image: url('{{config.text.img}}');background-position: {{( -textWidth + threshold*textWidth)}}px center;{{config.text.shadow?'text-shadow:0 0 '+config.text.shadow+'rpx '+config.text.color+' outset;':''}} {{config.text.font?('font-family:' + config.text.font): ''}}">
|
||||
{{config.text.content}}
|
||||
</text>
|
||||
</view>
|
||||
<slot name="parallax" />
|
||||
<slot />
|
||||
</view>
|
141
components/coolui-scroller/refresh/index.wxss
Normal file
@ -0,0 +1,141 @@
|
||||
.wx-coolui-scroller-refresh {
|
||||
width: 100%;
|
||||
background-size: cover;
|
||||
background-position: center bottom;
|
||||
background-repeat: no-repeat;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner {
|
||||
position: absolute;
|
||||
text-align: center;
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
margin-right: 20rpx;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down .line:nth-child(1) {
|
||||
display: block;
|
||||
width: 2px;
|
||||
height: 18px;
|
||||
background-color: #000;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 2px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down .line:nth-child(2) {
|
||||
width: 8px;
|
||||
height: 2px;
|
||||
background-color: #000;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 50%;
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: 0 50%;
|
||||
border-radius: 2px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down .line:nth-child(3) {
|
||||
width: 8px;
|
||||
height: 2px;
|
||||
background-color: #000;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
right: 50%;
|
||||
transform: rotate(45deg);
|
||||
transform-origin: 100% 50%;
|
||||
border-radius: 2px;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down.loading {
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down.loading .line {
|
||||
-webkit-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
display: block;
|
||||
position: absolute;
|
||||
margin: -18rpx 2px 2px -18rpx;
|
||||
border-width: 2px;
|
||||
border-style: solid;
|
||||
border-color: #6190e8 transparent transparent;
|
||||
border-radius: 50%;
|
||||
-webkit-animation: circle 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
animation: circle 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
||||
width: 36rpx;
|
||||
height: 36rpx;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform-origin: 50% 50%;
|
||||
background-color: transparent;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down.loading .line:nth-child(1) {
|
||||
-webkit-animation-delay: -.45s;
|
||||
animation-delay: -0.45s;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down.loading .line:nth-child(2) {
|
||||
-webkit-animation-delay: -.3s;
|
||||
animation-delay: -0.3s;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .down.loading .line:nth-child(3) {
|
||||
-webkit-animation-delay: -.15s;
|
||||
animation-delay: -0.15s;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .has-bg {
|
||||
font-weight: bold;
|
||||
background-clip: text;
|
||||
-webkit-background-clip: text;
|
||||
color: transparent !important;
|
||||
background-size: 100% auto;
|
||||
background-position: -100% -100%;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-refresh .refresh-inner .has-bg.loading {
|
||||
animation: play 0.5s line infinite;
|
||||
}
|
||||
|
||||
@keyframes circle {
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes play {
|
||||
from {
|
||||
opacity: 1;
|
||||
}
|
||||
to {
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
18
components/coolui-scroller/scroll-page/index.js
Normal file
@ -0,0 +1,18 @@
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true
|
||||
},
|
||||
relations: {
|
||||
'../scroller/index': {
|
||||
type: 'parent',
|
||||
linked() {}
|
||||
}
|
||||
},
|
||||
properties: {
|
||||
pageList: {
|
||||
type: Array,
|
||||
value: []
|
||||
}
|
||||
}
|
||||
})
|
4
components/coolui-scroller/scroll-page/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
6
components/coolui-scroller/scroll-page/index.wxml
Normal file
@ -0,0 +1,6 @@
|
||||
<view class="coolui-scroller-page">
|
||||
<view wx:if="{{ pageList.length == 1 && pageList[0].height }}" style="height: {{ pageList[0].height}}px"></view>
|
||||
<block wx:else>
|
||||
<slot></slot>
|
||||
</block>
|
||||
</view>
|
6
components/coolui-scroller/scroll-page/index.wxss
Normal file
@ -0,0 +1,6 @@
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
.wx-coolui-scroller-item {
|
||||
height: 100%;
|
||||
}
|
293
components/coolui-scroller/scroller/index.js
Normal file
@ -0,0 +1,293 @@
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true,
|
||||
},
|
||||
relations: {
|
||||
'../scroll-page/index': {
|
||||
type: 'child',
|
||||
linked: function (target) {},
|
||||
},
|
||||
'../nav/index': {
|
||||
type: 'child',
|
||||
linked: function (target) {},
|
||||
},
|
||||
'../empty/index': {
|
||||
type: 'child',
|
||||
linked: function (target) {},
|
||||
},
|
||||
'../refresh/index': {
|
||||
type: 'child',
|
||||
linked: function (target) {
|
||||
this.setData({
|
||||
type: target.data.type,
|
||||
refreshConfig: target.data.config,
|
||||
})
|
||||
},
|
||||
},
|
||||
'../nav-pannel/index': {
|
||||
type: 'parent',
|
||||
linked: function (target) {
|
||||
// console.log(target)
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
isEmpty: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
background: {
|
||||
type: String,
|
||||
value: '#f2f2f2',
|
||||
},
|
||||
isBackBtn: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
enableFlex: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
toView: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
top: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
animation: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
active: false,
|
||||
contentHeight: 0,
|
||||
triggered: false,
|
||||
isLoading: false,
|
||||
timeout: null,
|
||||
isBackToTopShow: false,
|
||||
threshold: 0,
|
||||
refreshConfig: {
|
||||
shake: false,
|
||||
height: 50,
|
||||
style: 'black',
|
||||
},
|
||||
},
|
||||
ready() {
|
||||
this.setWapHeight()
|
||||
this.refreshNodes = this.getRelationNodes('../refresh/index')
|
||||
this.refreshNode = this.refreshNodes[0] ? this.refreshNodes[0] : null
|
||||
},
|
||||
methods: {
|
||||
setWapHeight() {
|
||||
const that = this
|
||||
const query = that.createSelectorQuery().in(this)
|
||||
query
|
||||
.select('#content')
|
||||
.boundingClientRect(function (res) {
|
||||
if (res) {
|
||||
that.setData({
|
||||
contentHeight: res.height,
|
||||
})
|
||||
|
||||
that.triggerEvent('contentHeight', res.height)
|
||||
}
|
||||
})
|
||||
.select('#header')
|
||||
.boundingClientRect(function (headerRes) {
|
||||
if (headerRes) {
|
||||
that.setData({
|
||||
contentHeight: that.data.contentHeight - headerRes.height,
|
||||
})
|
||||
that.triggerEvent(
|
||||
'contentHeight',
|
||||
that.data.contentHeight - headerRes.height
|
||||
)
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
},
|
||||
debounce(fn, wait) {
|
||||
const that = this
|
||||
that.setData({
|
||||
timeout: null,
|
||||
})
|
||||
return function () {
|
||||
if (that.data.timeout !== null) {
|
||||
clearTimeout(that.data.timeout)
|
||||
}
|
||||
const timeout = setTimeout(() => {
|
||||
fn()
|
||||
}, wait)
|
||||
that.setData({
|
||||
timeout,
|
||||
})
|
||||
}
|
||||
},
|
||||
onLoadmore() {
|
||||
const that = this
|
||||
that.debounce(() => {
|
||||
that.triggerEvent('loadmore')
|
||||
if (that.data.refreshConfig.shake) {
|
||||
wx.vibrateShort()
|
||||
}
|
||||
}, 500)()
|
||||
},
|
||||
onDefaultRefresh() {
|
||||
const that = this
|
||||
if (that.data.type == 'default') {
|
||||
that.triggerEvent('refresh')
|
||||
that.debounce(() => {
|
||||
that.settriggered(false)
|
||||
}, 1000)()
|
||||
}
|
||||
},
|
||||
onRefresh() {
|
||||
const that = this
|
||||
if (that.data.refreshConfig.shake) {
|
||||
wx.vibrateShort()
|
||||
}
|
||||
if (this.data.isLoading) {
|
||||
console.log('refresh')
|
||||
wx.showNavigationBarLoading()
|
||||
if ('isAutoTriggered' in that.data.refreshConfig) {
|
||||
if (that.data.refreshConfig.isAutoTriggered) {
|
||||
that.triggerEvent('refresh')
|
||||
that.debounce(() => {
|
||||
that.settriggered(false)
|
||||
setTimeout(() => {
|
||||
that.onRestore()
|
||||
}, 300)
|
||||
}, 1000)()
|
||||
} else {
|
||||
if (that.data.triggered) {
|
||||
that.triggerEvent('refresh')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
that.triggerEvent('refresh')
|
||||
that.debounce(() => {
|
||||
that.settriggered(false)
|
||||
setTimeout(() => {
|
||||
that.onRestore()
|
||||
}, 300)
|
||||
}, 1000)()
|
||||
}
|
||||
}
|
||||
},
|
||||
onPulling(evt) {
|
||||
console.log('pull')
|
||||
const that = this
|
||||
that.settriggered(true).then(() => {
|
||||
// console.log(evt.detail.dy, that.data.refreshConfig.height);
|
||||
let p = Math.min(
|
||||
evt.detail.dy / (that.data.refreshConfig.height + 20),
|
||||
1
|
||||
)
|
||||
that.p = p ? p : 0
|
||||
that.setThreshold(that.p)
|
||||
})
|
||||
},
|
||||
settriggered(flag) {
|
||||
const that = this
|
||||
return new Promise((resolve) => {
|
||||
if (flag != that.data.triggered) {
|
||||
if (that.refreshNode) {
|
||||
that.refreshNode.setData({
|
||||
triggered: flag,
|
||||
})
|
||||
}
|
||||
that.setData(
|
||||
{
|
||||
triggered: flag,
|
||||
},
|
||||
() => {
|
||||
resolve()
|
||||
}
|
||||
)
|
||||
} else {
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
},
|
||||
setThreshold(p) {
|
||||
const that = this
|
||||
return new Promise((resolve) => {
|
||||
if (that.refreshNode) {
|
||||
that.refreshNode
|
||||
.changeThreshold({
|
||||
threshold: p,
|
||||
})
|
||||
.then(() => {
|
||||
resolve()
|
||||
})
|
||||
}
|
||||
})
|
||||
},
|
||||
onRestore() {
|
||||
const that = this
|
||||
if (that.data.isLoading) {
|
||||
console.log('restore')
|
||||
wx.hideNavigationBarLoading()
|
||||
that.triggerEvent('restore')
|
||||
that.debounce(() => {
|
||||
that.setThreshold(0).then(() => {
|
||||
that.p = 0
|
||||
that.refreshNode.setLoading({
|
||||
isloading: false,
|
||||
})
|
||||
that.setData({
|
||||
isLoading: false,
|
||||
triggered: false,
|
||||
})
|
||||
})
|
||||
}, 100)()
|
||||
}
|
||||
},
|
||||
scroll(e) {
|
||||
if (e.detail.scrollTop > 100 && this.data.isBackToTopShow == false) {
|
||||
this.setData({
|
||||
isBackToTopShow: true,
|
||||
})
|
||||
} else if (
|
||||
e.detail.scrollTop <= 100 &&
|
||||
this.data.isBackToTopShow == true
|
||||
) {
|
||||
this.setData({
|
||||
isBackToTopShow: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
dragend() {
|
||||
if (this.data.type != 'default') {
|
||||
if (this.p > 0.6 && this.data.isLoading == false) {
|
||||
this.setData(
|
||||
{
|
||||
isLoading: true,
|
||||
},
|
||||
() => {
|
||||
this.refreshNode
|
||||
.setLoading({
|
||||
isloading: true,
|
||||
})
|
||||
.then(() => {
|
||||
this.onRefresh()
|
||||
})
|
||||
}
|
||||
)
|
||||
} else {
|
||||
this.settriggered(false)
|
||||
}
|
||||
}
|
||||
},
|
||||
backToTop() {
|
||||
// this.triggerEvent("refresh");
|
||||
this.setData({
|
||||
top: 0,
|
||||
})
|
||||
},
|
||||
},
|
||||
})
|
5
components/coolui-scroller/scroller/index.json
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {
|
||||
}
|
||||
}
|
20
components/coolui-scroller/scroller/index.wxml
Normal file
@ -0,0 +1,20 @@
|
||||
<view id="content" class="wrap {{active?'active':''}}">
|
||||
<view class="slot-header" id="header">
|
||||
<slot name="header"></slot>
|
||||
</view>
|
||||
<scroll-view scroll-y class="scroll flex" enable-passive="{{true}}" enhanced="{{true}}" fast-deceleration="{{true}}" enable-back-to-top="{{true}}" enable-flex="{{enableFlex}}" refresher-enabled="{{type?true:false}}" refresher-threshold="{{refreshConfig.height?refreshConfig.height:50}}" lower-threshold="{{100}}" refresher-default-style="{{type == 'default' ? refreshConfig.style : 'none'}}" refresher-background="{{refreshConfig.background.color}}" refresher-triggered="{{triggered}}" bindrefresherrefresh="onDefaultRefresh" bindrefresherpulling="onPulling" bindrefresherrestore="onRestore" bindscrolltolower="onLoadmore" bindscroll="scroll" bind:touchend="dragend" scroll-top="{{top}}" scroll-with-animation="{{animation}}" scroll-into-view="{{toView}}" style="height:{{contentHeight}}px;">
|
||||
<view slot="refresher" wx:if="{{type != 'default'}}" class="refresh-container">
|
||||
<slot name="refresh"></slot>
|
||||
</view>
|
||||
<view class="inner" style="min-height:{{contentHeight}}px;">
|
||||
<slot></slot>
|
||||
<view style="height:{{contentHeight}}px" hidden="{{!isEmpty}}" class="slot-empty">
|
||||
<slot name="empty"></slot>
|
||||
</view>
|
||||
<view class="slot-loadmore" hidden="{{isEmpty}}">
|
||||
<slot name="loadmore"></slot>
|
||||
</view>
|
||||
</view>
|
||||
</scroll-view>
|
||||
<view class="backToTop" wx:if="{{isBackToTopShow && isBackBtn}}" bindtap="backToTop"></view>
|
||||
</view>
|
47
components/coolui-scroller/scroller/index.wxss
Normal file
BIN
components/coolui-scroller/search/icon/close.png
Normal file
After Width: | Height: | Size: 5.6 KiB |
85
components/coolui-scroller/search/index.js
Normal file
@ -0,0 +1,85 @@
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true,
|
||||
},
|
||||
relations: {
|
||||
'./coolui-scroller': {
|
||||
type: 'parent',
|
||||
linked() {},
|
||||
},
|
||||
},
|
||||
externalClasses: [
|
||||
'search-btn-class',
|
||||
'search-inner-class',
|
||||
'search-placeholder-class',
|
||||
],
|
||||
properties: {
|
||||
placeholder: {
|
||||
type: String,
|
||||
value: '请输入要搜索的内容',
|
||||
},
|
||||
button: {
|
||||
type: Object,
|
||||
value: {
|
||||
show: false,
|
||||
text: '搜索',
|
||||
},
|
||||
},
|
||||
round: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
key: String,
|
||||
},
|
||||
data: {
|
||||
// height: 100
|
||||
isBtnShow: false,
|
||||
isFocus: false,
|
||||
},
|
||||
methods: {
|
||||
heightChange() {},
|
||||
focus() {
|
||||
this.setData({
|
||||
isBtnShow: true,
|
||||
})
|
||||
},
|
||||
blur() {
|
||||
if (this.data.key.length == 0) {
|
||||
this.setData({
|
||||
isBtnShow: false,
|
||||
isFocus: false,
|
||||
})
|
||||
}
|
||||
},
|
||||
input({ detail }) {
|
||||
this.setData({
|
||||
key: detail.value,
|
||||
})
|
||||
},
|
||||
btnClick() {
|
||||
if (this.data.key) {
|
||||
this.triggerEvent('btnClick', {
|
||||
key: this.data.key,
|
||||
})
|
||||
}
|
||||
},
|
||||
clear() {
|
||||
this.setData({
|
||||
key: '',
|
||||
isFocus: true,
|
||||
})
|
||||
},
|
||||
confirm() {
|
||||
if (this.data.key) {
|
||||
this.triggerEvent('confirm', {
|
||||
key: this.data.key,
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
4
components/coolui-scroller/search/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
134
components/coolui-scroller/search/index.scss
Normal file
17
components/coolui-scroller/search/index.wxml
Normal file
@ -0,0 +1,17 @@
|
||||
<!-- components/coolui-scroller-item/coolui-scroller-item.wxml -->
|
||||
<view class="wx-coolui-scroller-search {{(button.show||isBtnShow)?'on':''}} {{clearable && key.length > 0?'clearable':''}}">
|
||||
<slot name="leftout"></slot>
|
||||
<view class="search-inner {{round?'round':''}}">
|
||||
<view class="search-placeholder">
|
||||
<view class="search-icon"></view>
|
||||
{{key.length==0?(placeholder?placeholder:"请输入要搜索的内容"):''}}
|
||||
</view>
|
||||
<input class="search-input" type="text" model:value="{{key}}" bind:tap="focus" bindblur="blur" focus="{{isFocus}}" bindconfirm="confirm" bindinput="input" />
|
||||
<view class="search-close" bind:tap="clear"></view>
|
||||
</view>
|
||||
<block wx:if="{{!button.hide}}">
|
||||
<button wx:if="{{button.show||isBtnShow}}" class="button search-btn" bind:tap="btnClick">
|
||||
{{button.text ? button.text : '搜索'}}
|
||||
</button>
|
||||
</block>
|
||||
</view>
|
126
components/coolui-scroller/search/index.wxss
Normal file
117
components/coolui-scroller/second-floor-refresh/index.js
Normal file
@ -0,0 +1,117 @@
|
||||
// pages/second-floor/circle/index.js
|
||||
Component({
|
||||
externalClasses: ['second-floor-refresh-class', 'second-floor-refresh-back'],
|
||||
relations: {
|
||||
'../second-floor/index': {
|
||||
type: 'parent',
|
||||
linked(target) {
|
||||
this.setData({
|
||||
target,
|
||||
})
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
refreshConfig: {
|
||||
type: Object,
|
||||
value: {
|
||||
loadingText: '正在加载',
|
||||
backText: '返回首页',
|
||||
downText: '下拉刷新',
|
||||
tipText: '松开刷新,继续下拉有惊喜~',
|
||||
moreText: '继续下拉有惊喜~',
|
||||
color: '#ffffff',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的初始数据
|
||||
*/
|
||||
data: {
|
||||
text: '',
|
||||
isLoading: false,
|
||||
isFloorShow: false,
|
||||
p: 0,
|
||||
scroll_height: 0,
|
||||
target: null,
|
||||
status: 'down',
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
setText(p) {
|
||||
if (p > 0 && p <= this.data.scroll_height / 6) {
|
||||
if (this.data.text !== this.data.refreshConfig.downText) {
|
||||
this.setData({
|
||||
text: this.data.refreshConfig.downText,
|
||||
status: 'down',
|
||||
})
|
||||
}
|
||||
} else if (
|
||||
p > this.data.scroll_height / 6 &&
|
||||
p <= this.data.scroll_height / 3
|
||||
) {
|
||||
if (this.data.text !== this.data.refreshConfig.tipText) {
|
||||
this.setData({
|
||||
text: this.data.refreshConfig.tipText,
|
||||
status: 'tip',
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if (this.data.text !== this.data.refreshConfig.moreText) {
|
||||
this.setData({
|
||||
text: this.data.refreshConfig.moreText,
|
||||
status: 'more',
|
||||
})
|
||||
}
|
||||
}
|
||||
this.setData({
|
||||
p,
|
||||
})
|
||||
},
|
||||
setLoading(flag) {
|
||||
this.setData({
|
||||
isLoading: flag,
|
||||
status: 'loading',
|
||||
text: this.data.refreshConfig.loadingText,
|
||||
})
|
||||
},
|
||||
setDown() {
|
||||
this.setData({
|
||||
isLoading: false,
|
||||
text: this.data.refreshConfig.downText,
|
||||
p: 0,
|
||||
status: 'down',
|
||||
})
|
||||
},
|
||||
setSecondShow(flag) {
|
||||
const text = flag ? this.data.refreshConfig.backText : ''
|
||||
this.setData({
|
||||
isFloorShow: flag,
|
||||
text,
|
||||
status: 'back',
|
||||
})
|
||||
},
|
||||
back() {
|
||||
if (this.data.isFloorShow) {
|
||||
this.data.target.back()
|
||||
}
|
||||
},
|
||||
},
|
||||
ready() {
|
||||
const defaultConfig = {
|
||||
loadingText: '正在加载',
|
||||
backText: '返回首页',
|
||||
downText: '下拉刷新',
|
||||
tipText: '松开刷新,继续下拉有惊喜~',
|
||||
moreText: '继续下拉有惊喜~',
|
||||
color: '#ffffff',
|
||||
}
|
||||
this.setData({
|
||||
refreshConfig: { ...defaultConfig, ...this.data.refreshConfig },
|
||||
})
|
||||
},
|
||||
})
|
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
164
components/coolui-scroller/second-floor-refresh/index.scss
Normal file
@ -0,0 +1,164 @@
|
||||
/* pages/second-floor/circle/index.wxss */
|
||||
|
||||
:host {
|
||||
display : block;
|
||||
width : 100%;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.second-floor-refresh {
|
||||
display : flex;
|
||||
align-items : center;
|
||||
justify-content: center;
|
||||
padding : 30rpx 0;
|
||||
line-height : 1em;
|
||||
|
||||
.circle {
|
||||
display : flex;
|
||||
width : 48rpx;
|
||||
height : 48rpx;
|
||||
margin-right: 20rpx;
|
||||
position : relative;
|
||||
border : none;
|
||||
|
||||
&.loading {
|
||||
border : 1px dashed;
|
||||
border-radius: 100%;
|
||||
animation : loading 1s infinite linear;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
width : 12px;
|
||||
height : 24px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.leftcircle {
|
||||
width : 22px;
|
||||
height : 22px;
|
||||
border : 1px solid;
|
||||
position : absolute;
|
||||
border-radius : 50%;
|
||||
left : 0rpx;
|
||||
top : 0rpx;
|
||||
border-bottom : 1px solid transparent !important;
|
||||
border-left : 1px solid transparent !important;
|
||||
transform : rotate(45deg);
|
||||
animation-name : circle_left;
|
||||
animation-duration : 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.right {
|
||||
width : 12px;
|
||||
height : 24px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rightcircle {
|
||||
width : 22px;
|
||||
height : 22px;
|
||||
border-radius : 50%;
|
||||
border : 1px solid;
|
||||
position : absolute;
|
||||
border-top : 1px solid transparent !important;
|
||||
border-right : 1px solid transparent !important;
|
||||
right : 0rpx;
|
||||
top : 0rpx;
|
||||
animation-name : circle_right;
|
||||
animation-duration : 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
transform : rotate(45deg);
|
||||
}
|
||||
|
||||
.circle.loading {
|
||||
|
||||
.leftcircle,
|
||||
.rightcircle {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.second-floor-refresh {
|
||||
.downicon {
|
||||
width : 12rpx;
|
||||
height : 12rpx;
|
||||
position : absolute;
|
||||
top : 50%;
|
||||
left : 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
|
||||
.line {
|
||||
&:nth-child(1) {
|
||||
display : block;
|
||||
width : 1px;
|
||||
height : 22rpx;
|
||||
background-color: #fff;
|
||||
position : absolute;
|
||||
top : 50%;
|
||||
left : 50%;
|
||||
transform : translate(-50%, -50%);
|
||||
border-radius : 2rpx;
|
||||
opacity : 1;
|
||||
}
|
||||
|
||||
&:nth-child(2) {
|
||||
width : 15rpx;
|
||||
height : 1px;
|
||||
background-color: #fff;
|
||||
display : block;
|
||||
position : absolute;
|
||||
bottom : -3px;
|
||||
left : 50%;
|
||||
transform : rotate(-45deg);
|
||||
transform-origin: 0 50%;
|
||||
border-radius : 2rpx;
|
||||
opacity : 1;
|
||||
}
|
||||
|
||||
&:nth-child(3) {
|
||||
width : 15rpx;
|
||||
height : 1px;
|
||||
background-color: #fff;
|
||||
display : block;
|
||||
position : absolute;
|
||||
bottom : -3px;
|
||||
right : 50%;
|
||||
transform : rotate(45deg);
|
||||
transform-origin: 100% 50%;
|
||||
border-radius : 2rpx;
|
||||
opacity : 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.circle.loading .downicon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
text {
|
||||
display : block;
|
||||
text-align : center;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
}
|
||||
|
||||
/* .second-floor-refresh .downicon.up {
|
||||
transform: translate(-50%, -50%) rotate(180deg);
|
||||
} */
|
18
components/coolui-scroller/second-floor-refresh/index.wxml
Normal file
@ -0,0 +1,18 @@
|
||||
<!-- pages/second-floor/circle/index.wxml -->
|
||||
<!-- <text>{{p}}</text> -->
|
||||
<view class="second-floor-refresh second-floor-refresh-class second-floor-refresh-{{status}}" bind:tap="back" style="color: {{refreshConfig.color}}">
|
||||
<view class="circle {{isLoading ? 'loading':''}}" wx:if="{{p < scroll_height / 3}}" style="border-color: {{refreshConfig.color}};">
|
||||
<view class="left">
|
||||
<view class="leftcircle" style="transform: rotate({{p < 50 ? (45 - p * 3.6) : -135}}deg);border-color: {{refreshConfig.color}};"></view>
|
||||
</view>
|
||||
<view class="right">
|
||||
<view class="rightcircle" style="transform: rotate({{(p >= 50 && p <= 100) ? (45 - (p - 50) * 3.6) : (p > 100 ? -135 : 45 )}}deg);border-color: {{refreshConfig.color}};"></view>
|
||||
</view>
|
||||
<view class="downicon {{(p < scroll_height / 3 && p > scroll_height / 6) ? 'up' : ''}}">
|
||||
<view class="line"></view>
|
||||
<view class="line"></view>
|
||||
<view class="line"></view>
|
||||
</view>
|
||||
</view>
|
||||
<text decode="true">{{text}}</text>
|
||||
</view>
|
155
components/coolui-scroller/second-floor-refresh/index.wxss
Normal file
@ -0,0 +1,155 @@
|
||||
/* pages/second-floor/circle/index.wxss */
|
||||
:host {
|
||||
display: block;
|
||||
width: 100%;
|
||||
font-size: 28rpx;
|
||||
}
|
||||
|
||||
.second-floor-refresh {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 30rpx 0;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
.second-floor-refresh .circle {
|
||||
display: flex;
|
||||
width: 48rpx;
|
||||
height: 48rpx;
|
||||
margin-right: 20rpx;
|
||||
position: relative;
|
||||
border: none;
|
||||
}
|
||||
|
||||
.second-floor-refresh .circle.loading {
|
||||
border: 1px dashed;
|
||||
border-radius: 100%;
|
||||
animation: loading 1s infinite linear;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
.left {
|
||||
width: 12px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.leftcircle {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border: 1px solid;
|
||||
position: absolute;
|
||||
border-radius: 50%;
|
||||
left: 0rpx;
|
||||
top: 0rpx;
|
||||
border-bottom: 1px solid transparent !important;
|
||||
border-left: 1px solid transparent !important;
|
||||
transform: rotate(45deg);
|
||||
animation-name: circle_left;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
}
|
||||
|
||||
.right {
|
||||
width: 12px;
|
||||
height: 24px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.rightcircle {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
border-radius: 50%;
|
||||
border: 1px solid;
|
||||
position: absolute;
|
||||
border-top: 1px solid transparent !important;
|
||||
border-right: 1px solid transparent !important;
|
||||
right: 0rpx;
|
||||
top: 0rpx;
|
||||
animation-name: circle_right;
|
||||
animation-duration: 2s;
|
||||
animation-timing-function: linear;
|
||||
animation-iteration-count: infinite;
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
.circle.loading .leftcircle,
|
||||
.circle.loading .rightcircle {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.second-floor-refresh .downicon {
|
||||
width: 12rpx;
|
||||
height: 12rpx;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.second-floor-refresh .downicon .line:nth-child(1) {
|
||||
display: block;
|
||||
width: 1px;
|
||||
height: 22rpx;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 2rpx;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.second-floor-refresh .downicon .line:nth-child(2) {
|
||||
width: 15rpx;
|
||||
height: 1px;
|
||||
background-color: #fff;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
left: 50%;
|
||||
transform: rotate(-45deg);
|
||||
transform-origin: 0 50%;
|
||||
border-radius: 2rpx;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.second-floor-refresh .downicon .line:nth-child(3) {
|
||||
width: 15rpx;
|
||||
height: 1px;
|
||||
background-color: #fff;
|
||||
display: block;
|
||||
position: absolute;
|
||||
bottom: -3px;
|
||||
right: 50%;
|
||||
transform: rotate(45deg);
|
||||
transform-origin: 100% 50%;
|
||||
border-radius: 2rpx;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.second-floor-refresh .circle.loading .downicon {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.second-floor-refresh text {
|
||||
display: block;
|
||||
text-align: center;
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
/* .second-floor-refresh .downicon.up {
|
||||
transform: translate(-50%, -50%) rotate(180deg);
|
||||
} */
|
546
components/coolui-scroller/second-floor/index.js
Normal file
@ -0,0 +1,546 @@
|
||||
// miniprogram_npm/coolui-scroller/second-floor/index.js
|
||||
Component({
|
||||
options: {
|
||||
multipleSlots: true,
|
||||
addGlobalClass: true,
|
||||
},
|
||||
externalClasses: ['second-floor-class'],
|
||||
relations: {
|
||||
'../second-floor-refresh/index': {
|
||||
type: 'child',
|
||||
linked(target) {
|
||||
// console.log(target);
|
||||
},
|
||||
},
|
||||
'../nav-bar/index': {
|
||||
type: 'child',
|
||||
linked(target) {
|
||||
// console.log(target.data)
|
||||
// console.log(target.data.statusBarHeight)
|
||||
// this.setData({
|
||||
// navBar: target,
|
||||
// })
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
threshold: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
offset: {
|
||||
type: Number,
|
||||
value: 0,
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer: function (newVal) {
|
||||
this.init()
|
||||
},
|
||||
},
|
||||
bottom: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
observer: function (newVal) {
|
||||
this.init()
|
||||
},
|
||||
},
|
||||
top: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer: function (newVal) {
|
||||
this.init()
|
||||
},
|
||||
},
|
||||
scale: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
observer: function (newVal) {
|
||||
this.init()
|
||||
},
|
||||
},
|
||||
tip: {
|
||||
type: Object,
|
||||
value: {
|
||||
show: false,
|
||||
height: 100,
|
||||
times: 1,
|
||||
duration: 2000,
|
||||
},
|
||||
},
|
||||
},
|
||||
data: {
|
||||
scroll_height: 0,
|
||||
touchy: 0,
|
||||
isLoading: false,
|
||||
isFloorShow: false,
|
||||
wapperAnimationData: {},
|
||||
innerAnimationData: {},
|
||||
statusBarHeight: 0,
|
||||
navBar: null,
|
||||
},
|
||||
lifetimes: {
|
||||
attached: function () {
|
||||
// 在组件实例进入页面节点树时执行
|
||||
// this.init()
|
||||
let info = wx.getSystemInfoSync()
|
||||
console.log(info)
|
||||
this.setData({
|
||||
scroll_height: info.windowHeight,
|
||||
})
|
||||
},
|
||||
},
|
||||
ready() {
|
||||
this.init(() => {
|
||||
this.navNodes = this.getRelationNodes('../nav-bar/index')
|
||||
this.navNode = this.navNodes[0] ? this.navNodes[0] : null
|
||||
this.setData({
|
||||
statusBarHeight: this.navNode.data.statusBarHeight,
|
||||
})
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
debounce(fn, wait) {
|
||||
const that = this
|
||||
that.setData({
|
||||
timeout: null,
|
||||
})
|
||||
return function () {
|
||||
if (that.data.timeout !== null) {
|
||||
clearTimeout(that.data.timeout)
|
||||
}
|
||||
const timeout = setTimeout(() => {
|
||||
fn()
|
||||
}, wait)
|
||||
that.setData({
|
||||
timeout,
|
||||
})
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @name: 初始化
|
||||
* @description: 根据设置初始化动画,初始化参数,初始化子组件
|
||||
* @return {*}
|
||||
*/
|
||||
init(callback = null) {
|
||||
let info = wx.getSystemInfoSync()
|
||||
this.refreshNodes = this.getRelationNodes('../second-floor-refresh/index')
|
||||
this.refreshNode = this.refreshNodes[0] ? this.refreshNodes[0] : null
|
||||
this.refreshNode.setData({
|
||||
scroll_height: this.data.scroll_height,
|
||||
})
|
||||
this.refreshNode.setDown()
|
||||
let animation = this.setAnimation(
|
||||
-this.data.scroll_height + this.data.offset,
|
||||
0
|
||||
)
|
||||
console.log(this.data.offset)
|
||||
let animationInner = null
|
||||
let scaleXy = this.data.scale ? 0.1 : 1
|
||||
if (this.data.top) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height,
|
||||
0,
|
||||
scaleXy,
|
||||
scaleXy
|
||||
)
|
||||
}
|
||||
if (this.data.center) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height / 2,
|
||||
0,
|
||||
scaleXy,
|
||||
scaleXy
|
||||
)
|
||||
}
|
||||
if (this.data.bottom) {
|
||||
animationInner = this.setAnimation(0, 0, scaleXy, scaleXy)
|
||||
}
|
||||
this.setData(
|
||||
{
|
||||
wapperAnimationData: animation.export(),
|
||||
innerAnimationData: animationInner ? animationInner.export() : {},
|
||||
threshold: this.data.threshold,
|
||||
},
|
||||
() => {
|
||||
this.wapper = this.selectComponent('.second-floor-wapper')
|
||||
if (callback) {
|
||||
callback()
|
||||
}
|
||||
if (this.data.tip.show) {
|
||||
this.tipShow()
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
tipShow(
|
||||
duration = this.data.tip.duration,
|
||||
wait = this.data.tip.duration,
|
||||
times = this.data.tip.times
|
||||
) {
|
||||
const animation = wx.createAnimation()
|
||||
let offset = -this.data.scroll_height + this.data.offset
|
||||
animation.translateY(offset).step({
|
||||
duration,
|
||||
timingFunction: 'ease-in',
|
||||
})
|
||||
this.setData(
|
||||
{
|
||||
wapperAnimationData: animation.export(),
|
||||
threshold: 0,
|
||||
},
|
||||
() => {
|
||||
this.refreshNode.setText(this.data.scroll_height / 2)
|
||||
if (this.data.tip.show) {
|
||||
setTimeout(() => {
|
||||
animation
|
||||
.translateY(-this.data.scroll_height + this.data.tip.height)
|
||||
.step({
|
||||
duration,
|
||||
timingFunction: 'ease-out',
|
||||
})
|
||||
this.setData(
|
||||
{
|
||||
wapperAnimationData: animation.export(),
|
||||
threshold: this.data.tip.height,
|
||||
},
|
||||
() => {
|
||||
this.refreshNode.setText(this.data.scroll_height / 2)
|
||||
if (times > 1) {
|
||||
setTimeout(() => {
|
||||
this.tipShow(duration, wait, times - 1)
|
||||
}, wait)
|
||||
} else {
|
||||
setTimeout(() => {
|
||||
this.setData(
|
||||
{
|
||||
tip: {
|
||||
show: false,
|
||||
height: this.data.tip.height,
|
||||
times: this.data.tip.times,
|
||||
},
|
||||
},
|
||||
() => {
|
||||
this.tipShow(duration, wait, times - 1)
|
||||
}
|
||||
)
|
||||
}, wait)
|
||||
}
|
||||
}
|
||||
)
|
||||
}, duration)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
/**
|
||||
* @name: 触摸拖拽开始
|
||||
* @description: 记录初始触摸位置
|
||||
* @param {*} e
|
||||
* @return {*}
|
||||
*/
|
||||
touchStart(e) {
|
||||
console.log(this.data.tip.show)
|
||||
// 正在刷新时不操作触摸
|
||||
if (this.data.tip.show) {
|
||||
return false
|
||||
}
|
||||
if (this.data.isLoading) {
|
||||
return false
|
||||
}
|
||||
this.setData({
|
||||
touchy: e.changedTouches[0].clientY,
|
||||
})
|
||||
},
|
||||
/**
|
||||
* @name: 拖动时执行
|
||||
* @description: 修改页面动画,传递触摸动态参数给refresh组件
|
||||
* @return {*}
|
||||
*/
|
||||
touchMove(e) {
|
||||
if (this.data.tip.show) {
|
||||
return false
|
||||
}
|
||||
// 正在刷新时不进行操作, 二楼已加载是不进行操作
|
||||
if (!this.data.isFloorShow && !this.data.isLoading) {
|
||||
const distance = Math.round(
|
||||
e.changedTouches[0].clientY - this.data.touchy
|
||||
)
|
||||
let scaleXy = 1
|
||||
if (this.data.scale) {
|
||||
scaleXy = 0.1 + distance / 200
|
||||
scaleXy = scaleXy >= 1 ? 1 : scaleXy
|
||||
}
|
||||
|
||||
if (distance > 0) {
|
||||
let animation = this.setAnimation(
|
||||
-this.data.scroll_height + distance + this.data.offset,
|
||||
0
|
||||
)
|
||||
|
||||
let animationInner = null
|
||||
|
||||
if (this.data.top) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height - distance,
|
||||
0,
|
||||
scaleXy,
|
||||
scaleXy
|
||||
)
|
||||
}
|
||||
|
||||
if (this.data.bottom) {
|
||||
animationInner = this.setAnimation(0, 0, scaleXy, scaleXy)
|
||||
}
|
||||
|
||||
if (this.data.center) {
|
||||
animationInner = this.setAnimation(
|
||||
(this.data.scroll_height - distance) / 2,
|
||||
0,
|
||||
scaleXy,
|
||||
scaleXy
|
||||
)
|
||||
}
|
||||
// console.log(animationInner);
|
||||
this.setData({
|
||||
wapperAnimationData: animation.export(),
|
||||
innerAnimationData: animationInner ? animationInner.export() : null,
|
||||
threshold: distance,
|
||||
})
|
||||
this.refreshNode.setText(distance)
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @name: 松手后执行
|
||||
* @description: 松手时如果拖拽的距离大于屏幕三分之一,直接执行拉到二楼动画,如果大于六分之一小于三分之一则回到六分之一并开启刷新状态,如果小于六分之一直接回弹
|
||||
* @return {*}
|
||||
*/
|
||||
touchEnd() {
|
||||
if (this.data.tip.show) {
|
||||
return false
|
||||
}
|
||||
// 正在刷新时不进行操作, 二楼已加载是不进行操作,只点屏幕不拖拽时不进行操作
|
||||
if (
|
||||
!this.data.isFloorShow &&
|
||||
this.data.threshold > 0 &&
|
||||
!this.data.isLoading
|
||||
) {
|
||||
// 大于3分之1 直接拉到二楼
|
||||
if (this.data.threshold > this.data.scroll_height / 3) {
|
||||
const animation = this.setAnimation(0, 400)
|
||||
let animationInner = null
|
||||
if (this.data.top) {
|
||||
animationInner = this.setAnimation(0, 400, 1, 1)
|
||||
}
|
||||
if (this.data.bottom) {
|
||||
animationInner = this.setAnimation(0, 0, 1, 1)
|
||||
}
|
||||
|
||||
if (this.data.center) {
|
||||
animationInner = this.setAnimation(0, 400, 1, 1)
|
||||
}
|
||||
this.setData(
|
||||
{
|
||||
wapperAnimationData: animation.export(),
|
||||
innerAnimationData: animationInner ? animationInner.export() : {},
|
||||
},
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
this.refreshNode.setSecondShow(true)
|
||||
this.setData({
|
||||
isFloorShow: true,
|
||||
})
|
||||
this.triggerEvent('secondShow')
|
||||
}, 400)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
if (this.data.threshold > this.data.scroll_height / 6) {
|
||||
// 大于6分之一,小于3分之一,回到 6分之一停顿开始刷新
|
||||
const animation = this.setAnimation(
|
||||
-this.data.scroll_height + this.data.scroll_height / 6,
|
||||
400
|
||||
)
|
||||
let animationInner = null
|
||||
if (this.data.top) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height - this.data.scroll_height / 6,
|
||||
400
|
||||
)
|
||||
}
|
||||
if (this.data.bottom) {
|
||||
animationInner = this.setAnimation(0, 0)
|
||||
}
|
||||
if (this.data.center) {
|
||||
animationInner = this.setAnimation(
|
||||
(this.data.scroll_height - this.data.scroll_height / 6) / 2,
|
||||
400
|
||||
)
|
||||
}
|
||||
this.setData(
|
||||
{
|
||||
wapperAnimationData: animation.export(),
|
||||
innerAnimationData: animationInner
|
||||
? animationInner.export()
|
||||
: {},
|
||||
},
|
||||
() => {
|
||||
this.triggerEvent('refresh')
|
||||
this.setData({
|
||||
isLoading: true,
|
||||
})
|
||||
this.refreshNode.setLoading(true)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
// 小于6分之一 直接回顶部
|
||||
this.back(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @name: 回弹及二楼关闭
|
||||
* @description: 拖动小于6分之一直接回顶部或外部自定义调用关闭二楼
|
||||
* @return {*}
|
||||
*/
|
||||
back(callback = true) {
|
||||
return new Promise((resolve) => {
|
||||
const animation = this.setAnimation(
|
||||
-this.data.scroll_height + this.data.offset,
|
||||
800
|
||||
)
|
||||
let animationInner = null
|
||||
|
||||
if (this.data.top) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height,
|
||||
800,
|
||||
1,
|
||||
this.data.scale ? 0 : 1
|
||||
)
|
||||
}
|
||||
if (this.data.bottom) {
|
||||
animationInner = this.setAnimation(0, 0, 1, this.data.scale ? 0 : 1)
|
||||
}
|
||||
if (this.data.center) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height / 2,
|
||||
800,
|
||||
1,
|
||||
this.data.scale ? 0 : 1
|
||||
)
|
||||
}
|
||||
this.setData(
|
||||
{
|
||||
wapperAnimationData: animation.export(),
|
||||
innerAnimationData: animationInner ? animationInner.export() : {},
|
||||
},
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
// this.refreshNode.setShow(false)
|
||||
this.refreshNode.setDown()
|
||||
this.setData(
|
||||
{
|
||||
isFloorShow: false,
|
||||
threshold: 0,
|
||||
},
|
||||
() => {
|
||||
if (callback) {
|
||||
this.triggerEvent('secondBack')
|
||||
resolve()
|
||||
}
|
||||
}
|
||||
)
|
||||
}, 800)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
/**
|
||||
* @name: 刷新后的回弹
|
||||
* @description: 刷新之后回弹方法,再请求完数据之后执行
|
||||
* @return {*}
|
||||
*/
|
||||
settriggered() {
|
||||
return new Promise((resolve) => {
|
||||
const animation = this.setAnimation(
|
||||
-this.data.scroll_height + this.data.offset,
|
||||
800
|
||||
)
|
||||
let animationInner = null
|
||||
|
||||
if (this.data.top) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height,
|
||||
800,
|
||||
1,
|
||||
this.data.scale ? 0 : 1
|
||||
)
|
||||
}
|
||||
if (this.data.bottom) {
|
||||
animationInner = this.setAnimation(0, 0, 1, this.data.scale ? 0 : 1)
|
||||
}
|
||||
if (this.data.center) {
|
||||
animationInner = this.setAnimation(
|
||||
this.data.scroll_height / 2,
|
||||
800,
|
||||
1,
|
||||
this.data.scale ? 0 : 1
|
||||
)
|
||||
}
|
||||
this.setData(
|
||||
{
|
||||
wapperAnimationData: animation.export(),
|
||||
innerAnimationData: animationInner ? animationInner.export() : {},
|
||||
isLoading: false,
|
||||
},
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
this.refreshNode.setDown()
|
||||
this.setData(
|
||||
{
|
||||
threshold: 0,
|
||||
},
|
||||
() => {
|
||||
resolve()
|
||||
}
|
||||
)
|
||||
}, 400)
|
||||
}
|
||||
)
|
||||
})
|
||||
},
|
||||
setAnimation(
|
||||
y,
|
||||
duration = 400,
|
||||
scale = 1,
|
||||
opacity = 1,
|
||||
timingFunction = 'ease-out'
|
||||
) {
|
||||
let transformOrigin = '50% 50% 0'
|
||||
if (this.data.top) {
|
||||
transformOrigin = '50% 0 0'
|
||||
}
|
||||
if (this.data.bottom) {
|
||||
transformOrigin = '50% 100% 0'
|
||||
}
|
||||
if (this.data.center) {
|
||||
transformOrigin = '50% 50% 0'
|
||||
}
|
||||
const animation = wx.createAnimation({
|
||||
delay: 0,
|
||||
duration: duration,
|
||||
timingFunction: timingFunction,
|
||||
transformOrigin: transformOrigin,
|
||||
})
|
||||
animation.translateY(y).scale(scale, scale).opacity(opacity)
|
||||
|
||||
animation.step()
|
||||
|
||||
return animation
|
||||
},
|
||||
},
|
||||
})
|
4
components/coolui-scroller/second-floor/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
34
components/coolui-scroller/second-floor/index.scss
Normal file
@ -0,0 +1,34 @@
|
||||
.wx-coolui-scroller-second-floor {
|
||||
overflow: hidden;
|
||||
height : 100vh !important;
|
||||
|
||||
.second-floor-wapper {
|
||||
// -webkit-transition: transformY(-50%) scale(1, 1);
|
||||
transform: translateY(-50%) scale(1, 1);
|
||||
height : 200vh;
|
||||
|
||||
.second-floor-inner {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.first-floor {
|
||||
height : 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.second-floor-inner .second-floor-text {
|
||||
width : 100%;
|
||||
position : absolute;
|
||||
bottom : 0;
|
||||
display : flex;
|
||||
justify-content: center;
|
||||
align-items : center;
|
||||
z-index : 99;
|
||||
}
|
||||
}
|
||||
|
||||
.second-floor-inner {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
20
components/coolui-scroller/second-floor/index.wxml
Normal file
@ -0,0 +1,20 @@
|
||||
<view class="wx-coolui-scroller-second-floor second-floor-class" style="" bind:touchstart="touchStart" bind:touchend="touchEnd" bind:touchmove="touchMove">
|
||||
<view class="second-floor-wapper" animation="{{wapperAnimationData}}">
|
||||
<view class="second-floor-inner" style="">
|
||||
<view style="height: 100vh;" animation="{{innerAnimationData}}">
|
||||
<slot name="second-floor"></slot>
|
||||
</view>
|
||||
<div class="second-floor-text">
|
||||
<slot name="second-floor-refresh"></slot>
|
||||
</div>
|
||||
</view>
|
||||
<view class="first-floor" style="">
|
||||
<view style="height: {{statusBarHeight}}px">
|
||||
<slot name="nav-bar"></slot>
|
||||
</view>
|
||||
<view style="height: calc(100vh - {{statusBarHeight}}px)">
|
||||
<slot></slot>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
33
components/coolui-scroller/second-floor/index.wxss
Normal file
@ -0,0 +1,33 @@
|
||||
.wx-coolui-scroller-second-floor {
|
||||
overflow: hidden;
|
||||
height: 100vh !important;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-second-floor .second-floor-wapper {
|
||||
transform: translateY(-50%) scale(1, 1);
|
||||
height: 200vh;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-second-floor .second-floor-wapper .second-floor-inner {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-second-floor .second-floor-wapper .first-floor {
|
||||
height: 100vh;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-second-floor .second-floor-wapper .second-floor-inner .second-floor-text {
|
||||
width: 100%;
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
z-index: 99;
|
||||
}
|
||||
|
||||
.wx-coolui-scroller-second-floor .second-floor-inner {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
139
components/coolui-scroller/sort/index/index.js
Normal file
@ -0,0 +1,139 @@
|
||||
// components/coolui-scroller-item/coolui-scroller-item.js
|
||||
Component({
|
||||
relations: {
|
||||
'../../coolui-scroller/index': {
|
||||
type: 'parent', // 关联的目标节点应为子节点
|
||||
linked() {},
|
||||
},
|
||||
'../item/index': {
|
||||
type: 'child',
|
||||
linked: function (target) {},
|
||||
linkChanged: function (target) {},
|
||||
unlinked: function (target) {},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
overlay: {
|
||||
type: Boolean,
|
||||
value: true,
|
||||
},
|
||||
overlayDuration: {
|
||||
type: Number,
|
||||
value: 500,
|
||||
},
|
||||
scroll: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
active: null,
|
||||
overlayHeight: 0,
|
||||
isOverLayShow: false,
|
||||
opacityAnimation: {},
|
||||
},
|
||||
|
||||
/**
|
||||
* 组件的方法列表
|
||||
*/
|
||||
methods: {
|
||||
setOverlayHeight() {
|
||||
const that = this
|
||||
wx.getSystemInfoAsync({
|
||||
success: (sysRes) => {
|
||||
const { windowHeight } = sysRes
|
||||
const query = that.createSelectorQuery().in(this)
|
||||
query
|
||||
.select('#overlay')
|
||||
.boundingClientRect(function (res) {
|
||||
if (res) {
|
||||
that.setData({
|
||||
overlayHeight: windowHeight - res.top,
|
||||
})
|
||||
}
|
||||
})
|
||||
.exec()
|
||||
},
|
||||
})
|
||||
},
|
||||
toggle(active) {
|
||||
const that = this
|
||||
let flag = false
|
||||
flag =
|
||||
active === that.data.active && that.data.active !== null
|
||||
? true
|
||||
: active == null
|
||||
? true
|
||||
: false
|
||||
that.setData({
|
||||
active: active,
|
||||
})
|
||||
this.toggleOverlay(flag)
|
||||
this.toggleDropdown()
|
||||
},
|
||||
toggleOverlay(flag) {
|
||||
const that = this
|
||||
var animation = wx.createAnimation({
|
||||
duration: that.data.overlayDuration,
|
||||
timingFunction: 'ease-in',
|
||||
})
|
||||
|
||||
if (flag) {
|
||||
if (that.data.isOverLayShow === true) {
|
||||
// 不显示
|
||||
animation.opacity(0).step()
|
||||
that.setData(
|
||||
{
|
||||
opacityAnimation: animation.export(),
|
||||
},
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
that.setData({
|
||||
isOverLayShow: false,
|
||||
})
|
||||
}, that.data.overlayDuration)
|
||||
}
|
||||
)
|
||||
} else {
|
||||
// 显示
|
||||
animation.opacity(1).step()
|
||||
this.setData(
|
||||
{
|
||||
isOverLayShow: true,
|
||||
},
|
||||
() => {
|
||||
that.setData({
|
||||
opacityAnimation: animation.export(),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
if (that.data.isOverLayShow !== true) {
|
||||
animation.opacity(1).step()
|
||||
this.setData(
|
||||
{
|
||||
isOverLayShow: true,
|
||||
},
|
||||
() => {
|
||||
that.setData({
|
||||
opacityAnimation: animation.export(),
|
||||
})
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
this.setOverlayHeight()
|
||||
},
|
||||
toggleDropdown() {
|
||||
var nodes = this.getRelationNodes('../item/index')
|
||||
nodes.forEach((item, index) => {
|
||||
item.toggleDropdown(this.data.active)
|
||||
})
|
||||
},
|
||||
close() {
|
||||
this.toggle(null)
|
||||
},
|
||||
},
|
||||
ready() {},
|
||||
})
|
4
components/coolui-scroller/sort/index/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
6
components/coolui-scroller/sort/index/index.wxml
Normal file
@ -0,0 +1,6 @@
|
||||
<view class="coolui-scroller-nav {{scroll?'scroll':'flex'}}">
|
||||
<slot></slot>
|
||||
</view>
|
||||
<block wx:if="{{overlay}}">
|
||||
<view class="overlay" id="overlay" style="height:{{overlayHeight}}px;" animation="{{opacityAnimation}}" hidden="{{!isOverLayShow}}" bind:tap="close" ></view>
|
||||
</block>
|
41
components/coolui-scroller/sort/index/index.wxss
Normal file
@ -0,0 +1,41 @@
|
||||
/* components/coolui-scroller-item/coolui-scroller-item.wxss */
|
||||
:host {
|
||||
display : block;
|
||||
width : 100%;
|
||||
box-shadow: 0 2px 12px rgb(100 101 102 / 12%);
|
||||
position : relative;
|
||||
}
|
||||
|
||||
.coolui-scroller-nav {
|
||||
width : 100%;
|
||||
height: 100rpx;
|
||||
}
|
||||
|
||||
.coolui-scroller-nav.flex {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.coolui-scroller-nav.scroll {
|
||||
white-space: nowrap;
|
||||
overflow-x : scroll;
|
||||
scroll-behavior:smooth
|
||||
}
|
||||
|
||||
.coolui-scroller-nav::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.coolui-scroller-nav-scroll {
|
||||
white-space: nowrap;
|
||||
overflow : visible;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
position : absolute;
|
||||
top : 100rpx;
|
||||
left : 0;
|
||||
width : 100%;
|
||||
height : 100vh;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
opacity : 0;
|
||||
}
|
166
components/coolui-scroller/sort/item/index.js
Normal file
@ -0,0 +1,166 @@
|
||||
// components/coolui-scroller-nav/item/index.js
|
||||
Component({
|
||||
relations: {
|
||||
"../index/index": {
|
||||
type: "parent",
|
||||
linked: function (target) {
|
||||
// console.log(target);
|
||||
},
|
||||
},
|
||||
},
|
||||
properties: {
|
||||
title: {
|
||||
type: String,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
},
|
||||
options: {
|
||||
type: Array,
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
},
|
||||
activeColor: {
|
||||
type: String,
|
||||
},
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
actionBar: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
data: {
|
||||
isDropdownShow: false,
|
||||
overlayDuration: 0,
|
||||
dropAnimation: {},
|
||||
select: null,
|
||||
selectArray: [],
|
||||
},
|
||||
methods: {
|
||||
toggle() {
|
||||
var nodes = this.getRelationNodes("../index/index");
|
||||
this.setData({
|
||||
overlayDuration: nodes[0].data.overlayDuration,
|
||||
});
|
||||
// console.log(this.data.name);
|
||||
nodes[0].toggle(this.data.name);
|
||||
},
|
||||
toggleDropdown(active) {
|
||||
if (active === this.data.name) {
|
||||
if (this.data.isDropdownShow === false) {
|
||||
if (this.data.multiple) {
|
||||
this.setData({
|
||||
selectArray: this.data.value ? this.data.value.split(",") : [],
|
||||
isDropdownShow: true,
|
||||
});
|
||||
} else {
|
||||
this.setData({
|
||||
select: parseInt(this.data.value),
|
||||
isDropdownShow: true,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.setData({
|
||||
isDropdownShow: false,
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.setData({
|
||||
isDropdownShow: false,
|
||||
});
|
||||
}
|
||||
},
|
||||
select(e) {
|
||||
var nodes = this.getRelationNodes("../index/index");
|
||||
if (this.data.multiple) {
|
||||
const selectArray = this.data.selectArray;
|
||||
const id = e.target.dataset.id;
|
||||
const isIn = this.inArray(id, selectArray);
|
||||
if (isIn === false) {
|
||||
selectArray.push(e.target.dataset.id);
|
||||
} else {
|
||||
selectArray.splice(isIn, 1);
|
||||
}
|
||||
this.setData({
|
||||
selectArray: selectArray.sort(),
|
||||
});
|
||||
} else {
|
||||
if (!this.data.actionBar) {
|
||||
this.setData(
|
||||
{
|
||||
select:
|
||||
e.target.dataset.id != this.data.select
|
||||
? e.target.dataset.id
|
||||
: null,
|
||||
value: e.target.dataset.id != this.data.select
|
||||
? e.target.dataset.id
|
||||
: null,
|
||||
},
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
nodes[0].toggle(null);
|
||||
}, 600);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.setData({
|
||||
select: e.target.dataset.id != this.data.select
|
||||
? e.target.dataset.id
|
||||
: null,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
inArray(search, array) {
|
||||
for (var i in array) {
|
||||
if (array[i] == search) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
},
|
||||
clear() {
|
||||
this.setData({
|
||||
value: "",
|
||||
selectArray: [],
|
||||
});
|
||||
},
|
||||
confirm() {
|
||||
var nodes = this.getRelationNodes("../index/index");
|
||||
if (this.data.multiple) {
|
||||
this.setData(
|
||||
{
|
||||
value: this.data.selectArray.join(","),
|
||||
},
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
nodes[0].toggle(null);
|
||||
}, 500);
|
||||
}
|
||||
);
|
||||
} else {
|
||||
this.setData(
|
||||
{
|
||||
value: this.data.select,
|
||||
},
|
||||
() => {
|
||||
setTimeout(() => {
|
||||
nodes[0].toggle(null);
|
||||
}, 500);
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
},
|
||||
ready() {},
|
||||
});
|
4
components/coolui-scroller/sort/item/index.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"component": true,
|
||||
"usingComponents": {}
|
||||
}
|
43
components/coolui-scroller/sort/item/index.wxml
Normal file
@ -0,0 +1,43 @@
|
||||
<wxs module="tools">
|
||||
function inArray(search, array) {
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (array[i] === search) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
module.exports.inArray = inArray;
|
||||
</wxs>
|
||||
<view class="coolui-scroller-nav-item" bindtap="toggle">
|
||||
<view class="item-title {{type == 'sort'?'sort':''}} {{isDropdownShow ? 'on' : ''}} {{value == 1 && type == 'sort' ? 'up':'down'}}" style="color: {{isDropdownShow ? activeColor : color}}">
|
||||
<view class="item-title-inner">
|
||||
{{type == 'sort'? (value == 0 ? options[0].title : options[value].title) : title}}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
<view class="dropdown-menu {{isDropdownShow ? 'on' : ''}}">
|
||||
<view class="dropdown-menu-inner {{isDropdownShow ? 'on' : ''}}">
|
||||
<view class="dropdown-menu-inner-scroll">
|
||||
<block wx:if="{{options}}">
|
||||
<block wx:if="{{multiple}}">
|
||||
<view class="option-item {{tools.inArray(index, selectArray)?'on':''}}" bind:tap="select" data-id="{{index}}" wx:for="{{options}}" wx:key="id">
|
||||
{{item.title}}
|
||||
</view>
|
||||
</block>
|
||||
<block wx:else>
|
||||
<view class="option-item {{index === select ? 'on' : ''}}" bind:tap="select" data-id="{{index}}" wx:for="{{options}}" wx:key="id">
|
||||
{{item.title}}
|
||||
</view>
|
||||
</block>
|
||||
</block>
|
||||
<block>
|
||||
<slot></slot>
|
||||
</block>
|
||||
</view>
|
||||
<view class="action-bar" wx:if="{{actionBar}}">
|
||||
<button type="default" bind:tap="clear">清空</button>
|
||||
<button type="primary" bind:tap="confirm" style="background:{{activeColor}}">确定</button>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
162
components/coolui-scroller/sort/item/index.wxss
Normal file
BIN
images/ic_check_icon.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
images/ic_empty_data.png
Executable file
After Width: | Height: | Size: 444 B |
BIN
images/ic_history_icon.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
images/ic_home_nomarl_icon.png
Normal file
After Width: | Height: | Size: 605 B |
BIN
images/ic_home_sel_icon.png
Normal file
After Width: | Height: | Size: 616 B |
BIN
images/ic_mine_nomarl_icon.png
Normal file
After Width: | Height: | Size: 932 B |
BIN
images/ic_mine_sel_icon.png
Normal file
After Width: | Height: | Size: 946 B |
BIN
images/ic_register_icon.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
images/ic_report_icon.png
Normal file
After Width: | Height: | Size: 2.4 KiB |