This commit is contained in:
2019-12-24 15:02:17 +08:00
365 changed files with 9339 additions and 9254 deletions

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,59 +1,59 @@
import { VantComponent } from '../common/component';
VantComponent({
props: {
show: Boolean,
title: String,
cancelText: String,
description: String,
round: {
type: Boolean,
value: true
},
zIndex: {
type: Number,
value: 100
},
actions: {
type: Array,
value: []
},
overlay: {
type: Boolean,
value: true
},
closeOnClickOverlay: {
type: Boolean,
value: true
},
closeOnClickAction: {
type: Boolean,
value: true
},
safeAreaInsetBottom: {
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);
if (this.data.closeOnClickAction) {
this.onClose();
}
}
},
onCancel() {
this.$emit('cancel');
},
onClose() {
this.$emit('close');
},
onClickOverlay() {
this.$emit('click-overlay');
this.onClose();
}
}
});
import { VantComponent } from '../common/component';
VantComponent({
props: {
show: Boolean,
title: String,
cancelText: String,
description: String,
round: {
type: Boolean,
value: true
},
zIndex: {
type: Number,
value: 100
},
actions: {
type: Array,
value: []
},
overlay: {
type: Boolean,
value: true
},
closeOnClickOverlay: {
type: Boolean,
value: true
},
closeOnClickAction: {
type: Boolean,
value: true
},
safeAreaInsetBottom: {
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);
if (this.data.closeOnClickAction) {
this.onClose();
}
}
},
onCancel() {
this.$emit('cancel');
},
onClose() {
this.$emit('close');
},
onClickOverlay() {
this.$emit('click-overlay');
this.onClose();
}
}
});

View File

@@ -1,8 +1,8 @@
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-popup": "../popup/index",
"van-loading": "../loading/index"
}
}
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-popup": "../popup/index",
"van-loading": "../loading/index"
}
}

View File

@@ -1,54 +1,54 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<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="onClickOverlay"
>
<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="{{ 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 }}"
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 custom-class="van-action-sheet__loading" 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>
<wxs src="../wxs/utils.wxs" module="utils" />
<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="onClickOverlay"
>
<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="{{ 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 }}"
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 custom-class="van-action-sheet__loading" 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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,210 +1,210 @@
import { VantComponent } from '../common/component';
import { pickerProps } from '../picker/shared';
const COLUMNSPLACEHOLDERCODE = '000000';
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
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: [] }],
typeToColumnsPlaceholder: {}
},
watch: {
value(value) {
this.code = value;
this.setValues();
},
areaList: 'setValues',
columnsNum(value) {
this.setData({
displayColumns: this.data.columns.slice(0, +value)
});
}
},
mounted() {
setTimeout(() => {
this.setValues();
}, 0);
},
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) {
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;
this.setValues().then(() => {
this.$emit('change', {
picker,
values: this.parseOutputValues(picker.getValues()),
index
});
});
},
getConfig(type) {
const { areaList } = this.data;
return (areaList && areaList[`${type}_list`]) || {};
},
getList(type, code) {
const { typeToColumnsPlaceholder } = this.data;
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);
}
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) {
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;
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();
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(code) {
this.code = code || '';
return this.setValues();
}
}
});
import { VantComponent } from '../common/component';
import { pickerProps } from '../picker/shared';
const COLUMNSPLACEHOLDERCODE = '000000';
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
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: [] }],
typeToColumnsPlaceholder: {}
},
watch: {
value(value) {
this.code = value;
this.setValues();
},
areaList: 'setValues',
columnsNum(value) {
this.setData({
displayColumns: this.data.columns.slice(0, +value)
});
}
},
mounted() {
setTimeout(() => {
this.setValues();
}, 0);
},
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) {
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;
this.setValues().then(() => {
this.$emit('change', {
picker,
values: this.parseOutputValues(picker.getValues()),
index
});
});
},
getConfig(type) {
const { areaList } = this.data;
return (areaList && areaList[`${type}_list`]) || {};
},
getList(type, code) {
const { typeToColumnsPlaceholder } = this.data;
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);
}
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) {
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;
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();
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(code) {
this.code = code || '';
return this.setValues();
}
}
});

View File

@@ -1,6 +1,6 @@
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}

View File

@@ -1,18 +1,18 @@
<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"
/>
<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"
/>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,68 +1,68 @@
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'],
data: {
style: ''
},
props: {
icon: String,
plain: Boolean,
block: Boolean,
round: Boolean,
square: Boolean,
loading: Boolean,
hairline: Boolean,
disabled: Boolean,
loadingText: String,
customStyle: String,
loadingType: {
type: String,
value: 'circular'
},
type: {
type: String,
value: 'default'
},
size: {
type: String,
value: 'normal'
},
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: {
onClick() {
if (!this.data.disabled && !this.data.loading) {
this.$emit('click');
}
}
}
});
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'],
data: {
style: ''
},
props: {
icon: String,
plain: Boolean,
block: Boolean,
round: Boolean,
square: Boolean,
loading: Boolean,
hairline: Boolean,
disabled: Boolean,
loadingText: String,
customStyle: String,
loadingType: {
type: String,
value: 'circular'
},
type: {
type: String,
value: 'default'
},
size: {
type: String,
value: 'normal'
},
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: {
onClick() {
if (!this.data.disabled && !this.data.loading) {
this.$emit('click');
}
}
}
});

View File

@@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index"
}
}
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-loading": "../loading/index"
}
}

View File

@@ -1,52 +1,52 @@
<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' : '' }}"
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 }}"
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 }}"
type="{{ loadingType }}"
color="{{ type === 'default' ? '#c9c9c9' : 'white' }}"
/>
<view
wx:if="{{ loadingText }}"
class="van-button__loading-text"
>
{{ loadingText }}
</view>
</block>
<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>
<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' : '' }}"
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 }}"
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 }}"
type="{{ loadingType }}"
color="{{ type === 'default' ? '#c9c9c9' : 'white' }}"
/>
<view
wx:if="{{ loadingText }}"
class="van-button__loading-text"
>
{{ loadingText }}
</view>
</block>
<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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,38 +1,38 @@
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');
}
}
});
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');
}
}
});

View File

@@ -1,6 +1,6 @@
{
"component": true,
"usingComponents": {
"van-tag": "../tag/index"
}
}
{
"component": true,
"usingComponents": {
"van-tag": "../tag/index"
}
}

View File

@@ -1,45 +1,45 @@
<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>
<slot name="bottom" />
</view>
</view>
</view>
<view class="van-card__footer">
<slot name="footer" />
</view>
</view>
<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>
<slot name="bottom" />
</view>
</view>
</view>
<view class="van-card__footer">
<slot name="footer" />
</view>
</view>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,10 +1,10 @@
import { VantComponent } from '../common/component';
VantComponent({
props: {
title: String,
border: {
type: Boolean,
value: true
}
}
});
import { VantComponent } from '../common/component';
VantComponent({
props: {
title: String,
border: {
type: Boolean,
value: true
}
}
});

View File

@@ -1,3 +1,3 @@
{
"component": true
{
"component": true
}

View File

@@ -1,9 +1,9 @@
<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>
<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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,37 +1,37 @@
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,
useLabelSlot: Boolean,
border: {
type: Boolean,
value: true
}
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
}
}
});
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,
useLabelSlot: Boolean,
border: {
type: Boolean,
value: true
}
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
}
}
});

View File

@@ -1,6 +1,6 @@
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}

View File

@@ -1,45 +1,45 @@
<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 }}</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">
<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>
<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 }}</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">
<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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,39 +1,39 @@
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'checkbox',
type: 'descendant',
linked(target) {
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: {
type: Array,
observer: 'updateChildren'
},
disabled: {
type: Boolean,
observer: 'updateChildren'
}
},
methods: {
updateChildren() {
(this.children || []).forEach((child) => this.updateChild(child));
},
updateChild(child) {
const { value, disabled } = this.data;
child.setData({
value: value.indexOf(child.data.name) !== -1,
disabled: disabled || child.data.disabled
});
}
}
});
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'checkbox',
type: 'descendant',
linked(target) {
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: {
type: Array,
observer: 'updateChildren'
},
disabled: {
type: Boolean,
observer: 'updateChildren'
}
},
methods: {
updateChildren() {
(this.children || []).forEach((child) => this.updateChild(child));
},
updateChild(child) {
const { value, disabled } = this.data;
child.setData({
value: value.indexOf(child.data.name) !== -1,
disabled: disabled || child.data.disabled
});
}
}
});

View File

@@ -1,3 +1,3 @@
{
"component": true
}
{
"component": true
}

View File

@@ -1 +1 @@
<slot />
<slot />

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,87 +1,87 @@
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',
linked(target) {
this.parent = target;
},
unlinked() {
this.parent = null;
}
},
classes: ['icon-class', 'label-class'],
props: {
value: Boolean,
disabled: Boolean,
useIconSlot: Boolean,
checkedColor: String,
labelPosition: String,
labelDisabled: Boolean,
shape: {
type: String,
value: 'round'
},
iconSize: {
type: null,
observer: 'setSizeWithUnit'
}
},
data: {
sizeWithUnit: '20px'
},
methods: {
emitChange(value) {
if (this.parent) {
this.setParentValue(this.parent, value);
}
else {
emit(this, value);
}
},
toggle() {
const { disabled, value } = this.data;
if (!disabled) {
this.emitChange(!value);
}
},
onClickLabel() {
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 (max && parentValue.length >= max) {
return;
}
if (parentValue.indexOf(name) === -1) {
parentValue.push(name);
emit(parent, parentValue);
}
}
else {
const index = parentValue.indexOf(name);
if (index !== -1) {
parentValue.splice(index, 1);
emit(parent, parentValue);
}
}
},
setSizeWithUnit(size) {
this.set({
sizeWithUnit: addUnit(size)
});
},
}
});
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',
linked(target) {
this.parent = target;
},
unlinked() {
this.parent = null;
}
},
classes: ['icon-class', 'label-class'],
props: {
value: Boolean,
disabled: Boolean,
useIconSlot: Boolean,
checkedColor: String,
labelPosition: String,
labelDisabled: Boolean,
shape: {
type: String,
value: 'round'
},
iconSize: {
type: null,
observer: 'setSizeWithUnit'
}
},
data: {
sizeWithUnit: '20px'
},
methods: {
emitChange(value) {
if (this.parent) {
this.setParentValue(this.parent, value);
}
else {
emit(this, value);
}
},
toggle() {
const { disabled, value } = this.data;
if (!disabled) {
this.emitChange(!value);
}
},
onClickLabel() {
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 (max && parentValue.length >= max) {
return;
}
if (parentValue.indexOf(name) === -1) {
parentValue.push(name);
emit(parent, parentValue);
}
}
else {
const index = parentValue.indexOf(name);
if (index !== -1) {
parentValue.splice(index, 1);
emit(parent, parentValue);
}
}
},
setSizeWithUnit(size) {
this.set({
sizeWithUnit: addUnit(size)
});
},
}
});

View File

@@ -1,6 +1,6 @@
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index"
}
}

View File

@@ -1,19 +1,19 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-checkbox custom-class">
<view class="van-checkbox__icon-wrap" bindtap="toggle">
<slot wx:if="{{ useIconSlot }}" name="icon" />
<van-icon
wx:else
name="success"
size="0.8em"
class="{{ utils.bem('checkbox__icon', [shape, { disabled, checked: value }]) }}"
style="font-size: {{ sizeWithUnit }};{{ checkedColor && value && !disabled ? 'border-color:' + checkedColor + '; background-color:' + checkedColor : '' }}"
custom-class="icon-class"
custom-style="line-height: 1.25em;"
/>
</view>
<view class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled }]) }}" bindtap="onClickLabel">
<slot />
</view>
</view>
<wxs src="../wxs/utils.wxs" module="utils" />
<view class="van-checkbox custom-class">
<view class="van-checkbox__icon-wrap" bindtap="toggle">
<slot wx:if="{{ useIconSlot }}" name="icon" />
<van-icon
wx:else
name="success"
size="0.8em"
class="{{ utils.bem('checkbox__icon', [shape, { disabled, checked: value }]) }}"
style="font-size: {{ sizeWithUnit }};{{ checkedColor && value && !disabled ? 'border-color:' + checkedColor + '; background-color:' + checkedColor : '' }}"
custom-class="icon-class"
custom-style="line-height: 1.25em;"
/>
</view>
<view class="label-class {{ utils.bem('checkbox__label', [labelPosition, { disabled }]) }}" bindtap="onClickLabel">
<slot />
</view>
</view>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,158 +1,158 @@
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();
}
});
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 File

@@ -1,3 +1,3 @@
{
"component": true
}
{
"component": true
}

View File

@@ -1,7 +1,7 @@
<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 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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,23 +1,23 @@
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.setData({ style });
}
}
}
});
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.setData({ style });
}
}
}
});

View File

@@ -1,3 +1,3 @@
{
"component": true
}
{
"component": true
}

View File

@@ -1,8 +1,8 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('col', [span]) }} {{ offset ? 'van-col--offset-' + offset : '' }}"
style="{{ style }}"
>
<slot />
</view>
<wxs src="../wxs/utils.wxs" module="utils" />
<view
class="custom-class {{ utils.bem('col', [span]) }} {{ offset ? 'van-col--offset-' + offset : '' }}"
style="{{ style }}"
>
<slot />
</view>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,96 +1,96 @@
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,
clickable: Boolean,
border: {
type: Boolean,
value: true
},
isLink: {
type: Boolean,
value: true
}
},
data: {
contentHeight: 0,
expanded: false,
transition: false
},
mounted() {
this.updateExpanded()
.then(nextTick)
.then(() => {
const data = { transition: true };
if (this.data.expanded) {
data.contentHeight = 'auto';
}
this.setData(data);
});
},
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'
});
}
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.setData({
contentHeight: 'auto'
});
}
}
}
});
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,
clickable: Boolean,
border: {
type: Boolean,
value: true
},
isLink: {
type: Boolean,
value: true
}
},
data: {
contentHeight: 0,
expanded: false,
transition: false
},
mounted() {
this.updateExpanded()
.then(nextTick)
.then(() => {
const data = { transition: true };
if (this.data.expanded) {
data.contentHeight = 'auto';
}
this.setData(data);
});
},
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'
});
}
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.setData({
contentHeight: 'auto'
});
}
}
}
});

View File

@@ -1,6 +1,6 @@
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index"
}
}

View File

@@ -1,44 +1,44 @@
<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 }}"
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"
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>
<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 }}"
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"
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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,50 +1,50 @@
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'collapse-item',
type: 'descendant',
linked(child) {
this.children.push(child);
},
unlinked(child) {
this.children = this.children.filter((item) => item !== 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);
}
}
});
import { VantComponent } from '../common/component';
VantComponent({
relation: {
name: 'collapse-item',
type: 'descendant',
linked(child) {
this.children.push(child);
},
unlinked(child) {
this.children = this.children.filter((item) => item !== 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 File

@@ -1,3 +1,3 @@
{
"component": true
}
{
"component": true
}

View File

@@ -1,3 +1,3 @@
<view class="custom-class van-collapse {{ border ? 'van-hairline--top-bottom' : '' }}">
<slot />
</view>
<view class="custom-class van-collapse {{ border ? 'van-hairline--top-bottom' : '' }}">
<slot />
</view>

View File

@@ -1,7 +1,7 @@
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 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";

View File

@@ -1,7 +1,7 @@
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';
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';

View File

@@ -1,3 +1,3 @@
import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
declare function VantComponent<Data, Props, Methods>(vantOptions?: VantComponentOptions<Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods>>): void;
export { VantComponent };
import { VantComponentOptions, CombinedComponentInstance } from '../definitions/index';
declare function VantComponent<Data, Props, Methods>(vantOptions?: VantComponentOptions<Data, Props, Methods, CombinedComponentInstance<Data, Props, Methods>>): void;
export { VantComponent };

View File

@@ -1,48 +1,48 @@
import { basic } from '../mixins/basic';
import { observe } from '../mixins/observer/index';
function mapKeys(source, target, map) {
Object.keys(map).forEach(key => {
if (source[key]) {
target[map[key]] = source[key];
}
});
}
function VantComponent(vantOptions = {}) {
const options = {};
mapKeys(vantOptions, options, {
data: 'data',
props: 'properties',
mixins: 'behaviors',
methods: 'methods',
beforeCreate: 'created',
created: 'attached',
mounted: 'ready',
relations: 'relations',
destroyed: 'detached',
classes: 'externalClasses'
});
const { relation } = vantOptions;
if (relation) {
options.relations = Object.assign(options.relations || {}, {
[`../${relation.name}/index`]: relation
});
}
// add default externalClasses
options.externalClasses = options.externalClasses || [];
options.externalClasses.push('custom-class');
// add default behaviors
options.behaviors = options.behaviors || [];
options.behaviors.push(basic);
// map field to form-field behavior
if (vantOptions.field) {
options.behaviors.push('wx://form-field');
}
// add default options
options.options = {
multipleSlots: true,
addGlobalClass: true
};
observe(vantOptions, options);
Component(options);
}
export { VantComponent };
import { basic } from '../mixins/basic';
import { observe } from '../mixins/observer/index';
function mapKeys(source, target, map) {
Object.keys(map).forEach(key => {
if (source[key]) {
target[map[key]] = source[key];
}
});
}
function VantComponent(vantOptions = {}) {
const options = {};
mapKeys(vantOptions, options, {
data: 'data',
props: 'properties',
mixins: 'behaviors',
methods: 'methods',
beforeCreate: 'created',
created: 'attached',
mounted: 'ready',
relations: 'relations',
destroyed: 'detached',
classes: 'externalClasses'
});
const { relation } = vantOptions;
if (relation) {
options.relations = Object.assign(options.relations || {}, {
[`../${relation.name}/index`]: relation
});
}
// add default externalClasses
options.externalClasses = options.externalClasses || [];
options.externalClasses.push('custom-class');
// add default behaviors
options.behaviors = options.behaviors || [];
options.behaviors.push(basic);
// map field to form-field behavior
if (vantOptions.field) {
options.behaviors.push('wx://form-field');
}
// add default options
options.options = {
multipleSlots: true,
addGlobalClass: true
};
observe(vantOptions, options);
Component(options);
}
export { VantComponent };

View File

@@ -1,8 +1,8 @@
/// <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;
/// <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;

View File

@@ -1,32 +1,32 @@
export function isDef(value) {
return value !== undefined && value !== null;
}
export function isObj(x) {
const type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
export function isNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
export function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
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;
}
export function isDef(value) {
return value !== undefined && value !== null;
}
export function isObj(x) {
const type = typeof x;
return x !== null && (type === 'object' || type === 'function');
}
export function isNumber(value) {
return /^\d+(\.\d+)?$/.test(value);
}
export function range(num, min, max) {
return Math.min(Math.max(num, min), max);
}
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;
}

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,100 +1,100 @@
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');
}
}
}
});
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 File

@@ -1,3 +1,3 @@
{
"component": true
}
{
"component": true
}

View File

@@ -1,4 +1,4 @@
<view class="van-count-down">
<slot wx:if="{{ useSlot }}"/>
<block wx:else>{{ formattedTime }}</block>
</view>
<view class="van-count-down">
<slot wx:if="{{ useSlot }}"/>
<block wx:else>{{ formattedTime }}</block>
</view>

View File

@@ -1,10 +1,10 @@
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;
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;

View File

@@ -1,57 +1,57 @@
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);
}
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);
}

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,297 +1,297 @@
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());
}
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 < 0 ? 0 : 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();
}
const defaultFormatter = (_, value) => value;
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), { value: null, filter: null, type: {
type: String,
value: 'datetime'
}, showToolbar: {
type: Boolean,
value: true
}, formatter: {
type: null,
value: defaultFormatter
}, 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: 'updateValue',
type: 'updateValue',
minDate: 'updateValue',
maxDate: 'updateValue',
minHour: 'updateValue',
maxHour: 'updateValue',
minMinute: 'updateValue',
maxMinute: 'updateValue'
},
methods: {
updateValue() {
const { data } = this;
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();
}
},
getPicker() {
if (this.picker == null) {
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 { 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;
});
if (filter) {
values = filter(type, values);
}
return { type, values };
});
return 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 = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1].values[indexes[1]]}`;
}
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 { type, formatter = defaultFormatter } = this.data;
const picker = this.getPicker();
if (type === 'time') {
const pair = value.split(':');
values = [
formatter('hour', pair[0]),
formatter('minute', pair[1])
];
}
else {
const date = new Date(value);
values = [
formatter('year', `${date.getFullYear()}`),
formatter('month', padZero(date.getMonth() + 1))
];
if (type === 'date') {
values.push(formatter('day', padZero(date.getDate())));
}
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 })
.then(() => this.updateColumns())
.then(() => picker.setValues(values));
}
},
created() {
const innerValue = this.correctValue(this.data.value);
this.updateColumnValue(innerValue).then(() => {
this.$emit('input', innerValue);
});
}
});
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());
}
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 < 0 ? 0 : 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();
}
const defaultFormatter = (_, value) => value;
VantComponent({
classes: ['active-class', 'toolbar-class', 'column-class'],
props: Object.assign(Object.assign({}, pickerProps), { value: null, filter: null, type: {
type: String,
value: 'datetime'
}, showToolbar: {
type: Boolean,
value: true
}, formatter: {
type: null,
value: defaultFormatter
}, 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: 'updateValue',
type: 'updateValue',
minDate: 'updateValue',
maxDate: 'updateValue',
minHour: 'updateValue',
maxHour: 'updateValue',
minMinute: 'updateValue',
maxMinute: 'updateValue'
},
methods: {
updateValue() {
const { data } = this;
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();
}
},
getPicker() {
if (this.picker == null) {
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 { 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;
});
if (filter) {
values = filter(type, values);
}
return { type, values };
});
return 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 = `${+data.columns[0].values[indexes[0]]}:${+data.columns[1].values[indexes[1]]}`;
}
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 { type, formatter = defaultFormatter } = this.data;
const picker = this.getPicker();
if (type === 'time') {
const pair = value.split(':');
values = [
formatter('hour', pair[0]),
formatter('minute', pair[1])
];
}
else {
const date = new Date(value);
values = [
formatter('year', `${date.getFullYear()}`),
formatter('month', padZero(date.getMonth() + 1))
];
if (type === 'date') {
values.push(formatter('day', padZero(date.getDate())));
}
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 })
.then(() => this.updateColumns())
.then(() => picker.setValues(values));
}
},
created() {
const innerValue = this.correctValue(this.data.value);
this.updateColumnValue(innerValue).then(() => {
this.$emit('input', innerValue);
});
}
});

View File

@@ -1,6 +1,6 @@
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}
{
"component": true,
"usingComponents": {
"van-picker": "../picker/index"
}
}

View File

@@ -1,16 +1,16 @@
<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 }}"
show-toolbar="{{ showToolbar }}"
visible-item-count="{{ visibleItemCount }}"
confirm-button-text="{{ confirmButtonText }}"
cancel-button-text="{{ cancelButtonText }}"
bind:change="onChange"
bind:confirm="onConfirm"
bind:cancel="onCancel"
/>
<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 }}"
show-toolbar="{{ showToolbar }}"
visible-item-count="{{ visibleItemCount }}"
confirm-button-text="{{ confirmButtonText }}"
cancel-button-text="{{ cancelButtonText }}"
bind:change="onChange"
bind:confirm="onConfirm"
bind:cancel="onCancel"
/>

View File

@@ -1,28 +1,28 @@
/// <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" />
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 {};

View File

@@ -1,112 +1,112 @@
/// <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" />
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 {};
}

View File

@@ -1,47 +1,47 @@
/// <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?: 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;
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;
/// <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?: 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;
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;

View File

@@ -1,63 +1,63 @@
let queue = [];
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
const Dialog = 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.setData(Object.assign({ onCancel: reject, onConfirm: resolve }, options));
queue.push(dialog);
}
else {
console.warn('未找到 van-dialog 节点,请确认 selector 及 context 是否正确');
}
});
};
Dialog.defaultOptions = {
show: true,
title: '',
width: null,
message: '',
zIndex: 100,
overlay: true,
selector: '#van-dialog',
className: '',
asyncClose: false,
transition: 'scale',
customStyle: '',
messageAlign: '',
overlayStyle: '',
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;
let queue = [];
function getContext() {
const pages = getCurrentPages();
return pages[pages.length - 1];
}
const Dialog = 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.setData(Object.assign({ onCancel: reject, onConfirm: resolve }, options));
queue.push(dialog);
}
else {
console.warn('未找到 van-dialog 节点,请确认 selector 及 context 是否正确');
}
});
};
Dialog.defaultOptions = {
show: true,
title: '',
width: null,
message: '',
zIndex: 100,
overlay: true,
selector: '#van-dialog',
className: '',
asyncClose: false,
transition: 'scale',
customStyle: '',
messageAlign: '',
overlayStyle: '',
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;

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,119 +1,119 @@
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: {
show: Boolean,
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
},
confirmButtonText: {
type: String,
value: '确认'
},
cancelButtonText: {
type: String,
value: '取消'
},
confirmButtonColor: {
type: String,
value: BLUE
},
cancelButtonColor: {
type: String,
value: GRAY
},
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.setData({
[`loading.${action}`]: true
});
}
this.onClose(action);
},
close() {
this.setData({
show: false
});
},
stopLoading() {
this.setData({
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);
}
},
setWidthWithUnit(val) {
this.setData({
widthWithUnit: addUnit(val)
});
}
}
});
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: {
show: Boolean,
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
},
confirmButtonText: {
type: String,
value: '确认'
},
cancelButtonText: {
type: String,
value: '取消'
},
confirmButtonColor: {
type: String,
value: BLUE
},
cancelButtonColor: {
type: String,
value: GRAY
},
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.setData({
[`loading.${action}`]: true
});
}
this.onClose(action);
},
close() {
this.setData({
show: false
});
},
stopLoading() {
this.setData({
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);
}
},
setWidthWithUnit(val) {
this.setData({
widthWithUnit: addUnit(val)
});
}
}
});

View File

@@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-button": "../button/index"
}
}
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-button": "../button/index"
}
}

View File

@@ -1,69 +1,69 @@
<van-popup
show="{{ show }}"
z-index="{{ zIndex }}"
overlay="{{ overlay }}"
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 || useTitleSlot }}"
class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}"
>
<slot wx:if="{{ useTitleSlot }}" name="title" />
<block wx:elif="{{ title }}"> {{ title }}</block>
</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 class="van-dialog__message-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"
custom-style="color: {{ cancelButtonColor }}"
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"
custom-style="color: {{ confirmButtonColor }}"
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>
<van-popup
show="{{ show }}"
z-index="{{ zIndex }}"
overlay="{{ overlay }}"
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 || useTitleSlot }}"
class="van-dialog__header {{ message || useSlot ? '' : 'van-dialog--isolated' }}"
>
<slot wx:if="{{ useTitleSlot }}" name="title" />
<block wx:elif="{{ title }}"> {{ title }}</block>
</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 class="van-dialog__message-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"
custom-style="color: {{ cancelButtonColor }}"
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"
custom-style="color: {{ confirmButtonColor }}"
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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,33 +1,33 @@
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: ''
}
}
});
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: ''
}
}
});

View File

@@ -1,4 +1,4 @@
{
"component": true,
"usingComponents": {}
{
"component": true,
"usingComponents": {}
}

View File

@@ -1,8 +1,8 @@
<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>
<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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,104 +1,104 @@
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'dropdown-menu',
type: 'ancestor',
linked(target) {
this.parent = target;
this.updateDataFromParent();
},
unlinked() {
this.parent = null;
}
},
props: {
value: {
type: null,
observer: 'rerender'
},
title: {
type: String,
observer: 'rerender'
},
disabled: Boolean,
titleClass: {
type: String,
observer: 'rerender'
},
options: {
type: Array,
value: [],
observer: 'rerender'
}
},
data: {
transition: true,
showPopup: false,
showWrapper: false,
displayTitle: ''
},
methods: {
rerender() {
wx.nextTick(() => {
this.parent && this.parent.updateItemListData();
});
},
updateDataFromParent() {
if (this.parent) {
const { overlay, duration, activeColor, closeOnClickOverlay, direction } = this.parent.data;
this.setData({
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction
});
}
},
onClickOverlay() {
this.toggle();
this.$emit('close');
},
onOptionTap(event) {
const { option } = event.currentTarget.dataset;
const { value } = option;
const shouldEmitChange = this.data.value !== value;
this.setData({ showPopup: false, value });
setTimeout(() => {
this.setData({ showWrapper: false });
}, this.data.duration || 0);
this.rerender();
if (shouldEmitChange) {
this.$emit('change', value);
}
},
toggle(show, options = {}) {
const { showPopup, duration } = this.data;
if (show == null) {
show = !showPopup;
}
if (show === showPopup) {
return;
}
if (!show) {
const time = options.immediate ? 0 : duration;
this.setData({ transition: !options.immediate, showPopup: show });
setTimeout(() => {
this.setData({ showWrapper: false });
}, time);
this.rerender();
return;
}
this.parent.getChildWrapperStyle().then((wrapperStyle = '') => {
this.setData({
transition: !options.immediate,
showPopup: show,
wrapperStyle,
showWrapper: true
});
this.rerender();
});
}
}
});
import { VantComponent } from '../common/component';
VantComponent({
field: true,
relation: {
name: 'dropdown-menu',
type: 'ancestor',
linked(target) {
this.parent = target;
this.updateDataFromParent();
},
unlinked() {
this.parent = null;
}
},
props: {
value: {
type: null,
observer: 'rerender'
},
title: {
type: String,
observer: 'rerender'
},
disabled: Boolean,
titleClass: {
type: String,
observer: 'rerender'
},
options: {
type: Array,
value: [],
observer: 'rerender'
}
},
data: {
transition: true,
showPopup: false,
showWrapper: false,
displayTitle: ''
},
methods: {
rerender() {
wx.nextTick(() => {
this.parent && this.parent.updateItemListData();
});
},
updateDataFromParent() {
if (this.parent) {
const { overlay, duration, activeColor, closeOnClickOverlay, direction } = this.parent.data;
this.setData({
overlay,
duration,
activeColor,
closeOnClickOverlay,
direction
});
}
},
onClickOverlay() {
this.toggle();
this.$emit('close');
},
onOptionTap(event) {
const { option } = event.currentTarget.dataset;
const { value } = option;
const shouldEmitChange = this.data.value !== value;
this.setData({ showPopup: false, value });
setTimeout(() => {
this.setData({ showWrapper: false });
}, this.data.duration || 0);
this.rerender();
if (shouldEmitChange) {
this.$emit('change', value);
}
},
toggle(show, options = {}) {
const { showPopup, duration } = this.data;
if (show == null) {
show = !showPopup;
}
if (show === showPopup) {
return;
}
if (!show) {
const time = options.immediate ? 0 : duration;
this.setData({ transition: !options.immediate, showPopup: show });
setTimeout(() => {
this.setData({ showWrapper: false });
}, time);
this.rerender();
return;
}
this.parent.getChildWrapperStyle().then((wrapperStyle = '') => {
this.setData({
transition: !options.immediate,
showPopup: show,
wrapperStyle,
showWrapper: true
});
this.rerender();
});
}
}
});

View File

@@ -1,8 +1,8 @@
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
}
{
"component": true,
"usingComponents": {
"van-popup": "../popup/index",
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
}

View File

@@ -1,44 +1,44 @@
<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>
<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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,121 +1,121 @@
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.push(target);
this.updateItemListData();
},
unlinked(target) {
this.children = this.children.filter((child) => child !== target);
this.updateItemListData();
}
},
props: {
activeColor: {
type: String,
observer: 'updateChildrenData'
},
overlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData'
},
zIndex: {
type: Number,
value: 10
},
duration: {
type: Number,
value: 200,
observer: 'updateChildrenData'
},
direction: {
type: String,
value: 'down',
observer: 'updateChildrenData'
},
closeOnClickOverlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData'
},
closeOnClickOutside: {
type: Boolean,
value: true
}
},
data: {
itemListData: []
},
beforeCreate() {
const { windowHeight } = wx.getSystemInfoSync();
this.windowHeight = windowHeight;
this.children = [];
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter(item => item !== this);
},
methods: {
updateItemListData() {
this.setData({
itemListData: this.children.map((child) => child.data)
});
},
updateChildrenData() {
this.children.forEach((child) => {
child.updateDataFromParent();
});
},
toggleItem(active) {
this.children.forEach((item, index) => {
const { showPopup } = item.data;
if (index === active) {
item.toggle();
}
else if (showPopup) {
item.toggle(false, { immediate: true });
}
});
},
close() {
this.children.forEach((child) => {
child.toggle(false, { immediate: true });
});
},
getChildWrapperStyle() {
const { zIndex, direction } = this.data;
return this.getRect('.van-dropdown-menu').then((rect) => {
const { top = 0, bottom = 0 } = rect;
const offset = direction === 'down' ? bottom : this.windowHeight - top;
let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`;
}
else {
wrapperStyle += `bottom: ${addUnit(offset)};`;
}
return wrapperStyle;
});
},
onTitleTap(event) {
const { index } = event.currentTarget.dataset;
const child = this.children[index];
if (!child.data.disabled) {
ARRAY.forEach(menuItem => {
if (menuItem &&
menuItem.data.closeOnClickOutside &&
menuItem !== this) {
menuItem.close();
}
});
this.toggleItem(index);
}
}
}
});
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.push(target);
this.updateItemListData();
},
unlinked(target) {
this.children = this.children.filter((child) => child !== target);
this.updateItemListData();
}
},
props: {
activeColor: {
type: String,
observer: 'updateChildrenData'
},
overlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData'
},
zIndex: {
type: Number,
value: 10
},
duration: {
type: Number,
value: 200,
observer: 'updateChildrenData'
},
direction: {
type: String,
value: 'down',
observer: 'updateChildrenData'
},
closeOnClickOverlay: {
type: Boolean,
value: true,
observer: 'updateChildrenData'
},
closeOnClickOutside: {
type: Boolean,
value: true
}
},
data: {
itemListData: []
},
beforeCreate() {
const { windowHeight } = wx.getSystemInfoSync();
this.windowHeight = windowHeight;
this.children = [];
ARRAY.push(this);
},
destroyed() {
ARRAY = ARRAY.filter(item => item !== this);
},
methods: {
updateItemListData() {
this.setData({
itemListData: this.children.map((child) => child.data)
});
},
updateChildrenData() {
this.children.forEach((child) => {
child.updateDataFromParent();
});
},
toggleItem(active) {
this.children.forEach((item, index) => {
const { showPopup } = item.data;
if (index === active) {
item.toggle();
}
else if (showPopup) {
item.toggle(false, { immediate: true });
}
});
},
close() {
this.children.forEach((child) => {
child.toggle(false, { immediate: true });
});
},
getChildWrapperStyle() {
const { zIndex, direction } = this.data;
return this.getRect('.van-dropdown-menu').then((rect) => {
const { top = 0, bottom = 0 } = rect;
const offset = direction === 'down' ? bottom : this.windowHeight - top;
let wrapperStyle = `z-index: ${zIndex};`;
if (direction === 'down') {
wrapperStyle += `top: ${addUnit(offset)};`;
}
else {
wrapperStyle += `bottom: ${addUnit(offset)};`;
}
return wrapperStyle;
});
},
onTitleTap(event) {
const { index } = event.currentTarget.dataset;
const child = this.children[index];
if (!child.data.disabled) {
ARRAY.forEach(menuItem => {
if (menuItem &&
menuItem.data.closeOnClickOutside &&
menuItem !== this) {
menuItem.close();
}
});
this.toggleItem(index);
}
}
}
});

View File

@@ -1,3 +1,3 @@
{
"component": true
{
"component": true
}

View File

@@ -1,23 +1,23 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<view class="van-dropdown-menu van-dropdown-menu--top-bottom">
<view
wx:for="{{ itemListData }}"
wx:key="index"
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">
{{ computed.displayTitle(item) }}
</view>
</view>
</view>
<slot />
</view>
<wxs src="../wxs/utils.wxs" module="utils" />
<wxs src="./index.wxs" module="computed" />
<view class="van-dropdown-menu van-dropdown-menu--top-bottom">
<view
wx:for="{{ itemListData }}"
wx:key="index"
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">
{{ computed.displayTitle(item) }}
</view>
</view>
</view>
<slot />
</view>

View File

@@ -1,16 +1,16 @@
/* eslint-disable */
function displayTitle(item) {
if (item.title) {
return item.title;
}
var match = item.options.filter(function(option) {
return option.value === item.value;
});
var displayTitle = match.length ? match[0].text : '';
return displayTitle;
}
module.exports = {
displayTitle: displayTitle
};
/* eslint-disable */
function displayTitle(item) {
if (item.title) {
return item.title;
}
var match = item.options.filter(function(option) {
return option.value === item.value;
});
var displayTitle = match.length ? match[0].text : '';
return displayTitle;
}
module.exports = {
displayTitle: displayTitle
};

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,108 +1,108 @@
import { VantComponent } from '../common/component';
import { getSystemInfoSync } from '../common/utils';
VantComponent({
field: true,
classes: ['input-class', 'right-icon-class'],
props: {
size: String,
icon: String,
label: String,
error: Boolean,
fixed: Boolean,
focus: Boolean,
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,
placeholder: String,
customStyle: String,
confirmType: String,
confirmHold: Boolean,
holdKeyboard: Boolean,
errorMessage: String,
arrowDirection: String,
placeholderStyle: String,
errorMessageAlign: String,
selectionEnd: {
type: Number,
value: -1
},
selectionStart: {
type: Number,
value: -1
},
showConfirmBar: {
type: Boolean,
value: true
},
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: {
focused: false,
system: getSystemInfoSync().system.split(' ').shift().toLowerCase()
},
methods: {
onInput(event) {
const { value = '' } = event.detail || {};
this.setData({ value }, () => {
this.emitChange(value);
});
},
onFocus(event) {
this.setData({ focused: true });
this.$emit('focus', event.detail);
},
onBlur(event) {
this.setData({ focused: false });
this.$emit('blur', event.detail);
},
onClickIcon() {
this.$emit('click-icon');
},
onClear() {
this.setData({ value: '' }, () => {
this.emitChange('');
this.$emit('clear', '');
});
},
onConfirm() {
this.$emit('confirm', this.data.value);
},
emitChange(value) {
this.$emit('input', value);
this.$emit('change', value);
}
}
});
import { VantComponent } from '../common/component';
import { getSystemInfoSync } from '../common/utils';
VantComponent({
field: true,
classes: ['input-class', 'right-icon-class'],
props: {
size: String,
icon: String,
label: String,
error: Boolean,
fixed: Boolean,
focus: Boolean,
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,
placeholder: String,
customStyle: String,
confirmType: String,
confirmHold: Boolean,
holdKeyboard: Boolean,
errorMessage: String,
arrowDirection: String,
placeholderStyle: String,
errorMessageAlign: String,
selectionEnd: {
type: Number,
value: -1
},
selectionStart: {
type: Number,
value: -1
},
showConfirmBar: {
type: Boolean,
value: true
},
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: {
focused: false,
system: getSystemInfoSync().system.split(' ').shift().toLowerCase()
},
methods: {
onInput(event) {
const { value = '' } = event.detail || {};
this.setData({ value }, () => {
this.emitChange(value);
});
},
onFocus(event) {
this.setData({ focused: true });
this.$emit('focus', event.detail);
},
onBlur(event) {
this.setData({ focused: false });
this.$emit('blur', event.detail);
},
onClickIcon() {
this.$emit('click-icon');
},
onClear() {
this.setData({ value: '' }, () => {
this.emitChange('');
this.$emit('clear', '');
});
},
onConfirm() {
this.$emit('confirm', this.data.value);
},
emitChange(value) {
this.$emit('input', value);
this.$emit('change', value);
}
}
});

View File

@@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
{
"component": true,
"usingComponents": {
"van-cell": "../cell/index",
"van-icon": "../icon/index"
}
}

View File

@@ -1,93 +1,93 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<van-cell
size="{{ size }}"
icon="{{ leftIcon }}"
title="{{ label }}"
center="{{ center }}"
border="{{ border }}"
is-link="{{ isLink }}"
required="{{ required }}"
clickable="{{ clickable }}"
title-width="{{ titleWidth }}"
custom-style="{{ customStyle }}"
arrow-direction="{{ arrowDirection }}"
custom-class="van-field"
>
<slot name="left-icon" slot="icon" />
<slot name="label" slot="title" />
<view class="{{ utils.bem('field__body', [type, system]) }}">
<textarea
wx:if="{{ type === 'textarea' }}"
class="input-class {{ utils.bem('field__input', [inputAlign, type, { disabled, error }]) }}"
fixed="{{ fixed }}"
focus="{{ focus }}"
value="{{ value }}"
disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
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 }]) }}"
type="{{ type }}"
focus="{{ focus }}"
value="{{ value }}"
disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
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="{{ clearable && focused && value && !readonly }}"
size="16px"
name="clear"
class="van-field__clear-root van-field__icon-root"
bindtouchstart="onClear"
/>
<view class="van-field__icon-container" bind:tap="onClickIcon">
<van-icon
wx:if="{{ rightIcon || icon }}"
size="16px"
name="{{ rightIcon || icon }}"
class="van-field__icon-root {{ iconClass }}"
custom-class="right-icon-class"
/>
<slot name="right-icon" />
<slot name="icon" />
</view>
<view 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>
<wxs src="../wxs/utils.wxs" module="utils" />
<van-cell
size="{{ size }}"
icon="{{ leftIcon }}"
title="{{ label }}"
center="{{ center }}"
border="{{ border }}"
is-link="{{ isLink }}"
required="{{ required }}"
clickable="{{ clickable }}"
title-width="{{ titleWidth }}"
custom-style="{{ customStyle }}"
arrow-direction="{{ arrowDirection }}"
custom-class="van-field"
>
<slot name="left-icon" slot="icon" />
<slot name="label" slot="title" />
<view class="{{ utils.bem('field__body', [type, system]) }}">
<textarea
wx:if="{{ type === 'textarea' }}"
class="input-class {{ utils.bem('field__input', [inputAlign, type, { disabled, error }]) }}"
fixed="{{ fixed }}"
focus="{{ focus }}"
value="{{ value }}"
disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
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 }]) }}"
type="{{ type }}"
focus="{{ focus }}"
value="{{ value }}"
disabled="{{ disabled || readonly }}"
maxlength="{{ maxlength }}"
placeholder="{{ placeholder }}"
placeholder-style="{{ placeholderStyle }}"
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="{{ clearable && focused && value && !readonly }}"
size="16px"
name="clear"
class="van-field__clear-root van-field__icon-root"
bindtouchstart="onClear"
/>
<view class="van-field__icon-container" bind:tap="onClickIcon">
<van-icon
wx:if="{{ rightIcon || icon }}"
size="16px"
name="{{ rightIcon || icon }}"
class="van-field__icon-root {{ iconClass }}"
custom-class="right-icon-class"
/>
<slot name="right-icon" />
<slot name="icon" />
</view>
<view 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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,41 +1,41 @@
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],
relation: {
type: 'ancestor',
name: 'goods-action',
linked(parent) {
this.parent = parent;
}
},
props: {
text: String,
color: String,
loading: Boolean,
disabled: Boolean,
type: {
type: String,
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
});
}
}
});
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],
relation: {
type: 'ancestor',
name: 'goods-action',
linked(parent) {
this.parent = parent;
}
},
props: {
text: String,
color: String,
loading: Boolean,
disabled: Boolean,
type: {
type: String,
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
});
}
}
});

View File

@@ -1,6 +1,6 @@
{
"component": true,
"usingComponents": {
"van-button": "../button/index"
}
}
{
"component": true,
"usingComponents": {
"van-button": "../button/index"
}
}

View File

@@ -1,28 +1,28 @@
<wxs src="../wxs/utils.wxs" module="utils" />
<van-button
square
id="{{ id }}"
lang="{{ lang }}"
type="{{ type }}"
color="{{ color }}"
loading="{{ loading }}"
disabled="{{ disabled }}"
open-type="{{ openType }}"
custom-class="{{ utils.bem('goods-action-button', [type, { first: isFirst, last: isLast }]) }}"
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>
<wxs src="../wxs/utils.wxs" module="utils" />
<van-button
square
id="{{ id }}"
lang="{{ lang }}"
type="{{ type }}"
color="{{ color }}"
loading="{{ loading }}"
disabled="{{ disabled }}"
open-type="{{ openType }}"
custom-class="{{ utils.bem('goods-action-button', [type, { first: isFirst, last: isLast }]) }}"
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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,22 +1,22 @@
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,
dot: Boolean,
info: String,
icon: String,
disabled: Boolean,
loading: Boolean
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
}
}
});
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,
dot: Boolean,
info: String,
icon: String,
disabled: Boolean,
loading: Boolean
},
methods: {
onClick(event) {
this.$emit('click', event.detail);
this.jumpLink();
}
}
});

View File

@@ -1,7 +1,7 @@
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-button": "../button/index"
}
}
{
"component": true,
"usingComponents": {
"van-icon": "../icon/index",
"van-button": "../button/index"
}
}

View File

@@ -1,38 +1,38 @@
<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-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>
<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-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>

View File

@@ -1 +1 @@
export {};
export {};

View File

@@ -1,22 +1,22 @@
import { VantComponent } from '../common/component';
VantComponent({
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
}
}
});
import { VantComponent } from '../common/component';
VantComponent({
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
}
}
});

View File

@@ -1,3 +1,3 @@
{
"component": true
}
{
"component": true
}

Some files were not shown because too many files have changed in this diff Show More