abc9441e by simon

默认提交

1 parent 9b2edcb6
Showing 44 changed files with 1106 additions and 226 deletions
......@@ -16,6 +16,10 @@ Component({
types: {
type: Array,
value: ["home", "return"]
},
pics: {
type: Array,
value: ["red-package"]
}
},
data: {
......@@ -44,6 +48,15 @@ Component({
})
break;
case "red-package":
wx.showModal({
title: '温馨提示',
content: '打赏功能尚未开放,敬请期待!',
showCancel: false,
success(res) {}
});
break;
default:
break;
}
......
......@@ -15,10 +15,18 @@
display: flex;
justify-content: center;
align-items: center;
background-color: rgba($color: #000000, $alpha: 0.6);
}
.iconfont {
font-size: 64px;
}
.pics{
height: $btnSize;
}
.point{
background-color: rgba($color: #000000, $alpha: 0.6);
}
}
......
<view class="comp">
<view wx:for="{{types}}" wx:key="{{index}}" data-data="{{item}}" bindtap="onTapHandler" class="btn">
<view wx:for="{{types}}" wx:key="{{index}}" data-data="{{item}}" bindtap="onTapHandler" class="btn point">
<span class="iconfont {{typeIconMap[item+''] }}"></span>
</view>
<view wx:for="{{pics}}" wx:key="{{index}}" data-data="{{item}}" bindtap="onTapHandler" class="btn">
<image mode="aspectFit" src="../../image/shortcut/red-package.png" class="pics" />
</view>
</view>
......
......@@ -2,7 +2,7 @@ let ENV_CONFIG = require('./env/index');
const APPID = ''
/** ====每次发布版本记得修改此环境配置==== */
const ENV = 'dev'; // Dev Prod
const ENV = 'Dev'; // Dev Prod
const NET_CONFIG = ENV_CONFIG[ENV];
const MOCKAPI = ENV_CONFIG.mockApi;
......
module.exports = {
mockApi: 'http://mock.simonfungc.com',
Dev: {
baseApi: 'https://ow.go.qudone.com/xxx',
baseApi: 'https://ow.go.qudone.com/kd_jyes_api/minipro',
commonApi: 'https://api.k.wxpai.cn/bizproxy'
},
Test: {
......
......@@ -2,7 +2,14 @@ module.exports = {
login: "/login", // post 通过wxcode换取sessionId
register: '/register', // post 注册(用户授权)
dataList: '/dataList', // 测试接口
// dataList: '/dataList', // 测试接口
bannerList: '/banner/list', // 轮播图
tabList: '/tab/list', // 获取标签
videoList: '/video/list', // 视频列表
videoAcccout: '/video/acccout', // 帐号下的视频
videoDetail: '/video/detail', // 视频详情
rewardDetail: '/hide/order', // 获得打赏视频
videoMore: '/video/more', // 更多推荐
/**
* 通用接口
......
......@@ -5,40 +5,60 @@ import {
let app = getApp();
Page({
data: {
isOverShare: true,
authorizeVisible: false,
total: 0,
page: 1,
size: 10,
dataList: [],
productList: [], // 产品列表
indexInfo: {},
userInfo: {}
userInfo: {},
options: {},
detailData: {}
},
onShareAppMessage() {
let detailData = this.data.detailData;
let title = detailData && detailData.videoName || "";
let path = `pages/detail/detail?c=${detailData.videoCode}`;
let imageUrl = detailData && detailData.thumbnail || "";
return {
title,
path,
imageUrl
}
},
onShareAppMessage() {},
showAuth() {
this.setData({
authorizeVisible: true
})
},
onLoad(options) {},
onLoad(options) {
this.setData({
options
});
this.queryVideoDetail();
this.initData();
},
/**
* 基础方法
* 授权完毕重拉数据用
*/
initData() {
this.queryVideoMore();
},
/**
* 到达底部
* 做加载更多操作
*/
onReachBottom() {
return;
if (this.data.dataList.length < this.data.total) {
this.setData({
page: this.data.page + 1
});
// this.queryDataList();
this.queryVideoMore();
}
},
......@@ -50,25 +70,41 @@ Page({
})
},
/**
* 到个人列表页面
*/
toPersonalList() {
let detailData = this.data.detailData;
if (detailData && detailData.accountCode) {
detailData.c = detailData.accountCode;
app.router.push({
path: "personalList",
query: detailData
})
}
},
/**
* 跳转详情页面
*/
onDetailHandler(evt) {
let curItem = getBindtapData(evt);
app.router.push({
path: "detail",
query: {
c: curItem.videoCode || ""
}
})
},
/**
* 请求DataList
*/
queryDataList() {
return;
queryVideoMore() {
return new Promise((resolve, reject) => {
app.post({
sid: false,
url: app.api.dataList,
url: app.api.videoMore,
data: {
page: this.data.page,
size: this.data.size,
......@@ -76,6 +112,7 @@ Page({
}).then((result) => {
let dataList = result.list;
dataList = this.data.dataList.concat(dataList);
console.log("dataList:", dataList);
this.setData({
dataList: dataList,
total: result.total
......@@ -86,6 +123,27 @@ Page({
},
/**
* 视频详情
*/
queryVideoDetail() {
return new Promise((resolve, reject) => {
app.post({
url: app.api.videoDetail,
data: {
videoCode: this.data.options.c
}
}).then((result) => {
this.setData({
detailData: result
})
resolve(result);
}).catch((err) => {
reject(err);
});
});
},
/**
* 隐藏蒙层
*/
hideMask() {
......
......@@ -24,11 +24,13 @@
width: 100%;
height: 944px;
background-color: #333333;
text-align: center;
.vid {
margin: 232px auto 0;
text-align: center;
margin: 160px auto 0;
width: 100%;
height: 360px;
// height: 400px;
}
.btn-wrap {
......
......@@ -6,13 +6,13 @@
<view class="content">
<!-- 视频详情 -->
<view class="detail">
<video objectFit="cover" class="vid" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/7e91e8a4c7b84e6fa4bada7c8617c9cf.mp4" />
<video objectFit="cover" class="vid" poster="{{detailData.thumbnail}}" src="{{detailData.videoUrl}}" />
<view class="btn-wrap">
<button class="btn">
<button open-type="share" class="btn">
<span class="t1 iconfont iconplane"></span>
<span class="t1">分享给好友</span>
</button>
<button class="btn btn2">
<button open-type="share" class="btn btn2">
<span class="t1 iconfont iconplane"></span>
<span class="t1">分享到群</span>
</button>
......@@ -21,10 +21,10 @@
<!-- 功能区 -->
<view class="func">
<view bindtap="toPersonalList" class="user">
<image class="portrait" mode="aspectFill" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" />
<image class="portrait" mode="aspectFill" src="{{detailData.headImage}}" />
<view class="desc">
<view class="t1 name">我爱我家</view>
<view class="t1 num">280个视频</view>
<view class="t1 name">{{detailData.accountName}}</view>
<view class="t1 num">{{detailData.count || 0}}个视频</view>
</view>
</view>
<view class="btn-wrap">
......@@ -48,10 +48,14 @@
<view class="more">
<view class="more-title">-- 更多推荐欣赏 --</view>
<view class="more-list">
<view wx:for="{{2}}" wx:key="{{index}}" class="more-list-item">
<view bindtap="onDetailHandler" data-data="{{item}}" data-index="{{index}}" wx:for="{{dataList}}" wx:key="{{index}}" class="more-list-item">
<view class="tit">{{item.videoName}}</view>
<image class="poster" src="{{item.thumbnail}}" />
</view>
<!-- <view wx:for="{{2}}" wx:key="{{index}}" class="more-list-item">
<view class="tit">新政策来了!家有小孩的都要过来看看</view>
<image class="poster" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" />
</view>
</view> -->
</view>
</view>
<!-- 返回首页按钮 -->
......@@ -62,4 +66,5 @@
</view>
</view>
</view>
<shortcut></shortcut>
<!-- <shortcut types="{{[]}}" pics="{{['red-package']}}"></shortcut> -->
<shortcut ></shortcut>
......
......@@ -5,41 +5,195 @@ import {
let app = getApp();
Page({
data: {
active: 0
authorizeVisible: false,
total: 0,
page: 1,
size: 10,
dataList: [],
tabList: [], // 标签列表
bannerList: [],
curTab: {},
queueCode: "", // 队列标识,每次请求,会返回一个队列标识,用户加载更多时候请携带queueCode参数
active: 0,
},
onShareAppMessage() {},
showAuth() {
this.setData({
authorizeVisible: true
})
},
onLoad(options) {
this.initData();
},
onLoad(options) {},
initData() {
this.queryTabList().then((result) => {
this.setData({
curTab: this.data.tabList[0]
})
this.resetPage();
this.queryBannerList();
this.queryVideoList();
});
},
onChange(event) {
wx.showToast({
title: `切换到标签 ${event.detail.name}`,
icon: 'none'
/**
* 到达底部
* 做加载更多操作
*/
onReachBottom() {
console.log("onReachBottom");
if (this.data.dataList.length < this.data.total) {
this.setData({
page: this.data.page + 1
});
this.queryVideoList();
}
},
// 重置页面列表 点击搜索条件时需要
resetPage() {
this.setData({
page: 1,
dataList: [],
queueCode: "",
})
},
onTabsChange(event) {
// console.log("this.data.tabList:", this.data.tabList);
// if (this.data.tabList && this.data.tabList.length > 0) {
// this.setData({
// curTab: this.data.tabList[event.detail.index]
// })
// this.resetPage();
// this.queryVideoList();
// }
},
onVanTabsHandler(event) {
console.log("event:", event);
let {
index,
title
} = event.detail;
if (this.data.tabList && this.data.tabList.length > 0) {
this.setData({
curTab: this.data.tabList[event.detail.index]
})
this.resetPage();
this.queryVideoList();
}
},
onVideoHandler(evt) {
onDetailHandler(evt) {
let curItem = getBindtapData(evt);
let curIndex = getBindtapData(evt, "index");
app.router.push({
path: "detail",
query: {
c: curIndex + ""
c: curItem.videoCode || ""
}
})
console.log("curItem:", curItem);
console.log("curIndex:", curIndex);
},
/**
* 获取列表
* 获取tab列表
*/
queryList() {
queryTabList() {
return new Promise((resolve, reject) => {
app.post({
sid: false,
url: app.api.tabList,
data: {}
}).then((result) => {
this.setData({
tabList: result
})
resolve(result);
}).catch((err) => {
reject(err)
});
});
},
/**
* 获取banner列表
*/
queryBannerList() {
return new Promise((resolve, reject) => {
app.post({
sid: false,
url: app.api.bannerList,
data: {
tabCode: this.data.curTab.tabCode || "",
}
}).then((result) => {
this.setData({
bannerList: result
})
resolve(result);
}).catch((err) => {
reject(err)
});
});
},
/**
* 获取视频列表
*/
queryVideoList() {
return new Promise((resolve, reject) => {
app.post({
sid: true,
url: app.api.videoList,
data: {
page: this.data.page,
size: this.data.size,
queueCode: this.data.queueCode,
tabCode: this.data.curTab.tabCode || "",
}
}).then((result) => {
let dataList = result.list;
dataList = this.data.dataList.concat(dataList);
this.setData({
dataList: dataList,
total: result.total,
queueCode: result.queueCode,
})
resolve(result);
}).catch((err) => {
reject(err)
});
});
},
/**
* 隐藏蒙层
*/
hideMask() {
this.setData({
productDetailVisible: false,
authorizeVisible: false,
})
},
/**
* 子组件事件
* @param {*} evt
*/
evtcomp(evt) {
let {
name,
data
} = evt.detail;
switch (name) {
// 隐藏蒙层
case "_evt_hide_mask":
this.hideMask();
break;
/**
* 重拉数据已在
*/
case "_evt_auth_complete":
// this.initData();
this.hideMask();
break;
default:
break;
}
},
})
......
......@@ -2,7 +2,7 @@
@import '../../assets/scss/utils';
.page {
$contentWidth: 670px;
padding-bottom: $pageBottom;
color: #333333;
......@@ -21,6 +21,39 @@
.content {
position: relative;
padding-top: 24px;
}
.banner {
position: relative;
.swiper {
width: $contentWidth;
height: 280px;
margin: 0 auto;
.swiper-image {
width: $contentWidth;
height: 250px;
}
}
.tit {
position: absolute;
bottom: 12px;
width: 750px;
height: 64px;
line-height: 64px;
left: 0;
right: 0;
margin: 0 auto;
text-align: center;
background-color: rgba($color: #000000, $alpha: 0.7);
color: #ffffff;
font-size: 30px;
}
}
.list {
......@@ -39,11 +72,13 @@
justify-content: center;
position: relative;
width: $contentWidth;
background-color: #dddddd;
.vid {
@include border-top-radius(16px);
width: $contentWidth;
pointer-events: none;
}
.tit {
......@@ -61,6 +96,19 @@
@include ellipsis(1);
}
.iconfont {
font-size: 160px;
position: absolute;
left: 0;
right: 0;
top: 100px;
margin: 0 auto;
text-align: center;
font-weight: bold;
// color: #efefef;
color: #ffffff;
}
}
&-func {
......@@ -122,3 +170,11 @@
border-width: 0;
}
}
.red-p {
.comp {
bottom: auto;
top: 15%;
}
}
......
......@@ -5,16 +5,41 @@
<view class="app__content main">
<view class="top-space"></view>
<van-sticky>
<van-tabs active="{{ active }}" bind:click="onVanTabsHandler">
<van-tab title="精彩推荐"></van-tab>
<van-tab title="一起旅行"></van-tab>
<van-tab title="齐家欢乐"></van-tab>
<van-tab title="童趣无限"></van-tab>
<van-tabs ellipsis="{{ false }}" active="{{ active }}" bind:click="onVanTabsHandler" bind:change="onTabsChange">
<van-tab wx:for="{{tabList}}" wx:key="{{index}}" title="{{item.tabName}}"></van-tab>
</van-tabs>
</van-sticky>
<view class="content">
<view class="banner" wx:if="{{bannerList && bannerList.length>0}}">
<swiper class="swiper" indicator-color="rgba(0,0,0,.3)" indicator-active-color="rgba(255,255,255,1)" indicator-dots="{{true}}" autoplay="{{true}}" interval="{{5000}}" duration="{{500}}">
<block wx:for="{{bannerList}}" wx:key="{{index}}">
<swiper-item>
<image class="swiper-image" src="{{item.imageUrl}}" mode="aspectFill" />
</swiper-item>
</block>
</swiper>
<view class="tit">banner名字</view>
</view>
<view class="list">
<view bindtap="onVideoHandler" wx:for="{{8}}" wx:key="index" data-data="{{item}}" data-index="{{index}}" class="list-item">
<view wx:for="{{dataList}}" wx:key="index" class="list-item">
<view bindtap="onDetailHandler" data-data="{{item}}" data-index="{{index}}" class="list-item-video">
<!-- <video objectFit="cover" class="vid" poster="{{item.thumbnail}}" src="{{item.videoUrl}}" /> -->
<image src="{{item.thumbnail}}" mode="aspectFill" />
<view class="tit">{{item.videoName}}</view>
<span class="iconfont iconicon-test16"></span>
</view>
<view class="list-item-func">
<view class="user">
<image class="portrait" mode="aspectFill" src="{{item.headImage}}" />
<text class="name">{{item.accountName || ""}}</text>
</view>
<button class="share" open-type="share">
<span class="t1 iconfont iconwechat"></span>
<span class="t1">分享</span>
</button>
</view>
</view>
<!-- <view bindtap="onDetailHandler" wx:for="{{8}}" wx:key="index" data-data="{{item}}" data-index="{{index}}" class="list-item">
<view class="list-item-video">
<video objectFit="cover" class="vid" poster="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/7e91e8a4c7b84e6fa4bada7c8617c9cf.mp4" />
<view class="tit">这是一个视频</view>
......@@ -29,8 +54,10 @@
<span class="t1">分享</span>
</button>
</view>
</view>
</view> -->
</view>
</view>
</view>
</view>
<shortcut class="red-p" types="{{[]}}" pics="{{['red-package']}}"></shortcut>
......
......@@ -5,41 +5,132 @@ import {
let app = getApp();
Page({
data: {
active: 0
isOverShare: true,
authorizeVisible: false,
total: 0,
page: 1,
size: 10,
dataList: [],
options: {},
},
onShareAppMessage() {
let detailData = this.data.detailData;
let title = detailData && detailData.videoName || "";
let path = `pages/detail/detail?c=${detailData.videoCode}`;
let imageUrl = detailData && detailData.thumbnail || "";
return {
title,
path,
imageUrl
}
},
showAuth() {
this.setData({
authorizeVisible: true
})
},
onLoad(options) {
let tempOptions = JSON.parse(decodeURIComponent(JSON.stringify(options)));
this.setData({
options: tempOptions
});
this.initData();
},
onLoad(options) {},
initData() {
this.resetPage();
this.queryVideoList();
},
onChange(event) {
wx.showToast({
title: `切换到标签 ${event.detail.name}`,
icon: 'none'
/**
* 到达底部
* 做加载更多操作
*/
onReachBottom() {
if (this.data.dataList.length < this.data.total) {
this.setData({
page: this.data.page + 1
});
this.queryVideoList();
}
},
onVanTabsHandler(event) {
console.log("event:", event);
let {
index,
title
} = event.detail;
// 重置页面列表 点击搜索条件时需要
resetPage() {
this.setData({
page: 1,
dataList: [],
queueCode: "",
})
},
onVideoHandler(evt) {
onDetailHandler(evt) {
let curItem = getBindtapData(evt);
let curIndex = getBindtapData(evt, "index");
app.router.push({
path: "detail",
query: {
c: curIndex + ""
c: curItem.videoCode || ""
}
})
},
/**
* 获取视频列表
*/
queryVideoList() {
return new Promise((resolve, reject) => {
app.post({
url: app.api.videoAcccout,
data: {
page: this.data.page,
size: this.data.size,
accountCode: this.data.options.c
}
}).then((result) => {
let dataList = result.list;
dataList = this.data.dataList.concat(dataList);
this.setData({
dataList: dataList,
total: result.total,
})
resolve(result);
}).catch((err) => {
reject(err)
});
});
},
/**
* 隐藏蒙层
*/
hideMask() {
this.setData({
productDetailVisible: false,
authorizeVisible: false,
})
console.log("curItem:", curItem);
console.log("curIndex:", curIndex);
},
/**
* 获取列列表
* 子组件事件
* @param {*} evt
*/
evtcomp(evt) {
let {
name,
data
} = evt.detail;
switch (name) {
// 隐藏蒙层
case "_evt_hide_mask":
this.hideMask();
break;
/**
* 重拉数据已在
*/
queryList() {
case "_evt_auth_complete":
// this.initData();
this.hideMask();
break;
default:
break;
}
},
})
......
......@@ -5,12 +5,28 @@
<view class="app__content main">
<view class="personal">
<view class="top-space"></view>
<view class="name">我爱我家 的视频列表</view>
<image class="portrait" mode="aspectFill" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" />
<view class="name">{{options.accountName}} 的视频列表</view>
<image class="portrait" mode="aspectFill" src="{{options.headImage}}" />
</view>
<view class="content">
<view class="list">
<view bindtap="onVideoHandler" wx:for="{{8}}" wx:key="index" data-data="{{item}}" data-index="{{index}}" class="list-item">
<view wx:for="{{dataList}}" wx:key="index" class="list-item">
<view bindtap="onDetailHandler" data-data="{{item}}" data-index="{{index}}" class="list-item-video">
<video objectFit="cover" class="vid" poster="{{item.thumbnail}}" src="{{item.videoUrl}}" />
<view class="tit">{{item.videoName}}</view>
</view>
<view class="list-item-func">
<view class="user">
<image class="portrait" mode="aspectFill" src="{{item.headImage}}" />
<text class="name">{{item.accountName || ""}}</text>
</view>
<button class="share" open-type="share">
<span class="t1 iconfont iconwechat"></span>
<span class="t1">分享</span>
</button>
</view>
</view>
<!-- <view bindtap="onVideoHandler" wx:for="{{8}}" wx:key="index" data-data="{{item}}" data-index="{{index}}" class="list-item">
<view class="list-item-video">
<video objectFit="cover" class="vid" poster="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/7e91e8a4c7b84e6fa4bada7c8617c9cf.mp4" />
<view class="tit">这是一个视频</view>
......@@ -25,7 +41,7 @@
<span class="t1">分享</span>
</button>
</view>
</view>
</view> -->
</view>
</view>
</view>
......
......@@ -82,12 +82,10 @@ VantComponent({
onChange(event) {
const { index, picker, value } = event.detail;
this.code = value[index].code;
let getValues = picker.getValues();
getValues = this.parseOutputValues(getValues);
this.setValues().then(() => {
this.$emit('change', {
picker,
values: getValues,
values: this.parseOutputValues(picker.getValues()),
index
});
});
......
......@@ -19,7 +19,7 @@ VantComponent({
childIndex: this.children.length
});
this.children.push(target);
// 收集 dropdown-item 的 data 挂在 data 上
// 收集 dorpdown-item 的 data 挂在 data 上
target &&
this.setData({
itemListData: this.data.itemListData.concat([target.data])
......
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-goods-action-button{border:none!important;height:40px!important;height:var(--goods-action-button-height,40px)!important;font-weight:500!important;font-weight:var(--font-weight-bold,500)!important;line-height:40px!important;line-height:var(--goods-action-button-height,40px)!important}.van-goods-action-button--first{display:block!important;margin-left:5px;border-top-left-radius:40px/2!important;border-top-left-radius:var(--goods-action-button-height,40px)/2!important;border-bottom-left-radius:40px/2!important;border-bottom-left-radius:var(--goods-action-button-height,40px)/2!important}.van-goods-action-button--last{display:block!important;margin-right:5px;border-top-right-radius:40px/2!important;border-top-right-radius:var(--goods-action-button-height,40px)/2!important;border-bottom-right-radius:40px/2!important;border-bottom-right-radius:var(--goods-action-button-height,40px)/2!important}.van-goods-action-button--warning{background:linear-gradient(90deg,#ffd01e,#ff8917);background:var(--goods-action-button-warning-color,linear-gradient(90deg,#ffd01e,#ff8917))}.van-goods-action-button--danger{background:linear-gradient(90deg,#ff6034,#ee0a24);background:var(--goods-action-button-danger-color,linear-gradient(90deg,#ff6034,#ee0a24))}@media (max-width:321px){.van-goods-action-button{font-size:13px}}
\ No newline at end of file
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}.van-goods-action-button{border:none!important;height:40px!important;height:var(--goods-action-button-height,40px)!important;font-weight:500!important;font-weight:var(--font-weight-bold,500)!important;line-height:40px!important;line-height:var(--goods-action-button-height,40px)!important}.van-goods-action-button--first{display:block!important;margin-left:5px;border-top-left-radius:20px!important;border-top-left-radius:var(--goods-action-button-border-radius,20px)!important;border-bottom-left-radius:20px!important;border-bottom-left-radius:var(--goods-action-button-border-radius,20px)!important}.van-goods-action-button--last{display:block!important;margin-right:5px;border-top-right-radius:20px!important;border-top-right-radius:var(--goods-action-button-border-radius,20px)!important;border-bottom-right-radius:20px!important;border-bottom-right-radius:var(--goods-action-button-border-radius,20px)!important}.van-goods-action-button--warning{background:linear-gradient(90deg,#ffd01e,#ff8917);background:var(--goods-action-button-warning-color,linear-gradient(90deg,#ffd01e,#ff8917))}.van-goods-action-button--danger{background:linear-gradient(90deg,#ff6034,#ee0a24);background:var(--goods-action-button-danger-color,linear-gradient(90deg,#ff6034,#ee0a24))}@media (max-width:321px){.van-goods-action-button{font-size:13px}}
\ No newline at end of file
......
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'index-bar',
type: 'ancestor',
linked(target) {
this.parent = target;
},
unlinked() {
this.parent = null;
}
},
props: {
useSlot: Boolean,
index: null
},
data: {
active: false,
wrapperStyle: '',
anchorStyle: ''
}
});
<view
class="van-index-anchor-wrapper"
style="{{ wrapperStyle }}"
>
<view
class="van-index-anchor {{ active ? 'van-index-anchor--active van-hairline--bottom' : '' }}"
style="{{ anchorStyle }}"
>
<slot wx:if="{{ useSlot }}"/>
<block wx:else>
<text>{{ index }}</text>
</block>
</view>
</view>
@import '../common/index.wxss';.van-index-anchor{padding:0 16px;padding:var(--index-anchor-padding,0 16px);color:#323233;color:var(--index-anchor-text-color,#323233);font-weight:500;font-weight:var(--index-anchor-font-weight,500);font-size:14px;font-size:var(--index-anchor-font-size,14px);line-height:32px;line-height:var(--index-anchor-line-height,32px);background-color:initial;background-color:var(--index-anchor-background-color,transparent)}.van-index-anchor--active{right:0;left:0;color:#07c160;color:var(--index-anchor-active-text-color,#07c160);background-color:#fff;background-color:var(--index-anchor-active-background-color,#fff)}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { GREEN } from '../common/color';
const indexList = () => {
const indexList = [];
const charCodeOfA = 'A'.charCodeAt(0);
for (let i = 0; i < 26; i++) {
indexList.push(String.fromCharCode(charCodeOfA + i));
}
return indexList;
};
VantComponent({
relation: {
name: 'index-anchor',
type: 'descendant',
linked() {
this.updateData();
},
linkChanged() {
this.updateData();
},
unlinked() {
this.updateData();
}
},
props: {
sticky: {
type: Boolean,
value: true
},
zIndex: {
type: Number,
value: 1
},
highlightColor: {
type: String,
value: GREEN
},
scrollTop: {
type: Number,
value: 0,
observer: 'onScroll'
},
stickyOffsetTop: {
type: Number,
value: 0
},
indexList: {
type: Array,
value: indexList()
}
},
data: {
activeAnchorIndex: null,
showSidebar: false
},
methods: {
updateData() {
this.timer && clearTimeout(this.timer);
this.timer = setTimeout(() => {
this.children = this.getRelationNodes('../index-anchor/index');
this.setData({
showSidebar: !!this.children.length
});
this.setRect().then(() => {
this.onScroll();
});
}, 0);
},
setRect() {
return Promise.all([
this.setAnchorsRect(),
this.setListRect(),
this.setSiderbarRect()
]);
},
setAnchorsRect() {
return Promise.all(this.children.map(anchor => (anchor.getRect('.van-index-anchor-wrapper').then((rect) => {
Object.assign(anchor, {
height: rect.height,
top: rect.top + this.data.scrollTop
});
}))));
},
setListRect() {
return this.getRect('.van-index-bar').then((rect) => {
Object.assign(this, {
height: rect.height,
top: rect.top + this.data.scrollTop
});
});
},
setSiderbarRect() {
return this.getRect('.van-index-bar__sidebar').then(res => {
this.sidebar = {
height: res.height,
top: res.top
};
});
},
setDiffData({ target, data }) {
const diffData = {};
Object.keys(data).forEach(key => {
if (target.data[key] !== data[key]) {
diffData[key] = data[key];
}
});
if (Object.keys(diffData).length) {
target.setData(diffData);
}
},
getAnchorRect(anchor) {
return anchor.getRect('.van-index-anchor-wrapper').then((rect) => ({
height: rect.height,
top: rect.top
}));
},
getActiveAnchorIndex() {
const { children } = this;
const { sticky, scrollTop, stickyOffsetTop } = this.data;
for (let i = this.children.length - 1; i >= 0; i--) {
const preAnchorHeight = i > 0 ? children[i - 1].height : 0;
const reachTop = sticky ? preAnchorHeight + stickyOffsetTop : 0;
if (reachTop + scrollTop >= children[i].top) {
return i;
}
}
return -1;
},
onScroll() {
const { children = [] } = this;
if (!children.length) {
return;
}
const { sticky, stickyOffsetTop, zIndex, highlightColor, scrollTop } = this.data;
const active = this.getActiveAnchorIndex();
this.setDiffData({
target: this,
data: {
activeAnchorIndex: active
}
});
if (sticky) {
let isActiveAnchorSticky = false;
if (active !== -1) {
isActiveAnchorSticky = children[active].top <= stickyOffsetTop + scrollTop;
}
children.forEach((item, index) => {
if (index === active) {
let wrapperStyle = '';
let anchorStyle = `
color: ${highlightColor};
`;
if (isActiveAnchorSticky) {
wrapperStyle = `
height: ${children[index].height}px;
`;
anchorStyle = `
position: fixed;
top: ${stickyOffsetTop}px;
z-index: ${zIndex};
color: ${highlightColor};
`;
}
this.setDiffData({
target: item,
data: {
active: true,
anchorStyle,
wrapperStyle
}
});
}
else if (index === active - 1) {
const currentAnchor = children[index];
const currentOffsetTop = currentAnchor.top;
const targetOffsetTop = index === children.length - 1
? this.top
: children[index + 1].top;
const parentOffsetHeight = targetOffsetTop - currentOffsetTop;
const translateY = parentOffsetHeight - currentAnchor.height;
const anchorStyle = `
position: relative;
transform: translate3d(0, ${translateY}px, 0);
z-index: ${zIndex};
color: ${highlightColor};
`;
this.setDiffData({
target: item,
data: {
active: true,
anchorStyle
}
});
}
else {
this.setDiffData({
target: item,
data: {
active: false,
anchorStyle: '',
wrapperStyle: '',
}
});
}
});
}
},
onClick(event) {
this.scrollToAnchor(event.target.dataset.index);
},
onTouchMove(event) {
const sidebarLength = this.children.length;
const touch = event.touches[0];
const itemHeight = this.sidebar.height / sidebarLength;
let index = Math.floor((touch.clientY - this.sidebar.top) / itemHeight);
if (index < 0) {
index = 0;
}
else if (index > sidebarLength - 1) {
index = sidebarLength - 1;
}
this.scrollToAnchor(index);
},
onTouchStop() {
this.scrollToAnchorIndex = null;
},
scrollToAnchor(index) {
if (typeof index !== 'number' || this.scrollToAnchorIndex === index) {
return;
}
this.scrollToAnchorIndex = index;
const anchor = this.children.filter(item => item.data.index === this.data.indexList[index])[0];
this.$emit('select', anchor.data.index);
anchor && wx.pageScrollTo({
duration: 0,
scrollTop: anchor.top
});
}
}
});
<view class="van-index-bar">
<slot />
<view
wx:if="{{ showSidebar }}"
class="van-index-bar__sidebar"
catch:tap="onClick"
catch:touchmove="onTouchMove"
catch:touchend="onTouchStop"
catch:touchcancel="onTouchStop"
>
<view
wx:for="{{ indexList }}"
wx:key="index"
class="van-index-bar__index"
style="z-index: {{ zIndex + 1 }}; color: {{ activeAnchorIndex === index ? highlightColor : '' }}"
data-index="{{ index }}"
>
{{ item }}
</view>
</view>
</view>
@import '../common/index.wxss';.van-index-bar{position:relative}.van-index-bar__sidebar{position:fixed;top:50%;right:0;display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;text-align:center;-webkit-transform:translateY(-50%);transform:translateY(-50%);-webkit-user-select:none;user-select:none}.van-index-bar__index{font-weight:500;padding:0 4px 0 16px;padding:0 var(--padding-base,4px) 0 var(--padding-md,16px);font-size:10px;font-size:var(--index-bar-index-font-size,10px);line-height:14px;line-height:var(--index-bar-index-line-height,14px)}
\ No newline at end of file
@import '../common/index.wxss';.van-nav-bar{position:relative;text-align:center;-webkit-user-select:none;user-select:none;height:44px;height:var(--nav-bar-height,44px);line-height:44px;line-height:var(--nav-bar-height,44px);background-color:#fff;background-color:var(--nav-bar-background-color,#fff)}.van-nav-bar__text{display:inline-block;vertical-align:middle;margin:0 -16px;margin:0 -var(--padding-md,16px);padding:0 -16px;padding:0 -var(--padding-md,16px);color:#1989fa;color:var(--nav-bar-text-color,#1989fa)}.van-nav-bar__text--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-nav-bar__arrow{vertical-align:middle;font-size:16px;font-size:var(--nav-bar-arrow-size,16px);color:#1989fa;color:var(--nav-bar-text-color,#1989fa)}.van-nav-bar__arrow+.van-nav-bar__text{margin-left:-20px;padding-left:25px}.van-nav-bar--fixed{position:fixed;top:0;left:0;width:100%}.van-nav-bar__title{max-width:60%;margin:0 auto;color:#323233;color:var(--nav-bar-title-text-color,#323233);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--nav-bar-title-font-size,16px)}.van-nav-bar__left,.van-nav-bar__right{position:absolute;bottom:0;font-size:14px;font-size:var(--font-size-md,14px)}.van-nav-bar__left{left:16px;left:var(--padding-md,16px)}.van-nav-bar__right{right:16px;right:var(--padding-md,16px)}
\ No newline at end of file
@import '../common/index.wxss';.van-nav-bar{position:relative;text-align:center;-webkit-user-select:none;user-select:none;height:44px;height:var(--nav-bar-height,44px);line-height:44px;line-height:var(--nav-bar-height,44px);background-color:#fff;background-color:var(--nav-bar-background-color,#fff)}.van-nav-bar__text{display:inline-block;vertical-align:middle;margin:0 -16px;margin:0 -var(--padding-md,16px);padding:0 16px;padding:0 var(--padding-md,16px);color:#1989fa;color:var(--nav-bar-text-color,#1989fa)}.van-nav-bar__text--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-nav-bar__arrow{vertical-align:middle;font-size:16px;font-size:var(--nav-bar-arrow-size,16px);color:#1989fa;color:var(--nav-bar-text-color,#1989fa)}.van-nav-bar__arrow+.van-nav-bar__text{margin-left:-20px;padding-left:25px}.van-nav-bar--fixed{position:fixed;top:0;left:0;width:100%}.van-nav-bar__title{max-width:60%;margin:0 auto;color:#323233;color:var(--nav-bar-title-text-color,#323233);font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--nav-bar-title-font-size,16px)}.van-nav-bar__left,.van-nav-bar__right{position:absolute;bottom:0;font-size:14px;font-size:var(--font-size-md,14px)}.van-nav-bar__left{left:16px;left:var(--padding-md,16px)}.van-nav-bar__right{right:16px;right:var(--padding-md,16px)}
\ No newline at end of file
......
......@@ -8,10 +8,7 @@ VantComponent({
readonly: Boolean,
disabled: Boolean,
allowHalf: Boolean,
size: {
type: null,
observer: 'setSizeWithUnit'
},
size: null,
icon: {
type: String,
value: 'star'
......@@ -47,8 +44,7 @@ VantComponent({
},
data: {
innerValue: 0,
gutterWithUnit: undefined,
sizeWithUnit: '20px'
gutterWithUnit: undefined
},
watch: {
value(value) {
......@@ -58,11 +54,6 @@ VantComponent({
}
},
methods: {
setSizeWithUnit(val) {
this.setData({
sizeWithUnit: addUnit(val)
});
},
setGutterWithUnit(val) {
this.setData({
gutterWithUnit: addUnit(val)
......
......@@ -8,10 +8,11 @@
class="van-rate__item"
wx:for="{{ count }}"
wx:key="index"
style="font-size: {{ sizeWithUnit }};padding-right: {{ index !== count - 1 ? gutterWithUnit : '' }}"
style="padding-right: {{ index !== count - 1 ? gutterWithUnit : '' }}"
>
<van-icon
name="{{ index + 1 <= innerValue ? icon : voidIcon }}"
size="{{ size }}"
class="van-rate__icon"
custom-class="icon-class"
data-score="{{ index }}"
......@@ -21,6 +22,7 @@
<van-icon
wx:if="{{ allowHalf }}"
size="{{ size }}"
name="{{ index + 0.5 <= innerValue ? icon : voidIcon }}"
class="{{ utils.bem('rate__icon', ['half']) }}"
custom-class="icon-class"
......
......@@ -17,6 +17,7 @@
/>
<view
wx:for="row"
wx:key="index"
wx:for-index="index"
class="{{ utils.bem('skeleton__row') }}"
style="{{ 'width:' + (isArray ? rowWidth[index] : rowWidth) }}"
......
import { VantComponent } from '../common/component';
const ROOT_ELEMENT = '.van-sticky';
VantComponent({
props: {
zIndex: {
......@@ -7,9 +8,27 @@ VantComponent({
},
offsetTop: {
type: Number,
value: 0
value: 0,
observer: 'observeContent'
},
disabled: Boolean
disabled: {
type: Boolean,
observer(value) {
if (!this.mounted) {
return;
}
value ? this.disconnectObserver() : this.initObserver();
}
},
container: {
type: null,
observer(target) {
if (typeof target !== 'function' || !this.data.height) {
return;
}
this.observeContainer();
}
}
},
data: {
wrapStyle: '',
......@@ -31,35 +50,91 @@ VantComponent({
});
}
},
observerContentScroll() {
getContainerRect() {
const nodesRef = this.data.container();
return new Promise(resolve => nodesRef.boundingClientRect(resolve).exec());
},
initObserver() {
this.disconnectObserver();
this.getRect(ROOT_ELEMENT).then((rect) => {
this.setData({ height: rect.height });
wx.nextTick(() => {
this.observeContent();
this.observeContainer();
});
});
},
disconnectObserver(observerName) {
if (observerName) {
const observer = this[observerName];
observer && observer.disconnect();
}
else {
this.contentObserver && this.contentObserver.disconnect();
this.containerObserver && this.containerObserver.disconnect();
}
},
observeContent() {
const { offsetTop } = this.data;
const intersectionObserver = this.createIntersectionObserver({
this.disconnectObserver('contentObserver');
const contentObserver = this.createIntersectionObserver({
thresholds: [0, 1]
});
this.contentObserver = contentObserver;
contentObserver.relativeToViewport({ top: -offsetTop });
contentObserver.observe(ROOT_ELEMENT, res => {
if (this.data.disabled) {
return;
}
this.setFixed(res.boundingClientRect.top);
});
},
observeContainer() {
if (typeof this.data.container !== 'function') {
return;
}
const { height } = this.data;
this.getContainerRect().then((rect) => {
this.containerHeight = rect.height;
this.disconnectObserver('containerObserver');
const containerObserver = this.createIntersectionObserver({
thresholds: [0, 1]
});
this.intersectionObserver = intersectionObserver;
intersectionObserver.relativeToViewport({ top: -offsetTop });
intersectionObserver.observe('.van-sticky', (res) => {
this.containerObserver = containerObserver;
containerObserver.relativeToViewport({
top: this.containerHeight - height
});
containerObserver.observe(ROOT_ELEMENT, res => {
if (this.data.disabled) {
return;
}
// @ts-ignore
const { top, height } = res.boundingClientRect;
const fixed = top <= offsetTop;
this.setFixed(res.boundingClientRect.top);
});
});
},
setFixed(top) {
const { offsetTop, height } = this.data;
const { containerHeight } = this;
const fixed = containerHeight && height
? top > height - containerHeight && top < offsetTop
: top < offsetTop;
this.$emit('scroll', {
scrollTop: top,
isFixed: fixed
});
this.setData({ fixed, height });
this.setData({ fixed });
wx.nextTick(() => {
this.setStyle();
});
});
}
},
mounted() {
this.observerContentScroll();
this.mounted = true;
if (!this.data.disabled) {
this.initObserver();
}
},
destroyed() {
this.intersectionObserver.disconnect();
this.disconnectObserver();
}
});
......
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class van-sticky }}" style="{{ containerStyle }}">
<view class="custom-class van-sticky" style="{{ containerStyle }}">
<view class="{{ utils.bem('sticky-wrap', { fixed }) }}" style="{{ wrapStyle }}">
<slot />
</view>
......
......@@ -22,10 +22,7 @@ VantComponent({
}
},
data: {
width: null,
inited: false,
active: false,
animated: false
active: false
},
watch: {
title: 'update',
......@@ -35,15 +32,20 @@ VantComponent({
titleStyle: 'update'
},
methods: {
setComputedName() {
this.computedName = this.data.name || this.index;
},
getComputedName() {
if (this.data.name !== '') {
return this.data.name;
}
return this.index;
},
updateRender(active, parent) {
const { data: parentData } = parent;
this.inited = this.inited || active;
this.setData({
active,
shouldRender: this.inited || !parentData.lazyRender
});
},
update() {
if (this.parent) {
this.parent.updateTabs();
......
<wxs src="../wxs/utils.wxs" module="utils" />
<view
wx:if="{{ animated || inited }}"
wx:if="{{ shouldRender }}"
class="custom-class {{ utils.bem('tab__pane', { active, inactive: !active }) }}"
style="{{ animated || active ? '' : 'display: none;' }} {{ width ? 'width:' + width + 'px;' : '' }}"
>
<slot />
</view>
......
@import '../common/index.wxss';.van-tab__pane{box-sizing:border-box;overflow-y:auto}.van-tab__pane--active{height:auto}.van-tab__pane--inactive{height:0;overflow:visible}
\ No newline at end of file
@import '../common/index.wxss';:host{-webkit-flex-shrink:0;flex-shrink:0;width:100%}.van-tab__pane,:host{box-sizing:border-box}.van-tab__pane{overflow-y:auto}.van-tab__pane--active{height:auto}.van-tab__pane--inactive{height:0;overflow:visible}
\ No newline at end of file
......
import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch';
import { nextTick, isDef, addUnit } from '../common/utils';
import { isDef, addUnit } from '../common/utils';
VantComponent({
mixins: [touch],
classes: ['nav-class', 'tab-class', 'tab-active-class', 'line-class'],
relation: {
name: 'tab',
type: 'descendant',
linked(child) {
child.index = this.children.length;
this.children.push(child);
this.updateTabs(this.data.tabs.concat(child.data));
linked(target) {
target.index = this.children.length;
this.children.push(target);
this.updateTabs();
},
unlinked(child) {
const index = this.children.indexOf(child);
const { tabs } = this.data;
tabs.splice(index, 1);
this.children.splice(index, 1);
let i = index;
while (i >= 0 && i < this.children.length) {
const currentChild = this.children[i];
currentChild.index--;
i++;
}
this.updateTabs(tabs);
unlinked(target) {
this.children = this.children
.filter((child) => child !== target)
.map((child, index) => {
child.index = index;
return child;
});
this.updateTabs();
}
},
props: {
......@@ -47,12 +43,15 @@ VantComponent({
value: -1,
observer: 'setLine'
},
titleActiveColor: String,
titleInactiveColor: String,
active: {
type: [String, Number],
value: 0,
observer(value) {
this.currentName = value;
this.setActiveTab();
observer(name) {
if (name !== this.getCurrentName()) {
this.setCurrentIndexByName(name);
}
}
},
type: {
......@@ -63,6 +62,10 @@ VantComponent({
type: Boolean,
value: true
},
ellipsis: {
type: Boolean,
value: true
},
duration: {
type: Number,
value: 0.3
......@@ -74,16 +77,20 @@ VantComponent({
swipeThreshold: {
type: Number,
value: 4,
observer() {
observer(value) {
this.setData({
scrollable: this.children.length > this.data.swipeThreshold
scrollable: this.children.length > value || !this.data.ellipsis
});
}
},
offsetTop: {
type: Number,
value: 0
}
},
lazyRender: {
type: Boolean,
value: true
},
},
data: {
tabs: [],
......@@ -91,51 +98,87 @@ VantComponent({
scrollLeft: 0,
scrollable: false,
trackStyle: '',
wrapStyle: '',
position: '',
currentIndex: 0
currentIndex: null,
container: null
},
beforeCreate() {
this.children = [];
},
mounted() {
this.setData({
container: () => this.createSelectorQuery().select('.van-tabs')
});
this.setLine(true);
this.setTrack();
this.scrollIntoView();
},
methods: {
updateTabs(tabs) {
tabs = tabs || this.data.tabs;
updateTabs() {
const { children = [], data } = this;
this.setData({
tabs,
scrollable: tabs.length > this.data.swipeThreshold
tabs: children.map((child) => child.data),
scrollable: this.children.length > data.swipeThreshold || !data.ellipsis
});
this.setActiveTab();
this.setCurrentIndexByName(this.getCurrentName() || data.active);
},
trigger(eventName, name) {
const { tabs, currentIndex } = this.data;
trigger(eventName) {
const { currentIndex } = this.data;
const child = this.children[currentIndex];
this.$emit(eventName, {
name,
title: tabs[currentIndex].title
index: currentIndex,
name: child.getComputedName(),
title: child.data.title
});
},
onTap(event) {
const { index } = event.currentTarget.dataset;
const child = this.children[index];
const computedName = child.getComputedName();
if (this.data.tabs[index].disabled) {
this.trigger('disabled', computedName);
if (child.data.disabled) {
this.trigger('disabled');
}
else {
this.trigger('click', computedName);
this.setActive(computedName);
this.setCurrentIndex(index);
wx.nextTick(() => {
this.trigger('click');
});
}
},
// correct the index of active tab
setCurrentIndexByName(name) {
const { children = [] } = this;
const matched = children.filter((child) => child.getComputedName() === name);
const defaultIndex = (children[0] || {}).index || 0;
this.setCurrentIndex(matched.length ? matched[0].index : defaultIndex);
},
setCurrentIndex(currentIndex) {
const { data, children = [] } = this;
if (!isDef(currentIndex) ||
currentIndex >= children.length ||
currentIndex < 0) {
return;
}
const shouldEmitChange = data.currentIndex !== null;
this.setData({ currentIndex });
children.forEach((item, index) => {
const active = index === currentIndex;
if (active !== item.data.active || !item.inited) {
item.updateRender(active, this);
}
});
wx.nextTick(() => {
this.setLine();
this.setTrack();
this.scrollIntoView();
this.trigger('input');
if (shouldEmitChange) {
this.trigger('change');
}
});
},
setActive(name) {
if (name !== this.currentName) {
this.currentName = name;
this.trigger('change', name);
this.setActiveTab();
getCurrentName() {
const activeTab = this.children[this.data.currentIndex];
if (activeTab) {
return activeTab.getComputedName();
}
},
setLine(skipTransition) {
......@@ -143,8 +186,11 @@ VantComponent({
return;
}
const { color, duration, currentIndex, lineWidth, lineHeight } = this.data;
this.getRect('.van-tab', true).then((rects) => {
this.getRect('.van-tab', true).then((rects = []) => {
const rect = rects[currentIndex];
if (rect == null) {
return;
}
const width = lineWidth !== -1 ? lineWidth : rect.width / 2;
const height = lineHeight !== -1
? `height: ${addUnit(lineHeight)}; border-radius: ${addUnit(lineHeight)};`
......@@ -170,51 +216,13 @@ VantComponent({
},
setTrack() {
const { animated, duration, currentIndex } = this.data;
if (!animated)
return '';
this.getRect('.van-tabs__content').then((rect) => {
const { width } = rect;
this.setData({
trackStyle: `
width: ${width * this.children.length}px;
left: ${-1 * currentIndex * width}px;
transition: left ${duration}s;
display: -webkit-box;
display: flex;
transform: translate3d(${-100 * currentIndex}%, 0, 0);
-webkit-transition-duration: ${animated ? duration : 0}s;
transition-duration: ${animated ? duration : 0}s;
`
});
const data = { width, animated };
this.children.forEach((item) => {
item.setData(data);
});
});
},
setActiveTab() {
if (!isDef(this.currentName)) {
const { active } = this.data;
const { children = [] } = this;
this.currentName =
active === '' && children.length
? children[0].getComputedName()
: active;
}
this.children.forEach((item, index) => {
const data = {
active: item.getComputedName() === this.currentName
};
if (data.active) {
this.setData({ currentIndex: index });
data.inited = true;
}
if (data.active !== item.data.active) {
item.setData(data);
}
});
nextTick(() => {
this.setLine();
this.setTrack();
this.scrollIntoView();
});
},
// scroll active tab into view
scrollIntoView() {
......@@ -235,6 +243,9 @@ VantComponent({
});
});
},
onTouchScroll(event) {
this.$emit('scroll', event.detail);
},
onTouchStart(event) {
if (!this.data.swipeable)
return;
......@@ -254,12 +265,10 @@ VantComponent({
const minSwipeDistance = 50;
if (direction === 'horizontal' && offsetX >= minSwipeDistance) {
if (deltaX > 0 && currentIndex !== 0) {
const child = this.children[currentIndex - 1];
this.setActive(child.getComputedName());
this.setCurrentIndex(currentIndex - 1);
}
else if (deltaX < 0 && currentIndex !== tabs.length - 1) {
const child = this.children[currentIndex - 1];
this.setActive(child.getComputedName());
this.setCurrentIndex(currentIndex + 1);
}
}
}
......
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="getters" />
<view class="custom-class {{ utils.bem('tabs', [type]) }}">
<van-sticky disabled="{{ !sticky }}" z-index="{{ zIndex }}" offset-top="{{ offsetTop }}">
<van-sticky
disabled="{{ !sticky }}"
z-index="{{ zIndex }}"
offset-top="{{ offsetTop }}"
container="{{ container }}"
bind:scroll="onTouchScroll"
>
<view class="{{ utils.bem('tabs__wrap', { scrollable }) }} {{ type === 'line' && border ? 'van-hairline--top-bottom' : '' }}">
<slot name="nav-left" />
......@@ -18,11 +25,11 @@
wx:for="{{ tabs }}"
wx:key="index"
data-index="{{ index }}"
class="van-ellipsis tab-class {{ index === currentIndex ? 'tab-active-class' : '' }} {{ utils.bem('tab', { active: index === currentIndex, disabled: item.disabled }) }}"
style="{{ color && index !== currentIndex && type === 'card' && !item.disabled ? 'color: ' + color : '' }} {{ color && index === currentIndex && type === 'card' ? ';background-color:' + color : '' }} {{ color ? ';border-color: ' + color : '' }} {{ scrollable ? ';flex-basis:' + (88 / swipeThreshold) + '%' : '' }}"
class="{{ getters.tabClass(index === currentIndex, ellipsis) }} {{ utils.bem('tab', { active: index === currentIndex, disabled: item.disabled, complete: !ellipsis }) }}"
style="{{ getters.tabStyle(index === currentIndex, ellipsis, color, type, item.disabled, titleActiveColor, titleInactiveColor, swipeThreshold, scrollable) }}"
bind:tap="onTap"
>
<view class="van-ellipsis" style="{{ item.titleStyle }}">
<view class="{{ ellipsis ? 'van-ellipsis' : '' }}" style="{{ item.titleStyle }}">
{{ item.title }}
<van-info
wx:if="{{ item.info !== null || item.dot }}"
......
/* eslint-disable */
function tabClass(active, ellipsis) {
var classes = ['tab-class'];
if (active) {
classes.push('tab-active-class');
}
if (ellipsis) {
classes.push('van-ellipsis');
}
return classes.join(' ');
}
function tabStyle(
active,
ellipsis,
color,
type,
disabled,
activeColor,
inactiveColor,
swipeThreshold,
scrollable
) {
var styles = [];
var isCard = type === 'card';
// card theme color
if (color && isCard) {
styles.push('border-color:' + color);
if (!disabled) {
if (active) {
styles.push('background-color:' + color);
} else {
styles.push('color:' + color);
}
}
}
var titleColor = active ? activeColor : inactiveColor;
if (titleColor) {
styles.push('color:' + titleColor);
}
if (scrollable && ellipsis) {
styles.push('flex-basis:' + 88 / swipeThreshold + '%');
}
return styles.join(';');
}
module.exports.tabClass = tabClass;
module.exports.tabStyle = tabStyle;
@import '../common/index.wxss';.van-tabs{position:relative;-webkit-tap-highlight-color:transparent}.van-tabs__wrap{display:-webkit-flex;display:flex;overflow:hidden}.van-tabs__wrap--scrollable .van-tab{-webkit-flex:0 0 22%;flex:0 0 22%}.van-tabs__scroll{background-color:#fff;background-color:var(--tabs-nav-background-color,#fff)}.van-tabs__scroll--line{box-sizing:initial;height:calc(100% + 15px)}.van-tabs__scroll--card{margin:0 16px;margin:0 var(--padding-md,16px)}.van-tabs__nav{position:relative;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none}.van-tabs__nav--card{box-sizing:border-box;height:30px;height:var(--tabs-card-height,30px);border:1px solid #ee0a24;border:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24);border-radius:2px;border-radius:var(--border-radius-sm,2px)}.van-tabs__nav--card .van-tab{color:#ee0a24;color:var(--tabs-default-color,#ee0a24);line-height:28px;line-height:calc(var(--tabs-card-height, 30px) - 2*var(--border-width-base, 1px));border-right:1px solid #ee0a24;border-right:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{color:#fff;color:var(--white,#fff);background-color:#ee0a24;background-color:var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tabs__line{position:absolute;bottom:0;left:0;z-index:1;height:3px;height:var(--tabs-bottom-bar-height,3px);border-radius:3px;border-radius:var(--tabs-bottom-bar-height,3px);background-color:#ee0a24;background-color:var(--tabs-bottom-bar-color,#ee0a24)}.van-tabs__track{position:relative}.van-tabs__content{overflow:hidden}.van-tabs--line .van-tabs__wrap{height:44px;height:var(--tabs-line-height,44px)}.van-tabs--card .van-tabs__wrap{height:30px;height:var(--tabs-card-height,30px)}.van-tab{position:relative;-webkit-flex:1;flex:1;box-sizing:border-box;min-width:0;padding:0 5px;text-align:center;cursor:pointer;color:#7d7e80;color:var(--tab-text-color,#7d7e80);font-size:14px;font-size:var(--tab-font-size,14px);line-height:44px;line-height:var(--tabs-line-height,44px)}.van-tab--active{font-weight:500;font-weight:var(--font-weight-bold,500);color:#323233;color:var(--tab-active-text-color,#323233)}.van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tab__title__info{position:relative!important;top:-1px!important;display:inline-block;-webkit-transform:translateX(0)!important;transform:translateX(0)!important}
\ No newline at end of file
@import '../common/index.wxss';.van-tabs{position:relative;-webkit-tap-highlight-color:transparent}.van-tabs__wrap{display:-webkit-flex;display:flex;overflow:hidden}.van-tabs__wrap--scrollable .van-tab{-webkit-flex:0 0 22%;flex:0 0 22%}.van-tabs__scroll{background-color:#fff;background-color:var(--tabs-nav-background-color,#fff)}.van-tabs__scroll--line{box-sizing:initial;height:calc(100% + 15px)}.van-tabs__scroll--card{margin:0 16px;margin:0 var(--padding-md,16px)}.van-tabs__nav{position:relative;display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none}.van-tabs__nav--card{box-sizing:border-box;height:30px;height:var(--tabs-card-height,30px);border:1px solid #ee0a24;border:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24);border-radius:2px;border-radius:var(--border-radius-sm,2px)}.van-tabs__nav--card .van-tab{color:#ee0a24;color:var(--tabs-default-color,#ee0a24);line-height:28px;line-height:calc(var(--tabs-card-height, 30px) - 2*var(--border-width-base, 1px));border-right:1px solid #ee0a24;border-right:var(--border-width-base,1px) solid var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab:last-child{border-right:none}.van-tabs__nav--card .van-tab.van-tab--active{color:#fff;color:var(--white,#fff);background-color:#ee0a24;background-color:var(--tabs-default-color,#ee0a24)}.van-tabs__nav--card .van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tabs__line{position:absolute;bottom:0;left:0;z-index:1;height:3px;height:var(--tabs-bottom-bar-height,3px);border-radius:3px;border-radius:var(--tabs-bottom-bar-height,3px);background-color:#ee0a24;background-color:var(--tabs-bottom-bar-color,#ee0a24)}.van-tabs__track{position:relative;display:-webkit-flex;display:flex;width:100%;height:100%;transition-property:-webkit-transform;transition-property:transform;transition-property:transform,-webkit-transform}.van-tabs__content{overflow:hidden}.van-tabs--line .van-tabs__wrap{height:44px;height:var(--tabs-line-height,44px)}.van-tabs--card .van-tabs__wrap{height:30px;height:var(--tabs-card-height,30px)}.van-tab{position:relative;-webkit-flex:1;flex:1;box-sizing:border-box;min-width:0;padding:0 5px;text-align:center;cursor:pointer;color:#7d7e80;color:var(--tab-text-color,#7d7e80);font-size:14px;font-size:var(--tab-font-size,14px);line-height:44px;line-height:var(--tabs-line-height,44px)}.van-tab--active{font-weight:500;font-weight:var(--font-weight-bold,500);color:#323233;color:var(--tab-active-text-color,#323233)}.van-tab--disabled{color:#c8c9cc;color:var(--tab-disabled-text-color,#c8c9cc)}.van-tab--complete{-webkit-flex:1 0 auto!important;flex:1 0 auto!important}.van-tab__title__info{position:relative!important;top:-1px!important;display:inline-block;-webkit-transform:translateX(0)!important;transform:translateX(0)!important}
\ No newline at end of file
......
......@@ -4,6 +4,7 @@ import { addUnit } from '../common/utils';
VantComponent({
props: {
disabled: Boolean,
multiple: Boolean,
uploadText: String,
previewSize: {
type: null,
......@@ -77,12 +78,8 @@ VantComponent({
wx.chooseImage({
count: multiple ? (newMaxCount > 9 ? 9 : newMaxCount) : 1,
sourceType: capture,
success: res => {
resolve(res);
},
fail: err => {
reject(err);
}
success: resolve,
fail: reject
});
});
}
......@@ -91,16 +88,12 @@ VantComponent({
wx.chooseMessageFile({
count: multiple ? newMaxCount : 1,
type: 'file',
success(res) {
resolve(res);
},
fail: err => {
reject(err);
}
success: resolve,
fail: reject
});
});
}
chooseFile.then(res => {
chooseFile.then((res) => {
const file = multiple ? res.tempFiles : res.tempFiles[0];
// 检查文件大小
if (file instanceof Array) {
......@@ -119,7 +112,7 @@ VantComponent({
this.$emit('before-read', {
file,
name,
callback: result => {
callback: (result) => {
if (result) {
// 开始上传
this.$emit('after-read', { file, name });
......