Commit b1af78f9 authored by Junling Bu's avatar Junling Bu
Browse files

chore[litemall-wx]: 使用vant-weapp 1.0

parent 07351378
import { VantComponent } from '../common/component';
import { addUnit, isDef } from '../common/utils';
const LONG_PRESS_START_TIME = 600;
const LONG_PRESS_INTERVAL = 200;
// add num and avoid float number
function add(num1, num2) {
const cardinal = Math.pow(10, 10);
return Math.round((num1 + num2) * cardinal) / cardinal;
}
VantComponent({
field: true,
classes: ['input-class', 'plus-class', 'minus-class'],
props: {
value: null,
integer: Boolean,
disabled: Boolean,
inputWidth: null,
buttonSize: null,
asyncChange: Boolean,
disableInput: Boolean,
decimalLength: {
type: Number,
value: null
},
min: {
type: null,
value: 1
},
max: {
type: null,
value: Number.MAX_SAFE_INTEGER
},
step: {
type: null,
value: 1
},
showPlus: {
type: Boolean,
value: true
},
showMinus: {
type: Boolean,
value: true
},
disablePlus: Boolean,
disableMinus: Boolean
},
watch: {
value(value) {
if (value === '') {
return;
}
const newValue = this.range(value);
if (typeof newValue === 'number' && +this.data.value !== newValue) {
this.setData({ value: newValue });
}
},
inputWidth() {
this.set({
inputStyle: this.computeInputStyle()
});
},
buttonSize() {
this.set({
inputStyle: this.computeInputStyle(),
buttonStyle: this.computeButtonStyle()
});
}
},
data: {
focus: false,
inputStyle: '',
buttonStyle: ''
},
created() {
this.setData({
value: this.range(this.data.value)
});
},
methods: {
isDisabled(type) {
if (type === 'plus') {
return this.data.disabled || this.data.disablePlus || this.data.value >= this.data.max;
}
return this.data.disabled || this.data.disableMinus || this.data.value <= this.data.min;
},
onFocus(event) {
this.$emit('focus', event.detail);
},
onBlur(event) {
const value = this.range(this.data.value);
this.triggerInput(value);
this.$emit('blur', event.detail);
},
// limit value range
range(value) {
value = String(value).replace(/[^0-9.-]/g, '');
// format range
value = value === '' ? 0 : +value;
value = Math.max(Math.min(this.data.max, value), this.data.min);
// format decimal
if (isDef(this.data.decimalLength)) {
value = value.toFixed(this.data.decimalLength);
}
return value;
},
onInput(event) {
const { value = '' } = event.detail || {};
this.triggerInput(value);
},
onChange() {
const { type } = this;
if (this.isDisabled(type)) {
this.$emit('overlimit', type);
return;
}
const diff = type === 'minus' ? -this.data.step : +this.data.step;
const value = add(+this.data.value, diff);
this.triggerInput(this.range(value));
this.$emit(type);
},
longPressStep() {
this.longPressTimer = setTimeout(() => {
this.onChange();
this.longPressStep();
}, LONG_PRESS_INTERVAL);
},
onTap(event) {
const { type } = event.currentTarget.dataset;
this.type = type;
this.onChange();
},
onTouchStart(event) {
clearTimeout(this.longPressTimer);
const { type } = event.currentTarget.dataset;
this.type = type;
this.isLongPress = false;
this.longPressTimer = setTimeout(() => {
this.isLongPress = true;
this.onChange();
this.longPressStep();
}, LONG_PRESS_START_TIME);
},
onTouchEnd() {
clearTimeout(this.longPressTimer);
},
triggerInput(value) {
this.setData({
value: this.data.asyncChange ? this.data.value : value
});
this.$emit('change', value);
},
computeInputStyle() {
let style = '';
if (this.data.inputWidth) {
style = `width: ${addUnit(this.data.inputWidth)};`;
}
if (this.data.buttonSize) {
style += `height: ${addUnit(this.data.buttonSize)};`;
}
return style;
},
computeButtonStyle() {
let style = '';
const size = addUnit(this.data.buttonSize);
if (this.data.buttonSize) {
style = `width: ${size};height: ${size};`;
}
return style;
}
}
});
{
"component": true
}
\ No newline at end of file
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-stepper custom-class">
<view
wx:if="{{ showMinus }}"
data-type="minus"
style="{{ buttonStyle }}"
class="minus-class {{ utils.bem('stepper__minus', { disabled: disabled || disableMinus || value <= min }) }}"
hover-class="van-stepper__minus--hover"
hover-stay-time="70"
bind:tap="onTap"
bind:touchstart="onTouchStart"
bind:touchend="onTouchEnd"
/>
<input
type="{{ integer ? 'number' : 'digit' }}"
class="input-class {{ utils.bem('stepper__input', { disabled: disabled || disableInput }) }}"
style="{{ inputStyle }}"
value="{{ value }}"
focus="{{ focus }}"
disabled="{{ disabled || disableInput }}"
bindinput="onInput"
bind:focus="onFocus"
bind:blur="onBlur"
/>
<view
wx:if="{{ showPlus }}"
data-type="plus"
style="{{ buttonStyle }}"
class="plus-class {{ utils.bem('stepper__plus', { disabled: disabled || disablePlus || value >= max }) }}"
hover-class="van-stepper__plus--hover"
hover-stay-time="70"
bind:tap="onTap"
bind:touchstart="onTouchStart"
bind:touchend="onTouchEnd"
/>
</view>
@import '../common/index.wxss';.van-stepper{font-size:0}.van-stepper__minus,.van-stepper__plus{position:relative;display:inline-block;box-sizing:border-box;margin:1px;vertical-align:middle;border:0;background-color:#f2f3f5;background-color:var(--stepper-background-color,#f2f3f5);color:#323233;color:var(--stepper-button-icon-color,#323233);width:28px;width:var(--stepper-input-height,28px);height:28px;height:var(--stepper-input-height,28px);padding:4px;padding:var(--padding-base,4px)}.van-stepper__minus:before,.van-stepper__plus:before{width:9px;height:1px}.van-stepper__minus:after,.van-stepper__plus:after{width:1px;height:9px}.van-stepper__minus:after,.van-stepper__minus:before,.van-stepper__plus:after,.van-stepper__plus:before{position:absolute;top:0;right:0;bottom:0;left:0;margin:auto;background-color:currentColor;content:""}.van-stepper__minus--hover,.van-stepper__plus--hover{background-color:#e8e8e8;background-color:var(--stepper-active-color,#e8e8e8)}.van-stepper__minus--disabled,.van-stepper__plus--disabled{color:#c8c9cc;color:var(--stepper-button-disabled-icon-color,#c8c9cc)}.van-stepper__minus--disabled,.van-stepper__minus--disabled.van-stepper__minus--hover,.van-stepper__minus--disabled.van-stepper__plus--hover,.van-stepper__plus--disabled,.van-stepper__plus--disabled.van-stepper__minus--hover,.van-stepper__plus--disabled.van-stepper__plus--hover{background-color:#f7f8fa;background-color:var(--stepper-button-disabled-color,#f7f8fa)}.van-stepper__minus{border-radius:4px 0 0 4px;border-radius:var(--stepper-border-radius,4px) 0 0 var(--stepper-border-radius,4px)}.van-stepper__minus:after{display:none}.van-stepper__plus{border-radius:0 4px 4px 0;border-radius:0 var(--stepper-border-radius,4px) var(--stepper-border-radius,4px) 0}.van-stepper__input{display:inline-block;box-sizing:border-box;min-height:0;margin:1px;padding:1px;text-align:center;vertical-align:middle;border:0;border-width:1px 0;border-radius:0;-webkit-appearance:none;font-size:14px;font-size:var(--stepper-input-font-size,14px);color:#323233;color:var(--stepper-input-text-color,#323233);background-color:#f2f3f5;background-color:var(--stepper-background-color,#f2f3f5);width:32px;width:var(--stepper-input-width,32px);height:28px;height:var(--stepper-input-height,28px)}.van-stepper__input--disabled{color:#c8c9cc;color:var(--stepper-input-disabled-text-color,#c8c9cc);background-color:#f2f3f5;background-color:var(--stepper-input-disabled-background-color,#f2f3f5)}
\ No newline at end of file
import { VantComponent } from '../common/component';
const ROOT_ELEMENT = '.van-sticky';
VantComponent({
props: {
zIndex: {
type: Number,
value: 99
},
offsetTop: {
type: Number,
value: 0,
observer: 'observeContent'
},
disabled: {
type: Boolean,
observer(value) {
if (!this.mounted) {
return;
}
value ? this.disconnectObserver() : this.initObserver();
}
},
container: {
type: null,
observer(target) {
if (typeof target !== 'function' || !this.data.height) {
return;
}
this.observeContainer();
}
}
},
data: {
wrapStyle: '',
containerStyle: ''
},
methods: {
setStyle() {
const { offsetTop, height, fixed, zIndex } = this.data;
if (fixed) {
this.setData({
wrapStyle: `top: ${offsetTop}px;`,
containerStyle: `height: ${height}px; z-index: ${zIndex};`
});
}
else {
this.setData({
wrapStyle: '',
containerStyle: ''
});
}
},
getContainerRect() {
const nodesRef = this.data.container();
return new Promise(resolve => nodesRef.boundingClientRect(resolve).exec());
},
initObserver() {
this.disconnectObserver();
this.getRect(ROOT_ELEMENT).then((rect) => {
this.setData({ height: rect.height });
wx.nextTick(() => {
this.observeContent();
this.observeContainer();
});
});
},
disconnectObserver(observerName) {
if (observerName) {
const observer = this[observerName];
observer && observer.disconnect();
}
else {
this.contentObserver && this.contentObserver.disconnect();
this.containerObserver && this.containerObserver.disconnect();
}
},
observeContent() {
const { offsetTop } = this.data;
this.disconnectObserver('contentObserver');
const contentObserver = this.createIntersectionObserver({
thresholds: [0, 1]
});
this.contentObserver = contentObserver;
contentObserver.relativeToViewport({ top: -offsetTop });
contentObserver.observe(ROOT_ELEMENT, res => {
if (this.data.disabled) {
return;
}
this.setFixed(res.boundingClientRect.top);
});
},
observeContainer() {
if (typeof this.data.container !== 'function') {
return;
}
const { height } = this.data;
this.getContainerRect().then((rect) => {
this.containerHeight = rect.height;
this.disconnectObserver('containerObserver');
const containerObserver = this.createIntersectionObserver({
thresholds: [0, 1]
});
this.containerObserver = containerObserver;
containerObserver.relativeToViewport({
top: this.containerHeight - height
});
containerObserver.observe(ROOT_ELEMENT, res => {
if (this.data.disabled) {
return;
}
this.setFixed(res.boundingClientRect.top);
});
});
},
setFixed(top) {
const { offsetTop, height } = this.data;
const { containerHeight } = this;
const fixed = containerHeight && height
? top > height - containerHeight && top < offsetTop
: top < offsetTop;
this.$emit('scroll', {
scrollTop: top,
isFixed: fixed
});
this.setData({ fixed });
wx.nextTick(() => {
this.setStyle();
});
}
},
mounted() {
this.mounted = true;
if (!this.data.disabled) {
this.initObserver();
}
},
destroyed() {
this.disconnectObserver();
}
});
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="custom-class van-sticky" style="{{ containerStyle }}">
<view class="{{ utils.bem('sticky-wrap', { fixed }) }}" style="{{ wrapStyle }}">
<slot />
</view>
</view>
@import '../common/index.wxss';.van-sticky{position:relative}.van-sticky-wrap--fixed{position:fixed;right:0;left:0}
\ No newline at end of file
import { VantComponent } from '../common/component';
VantComponent({
classes: [
'bar-class',
'price-class',
'button-class'
],
props: {
tip: {
type: null,
observer: 'updateTip'
},
tipIcon: String,
type: Number,
price: {
type: null,
observer: 'updatePrice'
},
label: String,
loading: Boolean,
disabled: Boolean,
buttonText: String,
currency: {
type: String,
value: '¥'
},
buttonType: {
type: String,
value: 'danger'
},
decimalLength: {
type: Number,
value: 2,
observer: 'updatePrice'
},
suffixLabel: String,
safeAreaInsetBottom: {
type: Boolean,
value: true
}
},
methods: {
updatePrice() {
const { price, decimalLength } = this.data;
this.setData({
hasPrice: typeof price === 'number',
priceStr: (price / 100).toFixed(decimalLength)
});
},
updateTip() {
this.setData({ hasTip: typeof this.data.tip === 'string' });
},
onSubmit(event) {
this.$emit('submit', event.detail);
}
}
});
{
"component": true,
"usingComponents": {
"van-button": "../button/index",
"van-icon": "../icon/index"
}
}
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-submit-bar custom-class">
<slot name="top" />
<view class="van-submit-bar__tip">
<van-icon
wx:if="{{ tipIcon }}"
size="12px"
name="{{ tipIcon }}"
custom-class="van-submit-bar__tip-icon"
/>
<view wx:if="{{ hasTip }}" class="van-submit-bar__tip-text">
{{ tip }}
</view>
<slot name="tip" />
</view>
<view class="bar-class {{ utils.bem('submit-bar__bar', { safe: safeAreaInsetBottom }) }}">
<slot />
<view wx:if="{{ hasPrice }}" class="van-submit-bar__text">
<text>{{ label || '合计:' }}</text>
<text class="van-submit-bar__price price-class">
<text class="van-submit-bar__currency">{{ currency }} </text>
<text>{{ priceStr }}</text>
</text>
<text class="van-submit-bar__suffix-label">{{ suffixLabel }}</text>
</view>
<van-button
square
size="large"
type="{{ buttonType }}"
loading="{{ loading }}"
disabled="{{ disabled }}"
class="van-submit-bar__button"
custom-class="button-class"
bind:click="onSubmit"
>
{{ loading ? '' : buttonText }}
</van-button>
</view>
</view>
@import '../common/index.wxss';.van-submit-bar{position:fixed;bottom:0;left:0;width:100%;-webkit-user-select:none;user-select:none;z-index:100;z-index:var(--submit-bar-z-index,100);background-color:#fff;background-color:var(--submit-bar-background-color,#fff)}.van-submit-bar__tip{padding:10px;padding:var(--submit-bar-tip-padding,10px);color:#f56723;color:var(--submit-bar-tip-color,#f56723);font-size:12px;font-size:var(--submit-bar-tip-font-size,12px);line-height:1.5;line-height:var(--submit-bar-tip-line-height,1.5);background-color:#fff7cc;background-color:var(--submit-bar-tip-background-color,#fff7cc)}.van-submit-bar__tip:empty{display:none}.van-submit-bar__tip-icon{width:12px;height:12px;margin-right:4px;vertical-align:middle;font-size:12px;font-size:var(--submit-bar-tip-icon-size,12px);min-width:18px;min-width:calc(var(--submit-bar-tip-icon-size, 12px)*1.5)}.van-submit-bar__tip-text{display:inline;vertical-align:middle}.van-submit-bar__bar{display:-webkit-flex;display:flex;-webkit-align-items:center;align-items:center;-webkit-justify-content:flex-end;justify-content:flex-end;height:50px;height:var(--submit-bar-height,50px);font-size:14px;font-size:var(--submit-bar-text-font-size,14px);background-color:#fff;background-color:var(--submit-bar-background-color,#fff)}.van-submit-bar__bar--safe{padding-bottom:env(safe-area-inset-bottom)}.van-submit-bar__text{-webkit-flex:1;flex:1;text-align:right;color:#323233;color:var(--submit-bar-text-color,#323233);padding-right:12px;padding-right:var(--padding-sm,12px);font-weight:500;font-weight:var(--font-weight-bold,500)}.van-submit-bar__price{color:#ee0a24;color:var(--submit-bar-price-color,#ee0a24);font-size:18px;font-size:var(--submit-bar-price-font-size,18px)}.van-submit-bar__currency{font-size:14px;font-size:var(--submit-bar-currency-font-size,14px)}.van-submit-bar__suffix-label{margin-left:5px}.van-submit-bar__button{width:110px;width:var(--submit-bar-button-width,110px)}
\ No newline at end of file
import { VantComponent } from '../common/component';
import { touch } from '../mixins/touch';
import { range } from '../common/utils';
const THRESHOLD = 0.3;
let ARRAY = [];
VantComponent({
props: {
disabled: Boolean,
leftWidth: {
type: Number,
value: 0
},
rightWidth: {
type: Number,
value: 0
},
asyncClose: Boolean,
name: {
type: [Number, String],
value: ''
}
},
mixins: [touch],
data: {
catchMove: false
},
created() {
this.offset = 0;
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter(item => item !== this);
},
methods: {
open(position) {
const { leftWidth, rightWidth } = this.data;
const offset = position === 'left' ? leftWidth : -rightWidth;
this.swipeMove(offset);
this.$emit('open', {
position,
name: this.data.name
});
},
close() {
this.swipeMove(0);
},
swipeMove(offset = 0) {
this.offset = range(offset, -this.data.rightWidth, this.data.leftWidth);
const transform = `translate3d(${this.offset}px, 0, 0)`;
const transition = this.dragging
? 'none'
: 'transform .6s cubic-bezier(0.18, 0.89, 0.32, 1)';
this.setData({
wrapperStyle: `
-webkit-transform: ${transform};
-webkit-transition: ${transition};
transform: ${transform};
transition: ${transition};
`
});
},
swipeLeaveTransition() {
const { leftWidth, rightWidth } = this.data;
const { offset } = this;
if (rightWidth > 0 && -offset > rightWidth * THRESHOLD) {
this.open('right');
}
else if (leftWidth > 0 && offset > leftWidth * THRESHOLD) {
this.open('left');
}
else {
this.swipeMove(0);
}
this.setData({ catchMove: false });
},
startDrag(event) {
if (this.data.disabled) {
return;
}
this.startOffset = this.offset;
this.touchStart(event);
},
noop() { },
onDrag(event) {
if (this.data.disabled) {
return;
}
this.touchMove(event);
if (this.direction !== 'horizontal') {
return;
}
this.dragging = true;
ARRAY.filter(item => item !== this).forEach(item => item.close());
this.setData({ catchMove: true });
this.swipeMove(this.startOffset + this.deltaX);
},
endDrag() {
if (this.data.disabled) {
return;
}
this.dragging = false;
this.swipeLeaveTransition();
},
onClick(event) {
const { key: position = 'outside' } = event.currentTarget.dataset;
this.$emit('click', position);
if (!this.offset) {
return;
}
if (this.data.asyncClose) {
this.$emit('close', {
position,
instance: this,
name: this.data.name
});
}
else {
this.swipeMove(0);
}
}
}
});
<view
class="van-swipe-cell"
data-key="cell"
catchtap="onClick"
bindtouchstart="startDrag"
catchtouchmove="{{ catchMove ? 'noop' : '' }}"
capture-bind:touchmove="onDrag"
bindtouchend="endDrag"
bindtouchcancel="endDrag"
>
<view style="{{ wrapperStyle }}">
<view wx:if="{{ leftWidth }}" class="van-swipe-cell__left" data-key="left" catch:tap="onClick">
<slot name="left" />
</view>
<slot />
<view wx:if="{{ rightWidth }}" class="van-swipe-cell__right" data-key="right" catch:tap="onClick">
<slot name="right" />
</view>
</view>
</view>
@import '../common/index.wxss';.van-swipe-cell{position:relative;overflow:hidden}.van-swipe-cell__left,.van-swipe-cell__right{position:absolute;top:0;height:100%}.van-swipe-cell__left{left:0;-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}.van-swipe-cell__right{right:0;-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment