W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
解釋: 可用于頁面任意區(qū)域;使用時需自行添加下拉邏輯改變 offset-y 參數(shù);smt-feed 組件對 smt-refresh 進行了封裝,支持手勢交互和 api 調(diào)起刷新。
屬性名 | 類型 | 必填 | 默認值 | 說明 |
---|---|---|---|---|
theme | String | 否 | - | 主題配置,默認淺色;深色主題請指定 dark |
loadingHgt | Number | 否 | 192px(需轉(zhuǎn)換為設(shè)備尺寸) | 加載區(qū)域高度 |
offsetY | Number | 否 | 0 | 垂直移動距離,*建議后續(xù)在 sjs 中使用 |
status | Number | 否 | 0 | 加載狀態(tài) 0: 未開始 1: 加載中 2: 展示話術(shù) |
text | String | 否 | 建議最多顯示 18 個漢字,超出內(nèi)容截斷 | 加載成功時的展示話術(shù) |
<view class="container {{theme}}" >
<view class="refresh-wrap {{theme}}">
<view class="mode-title {{theme}}">
<view class="mode-title-line-left"></view>
<view class="mode-title-text">手動下拉刷新</view>
<view class="mode-title-line-right"></view>
</view>
<view
class="smt-card-area"
catch:touchstart="noop"
catch:touchmove="noop"
catch:touchend="noop"
>
<smt-feed
class="smt-feed pull-down-refresh"
ext-cls-feed="custom-cls-feed"
ext-cls-loading="custom-cls-loading"
theme="{{theme}}"
pull-to-refresh
bind:refresh="onRefresh"
text="{{pullText}}"
>
<view class="list {{theme}}">
<view
class="{{'list-item ' + (val === 1 ? 'first' : '')}}"
s-for="val in list"
style="{{theme === 'dark' ? 'border-bottom: solid 1px rgba(255, 255, 255, .2);' : 'border-bottom: solid 1px #e0e0e0;'}}"
key="{{val}}"
>
<view class="left">
<view class="row begin"></view>
<view class="row center"></view>
<view class="row end"></view>
</view>
<view class="right"></view>
</view>
</view>
</smt-feed>
</view>
</view>
<view class="refresh-wrap">
<view class="mode-title {{theme}}">
<view class="mode-title-line-left"></view>
<view class="mode-title-text">自動刷新</view>
<view class="mode-title-line-right"></view>
</view>
<view class="smt-card-area" >
<smt-feed
class="smt-feed auto-refresh"
ext-cls-feed="custom-cls-feed"
theme="{{theme}}"
disable-touch
text="{{autoRefreshText}}"
>
<view class="list {{theme}}">
<view
class="{{'list-item ' + (val === 1 ? 'first' : '')}}"
s-for="val in list"
style="{{theme === 'dark' ? 'border-bottom: solid 1px rgba(255, 255, 255, .2);' : 'border-bottom: solid 1px #e0e0e0;'}}"
key="{{val}}"
>
<view class="left">
<view class="row begin"></view>
<view class="row center"></view>
<view class="row end"></view>
</view>
<view class="right"></view>
</view>
</view>
</smt-feed>
</view>
</view>
<view class="refresh-wrap">
<view class="mode-title {{theme}}">
<view class="mode-title-line-left"></view>
<view class="mode-title-text">刷新失敗</view>
<view class="mode-title-line-right"></view>
</view>
<view class="smt-card-area fail" >
<view class="fail {{fail ? 'enable' : ''}}"><view class="text">刷新失敗</view></view>
<smt-feed
class="smt-feed auto-refresh-fail"
ext-cls-feed="custom-cls-feed"
theme="{{theme}}"
disable-touch
>
<view class="list {{theme}}">
<view
class="{{'list-item ' + (val === 1 ? 'first' : '')}}"
s-for="val in list"
style="{{theme === 'dark' ? 'border-bottom: solid 1px rgba(255, 255, 255, .2);' : 'border-bottom: solid 1px #e0e0e0;'}}"
key="{{val}}"
>
<view class="left">
<view class="row begin"></view>
<view class="row center"></view>
<view class="row end"></view>
</view>
<view class="right"></view>
</view>
</view>
</smt-feed>
</view>
</view>
<view class="theme-control {{theme}}" >
<text>沉浸式主題</text>
<switch class="switch" color="{{dark ? '#f5f5f5' : '#ddd'}}" bind:change="themeChange"></switch>
</view>
</view>
{
"navigationBarTitleText": "刷新",
"usingComponents": {
"smt-feed": "@smt-ui/component/src/feed"
},
"navigationStyle": "default",
"disableSwipeBack": true
}
import {selComponent, syncSetData} from '@smt-ui/component/src/common/utils';
const systemInfo = (() => {
let info = {};
try {
info = swan.getSystemInfoSync();
}
catch (err) {
throw '獲取系統(tǒng)信息錯誤: ' + err;
}
return info;
})();
Page({ // eslint-disable-line
data: {
list: [1, 2, 3],
autoRefreshText: '不超過18個字',
pullText: '',
theme: 'dark',
fail: false,
statusBarHeight: systemInfo.statusBarHeight
},
/**
* 請求時長1200ms
*
* @param {number=} ms 默認1200毫秒
* @return {Promise}
*/
async fetchData(ms = 1200) {
const empty = Math.random() > .7;
const data = {
code: 0,
data: empty ? null : Array.from({length: Math.random() * 10 + 10 | 0}, (_, i) => i)
};
return new Promise(r => setTimeout(() => r(data), ms));
},
async guide() {
const refresh = await selComponent(this, '.pull-down-refresh');
refresh.startRefresh();
this.onRefresh();
},
/**
* 觸發(fā)刷新時回調(diào)
*/
async onRefresh() {
const refresh = await selComponent(this, '.pull-down-refresh');
const {data: list} = await this.fetchData();
await new Promise(r => setTimeout(r, 300));
await syncSetData(this, {
pullText: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
});
refresh.stopRefresh();
},
// 阻止冒泡: 多點觸控在滾動的頁面上會出問題
noop() {},
/**
* 自動加載
*
* @param {boolean} fail 是否失敗
*/
async autoRefresh(fail) {
const clkRefresh = await selComponent(this, '.auto-refresh' + (fail ? '-fail' : ''));
const autoLoad = async () => {
clkRefresh.startRefresh();
const {data: list} = await this.fetchData();
await new Promise(r => setTimeout(r, 300));
if (fail) {
await clkRefresh.closeLoading();
await syncSetData(this, {fail});
await new Promise(r => setTimeout(r, 3000));
await syncSetData(this, {fail: false});
return await autoLoad();
}
await syncSetData(this, {
list: list || this.data.list,
autoRefreshText: list ? `為你推薦${list.length}條更新` : '暫時沒有更新,休息一下'
});
await clkRefresh.stopRefresh();
await new Promise(r => setTimeout(r, 500)); // 加載完一輪等500ms
await autoLoad();
};
autoLoad();
},
themeChange({detail}) {
const checked = detail.checked;
this.setData({
theme: checked ? 'dark' : ''
});
swan.setBackgroundColor({
backgroundColor: checked ? '#3670c2' : '#f5f5f5'
});
},
swtichHdl({detail}) {
const checked = detail.checked;
this.setData({
theme: checked ? 'dark' : ''
});
},
onReady() {
swan.setBackgroundColor({
backgroundColor: '#f5f5f5'
});
this.setData({dark: false});
this.autoRefresh();
this.autoRefresh(true);
this.guide();
}
});
* {
margin: 1;
padding: 0;
box-sizing: border-box;
}
.container {
font-size: .16rem;
display: flex;
flex-direction: column;
justify-content: space-between;
min-height: 100%;
}
.mode-title {
display: flex;
justify-content: center;
align-items: center;
font-size: .16rem;
color: #000;
font-family: PingFangSC-Medium;
}
.mode-title-text {
margin: 0 .12rem;
}
.mode-title-line-left {
border-radius: 3px;
height: 1px;
width: .23rem;
background-image: linear-gradient(90deg, #f5f5f5 0%, #d5d5d5 100%);
}
.mode-title-line-right {
border-radius: 3px;
height: 1px;
width: .23rem;
background-image: linear-gradient(-90deg, #f5f5f5 0%, #d5d5d5 100%);
}
.theme-control{
width: 100%;
}
.refresh-wrap {
margin-bottom: .4rem;
}
.smt-card-area {
margin-top: .14rem;
}
.smt-card-area.fail {
position: relative;
}
.smt-card-area .fail {
display: flex;
position: absolute;
z-index: 1;
height: 100%;
width: 100%;
top: 0;
left: 0;
opacity: 0;
transition: opacity 120ms linear;
align-items: center;
justify-content: center;
}
.smt-card-area .fail.enable {
opacity: 1;
}
.smt-card-area .fail.enable .text {
display: flex;
background-color: rgba(0, 0, 0, .8);
color: #fff;
height: .43rem;
padding: 0 .17rem;
align-items: center;
border-radius: .08rem;
}
.container {
padding-top: .167rem;
padding-bottom: .85rem;
background-color: #f5f5f5;
transition: background-color 200ms linear;
}
.smt-feed {
height: 3.51rem;
display: block;
background-color: #fff;
}
.smt-feed.dark {
background-color: #fbfbfb;
}
.card-area.theme {
display: flex;
justify-content: space-between;
align-items: center;
padding: .16rem .17rem;
}
.card-area.theme .line-02 {
color: #999;
margin-top: .05rem;
font-size: .14rem;
}
.theme-control {
display: flex;
height: .58rem;
padding: 0 .17rem;
margin-top: .1rem;
align-items: center;
justify-content: space-between;
font-size: .16rem;
background-color: #fff;
transition: background-color 200ms linear;
}
.theme-control.dark {
background-color: #4985da;
color: #fff;
}
.mode-title-line.dark {
color: #fff;
}
.mode-title.dark .mode-title-text {
color: #fff;
transition: color 200ms linear;
}
.mode-title.dark .mode-title-line-left {
background-image: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, .3) 100%);
transition: background-image 200ms linear;
}
.mode-title.dark .mode-title-line-right {
background-image: linear-gradient(90deg, rgba(255, 255, 255, .3) 0%, rgba(255, 255, 255, 0) 100%);
transition: background-image 200ms linear;
}
.dark {
background-color: #3670c2;
}
.dark .custom-cls-loading {
background-color: #fff;
}
.dark .switch .swan-switch-input:after {
background-color: #38f;
}
.list {
transition: background-color 200ms linear;
padding: 0 .17rem;
}
.list-item {
display: flex;
justify-content: space-between;
height: 1.17rem;
box-sizing: border-box;
flex: none;
padding: .17rem 0;
color: #fff;
}
.list-item .left {
display: flex;
flex: auto;
flex-flow: column nowrap;
}
.list-item .left .row {
width: 100%;
height: .19rem;
background: #e0e0e0;
transition: background-color 200ms linear;
margin-bottom: .06rem;
}
.list-item .left .row.end {
height: .12rem;
margin-top: .27rem;
margin-bottom: 0;
width: 1.15rem;
}
.list-item .right {
display: flex;
justify-content: center;
align-items: center;
color: #ccc;
width: 1.24rem;
height: .83rem;
margin-left: .17rem;
border-radius: .03rem;
background: #e0e0e0;
transition: background-color 200ms linear;
}
.list.dark {
background-color: transparent;
}
.list.dark .list-item .left .row,
.list.dark .list-item .right {
background-color: rgba(255, 255, 255, .2);
}
設(shè)計指南
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: