9f6b00c9 by simon

默认提交

1 parent 2632c460
Showing 258 changed files with 1830 additions and 522 deletions
......@@ -11,7 +11,7 @@ module.exports = {
"enabledQcloud": false, //是否开启腾讯云COS 上传功能
// 腾讯云COS 上传功能配置表
"qcloud": {
"appid": "1111111",
"appid": "wxd5e3b4b2e7ce2c1a",
"secretId": "xxx",
"secretKey": "xxxxx",
"bucket": "xxxx",
......
......@@ -8,7 +8,7 @@
"minified": true,
"newFeature": true
},
"appid": "wxc57ed87f2569f701",
"appid": "wxd5e3b4b2e7ce2c1a",
"projectname": "gulp-example",
"condition": {}
}
......
{
"pages": [
"pages/index/index",
"pages/detail/detail",
"pages/more/more",
"pages/poster-example/poster-example",
"pages/authorize/authorize",
......@@ -9,31 +10,15 @@
"window": {
"backgroundTextStyle": "light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "mp-gulp-framework",
"navigationBarTitleText": "家有儿孙",
"navigationBarTextStyle": "black"
},
"tabBar": {
"color": "#7A7E83",
"selectedColor": "#CF4646",
"borderStyle": "black",
"backgroundColor": "#ffffff",
"list": [{
"pagePath": "pages/index/index",
"iconPath": "image/tabbar/home_D.png",
"selectedIconPath": "image/tabbar/home.png",
"text": "介绍"
},
{
"pagePath": "pages/more/more",
"iconPath": "image/tabbar/set_D.png",
"selectedIconPath": "image/tabbar/set.png",
"text": "更多"
}
]
},
"usingComponents": {
"authorize-comp": "../../component/authorize-comp/authorize-comp",
"empty-tips": "../../component/empty-tips/empty-tips",
"van-popup": "../../ui/vant-weapp/popup/index"
"van-popup": "../../ui/vant-weapp/popup/index",
"van-sticky": "../../ui/vant-weapp/sticky/index",
"van-tab": "../../ui/vant-weapp/tab/index",
"van-tabs": "../../ui/vant-weapp/tabs/index"
}
}
......
@import "support";
// // Margin
// .u-mt-smaller {
// margin-top: $marginTopSmaller;
// }
// .u-mt-small {
// margin-top: $marginTopSmall;
// }
// .u-mt-medium {
// margin-top: $marginTopMedium;
// }
// .u-mt-large {
// margin-top: $marginTopLarge;
// }
// .u-mt-larger {
// margin-top: $marginTopLarger;
// }
// .u-mb-smaller {
// margin-bottom: $marginTopSmaller;
// }
// .u-mb-small {
// margin-bottom: $marginTopSmall;
// }
// .u-mb-medium {
// margin-bottom: $marginTopMedium;
// }
// .u-mb-large {
// margin-bottom: $marginTopLarge;
// }
// .u-mb-larger {
// margin-bottom: $marginTopLarger;
// }
// // Padding
// .u-pt-smaller {
// padding-top: $paddingTopSmaller;
// }
// .u-pt-small {
// padding-top: $paddingTopSmall;
// }
// .u-pt-medium {
// padding-top: $paddingTopMedium;
// }
// .u-pt-large {
// padding-top: $paddingTopLarge;
// }
// .u-pt-larger {
// padding-top: $paddingTopLarger;
// }
// .u-pb-smaller {
// padding-bottom: $paddingTopSmaller;
// }
// .u-pb-small {
// padding-bottom: $paddingTopSmall;
// }
// .u-pb-medium {
// padding-bottom: $paddingTopMedium;
// }
// .u-pb-large {
// padding-bottom: $paddingTopLarge;
// }
// .u-pb-larger {
// padding-bottom: $paddingTopLarger;
// }
// // 布局方位
// .u-ta-c {
// text-align: center !important;
// }
// .u-ta-l {
// text-align: left !important;
// }
// .u-ta-r {
// text-align: right !important;
// }
// .u-fl-l {
// float: left;
// }
// .u-fl-n {
// float: none;
// }
// .u-fl-r {
// float: right;
// }
// .u-d-b {
// display: block;
// }
// .u-d-i {
// display: inline !important;
// }
// .u-d-ib {
// display: inline-block !important;
// }
// .u-d-n {
// display: none !important;
// }
// .u-d-t {
// display: table;
// table-layout: fixed;
// }
// .u-d-tc {
// display: table-cell;
// }
// .u-va-b {
// vertical-align: bottom;
// }
// .u-va-m {
// vertical-align: middle;
// }
// .u-va-t {
// vertical-align: top;
// }
// // clearfix
// .u-clearfix {
// @include clearfix;
// }
// // 虚拟格式
// .u-cur-d {
// cursor: default;
// }
// .u-cur-p {
// cursor: pointer;
// }
// // flex
// .u-flex {
// display: -webkit-box;
// display: -webkit-flex;
// display: flex;
// }
// .u-flex-item {
// -webkit-box-flex: 1;
// -webkit-flex: 1;
// flex: 1;
// }
// // 小程序中模拟ul、li
// .u-ul {
// padding-left: 30px;
// text-align: left;
// display: block;
// }
// .u-li {
// position: relative;
// font-size: $fontSizeSmall;
// line-height: $fontSizeSmall + 4px;
// margin-bottom: $marginTopSmall;
// &:before {
// position: absolute;
// content: " ";
// top: 14px;
// left: -20px;
// width: 8px;
// height: 8px;
// border-radius: 8px;
// background-color: $colorBlack;
// }
// }
.bis {
background-repeat: no-repeat;
background-size: 100% 100%;
......@@ -213,8 +16,6 @@
justify-content: space-between;
}
.fje {
display: flex;
justify-content: flex-end;
......
// // Margin
// $marginTopSmaller: 20px;
// $marginTopSmall: 30px;
// $marginTopMedium: 40px;
// $marginTopLarge: 60px;
// $marginTopLarger: 80px;
// // Padding
// $paddingTopSmaller: 20px;
// $paddingTopSmall: 30px;
// $paddingTopMedium: 40px;
// $paddingTopLarge: 60px;
// $paddingTopLarger: 80px;
// // Color
// Color
$colorBlue: #20A0FF;
$colorGreen: #13CE66;
$colorGray: #475669;
......@@ -39,3 +23,4 @@ $fontSizeLarger: 44px;
$colorMain:#3680EB;
$pageBottom:80px;
$contentWidth:690px;
......
import {
getBindtapData
} from '../../utils/util';
let app = getApp();
Page({
data: {
authorizeVisible: false,
total: 0,
page: 1,
size: 10,
productList: [], // 产品列表
indexInfo: {},
userInfo: {},
},
onShareAppMessage() {},
showAuth() {
this.setData({
authorizeVisible: true
})
},
onLoad(options) {},
/**
* 基础方法
* 授权完毕重拉数据用
*/
initData() {
},
/**
* 到达底部
* 做加载更多操作
*/
onReachBottom() {
if (this.data.dataList.length < this.data.total) {
this.setData({
page: this.data.page + 1
});
this.queryDataList();
}
},
// 重置页面列表 点击搜索条件时需要
resetPage() {
this.setData({
page: 1,
dataList: []
})
},
/**
* 请求DataList
*/
queryDataList() {
return;
return new Promise((resolve, reject) => {
app.post({
sid: false,
url: app.api.dataList,
data: {
page: this.data.page,
size: this.data.size,
},
}).then((result) => {
let dataList = result.list;
dataList = this.data.dataList.concat(dataList);
this.setData({
dataList: dataList,
total: result.total
})
resolve();
})
});
},
/**
* 隐藏蒙层
*/
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;
}
},
})
{
"navigationBarTitleText": ""
}
@import '../../assets/scss/mixins';
@import '../../assets/scss/utils';
.page {
.bgc {}
.bg {}
.main {
.top-space {
height: 0px;
}
.content {
position: relative;
}
}
.detail {
position: relative;
width: 100%;
height: 944px;
background-color: #333333;
.vid {
margin: 232px auto 0;
width: 100%;
height: 360px;
}
.btn-wrap {
color: #ffffff;
margin: 142px auto 0;
display: flex;
.btn {
width: 312px;
height: 94px;
font-size: 30px;
background-color: #3ec03c;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
.iconfont {
font-size: 48px;
}
.t1 {
padding: 0 6px;
}
}
.btn2 {
background-color: #ae3f48;
}
}
}
.func {
position: relative;
@extend .bb;
padding: 24px 24px;
display: flex;
justify-content: space-between;
align-items: center;
.user {
display: flex;
align-items: center;
flex: 1;
.portrait {
width: 72px;
height: 72px;
border-radius: 72px;
}
.desc {
@extend .bb;
padding-left: 24px;
display: flex;
align-items: center;
align-content: center;
flex-wrap: wrap;
.t1 {
width: 100%;
}
.name {
font-size: 28px;
}
.num {
font-size: 24px;
color: #8d8d8d;
}
}
}
.btn-wrap {
display: flex;
.btn {
margin-right: 24px;
width: 180px;
height: 68px;
font-size: 24px;
background-color: #3ec03c;
border-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
color: #ffffff;
.iconfont {
font-size: 32px;
}
.t1 {
padding: 0 6px;
}
&:last-child {
margin-right: 0;
}
}
.btn2 {
background-color: #fecd9f;
color: #7f776e;
}
}
}
.tit{
@extend .bb;
padding: 0 24px;
}
}
<view class="page">
<view class="app__bgc bgc"></view>
<view class="app__bg bg"></view>
<view class="app__content main">
<view class="top-space"></view>
<view class="content">
<view class="detail">
<video objectFit="cover" class="vid" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/7e91e8a4c7b84e6fa4bada7c8617c9cf.mp4" />
<view class="btn-wrap">
<button class="btn">
<span class="t1 iconfont iconplane"></span>
<span class="t1">分享给好友</span>
</button>
<button class="btn btn2">
<span class="t1 iconfont iconplane"></span>
<span class="t1">分享到群</span>
</button>
</view>
</view>
<view class="func">
<view class="user">
<image class="portrait" mode="aspectFill" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" />
<view class="desc">
<view class="t1 name">我爱我家</view>
<view class="t1 num">280个视频</view>
</view>
</view>
<view class="btn-wrap">
<view class="btn btn2">
<span>更多推荐</span>
</view>
<view class="btn">
<span class="t1 iconfont iconhome"></span>
<span>返回首页</span>
</view>
</view>
</view>
<view class="tit">超有创意的全家福,看了你也想拍!</view>
</view>
</view>
</view>
import {
getBindtapData
} from '../../utils/util'
let app = getApp();
Page({
data: {},
onLoad(options) {
data: {
active: 0
},
onLoad(options) {},
initData() {
},
onChange(event) {
wx.showToast({
title: `切换到标签 ${event.detail.name}`,
icon: 'none'
});
},
onVanTabsHandler(event) {
console.log("event:", event);
let {
index,
title
} = event.detail;
},
onVideoHandler(evt) {
let curItem = getBindtapData(evt);
let curIndex = getBindtapData(evt, "index");
app.router.push({
path: "detail",
query: {
c: curIndex + ""
}
})
console.log("curItem:", curItem);
console.log("curIndex:", curIndex);
},
/**
* 获取列列表
*/
queryList() {
}
})
......
{
"navigationBarTitleText": "首页"
}
......
......@@ -2,17 +2,118 @@
@import '../../assets/scss/utils';
.page {
.bgc {}
color: #333333;
font-size: 24px;
.bg {}
.bgc {
background-color: #efefef;
}
.main {
.top-space {
height: 0px;
.bg {}
.main {
.top-space {
height: 0px;
}
.content {
position: relative;
}
.list {
position: relative;
margin: 0 auto;
width: $contentWidth;
&-item {
position: relative;
background-color: #ffffff;
border-radius: 16px;
margin: 24px auto;
&-video {
display: flex;
justify-content: center;
position: relative;
width: $contentWidth;
.vid {
@include border-top-radius(16px);
width: $contentWidth;
pointer-events: none;
}
.tit {
color: #ffffff;
@extend .bb;
padding: 0 24px;
position: absolute;
width: 100%;
height: 64px;
line-height: 64px;
bottom: 0;
background-color: rgba($color: #000000, $alpha: 0.6);
@include border-top-radius(8px);
@include ellipsis(1);
}
}
.content {
position: relative;
&-func {
@extend .bb;
padding: 24px 24px;
height: 80px;
display: flex;
justify-content: space-between;
align-items: center;
.user {
display: flex;
align-items: center;
.portrait {
width: 48px;
height: 48px;
border-radius: 48px;
}
.name {
padding-left: 12px;
}
}
.share {
font-size: 24px;
display: flex;
justify-content: center;
align-items: center;
// width: 132px;
height: 48px;
color: #ffffff;
background-color: #3ec03c;
border-radius: 8px;
margin: 0;
.iconfont {
font-size: 32px;
}
.t1 {
padding: 0 6px;
}
}
}
}
}
}
.van-tab--active {
color: #fc464a;
}
.van-hairline--top-bottom:after {
border-width: 0;
}
}
......
......@@ -4,6 +4,33 @@
<!-- <view class="app__top-shadow"></view> -->
<view class="app__content main">
<view class="top-space"></view>
<view class="content">index</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>
</van-sticky>
<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 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>
</view>
<view class="list-item-func">
<view class="user">
<image class="portrait" mode="aspectFill" src="https://kd.cdn.xyiyang.com/pro/mzczcradmin/008194acee794506aac4c7200ce654dc.jpg" />
<text class="name">我爱我家</text>
</view>
<button class="share">
<span class="t1 iconfont iconwechat"></span>
<span class="t1">分享</span>
</button>
</view>
</view>
</view>
</view>
</view>
</view>
......
const routerPath = {
index: '/pages/index/index',
detail: '/pages/detail/detail',
authorize: '/pages/authorize/authorize', // 授权
example: '/pages/example/example',
more: '/pages/more/more',
......
import { VantComponent } from '../common/component';
import { safeArea } from '../mixins/safe-area';
VantComponent({
mixins: [safeArea()],
props: {
show: Boolean,
title: String,
cancelText: String,
description: String,
round: {
type: Boolean,
value: true
},
zIndex: {
type: Number,
value: 100
......@@ -21,6 +24,14 @@ VantComponent({
closeOnClickOverlay: {
type: Boolean,
value: true
},
closeOnClickAction: {
type: Boolean,
value: true
},
safeAreaInsetBottom: {
type: Boolean,
value: true
}
},
methods: {
......@@ -29,6 +40,9 @@ VantComponent({
const item = this.data.actions[index];
if (item && !item.disabled && !item.loading) {
this.$emit('select', item);
if (this.data.closeOnClickAction) {
this.onClose();
}
}
},
onCancel() {
......@@ -36,6 +50,10 @@ VantComponent({
},
onClose() {
this.$emit('close');
},
onClickOverlay() {
this.$emit('click-overlay');
this.onClose();
}
}
});
......
......@@ -3,12 +3,13 @@
<van-popup
show="{{ show }}"
position="bottom"
round="{{ round }}"
z-index="{{ zIndex }}"
overlay="{{ overlay }}"
custom-class="van-action-sheet"
safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClose"
bind:close="onClickOverlay"
>
<view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header">
{{ title }}
......@@ -18,12 +19,16 @@
bind:click="onClose"
/>
</view>
<view wx:if="{{ description }}" class="van-action-sheet__description">
{{ description }}
</view>
<view wx:if="{{ actions && actions.length }}">
<!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
<button
wx:for="{{ actions }}"
wx:key="index"
open-type="{{ item.openType }}"
style="{{ item.color ? 'color: ' + item.color : '' }}"
class="{{ utils.bem('action-sheet__item', { disabled: item.disabled || item.loading }) }} van-hairline--top {{ item.className || '' }}"
hover-class="van-action-sheet__item--hover"
data-index="{{ index }}"
......@@ -33,7 +38,7 @@
{{ item.name }}
<text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text>
</block>
<van-loading wx:else size="20px" />
<van-loading wx:else custom-class="van-action-sheet__loading" size="20px" />
</button>
</view>
<slot />
......
@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;color:#333}.van-action-sheet__cancel,.van-action-sheet__item{height:50px;font-size:16px;line-height:50px;text-align:center;background-color:#fff}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5}.van-action-sheet__cancel{height:60px}.van-action-sheet__cancel:before{display:block;height:10px;background-color:#f8f8f8;content:" "}.van-action-sheet__item--disabled{color:#c9c9c9}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff}.van-action-sheet__subname{margin-left:5px;font-size:12px;color:#7d7e80}.van-action-sheet__header{font-size:16px;font-weight:500;line-height:44px;text-align:center}.van-action-sheet__close{position:absolute!important;top:0;right:0;padding:0 15px;font-size:18px!important;line-height:inherit!important;color:#999}
\ No newline at end of file
@import '../common/index.wxss';.van-action-sheet{max-height:90%!important;max-height:var(--action-sheet-max-height,90%)!important;color:#323233;color:var(--action-sheet-item-text-color,#323233)}.van-action-sheet__cancel,.van-action-sheet__item{text-align:center;font-size:16px;font-size:var(--action-sheet-item-font-size,16px);line-height:50px;line-height:var(--action-sheet-item-height,50px);background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__cancel--hover,.van-action-sheet__item--hover{background-color:#f2f3f5;background-color:var(--active-color,#f2f3f5)}.van-action-sheet__cancel:before{display:block;content:" ";height:8px;height:var(--action-sheet-cancel-padding-top,8px);background-color:#f8f8f8;background-color:var(--action-sheet-cancel-padding-color,#f8f8f8)}.van-action-sheet__item--disabled{color:#c8c9cc;color:var(--action-sheet-item-disabled-text-color,#c8c9cc)}.van-action-sheet__item--disabled.van-action-sheet__item--hover{background-color:#fff;background-color:var(--action-sheet-item-background,#fff)}.van-action-sheet__subname{margin-left:4px;margin-left:var(--padding-base,4px);font-size:12px;font-size:var(--action-sheet-subname-font-size,12px);color:#7d7e80;color:var(--action-sheet-subname-color,#7d7e80)}.van-action-sheet__header{text-align:center;font-weight:500;font-weight:var(--font-weight-bold,500);font-size:16px;font-size:var(--action-sheet-header-font-size,16px);line-height:44px;line-height:var(--action-sheet-header-height,44px)}.van-action-sheet__description{text-align:center;padding:16px;padding:var(--padding-md,16px);color:#7d7e80;color:var(--action-sheet-description-color,#7d7e80);font-size:14px;font-size:var(--action-sheet-description-font-size,14px);line-height:20px;line-height:var(--action-sheet-description-line-height,20px)}.van-action-sheet__close{position:absolute!important;top:0;right:0;line-height:inherit!important;padding:0 12px;padding:var(--action-sheet-close-icon-padding,0 12px);font-size:18px!important;font-size:var(--action-sheet-close-icon-size,18px)!important;color:#969799;color:var(--action-sheet-close-icon-color,#969799)}.van-action-sheet__loading{display:-webkit-flex!important;display:flex!important;height:50px;height:var(--action-sheet-item-height,50px)}
\ No newline at end of file
......
import { VantComponent } from '../common/component';
import { pickerProps } from '../picker/shared';
const COLUMNSPLACEHOLDERCODE = '000000';
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
props: {
title: String,
value: String,
loading: Boolean,
cancelButtonText: String,
confirmButtonText: String,
itemHeight: {
type: Number,
value: 44
},
visibleItemCount: {
type: Number,
value: 5
},
columnsNum: {
type: [String, Number],
value: 3
},
areaList: {
props: Object.assign(Object.assign({}, pickerProps), { value: String, areaList: {
type: Object,
value: {}
}
},
}, columnsNum: {
type: null,
value: 3
}, columnsPlaceholder: {
type: Array,
observer(val) {
this.setData({
typeToColumnsPlaceholder: {
province: val[0] || '',
city: val[1] || '',
county: val[2] || '',
}
});
}
} }),
data: {
columns: [{ values: [] }, { values: [] }, { values: [] }],
displayColumns: [{ values: [] }, { values: [] }, { values: [] }]
displayColumns: [{ values: [] }, { values: [] }, { values: [] }],
typeToColumnsPlaceholder: {}
},
watch: {
value(value) {
......@@ -35,11 +33,16 @@ VantComponent({
},
areaList: 'setValues',
columnsNum(value) {
this.set({
this.setData({
displayColumns: this.data.columns.slice(0, +value)
});
}
},
mounted() {
setTimeout(() => {
this.setValues();
}, 0);
},
methods: {
getPicker() {
if (this.picker == null) {
......@@ -51,20 +54,40 @@ VantComponent({
this.emit('cancel', event.detail);
},
onConfirm(event) {
this.emit('confirm', event.detail);
const { index } = event.detail;
let { value } = event.detail;
value = this.parseOutputValues(value);
this.emit('confirm', { value, index });
},
emit(type, detail) {
detail.values = detail.value;
delete detail.value;
this.$emit(type, detail);
},
// parse output columns data
parseOutputValues(values) {
const { columnsPlaceholder } = this.data;
return values.map((value, index) => {
// save undefined value
if (!value)
return value;
value = JSON.parse(JSON.stringify(value));
if (!value.code || value.name === columnsPlaceholder[index]) {
value.code = '';
value.name = '';
}
return value;
});
},
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: picker.getValues(),
values: getValues,
index
});
});
......@@ -74,6 +97,7 @@ VantComponent({
return (areaList && areaList[`${type}_list`]) || {};
},
getList(type, code) {
const { typeToColumnsPlaceholder } = this.data;
let result = [];
if (type !== 'province' && !code) {
return result;
......@@ -90,6 +114,14 @@ VantComponent({
}
result = result.filter(item => item.code.indexOf(code) === 0);
}
if (typeToColumnsPlaceholder[type] && result.length) {
// set columns placeholder
const codeFill = type === 'province' ? '' : type === 'city' ? COLUMNSPLACEHOLDERCODE.slice(2, 4) : COLUMNSPLACEHOLDERCODE.slice(4, 6);
result.unshift({
code: `${code}${codeFill}`,
name: typeToColumnsPlaceholder[type]
});
}
return result;
},
getIndex(type, code) {
......@@ -109,7 +141,18 @@ VantComponent({
},
setValues() {
const county = this.getConfig('county');
let code = this.code || Object.keys(county)[0] || '';
let { code } = this;
if (!code) {
if (this.data.columnsPlaceholder.length) {
code = COLUMNSPLACEHOLDERCODE;
}
else if (Object.keys(county)[0]) {
code = Object.keys(county)[0];
}
else {
code = '';
}
}
const province = this.getList('province');
const city = this.getList('city', code.slice(0, 2));
const picker = this.getPicker();
......@@ -120,7 +163,6 @@ VantComponent({
stack.push(picker.setColumnValues(0, province, false));
stack.push(picker.setColumnValues(1, city, false));
if (city.length && code.slice(2, 4) === '00') {
;
[{ code }] = city;
}
stack.push(picker.setColumnValues(2, this.getList('county', code.slice(0, 4)), false));
......@@ -162,8 +204,8 @@ VantComponent({
}
return area;
},
reset() {
this.code = '';
reset(code) {
this.code = code || '';
return this.setValues();
}
}
......
@import '../common/index.wxss';.van-badge-group{width:85px}
\ No newline at end of file
@import '../common/index.wxss';.van-badge{display:block;padding:20px 12px 20px 9px;overflow:hidden;font-size:14px;line-height:1.4;color:#7d7e80;word-break:break-all;background-color:#f8f8f8;border-left:3px solid transparent;box-sizing:border-box;-webkit-user-select:none;user-select:none}.van-badge--hover{background-color:#f2f3f5}.van-badge:after{border-bottom-width:1px}.van-badge--active{font-weight:700;color:#333;border-color:#f44}.van-badge--active:after{border-right-width:1px}.van-badge--active,.van-badge--active.van-badge--hover{background-color:#fff}.van-badge__text{position:relative}
\ No newline at end of file
......@@ -4,7 +4,11 @@ import { openType } from '../mixins/open-type';
VantComponent({
mixins: [button, openType],
classes: ['hover-class', 'loading-class'],
data: {
style: ''
},
props: {
icon: String,
plain: Boolean,
block: Boolean,
round: Boolean,
......@@ -13,6 +17,11 @@ VantComponent({
hairline: Boolean,
disabled: Boolean,
loadingText: String,
customStyle: String,
loadingType: {
type: String,
value: 'circular'
},
type: {
type: String,
value: 'default'
......@@ -24,6 +33,29 @@ VantComponent({
loadingSize: {
type: String,
value: '20px'
},
color: {
type: String,
observer(color) {
let style = '';
if (color) {
style += `color: ${this.data.plain ? color : 'white'};`;
if (!this.data.plain) {
// Use background instead of backgroundColor to make linear-gradient work
style += `background: ${color};`;
}
// hide border when color is linear-gradient
if (color.indexOf('gradient') !== -1) {
style += 'border: 0;';
}
else {
style += `border-color: ${color};`;
}
}
if (style !== this.data.style) {
this.setData({ style });
}
}
}
},
methods: {
......
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index"
}
}
\ No newline at end of file
}
......
......@@ -3,9 +3,10 @@
<button
id="{{ id }}"
class="custom-class {{ utils.bem('button', [type, size, { block, round, plain, square, loading, disabled, hairline, unclickable: disabled || loading }]) }} {{ hairline ? 'van-hairline--surround' : '' }}"
open-type="{{ openType }}"
hover-class="van-button--active hover-class"
lang="{{ lang }}"
style="{{ style }} {{ customStyle }}"
open-type="{{ openType }}"
business-id="{{ businessId }}"
session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}"
......@@ -26,7 +27,8 @@
<van-loading
custom-class="loading-class"
size="{{ loadingSize }}"
color="{{ type === 'default' ? '#c9c9c9' : '' }}"
type="{{ loadingType }}"
color="{{ type === 'default' ? '#c9c9c9' : 'white' }}"
/>
<view
wx:if="{{ loadingText }}"
......@@ -35,5 +37,16 @@
{{ loadingText }}
</view>
</block>
<slot wx:else />
<block wx:else>
<van-icon
wx:if="{{ icon }}"
size="1.2em"
name="{{ icon }}"
class="van-button__icon"
custom-style="line-height: inherit;"
/>
<view class="van-button__text">
<slot />
</view>
</block>
</button>
......
@import '../common/index.wxss';.van-button{position:relative;display:inline-block;height:44px;padding:0;font-size:16px;line-height:42px;text-align:center;vertical-align:middle;box-sizing:border-box;border-radius:2px;-webkit-appearance:none;-webkit-text-size-adjust:100%}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;background-color:#000;border:inherit;border-color:#000;border-radius:inherit;content:" ";opacity:0;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#333;background-color:#fff;border:1px solid #eee}.van-button--primary{color:#fff;background-color:#07c160;border:1px solid #07c160}.van-button--info{color:#fff;background-color:#1989fa;border:1px solid #1989fa}.van-button--danger{color:#fff;background-color:#f44;border:1px solid #f44}.van-button--warning{color:#fff;background-color:#ff976a;border:1px solid #ff976a}.van-button--plain{background-color:#fff}.van-button--plain.van-button--primary{color:#07c160}.van-button--plain.van-button--info{color:#1989fa}.van-button--plain.van-button--danger{color:#f44}.van-button--plain.van-button--warning{color:#ff976a}.van-button--large{width:100%;height:50px;line-height:48px}.van-button--normal{padding:0 15px;font-size:14px}.van-button--small{height:30px;min-width:60px;padding:0 8px;font-size:12px;line-height:28px}.van-button--mini{display:inline-block;width:50px;height:22px;font-size:10px;line-height:20px}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:block;width:100%}.van-button--round{border-radius:10em}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5}.van-button__loading-text{margin-left:5px;display:inline-block;vertical-align:middle}.van-button--hairline{border-width:0;padding-top:1px}.van-button--hairline:after{border-width:1px;border-color:inherit;border-radius:4px}.van-button--hairline.van-button--round:after{border-radius:10em}.van-button--hairline.van-button--square:after{border-radius:0}
\ No newline at end of file
@import '../common/index.wxss';.van-button{position:relative;display:-webkit-inline-flex;display:inline-flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;padding:0;line-height:20px;text-align:center;vertical-align:middle;-webkit-appearance:none;-webkit-text-size-adjust:100%;height:44px;height:var(--button-default-height,44px);font-size:16px;font-size:var(--button-default-font-size,16px);transition:opacity .2s;transition:opacity var(--animation-duration-fast,.2s);border-radius:2px;border-radius:var(--button-border-radius,2px)}.van-button:before{position:absolute;top:50%;left:50%;width:100%;height:100%;border:inherit;border-radius:inherit;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%);opacity:0;content:" ";background-color:#000;background-color:var(--black,#000);border-color:#000;border-color:var(--black,#000)}.van-button:after{border-width:0}.van-button--active:before{opacity:.15}.van-button--unclickable:after{display:none}.van-button--default{color:#323233;color:var(--button-default-color,#323233);background-color:#fff;background-color:var(--button-default-background-color,#fff);border:1px solid #ebedf0;border:1px solid var(--button-default-border-color,#ebedf0)}.van-button--primary{color:#fff;color:var(--button-primary-color,#fff);background-color:#07c160;background-color:var(--button-primary-background-color,#07c160);border:1px solid #07c160;border:1px solid var(--button-primary-border-color,#07c160)}.van-button--info{color:#fff;color:var(--button-info-color,#fff);background-color:#1989fa;background-color:var(--button-info-background-color,#1989fa);border:1px solid #1989fa;border:1px solid var(--button-info-border-color,#1989fa)}.van-button--danger{color:#fff;color:var(--button-danger-color,#fff);background-color:#ee0a24;background-color:var(--button-danger-background-color,#ee0a24);border:1px solid #ee0a24;border:1px solid var(--button-danger-border-color,#ee0a24)}.van-button--warning{color:#fff;color:var(--button-warning-color,#fff);background-color:#ff976a;background-color:var(--button-warning-background-color,#ff976a);border:1px solid #ff976a;border:1px solid var(--button-warning-border-color,#ff976a)}.van-button--plain{background-color:#fff;background-color:var(--button-plain-background-color,#fff)}.van-button--plain.van-button--primary{color:#07c160;color:var(--button-primary-background-color,#07c160)}.van-button--plain.van-button--info{color:#1989fa;color:var(--button-info-background-color,#1989fa)}.van-button--plain.van-button--danger{color:#ee0a24;color:var(--button-danger-background-color,#ee0a24)}.van-button--plain.van-button--warning{color:#ff976a;color:var(--button-warning-background-color,#ff976a)}.van-button--large{width:100%;height:50px;height:var(--button-large-height,50px)}.van-button--normal{padding:0 15px;font-size:14px;font-size:var(--button-normal-font-size,14px)}.van-button--small{min-width:60px;min-width:var(--button-small-min-width,60px);height:30px;height:var(--button-small-height,30px);padding:0 8px;padding:0 var(--padding-xs,8px);font-size:12px;font-size:var(--button-small-font-size,12px)}.van-button--mini{display:inline-block;min-width:50px;min-width:var(--button-mini-min-width,50px);height:22px;height:var(--button-mini-height,22px);font-size:10px;font-size:var(--button-mini-font-size,10px)}.van-button--mini+.van-button--mini{margin-left:5px}.van-button--block{display:-webkit-flex;display:flex;width:100%}.van-button--round{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--square{border-radius:0}.van-button--disabled{opacity:.5;opacity:var(--button-disabled-opacity,.5)}.van-button__text{display:inline}.van-button__icon+.van-button__text:not(:empty),.van-button__loading-text{margin-left:4px}.van-button__icon{min-width:1em;line-height:inherit!important;vertical-align:top}.van-button--hairline{padding-top:1px;border-width:0}.van-button--hairline:after{border-color:inherit;border-width:1px;border-radius:4px;border-radius:calc(var(--button-border-radius, 2px)*2)}.van-button--hairline.van-button--round:after{border-radius:999px;border-radius:var(--button-round-border-radius,999px)}.van-button--hairline.van-button--square:after{border-radius:0}
\ No newline at end of file
......
......@@ -34,6 +34,7 @@
<view wx:if="{{ price || price === 0 }}" class="van-card__price price-class">{{ currency }} {{ price }}</view>
<view wx:if="{{ originPrice || originPrice === 0 }}" class="van-card__origin-price origin-price-class">{{ currency }} {{ originPrice }}</view>
<view wx:if="{{ num }}" class="van-card__num num-class">x {{ num }}</view>
<slot name="bottom" />
</view>
</view>
</view>
......
@import '../common/index.wxss';.van-card{position:relative;padding:5px 15px;font-size:12px;color:#333;background-color:#fafafa;box-sizing:border-box}.van-card__header{display:-webkit-flex;display:flex}.van-card__header--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-card__thumb{position:relative;width:90px;height:90px;margin-right:10px;-webkit-flex:none;flex:none}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%}.van-card__content{position:relative;min-width:0;-webkit-flex:1;flex:1}.van-card__desc,.van-card__title{word-break:break-all}.van-card__title{font-weight:700;line-height:16px}.van-card__desc{color:#7d7e80}.van-card__bottom,.van-card__desc{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#f44}.van-card__origin-price{display:inline-block;margin-left:5px;font-size:10px;color:#7d7e80;text-decoration:line-through}.van-card__num{float:right}.van-card__tag{position:absolute;top:2px;left:0}.van-card__footer{width:100%;text-align:right;-webkit-flex:none;flex:none}
\ No newline at end of file
@import '../common/index.wxss';.van-card{position:relative;box-sizing:border-box;padding:8px 16px;padding:var(--card-padding,8px 16px);font-size:12px;font-size:var(--card-font-size,12px);color:#323233;color:var(--card-text-color,#323233);background-color:#fafafa;background-color:var(--card-background-color,#fafafa)}.van-card__header{display:-webkit-flex;display:flex}.van-card__header--center{-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center}.van-card__thumb{position:relative;-webkit-flex:none;flex:none;width:90px;width:var(--card-thumb-size,90px);height:90px;height:var(--card-thumb-size,90px);margin-right:8px;margin-right:var(--padding-xs,8px)}.van-card__thumb:empty{display:none}.van-card__img{width:100%;height:100%}.van-card__content{position:relative;-webkit-flex:1;flex:1;min-width:0}.van-card__desc,.van-card__title{word-wrap:break-word}.van-card__title{font-weight:700;line-height:16px;line-height:var(--card-title-line-height,16px)}.van-card__desc{line-height:20px;line-height:var(--card-desc-line-height,20px);color:#7d7e80;color:var(--card-desc-color,#7d7e80)}.van-card__bottom{line-height:20px}.van-card__price{display:inline-block;font-weight:700;color:#ee0a24;color:var(--card-price-color,#ee0a24)}.van-card__origin-price{display:inline-block;margin-left:5px;text-decoration:line-through;font-size:10px;font-size:var(--card-origin-price-font-size,10px);color:#7d7e80;color:var(--card-origin-price-color,#7d7e80)}.van-card__num{float:right}.van-card__tag{position:absolute;top:2px;left:0}.van-card__footer{-webkit-flex:none;flex:none;width:100%;text-align:right}
\ No newline at end of file
......
@import '../common/index.wxss';.van-cell-group__title{font-size:14px;padding:15px 15px 5px;color:#999;line-height:16px}
\ No newline at end of file
@import '../common/index.wxss';.van-cell-group__title{padding:16px 16px 8px;padding:var(--cell-group-title-padding,16px 16px 8px);font-size:14px;font-size:var(--cell-group-title-font-size,14px);line-height:16px;line-height:var(--cell-group-title-line-height,16px);color:#969799;color:var(--cell-group-title-color,#969799)}
\ No newline at end of file
......
......@@ -22,6 +22,7 @@ VantComponent({
titleWidth: String,
customStyle: String,
arrowDirection: String,
useLabelSlot: Boolean,
border: {
type: Boolean,
value: true
......
......@@ -19,11 +19,13 @@
style="{{ titleWidth ? 'max-width:' + titleWidth + ';min-width:' + titleWidth : '' }}"
class="van-cell__title title-class"
>
<block wx:if="{{ title }}">
{{ title }}
<view wx:if="{{ label }}" class="van-cell__label label-class">{{ label }}</view>
</block>
<block wx:if="{{ title }}">{{ title }}</block>
<slot wx:else name="title" />
<view wx:if="{{ label || useLabelSlot }}" class="van-cell__label label-class">
<slot wx:if="{{ useLabelSlot }}" name="label" />
<block wx:elif="{{ label }}">{{ label }}</block>
</view>
</view>
<view class="van-cell__value value-class">
......
@import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;width:100%;padding:10px 15px;font-size:14px;line-height:24px;color:#333;background-color:#fff;box-sizing:border-box}.van-cell:after{content:" ";position:absolute;pointer-events:none;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;top:auto;left:15px;right:0;bottom:0;-webkit-transform:scaleY(.5);transform:scaleY(.5);border-bottom:1px solid #eee}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff}.van-cell__label{margin-top:3px;font-size:12px;line-height:18px;color:#999}.van-cell__value{overflow:hidden;color:#999;text-align:right;vertical-align:middle}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;height:24px;font-size:16px;-webkit-align-items:center;align-items:center}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#999}.van-cell__left-icon{line-height:24px;vertical-align:middle}.van-cell__right-icon{line-height:24px}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;left:7px;font-size:14px;color:#f44;content:"*"}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-bottom:12px}.van-cell--large .van-cell__title{font-size:16px}.van-cell--large .van-cell__label{font-size:14px}
\ No newline at end of file
@import '../common/index.wxss';.van-cell{position:relative;display:-webkit-flex;display:flex;box-sizing:border-box;width:100%;padding:10px 16px;padding:var(--cell-vertical-padding,10px) var(--cell-horizontal-padding,16px);font-size:14px;font-size:var(--cell-font-size,14px);line-height:24px;line-height:var(--cell-line-height,24px);color:#323233;color:var(--cell-text-color,#323233);background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:auto;right:0;bottom:0;left:16px;border-bottom:1px solid #ebedf0;-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-cell--borderless:after{display:none}.van-cell-group{background-color:#fff;background-color:var(--cell-background-color,#fff)}.van-cell__label{margin-top:3px;margin-top:var(--cell-label-margin-top,3px);font-size:12px;font-size:var(--cell-label-font-size,12px);line-height:18px;line-height:var(--cell-label-line-height,18px);color:#969799;color:var(--cell-label-color,#969799)}.van-cell__value{overflow:hidden;text-align:right;vertical-align:middle;color:#969799;color:var(--cell-value-color,#969799)}.van-cell__title,.van-cell__value{-webkit-flex:1;flex:1}.van-cell__title:empty,.van-cell__value:empty{display:none}.van-cell__left-icon-wrap,.van-cell__right-icon-wrap{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;height:24px;height:var(--cell-line-height,24px);font-size:16px;font-size:var(--cell-icon-size,16px)}.van-cell__left-icon-wrap{margin-right:5px}.van-cell__right-icon-wrap{margin-left:5px;color:#969799;color:var(--cell-right-icon-color,#969799)}.van-cell__left-icon{vertical-align:middle}.van-cell__left-icon,.van-cell__right-icon{line-height:24px;line-height:var(--cell-line-height,24px)}.van-cell--clickable.van-cell--hover{background-color:#f2f3f5;background-color:var(--cell-active-color,#f2f3f5)}.van-cell--required{overflow:visible}.van-cell--required:before{position:absolute;content:"*";left:8px;left:var(--padding-xs,8px);font-size:14px;font-size:var(--cell-font-size,14px);color:#ee0a24;color:var(--cell-required-color,#ee0a24)}.van-cell--center{-webkit-align-items:center;align-items:center}.van-cell--large{padding-top:12px;padding-top:var(--cell-large-vertical-padding,12px);padding-bottom:12px;padding-bottom:var(--cell-large-vertical-padding,12px)}.van-cell--large .van-cell__title{font-size:16px;font-size:var(--cell-large-title-font-size,16px)}.van-cell--large .van-cell__label{font-size:14px;font-size:var(--cell-large-label-font-size,14px)}
\ No newline at end of file
......
......@@ -5,29 +5,34 @@ VantComponent({
name: 'checkbox',
type: 'descendant',
linked(target) {
const { value, disabled } = this.data;
target.set({
value: value.indexOf(target.data.name) !== -1,
disabled: disabled || target.data.disabled
});
this.children = this.children || [];
this.children.push(target);
this.updateChild(target);
},
unlinked(target) {
this.children = this.children.filter((child) => child !== target);
}
},
props: {
max: Number,
value: Array,
disabled: Boolean
value: {
type: Array,
observer: 'updateChildren'
},
disabled: {
type: Boolean,
observer: 'updateChildren'
}
},
watch: {
value(value) {
const children = this.getRelationNodes('../checkbox/index');
children.forEach(child => {
child.set({ value: value.indexOf(child.data.name) !== -1 });
});
methods: {
updateChildren() {
(this.children || []).forEach((child) => this.updateChild(child));
},
disabled(disabled) {
const children = this.getRelationNodes('../checkbox/index');
children.forEach(child => {
child.set({ disabled: disabled || child.data.disabled });
updateChild(child) {
const { value, disabled } = this.data;
child.setData({
value: value.indexOf(child.data.name) !== -1,
disabled: disabled || child.data.disabled
});
}
}
......
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
"component": true
}
......
import { VantComponent } from '../common/component';
import { addUnit } from '../common/utils';
function emit(target, value) {
target.$emit('input', value);
target.$emit('change', value);
}
VantComponent({
field: true,
relation: {
name: 'checkbox-group',
type: 'ancestor'
type: 'ancestor',
linked(target) {
this.parent = target;
},
unlinked() {
this.parent = null;
}
},
classes: ['icon-class', 'label-class'],
props: {
value: null,
value: Boolean,
disabled: Boolean,
useIconSlot: Boolean,
checkedColor: String,
......@@ -16,52 +27,61 @@ VantComponent({
shape: {
type: String,
value: 'round'
},
iconSize: {
type: null,
observer: 'setSizeWithUnit'
}
},
data: {
sizeWithUnit: '20px'
},
methods: {
emitChange(value) {
const parent = this.getRelationNodes('../checkbox-group/index')[0];
if (parent) {
this.setParentValue(parent, value);
if (this.parent) {
this.setParentValue(this.parent, value);
}
else {
this.$emit('input', value);
this.$emit('change', value);
emit(this, value);
}
},
toggle() {
if (!this.data.disabled) {
this.emitChange(!this.data.value);
const { disabled, value } = this.data;
if (!disabled) {
this.emitChange(!value);
}
},
onClickLabel() {
if (!this.data.disabled && !this.data.labelDisabled) {
this.emitChange(!this.data.value);
const { labelDisabled, disabled, value } = this.data;
if (!disabled && !labelDisabled) {
this.emitChange(!value);
}
},
setParentValue(parent, value) {
const parentValue = parent.data.value.slice();
const { name } = this.data;
const { max } = parent.data;
if (value) {
if (parent.data.max && parentValue.length >= parent.data.max) {
if (max && parentValue.length >= max) {
return;
}
/* istanbul ignore else */
if (parentValue.indexOf(name) === -1) {
parentValue.push(name);
parent.$emit('input', parentValue);
parent.$emit('change', parentValue);
emit(parent, parentValue);
}
}
else {
const index = parentValue.indexOf(name);
/* istanbul ignore else */
if (index !== -1) {
parentValue.splice(index, 1);
parent.$emit('input', parentValue);
parent.$emit('change', parentValue);
emit(parent, parentValue);
}
}
}
},
setSizeWithUnit(size) {
this.set({
sizeWithUnit: addUnit(size)
});
},
}
});
......
......@@ -6,10 +6,11 @@
<van-icon
wx:else
name="success"
size="0.8em"
class="{{ utils.bem('checkbox__icon', [shape, { disabled, checked: value }]) }}"
style="{{ checkedColor && value && !disabled ? 'border-color:' + checkedColor + '; background-color:' + checkedColor : '' }}"
style="font-size: {{ sizeWithUnit }};{{ checkedColor && value && !disabled ? 'border-color:' + checkedColor + '; background-color:' + checkedColor : '' }}"
custom-class="icon-class"
custom-style="line-height: 20px;"
custom-style="line-height: 1.25em;"
/>
</view>
<view class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled }]) }}" bindtap="onClickLabel">
......
@import '../common/index.wxss';.van-checkbox{overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{display:inline-block;line-height:20px;vertical-align:middle}.van-checkbox__icon{display:block;font-size:14px;width:20px;height:20px;color:transparent;text-align:center;box-sizing:border-box;border:1px solid #e5e5e5;transition:.2s}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;border-color:#1989fa;background-color:#1989fa}.van-checkbox__icon--disabled{border-color:#c9c9c9;background-color:#eee}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c9c9c9}.van-checkbox__label{color:#333;margin-left:10px}.van-checkbox__label--left{float:left;margin:0 10px 0 0}.van-checkbox__label--disabled{color:#c9c9c9}.van-checkbox__label:empty{margin:0}
\ No newline at end of file
@import '../common/index.wxss';.van-checkbox{display:-webkit-flex;display:flex;overflow:hidden;-webkit-user-select:none;user-select:none}.van-checkbox__icon-wrap,.van-checkbox__label{line-height:20px;line-height:var(--checkbox-size,20px)}.van-checkbox__icon-wrap{-webkit-flex:none;flex:none}.van-checkbox__icon{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;box-sizing:border-box;width:1em;height:1em;color:transparent;text-align:center;transition-property:color,border-color,background-color;font-size:20px;font-size:var(--checkbox-size,20px);border:1px solid #e5e5e5;border:1px solid var(--checkbox-border-color,#e5e5e5);transition-duration:.2s;transition-duration:var(--checkbox-transition-duration,.2s)}.van-checkbox__icon--round{border-radius:100%}.van-checkbox__icon--checked{color:#fff;color:var(--white,#fff);background-color:#1989fa;background-color:var(--checkbox-checked-icon-color,#1989fa);border-color:#1989fa;border-color:var(--checkbox-checked-icon-color,#1989fa)}.van-checkbox__icon--disabled{background-color:#ebedf0;background-color:var(--checkbox-disabled-background-color,#ebedf0);border-color:#c8c9cc;border-color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__icon--disabled.van-checkbox__icon--checked{color:#c8c9cc;color:var(--checkbox-disabled-icon-color,#c8c9cc)}.van-checkbox__label{word-wrap:break-word;margin-left:10px;margin-left:var(--checkbox-label-margin,10px);color:#323233;color:var(--checkbox-label-color,#323233)}.van-checkbox__label--left{float:left;margin:0 10px 0 0;margin:0 var(--checkbox-label-margin,10px) 0 0}.van-checkbox__label--disabled{color:#c8c9cc;color:var(--checkbox-disabled-label-color,#c8c9cc)}.van-checkbox__label:empty{margin:0}
\ No newline at end of file
......
import { VantComponent } from '../common/component';
import { isObj } from '../common/utils';
import { BLUE, WHITE } from '../common/color';
function format(rate) {
return Math.min(Math.max(rate, 0), 100);
}
const PERIMETER = 2 * Math.PI;
const BEGIN_ANGLE = -Math.PI / 2;
const STEP = 1;
VantComponent({
props: {
text: String,
lineCap: {
type: String,
value: 'round'
},
value: {
type: Number,
value: 0,
observer: 'reRender'
},
speed: {
type: Number,
value: 50
},
size: {
type: Number,
value: 100,
observer: 'setStyle'
},
fill: String,
layerColor: {
type: String,
value: WHITE
},
color: {
type: [String, Object],
value: BLUE,
observer: 'setHoverColor'
},
strokeWidth: {
type: Number,
value: 4
},
clockwise: {
type: Boolean,
value: true
}
},
data: {
style: 'width: 100px; height: 100px;',
hoverColor: BLUE
},
methods: {
getContext() {
if (!this.ctx) {
this.ctx = wx.createCanvasContext('van-circle', this);
}
return this.ctx;
},
setHoverColor() {
const context = this.getContext();
const { color, size } = this.data;
let hoverColor = color;
if (isObj(color)) {
const LinearColor = context.createLinearGradient(size, 0, 0, 0);
Object.keys(color)
.sort((a, b) => parseFloat(a) - parseFloat(b))
.map(key => LinearColor.addColorStop(parseFloat(key) / 100, color[key]));
hoverColor = LinearColor;
}
this.setData({ hoverColor });
},
setStyle() {
const { size } = this.data;
const style = `width: ${size}px; height: ${size}px;`;
this.setData({ style });
},
presetCanvas(context, strokeStyle, beginAngle, endAngle, fill) {
const { strokeWidth, lineCap, clockwise, size } = this.data;
const position = size / 2;
const radius = position - strokeWidth / 2;
context.setStrokeStyle(strokeStyle);
context.setLineWidth(strokeWidth);
context.setLineCap(lineCap);
context.beginPath();
context.arc(position, position, radius, beginAngle, endAngle, !clockwise);
context.stroke();
if (fill) {
context.setFillStyle(fill);
context.fill();
}
},
renderLayerCircle(context) {
const { layerColor, fill } = this.data;
this.presetCanvas(context, layerColor, 0, PERIMETER, fill);
},
renderHoverCircle(context, formatValue) {
const { clockwise, hoverColor } = this.data;
// 结束角度
const progress = PERIMETER * (formatValue / 100);
const endAngle = clockwise
? BEGIN_ANGLE + progress
: 3 * Math.PI - (BEGIN_ANGLE + progress);
this.presetCanvas(context, hoverColor, BEGIN_ANGLE, endAngle);
},
drawCircle(currentValue) {
const context = this.getContext();
const { size } = this.data;
context.clearRect(0, 0, size, size);
this.renderLayerCircle(context);
const formatValue = format(currentValue);
if (formatValue !== 0) {
this.renderHoverCircle(context, formatValue);
}
context.draw();
},
reRender() {
// tofector 动画暂时没有想到好的解决方案
const { value, speed } = this.data;
if (speed <= 0 || speed > 1000) {
this.drawCircle(value);
return;
}
this.clearInterval();
this.currentValue = this.currentValue || 0;
this.interval = setInterval(() => {
if (this.currentValue !== value) {
if (this.currentValue < value) {
this.currentValue += STEP;
}
else {
this.currentValue -= STEP;
}
this.drawCircle(this.currentValue);
}
else {
this.clearInterval();
}
}, 1000 / speed);
},
clearInterval() {
if (this.interval) {
clearInterval(this.interval);
this.interval = null;
}
}
},
created() {
const { value } = this.data;
this.currentValue = value;
this.drawCircle(value);
},
destroyed() {
this.ctx = null;
this.clearInterval();
}
});
<view class="van-circle">
<canvas class="van-circle__canvas" style="{{ style }}" canvas-id="van-circle"></canvas>
<view wx:if="{{ !text }}" class="van-circle__text">
<slot></slot>
</view>
<cover-view wx:else class="van-circle__text">{{ text }}</cover-view>
</view>
\ No newline at end of file
@import '../common/index.wxss';.van-circle{position:relative;display:inline-block;text-align:center}.van-circle__text{position:absolute;top:50%;left:0;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);color:#323233;color:var(--circle-text-color,#323233)}
\ No newline at end of file
......@@ -16,7 +16,7 @@ VantComponent({
const padding = `${gutter / 2}px`;
const style = gutter ? `padding-left: ${padding}; padding-right: ${padding};` : '';
if (style !== this.data.style) {
this.set({ style });
this.setData({ style });
}
}
}
......
......@@ -16,6 +16,7 @@ VantComponent({
icon: String,
label: String,
disabled: Boolean,
clickable: Boolean,
border: {
type: Boolean,
value: true
......@@ -34,7 +35,11 @@ VantComponent({
this.updateExpanded()
.then(nextTick)
.then(() => {
this.set({ transition: true });
const data = { transition: true };
if (this.data.expanded) {
data.contentHeight = 'auto';
}
this.setData(data);
});
},
methods: {
......@@ -66,11 +71,9 @@ VantComponent({
contentHeight: height ? `${height}px` : 'auto'
});
}
else {
return this.set({ contentHeight: `${height}px` })
.then(nextTick)
.then(() => this.set({ contentHeight: 0 }));
}
return this.set({ contentHeight: `${height}px` })
.then(nextTick)
.then(() => this.set({ contentHeight: 0 }));
});
},
onClick() {
......@@ -84,7 +87,7 @@ VantComponent({
},
onTransitionEnd() {
if (this.data.expanded) {
this.set({
this.setData({
contentHeight: 'auto'
});
}
......
......@@ -5,9 +5,10 @@
title="{{ title }}"
title-class="title-class"
icon="{{ icon }}"
is-link="{{ isLink }}"
value="{{ value }}"
label="{{ label }}"
is-link="{{ isLink }}"
clickable="{{ clickable }}"
border="{{ border && expanded }}"
class="{{ utils.bem('collapse-item__title', { disabled, expanded }) }}"
right-icon-class="van-cell__right-icon"
......
@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:.3s}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c9c9c9!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__wrapper--transition{transition:height .3s ease-in-out}.van-collapse-item__content{padding:15px;font-size:13px;line-height:1.5;color:#999;background-color:#fff}
\ No newline at end of file
@import '../common/index.wxss';.van-collapse-item__title .van-cell__right-icon{-webkit-transform:rotate(90deg);transform:rotate(90deg);transition:-webkit-transform .3s;transition:transform .3s;transition:transform .3s,-webkit-transform .3s;transition:-webkit-transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s);transition:transform var(--collapse-item-transition-duration,.3s),-webkit-transform var(--collapse-item-transition-duration,.3s)}.van-collapse-item__title--expanded .van-cell__right-icon{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}.van-collapse-item__title--disabled .van-cell,.van-collapse-item__title--disabled .van-cell__right-icon{color:#c8c9cc!important;color:var(--collapse-item-title-disabled-color,#c8c9cc)!important}.van-collapse-item__title--disabled .van-cell--hover{background-color:#fff!important;background-color:var(--white,#fff)!important}.van-collapse-item__wrapper{overflow:hidden}.van-collapse-item__wrapper--transition{transition:height .3s ease-in-out}.van-collapse-item__content{padding:15px;padding:var(--collapse-item-content-padding,15px);color:#969799;color:var(--collapse-item-content-text-color,#969799);font-size:13px;font-size:var(--collapse-item-content-font-size,13px);line-height:1.5;line-height:var(--collapse-item-content-line-height,1.5);background-color:#fff;background-color:var(--collapse-item-content-background-color,#fff)}
\ No newline at end of file
......
......@@ -5,6 +5,9 @@ VantComponent({
type: 'descendant',
linked(child) {
this.children.push(child);
},
unlinked(child) {
this.children = this.children.filter((item) => item !== child);
}
},
props: {
......
export declare const RED = "#f44";
export declare const RED = "#ee0a24";
export declare const BLUE = "#1989fa";
export declare const WHITE = "#fff";
export declare const GREEN = "#07c160";
export declare const ORANGE = "#ff976a";
export declare const GRAY = "#323233";
export declare const GRAY_DARK = "#969799";
......
export const RED = '#f44';
export const RED = '#ee0a24';
export const BLUE = '#1989fa';
export const WHITE = '#fff';
export const GREEN = '#07c160';
export const ORANGE = '#ff976a';
export const GRAY = '#323233';
export const GRAY_DARK = '#969799';
......
declare function VantComponent<Data, Props, Watch, Methods, Computed>(vantOptions?: VantComponentOptions<Data, Props, Watch, Methods, Computed, CombinedComponentInstance<Data, Props, Watch, Methods, Computed>>): void;
import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
declare function VantComponent<Data, Props, Methods>(vantOptions?: VantComponentOptions<Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods>>): void;
export { VantComponent };
......
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{content:"";display:table;clear:both}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{content:" ";position:absolute;pointer-events:none;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;top:-50%;left:-50%;right:-50%;bottom:-50%;-webkit-transform:scale(.5);transform:scale(.5);border:0 solid #eee}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}.van-clearfix:after{display:table;clear:both;content:""}.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file
......
.van-clearfix:after{content:"";display:table;clear:both}
\ No newline at end of file
.van-clearfix:after{display:table;clear:both;content:""}
\ No newline at end of file
......
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}
\ No newline at end of file
.van-ellipsis{overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.van-multi-ellipsis--l2{-webkit-line-clamp:2}.van-multi-ellipsis--l2,.van-multi-ellipsis--l3{display:-webkit-box;overflow:hidden;text-overflow:ellipsis;-webkit-box-orient:vertical}.van-multi-ellipsis--l3{-webkit-line-clamp:3}
\ No newline at end of file
......
.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{content:" ";position:absolute;pointer-events:none;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;top:-50%;left:-50%;right:-50%;bottom:-50%;-webkit-transform:scale(.5);transform:scale(.5);border:0 solid #eee}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file
.van-hairline,.van-hairline--bottom,.van-hairline--left,.van-hairline--right,.van-hairline--surround,.van-hairline--top,.van-hairline--top-bottom{position:relative}.van-hairline--bottom:after,.van-hairline--left:after,.van-hairline--right:after,.van-hairline--surround:after,.van-hairline--top-bottom:after,.van-hairline--top:after,.van-hairline:after{position:absolute;box-sizing:border-box;-webkit-transform-origin:center;transform-origin:center;content:" ";pointer-events:none;top:-50%;right:-50%;bottom:-50%;left:-50%;border:0 solid #eee;-webkit-transform:scale(.5);transform:scale(.5)}.van-hairline--top:after{border-top-width:1px}.van-hairline--left:after{border-left-width:1px}.van-hairline--right:after{border-right-width:1px}.van-hairline--bottom:after{border-bottom-width:1px}.van-hairline--top-bottom:after{border-width:1px 0}.van-hairline--surround:after{border-width:1px}
\ No newline at end of file
......
declare function isDef(value: any): boolean;
declare function isObj(x: any): boolean;
declare function isNumber(value: any): boolean;
declare function range(num: number, min: number, max: number): number;
export { isObj, isDef, isNumber, range };
/// <reference types="miniprogram-api-typings" />
export declare function isDef(value: any): boolean;
export declare function isObj(x: any): boolean;
export declare function isNumber(value: any): boolean;
export declare function range(num: number, min: number, max: number): number;
export declare function nextTick(fn: Function): void;
export declare function getSystemInfoSync(): WechatMiniprogram.GetSystemInfoSuccessCallbackResult;
export declare function addUnit(value?: string | number): string | undefined;
......
function isDef(value) {
export function isDef(value) {
return value !== undefined && value !== null;
}
function isObj(x) {
export function isObj(x) {
const type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
function isNumber(value) {
return /^\d+$/.test(value);
export function isNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
function range(num, min, max) {
export function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
export { isObj, isDef, isNumber, range };
export function nextTick(fn) {
setTimeout(() => {
fn();
}, 1000 / 30);
}
let systemInfo = null;
export function getSystemInfoSync() {
if (systemInfo == null) {
systemInfo = wx.getSystemInfoSync();
}
return systemInfo;
}
export function addUnit(value) {
if (!isDef(value)) {
return undefined;
}
value = String(value);
return isNumber(value) ? `${value}px` : value;
}
......
import { VantComponent } from '../common/component';
import { isSameSecond, parseFormat, parseTimeData } from './utils';
function simpleTick(fn) {
return setTimeout(fn, 30);
}
VantComponent({
props: {
useSlot: Boolean,
millisecond: Boolean,
time: {
type: Number,
observer: 'reset'
},
format: {
type: String,
value: 'HH:mm:ss'
},
autoStart: {
type: Boolean,
value: true
}
},
data: {
timeData: parseTimeData(0),
formattedTime: '0'
},
destroyed() {
clearTimeout(this.tid);
this.tid = null;
},
methods: {
// 开始
start() {
if (this.counting) {
return;
}
this.counting = true;
this.endTime = Date.now() + this.remain;
this.tick();
},
// 暂停
pause() {
this.counting = false;
clearTimeout(this.tid);
},
// 重置
reset() {
this.pause();
this.remain = this.data.time;
this.setRemain(this.remain);
if (this.data.autoStart) {
this.start();
}
},
tick() {
if (this.data.millisecond) {
this.microTick();
}
else {
this.macroTick();
}
},
microTick() {
this.tid = simpleTick(() => {
this.setRemain(this.getRemain());
if (this.remain !== 0) {
this.microTick();
}
});
},
macroTick() {
this.tid = simpleTick(() => {
const remain = this.getRemain();
if (!isSameSecond(remain, this.remain) || remain === 0) {
this.setRemain(remain);
}
if (this.remain !== 0) {
this.macroTick();
}
});
},
getRemain() {
return Math.max(this.endTime - Date.now(), 0);
},
setRemain(remain) {
this.remain = remain;
const timeData = parseTimeData(remain);
if (this.data.useSlot) {
this.$emit('change', timeData);
}
this.setData({
formattedTime: parseFormat(this.data.format, timeData)
});
if (remain === 0) {
this.pause();
this.$emit('finish');
}
}
}
});
<view class="van-count-down">
<slot wx:if="{{ useSlot }}"/>
<block wx:else>{{ formattedTime }}</block>
</view>
@import '../common/index.wxss';.van-count-down{color:#323233;color:var(--count-down-text-color,#323233);font-size:14px;font-size:var(--count-down-font-size,14px);line-height:20px;line-height:var(--count-down-line-height,20px)}
\ No newline at end of file
export declare type TimeData = {
days: number;
hours: number;
minutes: number;
seconds: number;
milliseconds: number;
};
export declare function parseTimeData(time: number): TimeData;
export declare function parseFormat(format: string, timeData: TimeData): string;
export declare function isSameSecond(time1: number, time2: number): boolean;
function padZero(num, targetLength = 2) {
let str = num + '';
while (str.length < targetLength) {
str = '0' + str;
}
return str;
}
const SECOND = 1000;
const MINUTE = 60 * SECOND;
const HOUR = 60 * MINUTE;
const DAY = 24 * HOUR;
export function parseTimeData(time) {
const days = Math.floor(time / DAY);
const hours = Math.floor((time % DAY) / HOUR);
const minutes = Math.floor((time % HOUR) / MINUTE);
const seconds = Math.floor((time % MINUTE) / SECOND);
const milliseconds = Math.floor(time % SECOND);
return {
days,
hours,
minutes,
seconds,
milliseconds
};
}
export function parseFormat(format, timeData) {
const { days } = timeData;
let { hours, minutes, seconds, milliseconds } = timeData;
if (format.indexOf('DD') === -1) {
hours += days * 24;
}
else {
format = format.replace('DD', padZero(days));
}
if (format.indexOf('HH') === -1) {
minutes += hours * 60;
}
else {
format = format.replace('HH', padZero(hours));
}
if (format.indexOf('mm') === -1) {
seconds += minutes * 60;
}
else {
format = format.replace('mm', padZero(minutes));
}
if (format.indexOf('ss') === -1) {
milliseconds += seconds * 1000;
}
else {
format = format.replace('ss', padZero(seconds));
}
return format.replace('SSS', padZero(milliseconds, 3));
}
export function isSameSecond(time1, time2) {
return Math.floor(time1 / 1000) === Math.floor(time2 / 1000);
}
import { VantComponent } from '../common/component';
import { isDef } from '../common/utils';
import { pickerProps } from '../picker/shared';
const currentYear = new Date().getFullYear();
function isValidDate(date) {
return isDef(date) && !isNaN(new Date(date).getTime());
......@@ -12,7 +13,7 @@ function padZero(val) {
}
function times(n, iteratee) {
let index = -1;
const result = Array(n);
const result = Array(n < 0 ? 0 : n);
while (++index < n) {
result[index] = iteratee(index);
}
......@@ -29,100 +30,95 @@ function getTrueValue(formattedValue) {
function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}
const defaultFormatter = (_, value) => value;
VantComponent({
props: {
value: null,
title: String,
loading: Boolean,
itemHeight: {
type: Number,
value: 44
},
visibleItemCount: {
type: Number,
value: 5
},
confirmButtonText: {
type: String,
value: '确认'
},
cancelButtonText: {
type: String,
value: '取消'
},
type: {
classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), { value: null, filter: null, type: {
type: String,
value: 'datetime'
},
showToolbar: {
}, showToolbar: {
type: Boolean,
value: true
},
minDate: {
}, formatter: {
type: null,
value: defaultFormatter
}, minDate: {
type: Number,
value: new Date(currentYear - 10, 0, 1).getTime()
},
maxDate: {
}, maxDate: {
type: Number,
value: new Date(currentYear + 10, 11, 31).getTime()
},
minHour: {
}, minHour: {
type: Number,
value: 0
},
maxHour: {
}, maxHour: {
type: Number,
value: 23
},
minMinute: {
}, minMinute: {
type: Number,
value: 0
},
maxMinute: {
}, maxMinute: {
type: Number,
value: 59
}
},
} }),
data: {
innerValue: Date.now(),
columns: []
},
watch: {
value(val) {
value: 'updateValue',
type: 'updateValue',
minDate: 'updateValue',
maxDate: 'updateValue',
minHour: 'updateValue',
maxHour: 'updateValue',
minMinute: 'updateValue',
maxMinute: 'updateValue'
},
methods: {
updateValue() {
const { data } = this;
val = this.correctValue(val);
const val = this.correctValue(this.data.value);
const isEqual = val === data.innerValue;
if (!isEqual) {
this.updateColumnValue(val).then(() => {
this.$emit('input', val);
});
}
else {
this.updateColumns();
}
},
type: 'updateColumns',
minHour: 'updateColumns',
maxHour: 'updateColumns',
minMinute: 'updateColumns',
maxMinute: 'updateColumns'
},
methods: {
getPicker() {
if (this.picker == null) {
const picker = this.picker = this.selectComponent('.van-datetime-picker');
this.picker = this.selectComponent('.van-datetime-picker');
const { picker } = this;
const { setColumnValues } = picker;
picker.setColumnValues = (...args) => setColumnValues.apply(picker, [...args, false]);
}
return this.picker;
},
updateColumns() {
const results = this.getRanges().map(({ type, range }, index) => {
const values = times(range[1] - range[0] + 1, index => {
const { formatter = defaultFormatter } = this.data;
const results = this.getOriginColumns().map(column => ({
values: column.values.map(value => formatter(column.type, value))
}));
return this.set({ columns: results });
},
getOriginColumns() {
const { filter } = this.data;
const results = this.getRanges().map(({ type, range }) => {
let values = times(range[1] - range[0] + 1, index => {
let value = range[0] + index;
value = type === 'year' ? `${value}` : padZero(value);
return value;
});
return { values };
if (filter) {
values = filter(type, values);
}
return { type, values };
});
return this.set({ columns: results });
return results;
},
getRanges() {
const { data } = this;
......@@ -237,7 +233,7 @@ VantComponent({
const picker = this.getPicker();
if (data.type === 'time') {
const indexes = picker.getIndexes();
value = `${indexes[0] + data.minHour}:${indexes[1] + data.minMinute}`;
value = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1].values[indexes[1]]}`;
}
else {
const values = picker.getValues();
......@@ -265,20 +261,26 @@ VantComponent({
},
updateColumnValue(value) {
let values = [];
const { data } = this;
const { type, formatter = defaultFormatter } = this.data;
const picker = this.getPicker();
if (data.type === 'time') {
if (type === 'time') {
const pair = value.split(':');
values = [pair[0], pair[1]];
values = [
formatter('hour', pair[0]),
formatter('minute', pair[1])
];
}
else {
const date = new Date(value);
values = [`${date.getFullYear()}`, padZero(date.getMonth() + 1)];
if (data.type === 'date') {
values.push(padZero(date.getDate()));
values = [
formatter('year', `${date.getFullYear()}`),
formatter('month', padZero(date.getMonth() + 1))
];
if (type === 'date') {
values.push(formatter('day', padZero(date.getDate())));
}
if (data.type === 'datetime') {
values.push(padZero(date.getDate()), padZero(date.getHours()), padZero(date.getMinutes()));
if (type === 'datetime') {
values.push(formatter('day', padZero(date.getDate())), formatter('hour', padZero(date.getHours())), formatter('minute', padZero(date.getMinutes())));
}
}
return this.set({ innerValue: value })
......
<van-picker
class="van-datetime-picker"
active-class="active-class"
toolbar-class="toolbar-class"
column-class="column-class"
title="{{ title }}"
columns="{{ columns }}"
item-height="{{ itemHeight }}"
......
/// <reference types="miniprogram-api-typings" />
import { Weapp } from './weapp';
declare type RecordToAny<T> = {
[K in keyof T]: any;
};
export declare type CombinedComponentInstance<Data, Props, Methods> = Methods & WechatMiniprogram.Component.TrivialInstance & Weapp.FormField & {
data: Data & RecordToAny<Props>;
};
export interface VantComponentOptions<Data, Props, Methods, Instance> {
data?: Data;
field?: boolean;
classes?: string[];
mixins?: string[];
props?: Props & Weapp.PropertyOption;
watch?: Weapp.WatchOption<Instance>;
relation?: Weapp.RelationOption<Instance> & {
name: string;
};
relations?: {
[componentName: string]: Weapp.RelationOption<Instance>;
};
methods?: Methods & Weapp.MethodOption<Instance>;
beforeCreate?: (this: Instance) => void;
created?: (this: Instance) => void;
mounted?: (this: Instance) => void;
destroyed?: (this: Instance) => void;
}
export {};
/// <reference types="miniprogram-api-typings" />
export declare namespace Weapp {
export interface FormField {
data: {
name: string;
value: any;
};
}
interface Target {
id: string;
tagName: string;
dataset: {
[key: string]: any;
};
}
export interface Event {
/**
* 代表事件的类型。
*/
type: string;
/**
* 页面打开到触发事件所经过的毫秒数。
*/
timeStamp: number;
/**
* 触发事件的源组件。
*/
target: Target;
/**
* 事件绑定的当前组件。
*/
currentTarget: Target;
/**
* 额外的信息
*/
detail: any;
}
interface Touch {
/**
* 触摸点的标识符
*/
identifier: number;
/**
* 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
*/
pageX: number;
/**
* 距离文档左上角的距离,文档的左上角为原点 ,横向为X轴,纵向为Y轴
*/
pageY: number;
/**
* 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
*/
clientX: number;
/**
* 距离页面可显示区域(屏幕除去导航条)左上角距离,横向为X轴,纵向为Y轴
*/
clientY: number;
}
export interface TouchEvent extends Event {
touches: Array<Touch>;
changedTouches: Array<Touch>;
}
/**
* relation定义,miniprogram-api-typings缺少this定义
*/
export interface RelationOption<Instance> {
/** 目标组件的相对关系 */
type: 'parent' | 'child' | 'ancestor' | 'descendant';
/** 关系生命周期函数,当关系被建立在页面节点树中时触发,触发时机在组件attached生命周期之后 */
linked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
/** 关系生命周期函数,当关系在页面节点树中发生改变时触发,触发时机在组件moved生命周期之后 */
linkChanged?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
/** 关系生命周期函数,当关系脱离页面节点树时触发,触发时机在组件detached生命周期之后 */
unlinked?(this: Instance, target: WechatMiniprogram.Component.TrivialInstance): void;
/** 如果这一项被设置,则它表示关联的目标节点所应具有的behavior,所有拥有这一behavior的组件节点都会被关联 */
target?: string;
}
/**
* obverser定义,miniprogram-api-typings缺少this定义
*/
type Observer<Instance, T> = (this: Instance, newVal: T, oldVal: T, changedPath: Array<string | number>) => void;
/**
* watch定义
*/
export interface WatchOption<Instance> {
[name: string]: string | Observer<Instance, any>;
}
/**
* methods定义,miniprogram-api-typings缺少this定义
*/
export interface MethodOption<Instance> {
[name: string]: (this: Instance, ...args: any[]) => any;
}
export interface ComputedOption<Instance> {
[name: string]: (this: Instance) => any;
}
type PropertyType = StringConstructor | NumberConstructor | BooleanConstructor | ArrayConstructor | ObjectConstructor | FunctionConstructor | null;
export interface PropertyOption {
[name: string]: PropertyType | PropertyType[] | {
/** 属性类型 */
type: PropertyType | PropertyType[];
/** 属性初始值 */
value?: any;
/** 属性值被更改时的响应函数 */
observer?: string | Observer<WechatMiniprogram.Component.TrivialInstance, any>;
/** 属性的类型(可以指定多个) */
optionalTypes?: PropertyType[];
};
}
export {};
}
/// <reference types="miniprogram-api-typings" />
declare type DialogAction = 'confirm' | 'cancel';
declare type DialogOptions = {
lang?: string;
show?: boolean;
title?: string;
width?: string | number;
zIndex?: number;
context?: any;
context?: WechatMiniprogram.Page.TrivialInstance | WechatMiniprogram.Component.TrivialInstance;
message?: string;
overlay?: boolean;
selector?: string;
ariaLabel?: string;
className?: string;
customStyle?: string;
transition?: string;
asyncClose?: boolean;
businessId?: number;
sessionFrom?: string;
overlayStyle?: string;
appParameter?: string;
messageAlign?: string;
sendMessageImg?: string;
......
......@@ -4,13 +4,14 @@ function getContext() {
return pages[pages.length - 1];
}
const Dialog = options => {
options = Object.assign({}, Dialog.currentOptions, options);
options = Object.assign(Object.assign({}, Dialog.currentOptions), options);
return new Promise((resolve, reject) => {
const context = options.context || getContext();
const dialog = context.selectComponent(options.selector);
delete options.context;
delete options.selector;
if (dialog) {
dialog.set(Object.assign({ onCancel: reject, onConfirm: resolve }, options));
dialog.setData(Object.assign({ onCancel: reject, onConfirm: resolve }, options));
queue.push(dialog);
}
else {
......@@ -21,13 +22,17 @@ const Dialog = options => {
Dialog.defaultOptions = {
show: true,
title: '',
width: null,
message: '',
zIndex: 100,
overlay: true,
selector: '#van-dialog',
className: '',
asyncClose: false,
messageAlign: '',
transition: 'scale',
selector: '#van-dialog',
customStyle: '',
messageAlign: '',
overlayStyle: '',
confirmButtonText: '确认',
cancelButtonText: '取消',
showConfirmButton: true,
......
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
import { addUnit } from '../common/utils';
import { GRAY, BLUE } from '../common/color';
VantComponent({
mixins: [button, openType],
props: {
......@@ -8,11 +10,19 @@ VantComponent({
title: String,
message: String,
useSlot: Boolean,
className: String,
customStyle: String,
asyncClose: Boolean,
messageAlign: String,
overlayStyle: String,
useTitleSlot: Boolean,
showCancelButton: Boolean,
closeOnClickOverlay: Boolean,
confirmButtonOpenType: String,
width: {
type: null,
observer: 'setWidthWithUnit'
},
zIndex: {
type: Number,
value: 2000
......@@ -25,6 +35,14 @@ VantComponent({
type: String,
value: '取消'
},
confirmButtonColor: {
type: String,
value: BLUE
},
cancelButtonColor: {
type: String,
value: GRAY
},
showConfirmButton: {
type: Boolean,
value: true
......@@ -61,19 +79,19 @@ VantComponent({
},
handleAction(action) {
if (this.data.asyncClose) {
this.set({
this.setData({
[`loading.${action}`]: true
});
}
this.onClose(action);
},
close() {
this.set({
this.setData({
show: false
});
},
stopLoading() {
this.set({
this.setData({
loading: {
confirm: false,
cancel: false
......@@ -85,12 +103,17 @@ VantComponent({
this.close();
}
this.$emit('close', action);
//把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading
// 把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading
this.$emit(action, { dialog: this });
const callback = this.data[action === 'confirm' ? 'onConfirm' : 'onCancel'];
if (callback) {
callback(this);
}
},
setWidthWithUnit(val) {
this.setData({
widthWithUnit: addUnit(val)
});
}
}
});
......
......@@ -2,16 +2,19 @@
show="{{ show }}"
z-index="{{ zIndex }}"
overlay="{{ overlay }}"
custom-class="van-dialog"
transition="{{ transition }}"
custom-class="van-dialog {{ className }}"
custom-style="{{ widthWithUnit ? 'width: ' + widthWithUnit + ';' : '' }}{{ customStyle }}"
overlay-style="{{ overlayStyle }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClickOverlay"
>
<view
wx:if="{{ title }}"
wx:if="{{ title || useTitleSlot }}"
class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}"
>
{{ title }}
<slot wx:if="{{ useTitleSlot }}" name="title" />
<block wx:elif="{{ title }}"> {{ title }}</block>
</view>
<slot wx:if="{{ useSlot }}" />
......@@ -19,7 +22,7 @@
wx:elif="{{ message }}"
class="van-dialog__message {{ title ? 'van-dialog__message--has-title' : '' }} {{ messageAlign ? 'van-dialog__message--' + messageAlign : '' }}"
>
<text>{{ message }}</text>
<text class="van-dialog__message-text">{{ message }}</text>
</view>
<view class="van-hairline--top van-dialog__footer">
......@@ -29,6 +32,7 @@
loading="{{ loading.cancel }}"
class="van-dialog__button van-hairline--right"
custom-class="van-dialog__cancel"
custom-style="color: {{ cancelButtonColor }}"
bind:click="onCancel"
>
{{ cancelButtonText }}
......@@ -39,6 +43,7 @@
class="van-dialog__button"
loading="{{ loading.confirm }}"
custom-class="van-dialog__confirm"
custom-style="color: {{ confirmButtonColor }}"
open-type="{{ confirmButtonOpenType }}"
lang="{{ lang }}"
......
@import '../common/index.wxss';.van-dialog{width:85%;overflow:hidden;font-size:16px;background-color:#fff;border-radius:4px}.van-dialog__header{padding-top:25px;font-weight:500;text-align:center}.van-dialog__header--isolated{padding:25px 0}.van-dialog__message{max-height:60vh;padding:25px;overflow-y:auto;font-size:14px;line-height:1.5;text-align:center;-webkit-overflow-scrolling:touch}.van-dialog__message--has-title{padding-top:12px;color:#7d7e80}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog__confirm{color:#1989fa!important}.van-dialog-bounce-enter{opacity:0;-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7)}.van-dialog-bounce-leave-active{opacity:0;-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9)}
\ No newline at end of file
@import '../common/index.wxss';.van-dialog{top:45%!important;overflow:hidden;width:320px;width:var(--dialog-width,320px);font-size:16px;font-size:var(--dialog-font-size,16px);border-radius:16px;border-radius:var(--dialog-border-radius,16px);background-color:#fff;background-color:var(--dialog-background-color,#fff)}@media (max-width:321px){.van-dialog{width:90%;width:var(--dialog-small-screen-width,90%)}}.van-dialog__header{text-align:center;padding-top:24px;padding-top:var(--dialog-header-padding-top,24px);font-weight:500;font-weight:var(--dialog-header-font-weight,500);line-height:24px;line-height:var(--dialog-header-line-height,24px)}.van-dialog__header--isolated{padding:24px 0;padding:var(--dialog-header-isolated-padding,24px 0)}.van-dialog__message{overflow-y:auto;text-align:center;-webkit-overflow-scrolling:touch;font-size:14px;font-size:var(--dialog-message-font-size,14px);line-height:20px;line-height:var(--dialog-message-line-height,20px);max-height:60vh;max-height:var(--dialog-message-max-height,60vh);padding:24px;padding:var(--dialog-message-padding,24px)}.van-dialog__message-text{word-wrap:break-word}.van-dialog__message--has-title{padding-top:12px;padding-top:var(--dialog-has-title-message-padding-top,12px);color:#7d7e80;color:var(--dialog-has-title-message-text-color,#7d7e80)}.van-dialog__message--left{text-align:left}.van-dialog__message--right{text-align:right}.van-dialog__footer{display:-webkit-flex;display:flex}.van-dialog__button{-webkit-flex:1;flex:1}.van-dialog__cancel,.van-dialog__confirm{border:0!important}.van-dialog-bounce-enter{-webkit-transform:translate3d(-50%,-50%,0) scale(.7);transform:translate3d(-50%,-50%,0) scale(.7);opacity:0}.van-dialog-bounce-leave-active{-webkit-transform:translate3d(-50%,-50%,0) scale(.9);transform:translate3d(-50%,-50%,0) scale(.9);opacity:0}
\ No newline at end of file
......
import { VantComponent } from '../common/component';
VantComponent({
props: {
dashed: {
type: Boolean,
value: false
},
hairline: {
type: Boolean,
value: false
},
contentPosition: {
type: String,
value: ''
},
fontSize: {
type: Number,
value: ''
},
borderColor: {
type: String,
value: ''
},
textColor: {
type: String,
value: ''
},
customStyle: {
type: String,
value: ''
}
}
});
{
"component": true,
"usingComponents": {}
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('divider', [{dashed, hairline}, contentPosition]) }}"
style="{{ borderColor ? 'border-color: ' + borderColor + ';' : '' }}{{ textColor ? 'color: ' + textColor + ';' : '' }} {{ fontSize ? 'font-size: ' + fontSize + 'px;' : '' }} {{ customStyle }}"
>
<slot />
</view>
@import '../common/index.wxss';.van-divider{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;margin:16px 0;margin:var(--divider-margin,16px 0);color:#969799;color:var(--divider-text-color,#969799);font-size:14px;font-size:var(--divider-font-size,14px);line-height:24px;line-height:var(--divider-line-height,24px);border:0 solid #ebedf0;border-color:var(--divider-border-color,#ebedf0)}.van-divider:after,.van-divider:before{display:block;-webkit-flex:1;flex:1;box-sizing:border-box;height:1px;border-color:inherit;border-style:inherit;border-width:1px 0 0}.van-divider:before{content:""}.van-divider--hairline:after,.van-divider--hairline:before{-webkit-transform:scaleY(.5);transform:scaleY(.5)}.van-divider--dashed{border-style:dashed}.van-divider--center:before,.van-divider--left:before,.van-divider--right:before{margin-right:16px;margin-right:var(--divider-content-padding,16px)}.van-divider--center:after,.van-divider--left:after,.van-divider--right:after{content:"";margin-left:16px;margin-left:var(--divider-content-padding,16px)}.van-divider--left:before{max-width:10%;max-width:var(--divider-content-left-width,10%)}.van-divider--right:after{max-width:10%;max-width:var(--divider-content-right-width,10%)}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'dropdown-menu',
type: 'ancestor',
linked(target) {
this.parent = target;
},
unlinked() {
this.parent = null;
}
},
props: {
value: null,
title: String,
disabled: Boolean,
titleClass: String,
options: {
type: Array,
value: []
}
},
data: {
transition: true,
showPopup: false,
showWrapper: false,
displayTitle: ''
},
created() {
this.setData({ displayTitle: this.computedDisplayTitle(this.data.value) });
},
methods: {
computedDisplayTitle(curValue) {
const { title, options } = this.data;
if (title) {
return title;
}
const match = options.filter(option => option.value === curValue);
const displayTitle = match.length ? match[0].text : '';
return displayTitle;
},
onClickOverlay() {
this.toggle();
this.$emit('close');
},
onOptionTap(event) {
let { value, displayTitle } = this.data;
const { option } = event.currentTarget.dataset;
const { value: optionValue } = option;
if (optionValue !== value) {
value = optionValue;
displayTitle = this.computedDisplayTitle(optionValue);
this.$emit('change', optionValue);
}
this.setData({ showPopup: false, value, displayTitle });
const time = this.data.duration || 0;
setTimeout(() => {
this.setData({ showWrapper: false });
}, time);
// parent 中的 itemListData 是 children 上的数据的集合
// 数据的更新由 children 各自维护,但是模板的更新需要额外触发 parent 的 setData
this.parent.setData({ itemListData: this.parent.data.itemListData });
},
toggle() {
const { childIndex } = this.data;
this.parent.toggleItem(childIndex);
}
}
});
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-cell": "../cell/index",
"van-switch": "../switch/index"
"van-icon": "../icon/index"
}
}
......
<wxs src="../wxs/utils.wxs" module="utils" />
<view
wx:if="{{ showWrapper }}"
class="{{ utils.bem('dropdown-item', direction) }}"
style="{{ wrapperStyle }}"
>
<van-popup
show="{{ showPopup }}"
custom-style="position: absolute;"
overlay-style="position: absolute;"
overlay="{{ overlay }}"
position="{{ direction === 'down' ? 'top' : 'bottom' }}"
duration="{{ transition ? duration : 0 }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClickOverlay"
>
<van-cell
wx:for="{{ options }}"
wx:key="{{ item.value }}"
data-option="{{ item }}"
class="{{ utils.bem('dropdown-item__option', { active: item.value === value } ) }}"
clickable
icon="{{ item.icon }}"
bind:tap="onOptionTap"
>
<view
slot="title"
class="van-dropdown-item__title"
style="{{ item.value === value ? 'color:' + activeColor : '' }}"
>
{{ item.text }}
</view>
<van-icon
wx:if="{{ item.value === value }}"
name="success"
class="van-dropdown-item__icon"
color="{{ activeColor }}"
/>
</van-cell>
<slot />
</van-popup>
</view>
@import '../common/index.wxss';.van-dropdown-item{position:fixed;right:0;left:0;overflow:hidden}.van-dropdown-item__option{text-align:left}.van-dropdown-item__option--active .van-dropdown-item__icon,.van-dropdown-item__option--active .van-dropdown-item__title{color:#1989fa;color:var(--dropdown-menu-option-active-color,#1989fa)}.van-dropdown-item--up{top:0}.van-dropdown-item--down{bottom:0}.van-dropdown-item__icon{display:block;line-height:inherit}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { addUnit } from '../common/utils';
let ARRAY = [];
VantComponent({
field: true,
relation: {
name: 'dropdown-item',
type: 'descendant',
linked(target) {
this.children = this.children || [];
// 透传 props 给 dropdown-item
const { overlay, duration, activeColor, closeOnClickOverlay, direction } = this.data;
this.updateChildData(target, {
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction,
childIndex: this.children.length
});
this.children.push(target);
// 收集 dropdown-item 的 data 挂在 data 上
target &&
this.setData({
itemListData: this.data.itemListData.concat([target.data])
});
},
unlinked(target) {
this.children = this.children.filter((child) => child !== target);
}
},
props: {
activeColor: String,
overlay: {
type: Boolean,
value: true
},
zIndex: {
type: Number,
value: 10
},
duration: {
type: Number,
value: 200
},
direction: {
type: String,
value: 'down'
},
closeOnClickOverlay: {
type: Boolean,
value: true
},
closeOnClickOutside: {
type: Boolean,
value: true
}
},
data: {
itemListData: []
},
created() {
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter(item => item !== this);
},
methods: {
updateChildData(childItem, newData, needRefreshList = false) {
childItem.setData(newData);
if (needRefreshList) {
// dropdown-item data 更新,涉及到 title 的展示,触发模板更新
this.setData({ itemListData: this.data.itemListData });
}
},
toggleItem(active) {
this.children.forEach((item, index) => {
const { showPopup } = item.data;
if (index === active) {
this.toggleChildItem(item);
}
else if (showPopup) {
this.toggleChildItem(item, false, { immediate: true });
}
});
},
toggleChildItem(childItem, show, options = {}) {
const { showPopup, duration } = childItem.data;
if (show === undefined)
show = !showPopup;
if (show === showPopup) {
return;
}
const newChildData = { transition: !options.immediate, showPopup: show };
if (!show) {
const time = options.immediate ? 0 : duration;
this.updateChildData(childItem, Object.assign({}, newChildData), true);
setTimeout(() => {
this.updateChildData(childItem, { showWrapper: false }, true);
}, time);
return;
}
this.getChildWrapperStyle().then((wrapperStyle = '') => {
this.updateChildData(childItem, Object.assign(Object.assign({}, newChildData), { wrapperStyle, showWrapper: true }), true);
});
},
close() {
this.children.forEach((item) => {
this.toggleChildItem(item, false, { immediate: true });
});
},
getChildWrapperStyle() {
const { windowHeight } = wx.getSystemInfoSync();
const { zIndex, direction } = this.data;
let offset = 0;
return this.getRect('.van-dropdown-menu').then(rect => {
const { top = 0, bottom = 0 } = rect;
if (direction === 'down') {
offset = bottom;
}
else {
offset = windowHeight - top;
}
let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`;
}
else {
wrapperStyle += `bottom: ${addUnit(offset)};`;
}
return Promise.resolve(wrapperStyle);
});
},
onTitleTap(event) {
// item ---> dropdown-item
const { item, index } = event.currentTarget.dataset;
if (!item.disabled) {
// menuItem ---> dropdown-menu
ARRAY.forEach(menuItem => {
if (menuItem && menuItem.data.closeOnClickOutside && menuItem !== this) {
menuItem.close();
}
});
this.toggleItem(index);
}
}
}
});
{
"component": true
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-dropdown-menu van-dropdown-menu--top-bottom">
<view
wx:for="{{ itemListData }}"
wx:key="index"
data-item="{{ item }}"
data-index="{{ index }}"
class="{{ utils.bem('dropdown-menu__item', { disabled: item.disabled }) }}"
bind:tap="onTitleTap"
>
<view
class="{{ item.titleClass }} {{ utils.bem('dropdown-menu__title', { active: item.showPopup, down: item.showPopup === (direction === 'down') }) }}"
style="{{ item.showPopup ? 'color:' + activeColor : '' }}"
>
<view class="van-ellipsis">
{{item.displayTitle}}
</view>
</view>
</view>
<slot />
</view>
@import '../common/index.wxss';.van-dropdown-menu{display:-webkit-flex;display:flex;-webkit-user-select:none;user-select:none;height:50px;height:var(--dropdown-menu-height,50px);background-color:#fff;background-color:var(--dropdown-menu-background-color,#fff)}.van-dropdown-menu__item{display:-webkit-flex;display:flex;-webkit-flex:1;flex:1;-webkit-align-items:center;align-items:center;-webkit-justify-content:center;justify-content:center;min-width:0}.van-dropdown-menu__item:active{opacity:.7}.van-dropdown-menu__item--disabled:active{opacity:1}.van-dropdown-menu__item--disabled .van-dropdown-menu__title{color:#969799;color:var(--dropdown-menu-title-disabled-text-color,#969799)}.van-dropdown-menu__title{position:relative;box-sizing:border-box;max-width:100%;padding:0 8px;padding:var(--dropdown-menu-title-padding,0 8px);color:#323233;color:var(--dropdown-menu-title-text-color,#323233);font-size:15px;font-size:var(--dropdown-menu-title-font-size,15px);line-height:18px;line-height:var(--dropdown-menu-title-line-height,18px)}.van-dropdown-menu__title:after{position:absolute;top:50%;right:-4px;margin-top:-5px;border-color:transparent transparent currentcolor currentcolor;border-style:solid;border-width:3px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);opacity:.8;content:""}.van-dropdown-menu__title--active{color:#1989fa;color:var(--dropdown-menu-title-active-text-color,#1989fa)}.van-dropdown-menu__title--down:after{margin-top:-1px;-webkit-transform:rotate(135deg);transform:rotate(135deg)}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { getSystemInfoSync } from '../common/utils';
VantComponent({
field: true,
classes: ['input-class'],
classes: ['input-class', 'right-icon-class'],
props: {
size: String,
icon: String,
......@@ -12,27 +13,37 @@ VantComponent({
center: Boolean,
isLink: Boolean,
leftIcon: String,
rightIcon: String,
disabled: Boolean,
autosize: Boolean,
readonly: Boolean,
required: Boolean,
password: Boolean,
iconClass: String,
clearable: Boolean,
clickable: Boolean,
inputAlign: String,
errorMessageAlign: String,
customClass: String,
placeholder: String,
customStyle: String,
confirmType: String,
confirmHold: Boolean,
holdKeyboard: Boolean,
errorMessage: String,
placeholder: String,
customStyle: String,
useIconSlot: Boolean,
useButtonSlot: Boolean,
arrowDirection: String,
placeholderStyle: String,
errorMessageAlign: String,
selectionEnd: {
type: Number,
value: -1
},
selectionStart: {
type: Number,
value: -1
},
showConfirmBar: {
type: Boolean,
value: true
},
placeholderStyle: String,
adjustPosition: {
type: Boolean,
value: true
......@@ -59,63 +70,29 @@ VantComponent({
}
},
data: {
showClear: false
},
beforeCreate() {
this.focused = false;
focused: false,
system: getSystemInfoSync().system.split(' ').shift().toLowerCase()
},
methods: {
onInput(event) {
const { value = '' } = event.detail || {};
this.set({
value,
showClear: this.getShowClear(value)
}, () => {
this.setData({ value }, () => {
this.emitChange(value);
});
},
onFocus(event) {
const { value = '', height = 0 } = event.detail || {};
this.$emit('focus', { value, height });
this.focused = true;
this.blurFromClear = false;
this.set({
showClear: this.getShowClear()
});
this.setData({ focused: true });
this.$emit('focus', event.detail);
},
onBlur(event) {
const { value = '', cursor = 0 } = event.detail || {};
this.$emit('blur', { value, cursor });
this.focused = false;
const showClear = this.getShowClear();
if (this.data.value === value) {
this.set({
showClear
});
}
else if (!this.blurFromClear) {
// fix: the handwritten keyboard does not trigger input change
this.set({
value,
showClear
}, () => {
this.emitChange(value);
});
}
this.setData({ focused: false });
this.$emit('blur', event.detail);
},
onClickIcon() {
this.$emit('click-icon');
},
getShowClear(value) {
value = value === undefined ? this.data.value : value;
return (this.data.clearable && this.focused && value && !this.data.readonly);
},
onClear() {
this.blurFromClear = true;
this.set({
value: '',
showClear: this.getShowClear('')
}, () => {
this.setData({ value: '' }, () => {
this.emitChange('');
this.$emit('clear', '');
});
......
<wxs src="../wxs/utils.wxs" module="utils" />
<van-cell
size="{{ size }}"
icon="{{ leftIcon }}"
title="{{ label }}"
center="{{ center }}"
border="{{ border }}"
is-link="{{ isLink }}"
required="{{ required }}"
custom-style="{{ customStyle }}"
clickable="{{ clickable }}"
title-width="{{ titleWidth }}"
custom-style="{{ customStyle }}"
arrow-direction="{{ arrowDirection }}"
custom-class="van-field"
size="{{ size }}"
>
<slot name="left-icon" slot="icon" />
<slot name="label" slot="title" />
<view class="van-field__body {{ type === 'textarea' ? 'van-field__body--textarea' : '' }}">
<view class="{{ utils.bem('field__body', [type, system]) }}">
<textarea
wx:if="{{ type === 'textarea' }}"
class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}"
class="input-class {{ utils.bem('field__input', [inputAlign, type, { disabled, error }]) }}"
fixed="{{ fixed }}"
focus="{{ focus }}"
value="{{ value }}"
disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}"
auto-height="{{ autosize }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
placeholder-class="{{ error ? 'van-field__input--error' : 'van-field__placeholder' }}"
placeholder-class="{{ utils.bem('field__placeholder', { error }) }}"
auto-height="{{ autosize }}"
cursor-spacing="{{ cursorSpacing }}"
adjust-position="{{ adjustPosition }}"
show-confirm-bar="{{ showConfirmBar }}"
hold-keyboard="{{ holdKeyboard }}"
selection-end="{{ selectionEnd }}"
selection-start="{{ selectionStart }}"
bindinput="onInput"
bind:blur="onBlur"
bind:focus="onFocus"
bind:confirm="onConfirm"
/>
>
</textarea>
<input
wx:else
class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}"
......@@ -45,34 +51,39 @@
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
placeholder-class="{{ error ? 'van-field__input--error' : 'van-field__placeholder' }}"
placeholder-class="{{ utils.bem('field__placeholder', { error }) }}"
confirm-type="{{ confirmType }}"
confirm-hold="{{ confirmHold }}"
hold-keyboard="{{ holdKeyboard }}"
cursor-spacing="{{ cursorSpacing }}"
adjust-position="{{ adjustPosition }}"
selection-end="{{ selectionEnd }}"
selection-start="{{ selectionStart }}"
password="{{ password || type === 'password' }}"
bindinput="onInput"
bind:blur="onBlur"
bind:focus="onFocus"
bind:confirm="onConfirm"
/>
<van-icon
wx:if="{{ showClear }}"
wx:if="{{ clearable && focused && value && !readonly }}"
size="16px"
name="clear"
class="van-field__clear-root"
custom-class="van-field__clear"
bind:touchstart="onClear"
class="van-field__clear-root van-field__icon-root"
bindtouchstart="onClear"
/>
<view class="van-field__icon-container" wx:if="{{ icon || useIconSlot }}" bind:tap="onClickIcon">
<view class="van-field__icon-container" bind:tap="onClickIcon">
<van-icon
wx:if="{{ icon }}"
wx:if="{{ rightIcon || icon }}"
size="16px"
name="{{ icon }}"
custom-class="van-field__icon {{ iconClass }}"
name="{{ rightIcon || icon }}"
class="van-field__icon-root {{ iconClass }}"
custom-class="right-icon-class"
/>
<slot wx:else name="icon" />
<slot name="right-icon" />
<slot name="icon" />
</view>
<view wx:if="{{ useButtonSlot }}" class="van-field__button">
<view class="van-field__button">
<slot name="button" />
</view>
</view>
......
@import '../common/index.wxss';.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{min-height:24px}.van-field__input{display:block;width:100%;height:24px;min-height:24px;padding:0;margin:0;line-height:inherit;color:#333;text-align:left;background-color:initial;border:0;box-sizing:border-box;resize:none}.van-field__input--disabled{color:#999;background-color:initial;opacity:1}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__input--error{color:#f44}.van-field__placeholder{color:#999}.van-field__clear-root{display:-webkit-flex;display:flex;height:24px;-webkit-align-items:center;align-items:center}.van-field__button,.van-field__clear,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear,.van-field__icon-container{padding:0 10px;margin-right:-10px;line-height:inherit;vertical-align:middle}.van-field__clear{color:#c9c9c9}.van-field__icon-container{color:#999}.van-field__icon{display:block!important}.van-field__button{padding-left:10px}.van-field__error-message{font-size:12px;color:#f44;text-align:left}.van-field__error--center{text-align:center}.van-field__error--right{text-align:right}
\ No newline at end of file
@import '../common/index.wxss';.van-field__body{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center}.van-field__body--textarea{line-height:1.2em;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__body--textarea.van-field__body--ios{margin-top:-4.5px}.van-field__input{position:relative;display:block;box-sizing:border-box;width:100%;margin:0;padding:0;line-height:inherit;text-align:left;background-color:initial;border:0;resize:none;color:#323233;color:var(--field-input-text-color,#323233);height:24px;height:var(--cell-line-height,24px);min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__input--textarea{height:18px;height:var(--field-text-area-min-height,18px);min-height:18px;min-height:var(--field-text-area-min-height,18px)}.van-field__input--error{color:#ee0a24;color:var(--field-input-error-text-color,#ee0a24)}.van-field__input--disabled{background-color:initial;opacity:1;color:#969799;color:var(--field-input-disabled-text-color,#969799)}.van-field__input--center{text-align:center}.van-field__input--right{text-align:right}.van-field__placeholder{position:absolute;top:0;right:0;left:0;pointer-events:none;color:#969799;color:var(--field-placeholder-text-color,#969799)}.van-field__placeholder--error{color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__icon-root{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;min-height:24px;min-height:var(--cell-line-height,24px)}.van-field__clear-root,.van-field__icon-container{line-height:inherit;vertical-align:middle;padding:0 8px;padding:0 var(--padding-xs,8px);margin-right:-8px;margin-right:-var(--padding-xs,8px)}.van-field__button,.van-field__clear-root,.van-field__icon-container{-webkit-flex-shrink:0;flex-shrink:0}.van-field__clear-root{color:#c8c9cc;color:var(--field-clear-icon-color,#c8c9cc)}.van-field__icon-container{color:#969799;color:var(--field-icon-container-color,#969799)}.van-field__icon-container:empty{display:none}.van-field__button{padding-left:8px;padding-left:var(--padding-xs,8px)}.van-field__button:empty{display:none}.van-field__error-message{text-align:left;font-size:12px;font-size:var(--field-error-message-text-font-size,12px);color:#ee0a24;color:var(--field-error-message-color,#ee0a24)}.van-field__error-message--center{text-align:center}.van-field__error-message--right{text-align:right}
\ No newline at end of file
......
......@@ -4,8 +4,16 @@ import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [link, button, openType],
relation: {
type: 'ancestor',
name: 'goods-action',
linked(parent) {
this.parent = parent;
}
},
props: {
text: String,
color: String,
loading: Boolean,
disabled: Boolean,
type: {
......@@ -13,10 +21,21 @@ VantComponent({
value: 'danger'
}
},
mounted() {
this.updateStyle();
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
},
updateStyle() {
const { children = [] } = this.parent;
const index = children.indexOf(this);
this.setData({
isFirst: index === 0,
isLast: index === children.length - 1
});
}
}
});
......
<wxs src="../wxs/utils.wxs" module="utils" />
<van-button
square
id="{{ id }}"
size="large"
lang="{{ lang }}"
type="{{ type }}"
color="{{ color }}"
loading="{{ loading }}"
disabled="{{ disabled }}"
open-type="{{ openType }}"
custom-class="custom-class"
custom-class="{{ utils.bem('goods-action-button', [type, { first: isFirst, last: isLast }]) }}"
business-id="{{ businessId }}"
session-from="{{ sessionFrom }}"
app-parameter="{{ appParameter }}"
......
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}
\ 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: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
......
......@@ -7,6 +7,7 @@ VantComponent({
mixins: [link, button, openType],
props: {
text: String,
dot: Boolean,
info: String,
icon: String,
disabled: Boolean,
......
......@@ -22,14 +22,17 @@
bindgetphonenumber="bindGetPhoneNumber"
bindlaunchapp="bindLaunchApp"
>
<view class="van-goods-action-icon__content van-hairline--right">
<view class="van-goods-action-icon__content">
<van-icon
wx:if="{{ icon }}"
size="20px"
name="{{ icon }}"
dot="{{ dot }}"
info="{{ info }}"
class="van-goods-action-icon__icon"
custom-class="icon-class"
/>
<slot name="icon" />
<text class="text-class">{{ text }}</text>
</view>
</van-button>
......
@import '../common/index.wxss';.van-goods-action-icon{width:50px!important;border:none!important}.van-goods-action-icon__content{display:-webkit-flex;display:flex;height:100%;font-size:10px;line-height:1;color:#7d7e80;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:center;justify-content:center}.van-goods-action-icon__icon{margin-bottom:4px}
\ No newline at end of file
@import '../common/index.wxss';.van-goods-action-icon{border:none!important;width:50px!important;width:var(--goods-action-icon-height,50px)!important}.van-goods-action-icon__content{display:-webkit-flex;display:flex;-webkit-flex-direction:column;flex-direction:column;-webkit-justify-content:center;justify-content:center;height:100%;line-height:1;font-size:10px;font-size:var(--goods-action-icon-font-size,10px);color:#7d7e80;color:var(--goods-action-icon-text-color,#7d7e80)}.van-goods-action-icon__icon{margin-bottom:4px}
\ No newline at end of file
......
import { VantComponent } from '../common/component';
import { safeArea } from '../mixins/safe-area';
VantComponent({
mixins: [safeArea()]
relation: {
type: 'descendant',
name: 'goods-action-button',
linked(child) {
this.children.push(child);
},
unlinked(child) {
this.children = this.children.filter((item) => item !== child);
}
},
beforeCreate() {
this.children = [];
},
props: {
safeAreaInsetBottom: {
type: Boolean,
value: true
}
}
});
......
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class {{ utils.bem('goods-action', { safe: isIPhoneX && safeAreaInsetBottom }) }}">
<view class="custom-class {{ utils.bem('goods-action', { safe: safeAreaInsetBottom }) }}">
<slot />
</view>
......