5e7fefff by simon

默认提交

1 parent bdaddaca
Showing 227 changed files with 1918 additions and 15 deletions
......@@ -11,7 +11,7 @@
</view>
<view class="bid">
我要报价
<input value="{{bidPrice}}" class="val" bindinput="bindBidPriceInput" class="ipt" placeholder="{{maxPrice + productInfo.minScope}}" />
<input value="{{bidPrice}}" class="val" bindinput="bindBidPriceInput" class="ipt" placeholder="{{filter.Fen2Yuan(maxPrice + productInfo.minScope)}}" />
</view>
</view>
......
......@@ -14,6 +14,7 @@
top: 16px;
font-size: 40px;
color: #333333;
z-index: 11;
}
.succ {
......
......@@ -28,6 +28,7 @@ Page({
wxTimerList: {},
lastTime: "",
bidPrice: 0, // 我的出价 单位元
isTimeEnd: false, //倒计时结束
},
onShareAppMessage() {},
showAuth() {
......@@ -53,12 +54,20 @@ Page({
initData() {
this.queryMember().then((result) => {
this.refreshView();
this.openSocket();
});
},
/**
* 刷新页面
*/
refreshView() {
this.queryAuctionDetail().then((result) => {
this.removeTimer();
this.startTimer();
})
this.queryAuctionRecordLast();
this.openSocket();
});
},
// 开始倒计时
......@@ -73,6 +82,9 @@ Page({
wxTimer = new timer({
beginTime: beginTime,
complete() {
_this.setData({
isTimeEnd: true
})
_this.removeTimer();
_this.queryAuctionDetail();
},
......@@ -288,6 +300,7 @@ Page({
socketStatus: 'connected',
waitingResponse: false
})
this.refreshView();
})
wx.onSocketClose(() => {
......@@ -307,10 +320,11 @@ Page({
// 监听服务器推送消息
wx.onSocketMessage(message => {
console.log('socket message:', message)
console.log('socket message:', message);
this.setData({
loading: false
})
});
this.refreshView();
})
// 打开信道
......
......@@ -23,7 +23,7 @@
<text class="price">¥{{filter.Fen2Yuan(maxPrice)}}</text>
<text class="t1">当前价格</text>
</view>
<view class="func-ele func-right {{productInfo.status != 1 ? 'disable' : ''}}">
<view class="func-ele func-right {{productInfo.status != 1 || isTimeEnd ? 'disable' : ''}}">
<text wx:if="{{productInfo.status == 0}}" class="t1 t2">拍卖未开始</text>
<text wx:if="{{productInfo.status == 1}}" class="t1">拍卖进行中</text>
<text wx:if="{{productInfo.status == 2}}" class="t1 t2">拍卖已结束</text>
......@@ -78,7 +78,7 @@
</view>
</view>
<!-- 按钮 -->
<view bindtap="onSubmitHandler" class="submit-btn {{productInfo.status != 1 ? 'disable' : ''}}">
<view bindtap="onSubmitHandler" class="submit-btn {{productInfo.status != 1 || isTimeEnd ? 'disable' : ''}}">
我要出价
</view>
</view>
......
......@@ -20,12 +20,10 @@ Page({
})
},
onShow() {
},
onLoad(options) {
this.resetPage();
this.initData();
},
onLoad(options) {},
initData() {
this.queryAuctionList();
},
......@@ -79,6 +77,12 @@ Page({
success(res) {}
})
}
} else {
wx.showModal({
content: "活动已结束",
showCancel: false,
success(res) {}
})
}
},
......
......@@ -20,6 +20,7 @@ Page({
lastTime: "",
isSellOut: false,
orderStatus: 0, // 0.未下单 1.下单成功
isTimeEnd: false, //倒计时结束
},
onShareAppMessage() {},
showAuth() {
......@@ -62,6 +63,9 @@ Page({
wxTimer = new timer({
beginTime: beginTime,
complete() {
_this.setData({
isTimeEnd: true
})
_this.removeTimer();
_this.querySeckillDetail();
},
......
......@@ -24,7 +24,7 @@
<text class="t1 line-th">¥{{filter.Fen2Yuan(productInfo.specialPrice)}}</text>
<text class="t1">仅剩{{productInfo.stock}}个</text>
</view>
<view class="func-ele func-right {{productInfo.status != 1 ? 'disable' : ''}}">
<view class="func-ele func-right {{productInfo.status != 1 || isTimeEnd ? 'disable' : ''}}">
<text wx:if="{{productInfo.status == 0}}" class="t1 t2">秒杀未开始</text>
<text wx:if="{{productInfo.status == 1}}" class="t1">秒杀进行中</text>
<text wx:if="{{productInfo.status == 2}}" class="t1 t2">秒杀已结束</text>
......@@ -42,7 +42,7 @@
</view>
</view>
<!-- 按钮 -->
<view bindtap="onSubmitHandler" class="submit-btn {{productInfo.status != 1 ? 'disable' : ''}}">
<view bindtap="onSubmitHandler" class="submit-btn {{productInfo.status != 1 || isTimeEnd ? 'disable' : ''}}">
立即秒杀
</view>
</view>
......
......@@ -20,12 +20,12 @@ Page({
})
},
onShow() {
},
onLoad(options) {
this.resetPage();
this.initData();
},
onLoad(options) {
},
initData() {
this.querySeckillList();
},
......
import { VantComponent } from '../common/component';
import { safeArea } from '../mixins/safe-area';
VantComponent({
mixins: [safeArea()],
props: {
show: Boolean,
title: String,
cancelText: String,
zIndex: {
type: Number,
value: 100
},
actions: {
type: Array,
value: []
},
overlay: {
type: Boolean,
value: true
},
closeOnClickOverlay: {
type: Boolean,
value: true
}
},
methods: {
onSelect(event) {
const { index } = event.currentTarget.dataset;
const item = this.data.actions[index];
if (item && !item.disabled && !item.loading) {
this.$emit('select', item);
}
},
onCancel() {
this.$emit('cancel');
},
onClose() {
this.$emit('close');
}
}
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-popup": "../popup/index",
"van-loading": "../loading/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<van-popup
show="{{ show }}"
position="bottom"
z-index="{{ zIndex }}"
overlay="{{ overlay }}"
custom-class="van-action-sheet"
safe-area-inset-bottom="{{ safeAreaInsetBottom }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClose"
>
<view wx:if="{{ title }}" class="van-hairline--bottom van-action-sheet__header">
{{ title }}
<van-icon
name="close"
custom-class="van-action-sheet__close"
bind:click="onClose"
/>
</view>
<view wx:if="{{ actions && actions.length }}">
<!-- button外包一层view,防止actions动态变化,导致渲染时button被打散 -->
<button
wx:for="{{ actions }}"
wx:key="index"
open-type="{{ item.openType }}"
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 }}"
bind:tap="onSelect"
>
<block wx:if="{{ !item.loading }}">
{{ item.name }}
<text wx:if="{{ item.subname }}" class="van-action-sheet__subname" >{{ item.subname }}</text>
</block>
<van-loading wx:else size="20px" />
</button>
</view>
<slot />
<view
wx:if="{{ cancelText }}"
class="van-action-sheet__cancel"
hover-class="van-action-sheet__cancel--hover"
hover-stay-time="70"
bind:tap="onCancel"
>
{{ cancelText }}
</view>
</van-popup>
@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 { VantComponent } from '../common/component';
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: {
type: Object,
value: {}
}
},
data: {
columns: [{ values: [] }, { values: [] }, { values: [] }],
displayColumns: [{ values: [] }, { values: [] }, { values: [] }]
},
watch: {
value(value) {
this.code = value;
this.setValues();
},
areaList: 'setValues',
columnsNum(value) {
this.set({
displayColumns: this.data.columns.slice(0, +value)
});
}
},
methods: {
getPicker() {
if (this.picker == null) {
this.picker = this.selectComponent('.van-area__picker');
}
return this.picker;
},
onCancel(event) {
this.emit('cancel', event.detail);
},
onConfirm(event) {
this.emit('confirm', event.detail);
},
emit(type, detail) {
detail.values = detail.value;
delete detail.value;
this.$emit(type, detail);
},
onChange(event) {
const { index, picker, value } = event.detail;
this.code = value[index].code;
this.setValues().then(() => {
this.$emit('change', {
picker,
values: picker.getValues(),
index
});
});
},
getConfig(type) {
const { areaList } = this.data;
return (areaList && areaList[`${type}_list`]) || {};
},
getList(type, code) {
let result = [];
if (type !== 'province' && !code) {
return result;
}
const list = this.getConfig(type);
result = Object.keys(list).map(code => ({
code,
name: list[code]
}));
if (code) {
// oversea code
if (code[0] === '9' && type === 'city') {
code = '9';
}
result = result.filter(item => item.code.indexOf(code) === 0);
}
return result;
},
getIndex(type, code) {
let compareNum = type === 'province' ? 2 : type === 'city' ? 4 : 6;
const list = this.getList(type, code.slice(0, compareNum - 2));
// oversea code
if (code[0] === '9' && type === 'province') {
compareNum = 1;
}
code = code.slice(0, compareNum);
for (let i = 0; i < list.length; i++) {
if (list[i].code.slice(0, compareNum) === code) {
return i;
}
}
return 0;
},
setValues() {
const county = this.getConfig('county');
let code = this.code || Object.keys(county)[0] || '';
const province = this.getList('province');
const city = this.getList('city', code.slice(0, 2));
const picker = this.getPicker();
if (!picker) {
return;
}
const stack = [];
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));
return Promise.all(stack)
.catch(() => { })
.then(() => picker.setIndexes([
this.getIndex('province', code),
this.getIndex('city', code),
this.getIndex('county', code)
]))
.catch(() => { });
},
getValues() {
const picker = this.getPicker();
return picker ? picker.getValues().filter(value => !!value) : [];
},
getDetail() {
const values = this.getValues();
const area = {
code: '',
country: '',
province: '',
city: '',
county: ''
};
if (!values.length) {
return area;
}
const names = values.map((item) => item.name);
area.code = values[values.length - 1].code;
if (area.code[0] === '9') {
area.country = names[1] || '';
area.province = names[2] || '';
}
else {
area.province = names[0] || '';
area.city = names[1] || '';
area.county = names[2] || '';
}
return area;
},
reset() {
this.code = '';
return this.setValues();
}
}
});
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}
<van-picker
class="van-area__picker"
active-class="active-class"
toolbar-class="toolbar-class"
column-class="column-class"
show-toolbar
value-key="name"
title="{{ title }}"
loading="{{ loading }}"
columns="{{ displayColumns }}"
item-height="{{ itemHeight }}"
visible-item-count="{{ visibleItemCount }}"
cancel-button-text="{{ cancelButtonText }}"
confirm-button-text="{{ confirmButtonText }}"
bind:change="onChange"
bind:confirm="onConfirm"
bind:cancel="onCancel"
/>
@import '../common/index.wxss';
\ No newline at end of file
import { VantComponent } from '../common/component';
import { isNumber } from '../common/utils';
VantComponent({
relation: {
name: 'badge',
type: 'descendant',
linked(target) {
this.badges.push(target);
this.setActive();
},
unlinked(target) {
this.badges = this.badges.filter(item => item !== target);
this.setActive();
}
},
props: {
active: {
type: Number,
value: 0
}
},
watch: {
active: 'setActive'
},
beforeCreate() {
this.badges = [];
this.currentActive = -1;
},
methods: {
setActive(badge) {
let { active } = this.data;
const { badges } = this;
if (badge && !isNumber(badge)) {
active = badges.indexOf(badge);
}
if (active === this.currentActive) {
return;
}
if (this.currentActive !== -1 && badges[this.currentActive]) {
this.$emit('change', active);
badges[this.currentActive].setActive(false);
}
if (badges[active]) {
badges[active].setActive(true);
this.currentActive = active;
}
}
}
});
<view class="van-badge-group van-hairline--top-bottom custom-class">
<slot />
</view>
@import '../common/index.wxss';.van-badge-group{width:85px}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
relation: {
type: 'ancestor',
name: 'badge-group'
},
props: {
info: null,
title: String
},
methods: {
onClick() {
const group = this.getRelationNodes('../badge-group/index')[0];
if (group) {
group.setActive(this);
}
},
setActive(active) {
this.set({ active });
}
}
});
{
"component": true,
"usingComponents": {
"van-info": "../info/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="{{ utils.bem('badge', { active }) }} van-hairline custom-class"
hover-class="van-badge--hover"
hover-stay-time="70"
bind:tap="onClick"
>
<view class="van-badge__text">
<van-info
wx:if="{{ info !== null }}"
info="{{ info }}"
custom-style="right: 4px"
/>
{{ title }}
</view>
</view>
@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
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [button, openType],
classes: ['hover-class', 'loading-class'],
props: {
plain: Boolean,
block: Boolean,
round: Boolean,
square: Boolean,
loading: Boolean,
hairline: Boolean,
disabled: Boolean,
loadingText: String,
type: {
type: String,
value: 'default'
},
size: {
type: String,
value: 'normal'
},
loadingSize: {
type: String,
value: '20px'
}
},
methods: {
onClick() {
if (!this.data.disabled && !this.data.loading) {
this.$emit('click');
}
}
}
});
{
"component": true,
"usingComponents": {
"van-loading": "../loading/index"
}
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<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 }}"
business-id="{{ businessId }}"
session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}"
send-message-path="{{ sendMessagePath }}"
send-message-img="{{ sendMessageImg }}"
show-message-card="{{ showMessageCard }}"
app-parameter="{{ appParameter }}"
aria-label="{{ ariaLabel }}"
bindtap="onClick"
bindgetuserinfo="bindGetUserInfo"
bindcontact="bindContact"
bindgetphonenumber="bindGetPhoneNumber"
binderror="bindError"
bindlaunchapp="bindLaunchApp"
bindopensetting="bindOpenSetting"
>
<block wx:if="{{ loading }}">
<van-loading
custom-class="loading-class"
size="{{ loadingSize }}"
color="{{ type === 'default' ? '#c9c9c9' : '' }}"
/>
<view
wx:if="{{ loadingText }}"
class="van-button__loading-text"
>
{{ loadingText }}
</view>
</block>
<slot wx:else />
</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 { link } from '../mixins/link';
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'num-class',
'desc-class',
'thumb-class',
'title-class',
'price-class',
'origin-price-class',
],
mixins: [link],
props: {
tag: String,
num: String,
desc: String,
thumb: String,
title: String,
price: String,
centered: Boolean,
lazyLoad: Boolean,
thumbLink: String,
originPrice: String,
thumbMode: {
type: String,
value: 'aspectFit'
},
currency: {
type: String,
value: '¥'
}
},
methods: {
onClickThumb() {
this.jumpLink('thumbLink');
}
}
});
{
"component": true,
"usingComponents": {
"van-tag": "../tag/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class van-card">
<view class="{{ utils.bem('card__header', { center: centered }) }}">
<view class="van-card__thumb" bind:tap="onClickThumb">
<image
wx:if="{{ thumb }}"
src="{{ thumb }}"
mode="{{ thumbMode }}"
lazy-load="{{ lazyLoad }}"
class="van-card__img thumb-class"
/>
<slot name="thumb" />
<van-tag
wx:if="{{ tag }}"
mark
type="danger"
custom-class="van-card__tag"
>
{{ tag }}
</van-tag>
</view>
<view class="van-card__content">
<view wx:if="{{ title }}" class="van-card__title title-class">{{ title }}</view>
<slot wx:else name="title" />
<view wx:if="{{ desc }}" class="van-card__desc desc-class">{{ desc }}</view>
<slot wx:else name="desc" />
<slot name="tags" />
<view class="van-card__bottom">
<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>
</view>
</view>
</view>
<view class="van-card__footer">
<slot name="footer" />
</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 { VantComponent } from '../common/component';
VantComponent({
props: {
title: String,
border: {
type: Boolean,
value: true
}
}
});
{
"component": true
}
\ No newline at end of file
<view
wx:if="{{ title }}"
class="van-cell-group__title"
>
{{ title }}
</view>
<view class="custom-class van-cell-group {{ border ? 'van-hairline--top-bottom' : '' }}">
<slot />
</view>
@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 { link } from '../mixins/link';
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'title-class',
'label-class',
'value-class',
'right-icon-class',
'hover-class'
],
mixins: [link],
props: {
title: null,
value: null,
icon: String,
size: String,
label: String,
center: Boolean,
isLink: Boolean,
required: Boolean,
clickable: Boolean,
titleWidth: String,
customStyle: String,
arrowDirection: String,
border: {
type: Boolean,
value: true
}
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
}
}
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('cell', [size, { center, required, borderless: !border, clickable: isLink || clickable }]) }}"
hover-class="van-cell--hover hover-class"
hover-stay-time="70"
style="{{ customStyle }}"
bind:tap="onClick"
>
<van-icon
wx:if="{{ icon }}"
name="{{ icon }}"
class="van-cell__left-icon-wrap"
custom-class="van-cell__left-icon"
/>
<slot wx:else name="icon" />
<view
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>
<slot wx:else name="title" />
</view>
<view class="van-cell__value value-class">
<block wx:if="{{ value || value === 0 }}">{{ value }}</block>
<slot wx:else />
</view>
<van-icon
wx:if="{{ isLink }}"
name="{{ arrowDirection ? 'arrow' + '-' + arrowDirection : 'arrow' }}"
class="van-cell__right-icon-wrap right-icon-class"
custom-class="van-cell__right-icon"
/>
<slot wx:else name="right-icon" />
<slot name="extra" />
</view>
@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 { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'row',
type: 'ancestor'
},
props: {
span: Number,
offset: Number
},
data: {
style: ''
},
methods: {
setGutter(gutter) {
const padding = `${gutter / 2}px`;
const style = gutter ? `padding-left: ${padding}; padding-right: ${padding};` : '';
if (style !== this.data.style) {
this.set({ style });
}
}
}
});
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('col', [span]) }} {{ offset ? 'van-col--offset-' + offset : '' }}"
style="{{ style }}"
>
<slot />
</view>
@import '../common/index.wxss';.van-col{float:left;box-sizing:border-box}.van-col--1{width:4.16666667%}.van-col--offset-1{margin-left:4.16666667%}.van-col--2{width:8.33333333%}.van-col--offset-2{margin-left:8.33333333%}.van-col--3{width:12.5%}.van-col--offset-3{margin-left:12.5%}.van-col--4{width:16.66666667%}.van-col--offset-4{margin-left:16.66666667%}.van-col--5{width:20.83333333%}.van-col--offset-5{margin-left:20.83333333%}.van-col--6{width:25%}.van-col--offset-6{margin-left:25%}.van-col--7{width:29.16666667%}.van-col--offset-7{margin-left:29.16666667%}.van-col--8{width:33.33333333%}.van-col--offset-8{margin-left:33.33333333%}.van-col--9{width:37.5%}.van-col--offset-9{margin-left:37.5%}.van-col--10{width:41.66666667%}.van-col--offset-10{margin-left:41.66666667%}.van-col--11{width:45.83333333%}.van-col--offset-11{margin-left:45.83333333%}.van-col--12{width:50%}.van-col--offset-12{margin-left:50%}.van-col--13{width:54.16666667%}.van-col--offset-13{margin-left:54.16666667%}.van-col--14{width:58.33333333%}.van-col--offset-14{margin-left:58.33333333%}.van-col--15{width:62.5%}.van-col--offset-15{margin-left:62.5%}.van-col--16{width:66.66666667%}.van-col--offset-16{margin-left:66.66666667%}.van-col--17{width:70.83333333%}.van-col--offset-17{margin-left:70.83333333%}.van-col--18{width:75%}.van-col--offset-18{margin-left:75%}.van-col--19{width:79.16666667%}.van-col--offset-19{margin-left:79.16666667%}.van-col--20{width:83.33333333%}.van-col--offset-20{margin-left:83.33333333%}.van-col--21{width:87.5%}.van-col--offset-21{margin-left:87.5%}.van-col--22{width:91.66666667%}.van-col--offset-22{margin-left:91.66666667%}.van-col--23{width:95.83333333%}.van-col--offset-23{margin-left:95.83333333%}.van-col--24{width:100%}.van-col--offset-24{margin-left:100%}
\ No newline at end of file
import { VantComponent } from '../common/component';
const nextTick = () => new Promise(resolve => setTimeout(resolve, 20));
VantComponent({
classes: ['title-class', 'content-class'],
relation: {
name: 'collapse',
type: 'ancestor',
linked(parent) {
this.parent = parent;
}
},
props: {
name: null,
title: null,
value: null,
icon: String,
label: String,
disabled: Boolean,
border: {
type: Boolean,
value: true
},
isLink: {
type: Boolean,
value: true
}
},
data: {
contentHeight: 0,
expanded: false,
transition: false
},
mounted() {
this.updateExpanded()
.then(nextTick)
.then(() => {
this.set({ transition: true });
});
},
methods: {
updateExpanded() {
if (!this.parent) {
return Promise.resolve();
}
const { value, accordion } = this.parent.data;
const { children = [] } = this.parent;
const { name } = this.data;
const index = children.indexOf(this);
const currentName = name == null ? index : name;
const expanded = accordion
? value === currentName
: (value || []).some((name) => name === currentName);
const stack = [];
if (expanded !== this.data.expanded) {
stack.push(this.updateStyle(expanded));
}
stack.push(this.set({ index, expanded }));
return Promise.all(stack);
},
updateStyle(expanded) {
return this.getRect('.van-collapse-item__content')
.then((rect) => rect.height)
.then((height) => {
if (expanded) {
return this.set({
contentHeight: height ? `${height}px` : 'auto'
});
}
else {
return this.set({ contentHeight: `${height}px` })
.then(nextTick)
.then(() => this.set({ contentHeight: 0 }));
}
});
},
onClick() {
if (this.data.disabled) {
return;
}
const { name, expanded } = this.data;
const index = this.parent.children.indexOf(this);
const currentName = name == null ? index : name;
this.parent.switch(currentName, !expanded);
},
onTransitionEnd() {
if (this.data.expanded) {
this.set({
contentHeight: 'auto'
});
}
}
}
});
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-collapse-item custom-class {{ index !== 0 ? 'van-hairline--top' : '' }}">
<van-cell
title="{{ title }}"
title-class="title-class"
icon="{{ icon }}"
is-link="{{ isLink }}"
value="{{ value }}"
label="{{ label }}"
border="{{ border && expanded }}"
class="{{ utils.bem('collapse-item__title', { disabled, expanded }) }}"
right-icon-class="van-cell__right-icon"
custom-class="van-cell"
hover-class="van-cell--hover"
bind:click="onClick"
>
<slot
name="title"
slot="title"
/>
<slot
name="icon"
slot="icon"
/>
<slot name="value" />
<slot
name="right-icon"
slot="right-icon"
/>
</van-cell>
<view
class="{{ utils.bem('collapse-item__wrapper', { transition }) }}"
style="height: {{ contentHeight }};"
bind:transitionend="onTransitionEnd"
>
<view
class="van-collapse-item__content content-class"
>
<slot />
</view>
</view>
</view>
@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 { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'collapse-item',
type: 'descendant',
linked(child) {
this.children.push(child);
}
},
props: {
value: {
type: null,
observer: 'updateExpanded'
},
accordion: {
type: Boolean,
observer: 'updateExpanded'
},
border: {
type: Boolean,
value: true
}
},
beforeCreate() {
this.children = [];
},
methods: {
updateExpanded() {
this.children.forEach((child) => {
child.updateExpanded();
});
},
switch(name, expanded) {
const { accordion, value } = this.data;
if (!accordion) {
name = expanded
? (value || []).concat(name)
: (value || []).filter((activeName) => activeName !== name);
}
else {
name = expanded ? name : '';
}
this.$emit('change', name);
this.$emit('input', name);
}
}
});
<view class="custom-class van-collapse {{ border ? 'van-hairline--top-bottom' : '' }}">
<slot />
</view>
@import '../common/index.wxss';
\ No newline at end of file
import { VantComponent } from '../common/component';
import { isDef } from '../common/utils';
const currentYear = new Date().getFullYear();
function isValidDate(date) {
return isDef(date) && !isNaN(new Date(date).getTime());
}
function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
function padZero(val) {
return `00${val}`.slice(-2);
}
function times(n, iteratee) {
let index = -1;
const result = Array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
function getTrueValue(formattedValue) {
if (!formattedValue)
return;
while (isNaN(parseInt(formattedValue, 10))) {
formattedValue = formattedValue.slice(1);
}
return parseInt(formattedValue, 10);
}
function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}
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: {
type: String,
value: 'datetime'
},
showToolbar: {
type: Boolean,
value: true
},
minDate: {
type: Number,
value: new Date(currentYear - 10, 0, 1).getTime()
},
maxDate: {
type: Number,
value: new Date(currentYear + 10, 11, 31).getTime()
},
minHour: {
type: Number,
value: 0
},
maxHour: {
type: Number,
value: 23
},
minMinute: {
type: Number,
value: 0
},
maxMinute: {
type: Number,
value: 59
}
},
data: {
innerValue: Date.now(),
columns: []
},
watch: {
value(val) {
const { data } = this;
val = this.correctValue(val);
const isEqual = val === data.innerValue;
if (!isEqual) {
this.updateColumnValue(val).then(() => {
this.$emit('input', val);
});
}
},
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');
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 => {
let value = range[0] + index;
value = type === 'year' ? `${value}` : padZero(value);
return value;
});
return { values };
});
return this.set({ columns: results });
},
getRanges() {
const { data } = this;
if (data.type === 'time') {
return [
{
type: 'hour',
range: [data.minHour, data.maxHour]
},
{
type: 'minute',
range: [data.minMinute, data.maxMinute]
}
];
}
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', data.innerValue);
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', data.innerValue);
const result = [
{
type: 'year',
range: [minYear, maxYear]
},
{
type: 'month',
range: [minMonth, maxMonth]
},
{
type: 'day',
range: [minDate, maxDate]
},
{
type: 'hour',
range: [minHour, maxHour]
},
{
type: 'minute',
range: [minMinute, maxMinute]
}
];
if (data.type === 'date')
result.splice(3, 2);
if (data.type === 'year-month')
result.splice(2, 3);
return result;
},
correctValue(value) {
const { data } = this;
// validate value
const isDateType = data.type !== 'time';
if (isDateType && !isValidDate(value)) {
value = data.minDate;
}
else if (!isDateType && !value) {
const { minHour } = data;
value = `${padZero(minHour)}:00`;
}
// time type
if (!isDateType) {
let [hour, minute] = value.split(':');
hour = padZero(range(hour, data.minHour, data.maxHour));
minute = padZero(range(minute, data.minMinute, data.maxMinute));
return `${hour}:${minute}`;
}
// date type
value = Math.max(value, data.minDate);
value = Math.min(value, data.maxDate);
return value;
},
getBoundary(type, innerValue) {
const value = new Date(innerValue);
const boundary = new Date(this.data[`${type}Date`]);
const year = boundary.getFullYear();
let month = 1;
let date = 1;
let hour = 0;
let minute = 0;
if (type === 'max') {
month = 12;
date = getMonthEndDay(value.getFullYear(), value.getMonth() + 1);
hour = 23;
minute = 59;
}
if (value.getFullYear() === year) {
month = boundary.getMonth() + 1;
if (value.getMonth() + 1 === month) {
date = boundary.getDate();
if (value.getDate() === date) {
hour = boundary.getHours();
if (value.getHours() === hour) {
minute = boundary.getMinutes();
}
}
}
}
return {
[`${type}Year`]: year,
[`${type}Month`]: month,
[`${type}Date`]: date,
[`${type}Hour`]: hour,
[`${type}Minute`]: minute
};
},
onCancel() {
this.$emit('cancel');
},
onConfirm() {
this.$emit('confirm', this.data.innerValue);
},
onChange() {
const { data } = this;
let value;
const picker = this.getPicker();
if (data.type === 'time') {
const indexes = picker.getIndexes();
value = `${indexes[0] + data.minHour}:${indexes[1] + data.minMinute}`;
}
else {
const values = picker.getValues();
const year = getTrueValue(values[0]);
const month = getTrueValue(values[1]);
const maxDate = getMonthEndDay(year, month);
let date = getTrueValue(values[2]);
if (data.type === 'year-month') {
date = 1;
}
date = date > maxDate ? maxDate : date;
let hour = 0;
let minute = 0;
if (data.type === 'datetime') {
hour = getTrueValue(values[3]);
minute = getTrueValue(values[4]);
}
value = new Date(year, month - 1, date, hour, minute);
}
value = this.correctValue(value);
this.updateColumnValue(value).then(() => {
this.$emit('input', value);
this.$emit('change', picker);
});
},
updateColumnValue(value) {
let values = [];
const { data } = this;
const picker = this.getPicker();
if (data.type === 'time') {
const pair = value.split(':');
values = [pair[0], pair[1]];
}
else {
const date = new Date(value);
values = [`${date.getFullYear()}`, padZero(date.getMonth() + 1)];
if (data.type === 'date') {
values.push(padZero(date.getDate()));
}
if (data.type === 'datetime') {
values.push(padZero(date.getDate()), padZero(date.getHours()), padZero(date.getMinutes()));
}
}
return this.set({ innerValue: value })
.then(() => this.updateColumns())
.then(() => picker.setValues(values));
}
},
created() {
const innerValue = this.correctValue(this.data.value);
this.updateColumnValue(innerValue).then(() => {
this.$emit('input', innerValue);
});
}
});
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}
<van-picker
class="van-datetime-picker"
title="{{ title }}"
columns="{{ columns }}"
item-height="{{ itemHeight }}"
show-toolbar="{{ showToolbar }}"
visible-item-count="{{ visibleItemCount }}"
confirm-button-text="{{ confirmButtonText }}"
cancel-button-text="{{ cancelButtonText }}"
bind:change="onChange"
bind:confirm="onConfirm"
bind:cancel="onCancel"
/>
@import '../common/index.wxss';
\ No newline at end of file
declare type DialogAction = 'confirm' | 'cancel';
declare type DialogOptions = {
lang?: string;
show?: boolean;
title?: string;
zIndex?: number;
context?: any;
message?: string;
overlay?: boolean;
selector?: string;
ariaLabel?: string;
transition?: string;
asyncClose?: boolean;
businessId?: number;
sessionFrom?: string;
appParameter?: string;
messageAlign?: string;
sendMessageImg?: string;
showMessageCard?: boolean;
sendMessagePath?: string;
sendMessageTitle?: string;
confirmButtonText?: string;
cancelButtonText?: string;
showConfirmButton?: boolean;
showCancelButton?: boolean;
closeOnClickOverlay?: boolean;
confirmButtonOpenType?: string;
};
interface Dialog {
(options: DialogOptions): Promise<DialogAction>;
alert?: (options: DialogOptions) => Promise<DialogAction>;
confirm?: (options: DialogOptions) => Promise<DialogAction>;
close?: () => void;
stopLoading?: () => void;
install?: () => void;
setDefaultOptions?: (options: DialogOptions) => void;
resetDefaultOptions?: () => void;
defaultOptions?: DialogOptions;
currentOptions?: DialogOptions;
}
declare const Dialog: Dialog;
export default Dialog;
let queue = [];
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
const Dialog = options => {
options = Object.assign({}, Dialog.currentOptions, options);
return new Promise((resolve, reject) => {
const context = options.context || getContext();
const dialog = context.selectComponent(options.selector);
delete options.selector;
if (dialog) {
dialog.set(Object.assign({ onCancel: reject, onConfirm: resolve }, options));
queue.push(dialog);
}
else {
console.warn('未找到 van-dialog 节点,请确认 selector 及 context 是否正确');
}
});
};
Dialog.defaultOptions = {
show: true,
title: '',
message: '',
zIndex: 100,
overlay: true,
asyncClose: false,
messageAlign: '',
transition: 'scale',
selector: '#van-dialog',
confirmButtonText: '确认',
cancelButtonText: '取消',
showConfirmButton: true,
showCancelButton: false,
closeOnClickOverlay: false,
confirmButtonOpenType: ''
};
Dialog.alert = Dialog;
Dialog.confirm = options => Dialog(Object.assign({ showCancelButton: true }, options));
Dialog.close = () => {
queue.forEach(dialog => {
dialog.close();
});
queue = [];
};
Dialog.stopLoading = () => {
queue.forEach(dialog => {
dialog.stopLoading();
});
};
Dialog.setDefaultOptions = options => {
Object.assign(Dialog.currentOptions, options);
};
Dialog.resetDefaultOptions = () => {
Dialog.currentOptions = Object.assign({}, Dialog.defaultOptions);
};
Dialog.resetDefaultOptions();
export default Dialog;
import { VantComponent } from '../common/component';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [button, openType],
props: {
show: Boolean,
title: String,
message: String,
useSlot: Boolean,
asyncClose: Boolean,
messageAlign: String,
showCancelButton: Boolean,
closeOnClickOverlay: Boolean,
confirmButtonOpenType: String,
zIndex: {
type: Number,
value: 2000
},
confirmButtonText: {
type: String,
value: '确认'
},
cancelButtonText: {
type: String,
value: '取消'
},
showConfirmButton: {
type: Boolean,
value: true
},
overlay: {
type: Boolean,
value: true
},
transition: {
type: String,
value: 'scale'
}
},
data: {
loading: {
confirm: false,
cancel: false
}
},
watch: {
show(show) {
!show && this.stopLoading();
}
},
methods: {
onConfirm() {
this.handleAction('confirm');
},
onCancel() {
this.handleAction('cancel');
},
onClickOverlay() {
this.onClose('overlay');
},
handleAction(action) {
if (this.data.asyncClose) {
this.set({
[`loading.${action}`]: true
});
}
this.onClose(action);
},
close() {
this.set({
show: false
});
},
stopLoading() {
this.set({
loading: {
confirm: false,
cancel: false
}
});
},
onClose(action) {
if (!this.data.asyncClose) {
this.close();
}
this.$emit('close', action);
//把 dialog 实例传递出去,可以通过 stopLoading() 在外部关闭按钮的 loading
this.$emit(action, { dialog: this });
const callback = this.data[action === 'confirm' ? 'onConfirm' : 'onCancel'];
if (callback) {
callback(this);
}
}
}
});
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-button": "../button/index"
}
}
<van-popup
show="{{ show }}"
z-index="{{ zIndex }}"
overlay="{{ overlay }}"
custom-class="van-dialog"
transition="{{ transition }}"
close-on-click-overlay="{{ closeOnClickOverlay }}"
bind:close="onClickOverlay"
>
<view
wx:if="{{ title }}"
class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}"
>
{{ title }}
</view>
<slot wx:if="{{ useSlot }}" />
<view
wx:elif="{{ message }}"
class="van-dialog__message {{ title ? 'van-dialog__message--has-title' : '' }} {{ messageAlign ? 'van-dialog__message--' + messageAlign : '' }}"
>
<text>{{ message }}</text>
</view>
<view class="van-hairline--top van-dialog__footer">
<van-button
wx:if="{{ showCancelButton }}"
size="large"
loading="{{ loading.cancel }}"
class="van-dialog__button van-hairline--right"
custom-class="van-dialog__cancel"
bind:click="onCancel"
>
{{ cancelButtonText }}
</van-button>
<van-button
wx:if="{{ showConfirmButton }}"
size="large"
class="van-dialog__button"
loading="{{ loading.confirm }}"
custom-class="van-dialog__confirm"
open-type="{{ confirmButtonOpenType }}"
lang="{{ lang }}"
business-id="{{ businessId }}"
session-from="{{ sessionFrom }}"
send-message-title="{{ sendMessageTitle }}"
send-message-path="{{ sendMessagePath }}"
send-message-img="{{ sendMessageImg }}"
show-message-card="{{ showMessageCard }}"
app-parameter="{{ appParameter }}"
bind:click="onConfirm"
bindgetuserinfo="bindGetUserInfo"
bindcontact="bindContact"
bindgetphonenumber="bindGetPhoneNumber"
binderror="bindError"
bindlaunchapp="bindLaunchApp"
bindopensetting="bindOpenSetting"
>
{{ confirmButtonText }}
</van-button>
</view>
</van-popup>
@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 { VantComponent } from '../common/component';
VantComponent({
field: true,
classes: ['input-class'],
props: {
size: String,
icon: String,
label: String,
error: Boolean,
fixed: Boolean,
focus: Boolean,
center: Boolean,
isLink: Boolean,
leftIcon: String,
disabled: Boolean,
autosize: Boolean,
readonly: Boolean,
required: Boolean,
iconClass: String,
clearable: Boolean,
inputAlign: String,
errorMessageAlign: String,
customClass: String,
confirmType: String,
confirmHold: Boolean,
errorMessage: String,
placeholder: String,
customStyle: String,
useIconSlot: Boolean,
useButtonSlot: Boolean,
showConfirmBar: {
type: Boolean,
value: true
},
placeholderStyle: String,
adjustPosition: {
type: Boolean,
value: true
},
cursorSpacing: {
type: Number,
value: 50
},
maxlength: {
type: Number,
value: -1
},
type: {
type: String,
value: 'text'
},
border: {
type: Boolean,
value: true
},
titleWidth: {
type: String,
value: '90px'
}
},
data: {
showClear: false
},
beforeCreate() {
this.focused = false;
},
methods: {
onInput(event) {
const { value = '' } = event.detail || {};
this.set({
value,
showClear: this.getShowClear(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()
});
},
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);
});
}
},
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.emitChange('');
this.$emit('clear', '');
});
},
onConfirm() {
this.$emit('confirm', this.data.value);
},
emitChange(value) {
this.$emit('input', value);
this.$emit('change', value);
}
}
});
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<van-cell
icon="{{ leftIcon }}"
title="{{ label }}"
center="{{ center }}"
border="{{ border }}"
is-link="{{ isLink }}"
required="{{ required }}"
custom-style="{{ customStyle }}"
title-width="{{ titleWidth }}"
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' : '' }}">
<textarea
wx:if="{{ type === 'textarea' }}"
class="input-class {{ utils.bem('field__input', [inputAlign, { 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' }}"
cursor-spacing="{{ cursorSpacing }}"
adjust-position="{{ adjustPosition }}"
show-confirm-bar="{{ showConfirmBar }}"
bindinput="onInput"
bind:blur="onBlur"
bind:focus="onFocus"
bind:confirm="onConfirm"
/>
<input
wx:else
class="input-class {{ utils.bem('field__input', [inputAlign, { disabled, error }]) }}"
type="{{ type }}"
focus="{{ focus }}"
value="{{ value }}"
disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
placeholder-class="{{ error ? 'van-field__input--error' : 'van-field__placeholder' }}"
confirm-type="{{ confirmType }}"
confirm-hold="{{ confirmHold }}"
cursor-spacing="{{ cursorSpacing }}"
adjust-position="{{ adjustPosition }}"
bindinput="onInput"
bind:blur="onBlur"
bind:focus="onFocus"
bind:confirm="onConfirm"
/>
<van-icon
wx:if="{{ showClear }}"
size="16px"
name="clear"
class="van-field__clear-root"
custom-class="van-field__clear"
bind:touchstart="onClear"
/>
<view class="van-field__icon-container" wx:if="{{ icon || useIconSlot }}" bind:tap="onClickIcon">
<van-icon
wx:if="{{ icon }}"
size="16px"
name="{{ icon }}"
custom-class="van-field__icon {{ iconClass }}"
/>
<slot wx:else name="icon" />
</view>
<view wx:if="{{ useButtonSlot }}" class="van-field__button">
<slot name="button" />
</view>
</view>
<view wx:if="{{ errorMessage }}" class="van-field__error-message {{ utils.bem('field__error', [errorMessageAlign, { disabled, error }]) }}">
{{ errorMessage }}
</view>
</van-cell>
@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 { VantComponent } from '../common/component';
import { link } from '../mixins/link';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
mixins: [link, button, openType],
props: {
text: String,
loading: Boolean,
disabled: Boolean,
type: {
type: String,
value: 'danger'
}
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
}
}
});
{
"component": true,
"usingComponents": {
"van-button": "../button/index"
}
}
<van-button
square
id="{{ id }}"
size="large"
lang="{{ lang }}"
type="{{ type }}"
loading="{{ loading }}"
disabled="{{ disabled }}"
open-type="{{ openType }}"
custom-class="custom-class"
business-id="{{ businessId }}"
session-from="{{ sessionFrom }}"
app-parameter="{{ appParameter }}"
send-message-img="{{ sendMessageImg }}"
send-message-path="{{ sendMessagePath }}"
show-message-card="{{ showMessageCard }}"
send-message-title="{{ sendMessageTitle }}"
bind:click="onClick"
binderror="bindError"
bindcontact="bindContact"
bindopensetting="bindOpenSetting"
bindgetuserinfo="bindGetUserInfo"
bindgetphonenumber="bindGetPhoneNumber"
bindlaunchapp="bindLaunchApp"
>
{{ text }}
</van-button>
@import '../common/index.wxss';:host{-webkit-flex:1;flex:1}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { link } from '../mixins/link';
import { button } from '../mixins/button';
import { openType } from '../mixins/open-type';
VantComponent({
classes: ['icon-class', 'text-class'],
mixins: [link, button, openType],
props: {
text: String,
info: String,
icon: String,
disabled: Boolean,
loading: Boolean
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
}
}
});
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-button": "../button/index"
}
}
<van-button
square
id="{{ id }}"
size="large"
lang="{{ lang }}"
loading="{{ loading }}"
disabled="{{ disabled }}"
open-type="{{ openType }}"
business-id="{{ businessId }}"
custom-class="van-goods-action-icon"
session-from="{{ sessionFrom }}"
app-parameter="{{ appParameter }}"
send-message-img="{{ sendMessageImg }}"
send-message-path="{{ sendMessagePath }}"
show-message-card="{{ showMessageCard }}"
send-message-title="{{ sendMessageTitle }}"
bind:click="onClick"
binderror="bindError"
bindcontact="bindContact"
bindopensetting="bindOpenSetting"
bindgetuserinfo="bindGetUserInfo"
bindgetphonenumber="bindGetPhoneNumber"
bindlaunchapp="bindLaunchApp"
>
<view class="van-goods-action-icon__content van-hairline--right">
<van-icon
size="20px"
name="{{ icon }}"
info="{{ info }}"
class="van-goods-action-icon__icon"
custom-class="icon-class"
/>
<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 { VantComponent } from '../common/component';
import { safeArea } from '../mixins/safe-area';
VantComponent({
mixins: [safeArea()]
});
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class {{ utils.bem('goods-action', { safe: isIPhoneX && safeAreaInsetBottom }) }}">
<slot />
</view>
@import '../common/index.wxss';.van-goods-action{position:fixed;right:0;bottom:0;left:0;display:-webkit-flex;display:flex;background-color:#fff}.van-goods-action--safe{padding-bottom:34px}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
props: {
info: null,
customStyle: String
}
});
<view
wx:if="{{ info !== null }}"
class="custom-class van-info"
style="{{ customStyle }}"
>{{ info }}</view>
@import '../common/index.wxss';.van-info{position:absolute;top:-8px;right:0;min-width:16px;padding:0 3px;font-family:PingFang SC,Helvetica Neue,Arial,sans-serif;font-size:12px;font-weight:500;line-height:14px;color:#fff;text-align:center;white-space:nowrap;background-color:#f44;border:1px solid #fff;border-radius:16px;-webkit-transform:translateX(50%);transform:translateX(50%);box-sizing:border-box;-webkit-transform-origin:100%;transform-origin:100%}
\ No newline at end of file