Merge branch 'dev' of https://github.com/youzan/vant into dev

This commit is contained in:
陈嘉涵 2019-01-19 09:52:17 +08:00
commit 6cca433410
112 changed files with 1908 additions and 2572 deletions

View File

@ -77,8 +77,7 @@
"@vant/doc": "^1.0.22",
"@vant/eslint-config": "^1.0.8",
"@vant/markdown-loader": "^1.0.3",
"@vue/babel-helper-vue-jsx-merge-props": "^1.0.0-beta.1",
"@vue/babel-preset-jsx": "^1.0.0-beta.1",
"@vue/babel-preset-jsx": "^1.0.0-beta.2",
"@vue/server-test-utils": "^1.0.0-beta.28",
"@vue/test-utils": "^1.0.0-beta.28",
"autoprefixer": "^9.4.3",

View File

@ -0,0 +1,78 @@
import { use, isAndroid } from '../utils';
import Cell from '../cell';
import Field from '../field';
const [sfc, bem, t] = use('address-edit-detail');
const android = isAndroid();
export default sfc({
props: {
value: String,
error: Boolean,
focused: Boolean,
detailRows: Number,
searchResult: Array,
showSearchResult: Boolean
},
methods: {
onSelect(express) {
this.$emit('select-search', express);
this.$emit('input', `${express.address || ''} ${express.name || ''}`.trim());
}
},
render(h) {
const { value, focused, searchResult } = this;
const Finish = value && focused && android && (
<div
slot="icon"
class={bem('finish')}
onClick={() => {
this.$refs.field.blur();
}}
>
{t('complete')}
</div>
);
const SearchList =
focused &&
searchResult &&
this.showSearchResult &&
searchResult.map(express => (
<Cell
key={express.name + express.address}
title={express.name}
label={express.address}
icon="location-o"
clickable
onClick={() => {
this.onSelect(express);
}}
/>
));
return (
<Cell class={bem()}>
<Field
autosize
ref="field"
rows={this.detailRows}
clearable={!android}
type="textarea"
maxlength="200"
value={this.value}
error={this.error}
label={t('label')}
placeholder={t('placeholder')}
{...{ on: this.$listeners }}
>
{Finish}
</Field>
{SearchList}
</Cell>
);
}
});

View File

@ -1,81 +0,0 @@
<template>
<cell :class="b()">
<field
v-on="$listeners"
autosize
ref="field"
:rows="detailRows"
:clearable="!isAndroid"
type="textarea"
maxlength="200"
:value="value"
:error="error"
:label="$t('label')"
:placeholder="$t('placeholder')"
>
<div
v-if="showIcon && isAndroid"
v-text="$t('complete')"
slot="icon"
:class="b('finish')"
@click="$refs.field.blur()"
/>
</field>
<cell
v-for="express in searchList"
:key="express.name + express.address"
:title="express.name"
:label="express.address"
icon="location-o"
clickable
@click="onSelect(express)"
/>
</cell>
</template>
<script>
import create from '../utils/create';
import Field from '../field';
import { isAndroid } from '../utils';
export default create({
name: 'address-edit-detail',
components: {
Field
},
props: {
value: String,
error: Boolean,
focused: Boolean,
detailRows: Number,
searchResult: Array,
showSearchResult: Boolean
},
created() {
this.isAndroid = isAndroid();
},
computed: {
searchList() {
if (this.showSearchResult && this.focused) {
return this.searchResult || [];
}
return [];
},
showIcon() {
return this.value && this.focused;
}
},
methods: {
onSelect(express) {
this.$emit('select-search', express);
this.$emit('input', `${express.address || ''} ${express.name || ''}`.trim());
}
}
});
</script>

View File

@ -1,115 +1,16 @@
<template>
<div :class="b()">
<field
v-model="data.name"
clearable
:label="$t('name')"
:placeholder="$t('namePlaceholder')"
:error="errorInfo.name"
@focus="onFocus('name')"
/>
<field
v-model="data.tel"
clearable
type="tel"
:label="$t('tel')"
:placeholder="$t('telPlaceholder')"
:error="errorInfo.tel"
@focus="onFocus('tel')"
/>
<field
v-show="showArea"
readonly
:label="$t('area')"
:placeholder="$t('areaPlaceholder')"
:value="areaText"
@click="showAreaPopup = true"
/>
<address-edit-detail
v-show="showDetail"
:focused="detailFocused"
:value="data.addressDetail"
:error="errorInfo.addressDetail"
:detail-rows="detailRows"
:search-result="searchResult"
:show-search-result="showSearchResult"
@focus="onFocus('addressDetail')"
@blur="detailFocused = false"
@input="onChangeDetail"
@select-search="$emit('select-search', $event)"
/>
<field
v-if="showPostal"
v-show="!hideBottomFields"
v-model="data.postalCode"
type="tel"
maxlength="6"
:label="$t('postal')"
:placeholder="$t('postal')"
:error="errorInfo.postalCode"
@focus="onFocus('postalCode')"
/>
<slot />
<switch-cell
v-if="showSetDefault"
v-show="!hideBottomFields"
v-model="data.isDefault"
:title="$t('defaultAddress')"
@change="$emit('change-default', $event)"
/>
<div
v-show="!hideBottomFields"
:class="b('buttons')"
>
<van-button
block
:loading="isSaving"
type="danger"
:text="saveButtonText || $t('save')"
@click="onSave"
/>
<van-button
v-if="showDelete"
block
:loading="isDeleting"
:text="deleteButtonText || $t('delete')"
@click="onDelete"
/>
</div>
<popup
v-model="showAreaPopup"
position="bottom"
:lazy-render="false"
get-container="body"
>
<van-area
ref="area"
:loading="!areaListLoaded"
:value="data.areaCode"
:area-list="areaList"
@confirm="onAreaConfirm"
@cancel="showAreaPopup = false"
/>
</popup>
</div>
</template>
<script>
/* eslint-disable camelcase */
import create from '../utils/create';
import { isObj } from '../utils';
import { use, isObj } from '../utils';
import Area from '../area';
import Field from '../field';
import VanButton from '../button';
import Popup from '../popup';
import Toast from '../toast';
import Button from '../button';
import Dialog from '../dialog';
import VanArea from '../area';
import AddressEditDetail from './Detail';
import Detail from './Detail';
import SwitchCell from '../switch-cell';
import validateMobile from '../utils/validate/mobile';
const [sfc, bem, t] = use('address-edit');
const defaultData = {
name: '',
tel: '',
@ -123,18 +24,7 @@ const defaultData = {
isDefault: false
};
export default create({
name: 'address-edit',
components: {
Field,
Popup,
VanArea,
VanButton,
SwitchCell,
AddressEditDetail
},
export default sfc({
props: {
areaList: Object,
isSaving: Boolean,
@ -184,11 +74,6 @@ export default create({
},
computed: {
// hide bottom field when use search && detail get focused
hideBottomFields() {
return this.searchResult.length && this.detailFocused;
},
areaListLoaded() {
return isObj(this.areaList) && Object.keys(this.areaList).length;
},
@ -276,7 +161,6 @@ export default create({
getErrorMessage(key) {
const value = String(this.data[key] || '').trim();
const { $t } = this;
if (this.validator) {
const message = this.validator(key, value);
@ -287,21 +171,21 @@ export default create({
switch (key) {
case 'name':
return value ? '' : $t('nameEmpty');
return value ? '' : t('nameEmpty');
case 'tel':
return this.telValidator(value) ? '' : $t('telInvalid');
return this.telValidator(value) ? '' : t('telInvalid');
case 'areaCode':
return value ? '' : $t('areaEmpty');
return value ? '' : t('areaEmpty');
case 'addressDetail':
return value ? '' : $t('addressEmpty');
return value ? '' : t('addressEmpty');
case 'postalCode':
return value && !/^\d{6}$/.test(value) ? $t('postalEmpty') : '';
return value && !/^\d{6}$/.test(value) ? t('postalEmpty') : '';
}
},
onDelete() {
Dialog.confirm({
title: this.$t('confirmDelete')
title: t('confirmDelete')
})
.then(() => {
this.$emit('delete', this.data);
@ -328,6 +212,119 @@ export default create({
setAddressDetail(value) {
this.data.addressDetail = value;
}
},
render(h) {
const { data, errorInfo } = this;
const onFocus = name => () => this.onFocus(name);
// hide bottom field when use search && detail get focused
const hideBottomFields = this.searchResult.length && this.detailFocused;
return (
<div class={bem()}>
<Field
v-model={data.name}
clearable
label={t('name')}
placeholder={t('namePlaceholder')}
error={errorInfo.name}
onFocus={onFocus('name')}
/>
<Field
v-model={data.tel}
clearable
type="tel"
label={t('tel')}
placeholder={t('telPlaceholder')}
error={errorInfo.tel}
onFocus={onFocus('tel')}
/>
<Field
v-show={this.showArea}
readonly
label={t('area')}
placeholder={t('areaPlaceholder')}
value={this.areaText}
onClick={() => {
this.showAreaPopup = true;
}}
/>
<Detail
v-show={this.showDetail}
focused={this.detailFocused}
value={data.addressDetail}
error={errorInfo.addressDetail}
detailRows={this.detailRows}
searchResult={this.searchResult}
showSearchResult={this.showSearchResult}
onFocus={onFocus('addressDetail')}
onBlur={() => {
this.detailFocused = false;
}}
onInput={this.onChangeDetail}
onSelect-search={event => {
this.$emit('select-search', event);
}}
/>
{this.showPostal && (
<Field
v-show={!hideBottomFields}
v-model={data.postalCode}
type="tel"
maxlength="6"
label={t('postal')}
placeholder={t('postal')}
error={errorInfo.postalCode}
onFocus={onFocus('postalCode')}
/>
)}
{this.$slots.default}
{this.showSetDefault && (
<SwitchCell
v-model={data.isDefault}
v-show={!hideBottomFields}
title={t('defaultAddress')}
onChange={event => {
this.$emit('change-default', event);
}}
/>
)}
<div v-show={!hideBottomFields} class={bem('buttons')}>
<Button
block
loading={this.isSaving}
type="danger"
text={this.saveButtonText || t('save')}
onClick={this.onSave}
/>
{this.showDelete && (
<Button
block
loading={this.isDeleting}
text={this.deleteButtonText || t('delete')}
onClick={this.onDelete}
/>
)}
</div>
<Popup
v-model={this.showAreaPopup}
position="bottom"
lazyRender={false}
getContainer="body"
>
<Area
ref="area"
loading={!this.areaListLoaded}
value={data.areaCode}
areaList={this.areaList}
onConfirm={this.onAreaConfirm}
onCancel={() => {
this.showAreaPopup = false;
}}
/>
</Popup>
</div>
);
}
});
</script>

View File

@ -5,79 +5,41 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-address-edit">
<div placeholder="收货人姓名" class="van-cell van-field">
<div class="van-cell__title"><span>姓名</span>
</div>
<div class="van-cell__title"><span>姓名</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="收货人姓名" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="收货人姓名" value="" class="van-field__control"></div>
</div>
</div>
<div placeholder="收货人手机号" class="van-cell van-field">
<div class="van-cell__title"><span>电话</span>
</div>
<div class="van-cell__title"><span>电话</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="tel" placeholder="收货人手机号" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="收货人手机号" value="" class="van-field__control"></div>
</div>
</div>
<div placeholder="选择省 / 市 / 区" class="van-cell van-field">
<div class="van-cell__title"><span>地区</span>
</div>
<div class="van-cell__title"><span>地区</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="选择省 / 市 / 区" readonly="readonly" value="" class="van-field__control"></div>
</div>
</div>
<div class="van-cell van-address-edit-detail">
<div class="van-cell__value van-cell__value--alone">
<div rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-cell van-field">
<div class="van-cell__title"><span>详细地址</span>
</div>
<div class="van-cell__title"><span>详细地址</span></div>
<div class="van-cell__value">
<div class="van-field__body"><textarea rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-field__control"></textarea>
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><textarea rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-field__control"></textarea></div>
</div>
</div>
</div>
</div>
<div maxlength="6" placeholder="邮政编码" class="van-cell van-field">
<div class="van-cell__title"><span>邮政编码</span>
</div>
<div class="van-cell__title"><span>邮政编码</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="tel" maxlength="6" placeholder="邮政编码" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input maxlength="6" placeholder="邮政编码" value="" class="van-field__control"></div>
</div>
</div>
<div class="van-cell van-cell--center van-cell--borderless van-switch-cell">
<div class="van-cell__title"><span>设为默认收货地址</span>
</div>
<div class="van-cell__title"><span>设为默认收货地址</span></div>
<div class="van-cell__value">
<div title="设为默认收货地址" class="van-switch" style="font-size:24px;background-color:undefined;">
<div class="van-switch__node">
@ -85,9 +47,8 @@ exports[`renders demo correctly 1`] = `
</div>
</div>
</div>
</div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button> <button class="van-button van-button--default van-button--normal van-button--block"><span class="van-button__text">删除</span></button></div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button><button class="van-button van-button--default van-button--normal van-button--block"><span class="van-button__text">删除</span></button></div>
<div class="van-popup van-popup--bottom" style="display:none;">
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">

View File

@ -3,68 +3,34 @@
exports[`create a AddressEdit 1`] = `
<div class="van-address-edit">
<div placeholder="收货人姓名" class="van-cell van-field">
<div class="van-cell__title"><span>姓名</span>
</div>
<div class="van-cell__title"><span>姓名</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="收货人姓名" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="收货人姓名" value="" class="van-field__control"></div>
</div>
</div>
<div placeholder="收货人手机号" class="van-cell van-field">
<div class="van-cell__title"><span>电话</span>
</div>
<div class="van-cell__title"><span>电话</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="tel" placeholder="收货人手机号" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="收货人手机号" value="" class="van-field__control"></div>
</div>
</div>
<div placeholder="选择省 / 市 / 区" class="van-cell van-field">
<div class="van-cell__title"><span>地区</span>
</div>
<div class="van-cell__title"><span>地区</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="选择省 / 市 / 区" readonly="readonly" value="" class="van-field__control"></div>
</div>
</div>
<div class="van-cell van-address-edit-detail">
<div class="van-cell__value van-cell__value--alone">
<div rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-cell van-field">
<div class="van-cell__title"><span>详细地址</span>
</div>
<div class="van-cell__title"><span>详细地址</span></div>
<div class="van-cell__value">
<div class="van-field__body"><textarea rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-field__control"></textarea>
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><textarea rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-field__control"></textarea></div>
</div>
</div>
</div>
</div>
<!---->
<!---->
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button>
<!---->
</div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button></div>
<div name="popup-slide-bottom" class="van-popup van-popup--bottom" style="display:none;">
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">
@ -73,7 +39,7 @@ exports[`create a AddressEdit 1`] = `
<div class="van-picker__confirm">确认</div>
</div>
<div class="van-picker__loading">
<div class="van-loading van-loading--circular van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
</div>
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column" style="height:220px;">
@ -95,79 +61,41 @@ exports[`create a AddressEdit 1`] = `
exports[`create a AddressEdit with props 1`] = `
<div class="van-address-edit">
<div placeholder="收货人姓名" class="van-cell van-field">
<div class="van-cell__title"><span>姓名</span>
</div>
<div class="van-cell__title"><span>姓名</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="收货人姓名" value="测试" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="收货人姓名" value="测试" class="van-field__control"></div>
</div>
</div>
<div placeholder="收货人手机号" class="van-cell van-field">
<div class="van-cell__title"><span>电话</span>
</div>
<div class="van-cell__title"><span>电话</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="tel" placeholder="收货人手机号" value="13000000000" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="收货人手机号" value="13000000000" class="van-field__control"></div>
</div>
</div>
<div placeholder="选择省 / 市 / 区" class="van-cell van-field">
<div class="van-cell__title"><span>地区</span>
</div>
<div class="van-cell__title"><span>地区</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" readonly="readonly" placeholder="选择省 / 市 / 区" value="北京市/朝阳区" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="选择省 / 市 / 区" readonly="readonly" value="北京市/朝阳区" class="van-field__control"></div>
</div>
</div>
<div class="van-cell van-address-edit-detail">
<div class="van-cell__value van-cell__value--alone">
<div rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-cell van-field">
<div class="van-cell__title"><span>详细地址</span>
</div>
<div class="van-cell__title"><span>详细地址</span></div>
<div class="van-cell__value">
<div class="van-field__body"><textarea rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-field__control">详细地址</textarea>
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><textarea rows="1" maxlength="200" placeholder="街道门牌、楼层房间号等信息" class="van-field__control">详细地址</textarea></div>
</div>
</div>
</div>
</div>
<div maxlength="6" placeholder="邮政编码" class="van-cell van-field">
<div class="van-cell__title"><span>邮政编码</span>
</div>
<div class="van-cell__title"><span>邮政编码</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="tel" maxlength="6" placeholder="邮政编码" value="10000" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input maxlength="6" placeholder="邮政编码" value="10000" class="van-field__control"></div>
</div>
</div>
<div class="van-cell van-cell--center van-cell--borderless van-switch-cell">
<div class="van-cell__title"><span>设为默认收货地址</span>
</div>
<div class="van-cell__title"><span>设为默认收货地址</span></div>
<div class="van-cell__value">
<div title="设为默认收货地址" class="van-switch van-switch--on" style="font-size:24px;background-color:undefined;">
<div class="van-switch__node">
@ -175,11 +103,8 @@ exports[`create a AddressEdit with props 1`] = `
</div>
</div>
</div>
</div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button>
<!---->
</div>
<div class="van-address-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button></div>
<div name="popup-slide-bottom" class="van-popup van-popup--bottom" style="display:none;">
<div class="van-picker van-area">
<div class="van-hairline--top-bottom van-picker__toolbar">

View File

@ -218,6 +218,8 @@ test('delete address', async () => {
const deleteButton = wrapper.findAll('.van-button').at(1);
deleteButton.trigger('click');
await later();
document.querySelector('.van-dialog__cancel').click();
deleteButton.trigger('click');
document.querySelector('.van-dialog__confirm').click();

View File

@ -0,0 +1,47 @@
import { use } from '../utils';
import Icon from '../icon';
import Cell from '../cell';
import Radio from '../radio';
const [sfc, bem] = use('address-item');
export default sfc({
props: {
data: Object,
disabled: Boolean,
switchable: Boolean
},
methods: {
onSelect() {
if (this.switchable) {
this.$emit('select');
}
}
},
render(h) {
const { data, disabled, switchable } = this;
return (
<Cell
class={bem({ disabled, unswitchable: !switchable })}
is-link={!disabled && switchable}
onClick={this.onSelect}
>
<Radio name={data.id}>
<div class={bem('name')}>{`${data.name}${data.tel}`}</div>
<div class={bem('address')}>{data.address}</div>
</Radio>
<Icon
slot="right-icon"
name="edit"
class={bem('edit')}
onClick={event => {
event.stopPropagation();
this.$emit('edit');
}}
/>
</Cell>
);
}
});

View File

@ -1,48 +0,0 @@
<template>
<cell
:class="b({ disabled, unswitchable: !switchable })"
:is-link="!disabled && switchable"
@click="onSelect"
>
<radio :name="data.id">
<div :class="b('name')">{{ data.name }}{{ data.tel }}</div>
<div
v-text="data.address"
:class="b('address')"
/>
</radio>
<icon
slot="right-icon"
name="edit"
:class="b('edit')"
@click.stop="$emit('edit')"
/>
</cell>
</template>
<script>
import Radio from '../radio';
import create from '../utils/create';
export default create({
name: 'address-item',
components: {
Radio
},
props: {
data: Object,
disabled: Boolean,
switchable: Boolean
},
methods: {
onSelect() {
if (this.switchable) {
this.$emit('select');
}
}
}
});
</script>

View File

@ -0,0 +1,63 @@
import { use } from '../utils';
import Button from '../button';
import RadioGroup from '../radio-group';
import AddressItem from './Item';
const [sfc, bem, t] = use('address-list');
export default sfc({
props: {
list: Array,
disabledList: Array,
disabledText: String,
addButtonText: String,
value: [String, Number],
switchable: {
type: Boolean,
default: true
}
},
render(h) {
const getList = (list, disabled) =>
list.map((item, index) => (
<AddressItem
data={item}
key={item.id}
disabled={disabled}
switchable={this.switchable && !disabled}
onSelect={() => {
this.$emit(disabled ? 'select-disabled' : 'select', item, index);
}}
onEdit={() => {
this.$emit(disabled ? 'edit-disabled' : 'edit', item, index);
}}
/>
));
const List = getList(this.list);
const DisabledList = getList(this.disabledList, true);
return (
<div class={bem()}>
{this.$slots.top}
<RadioGroup value={this.value} onInput={event => this.$emit('input', event)}>
{List}
</RadioGroup>
{this.disabledText && <div class={bem('disabled-text')}>{this.disabledText}</div>}
{DisabledList}
{this.$slots.default}
<Button
square
size="large"
type="danger"
class={bem('add')}
text={this.addButtonText || t('add')}
onClick={() => {
this.$emit('add');
}}
/>
</div>
);
}
});

View File

@ -1,73 +0,0 @@
<template>
<div :class="b()">
<slot name="top" />
<radio-group
:value="value"
@input="$emit('input', $event)"
>
<cell-group>
<address-item
v-for="(item, index) in list"
:data="item"
:key="item.id"
:switchable="switchable"
@select="$emit('select', item, index)"
@edit="$emit('edit', item, index)"
/>
</cell-group>
</radio-group>
<div
v-if="disabledText"
v-text="disabledText"
:class="b('disabled-text')"
/>
<cell-group v-if="disabledList.length">
<address-item
v-for="(item, index) in disabledList"
disabled
:data="item"
:key="item.id"
@select="$emit('select-disabled', item, index)"
@edit="$emit('edit-disabled', item, index)"
/>
</cell-group>
<slot />
<van-button
square
size="large"
type="danger"
:class="b('add')"
:text="addButtonText || $t('add')"
@click="$emit('add')"
/>
</div>
</template>
<script>
import create from '../utils/create';
import RadioGroup from '../radio-group';
import VanButton from '../button';
import AddressItem from './Item';
export default create({
name: 'address-list',
components: {
RadioGroup,
VanButton,
AddressItem
},
props: {
list: Array,
disabledList: Array,
disabledText: String,
addButtonText: String,
value: [String, Number],
switchable: {
type: Boolean,
default: true
}
}
});
</script>

View File

@ -5,39 +5,26 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-address-list">
<div class="van-radio-group">
<div class="van-cell-group van-hairline--top-bottom">
<div class="van-cell van-cell--clickable van-address-item">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label"><div class="van-address-item__name">张三13000000000</div> <div class="van-address-item__address">浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室</div></span></div>
</div>
<i class="van-icon van-icon-edit van-address-item__edit" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
</div>
<div class="van-cell van-cell--clickable van-address-item">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="2" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label"><div class="van-address-item__name">李四1310000000</div> <div class="van-address-item__address">浙江省杭州市拱墅区莫干山路 50 号</div></span></div>
</div>
<i class="van-icon van-icon-edit van-address-item__edit" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
</div>
<div class="van-cell van-cell--clickable van-address-item">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label"><div class="van-address-item__name">张三13000000000</div><div class="van-address-item__address">浙江省杭州市西湖区文三路 138 号东方通信大厦 7 楼 501 室</div></span></div>
</div><i class="van-icon van-icon-edit van-address-item__edit" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-cell van-cell--clickable van-address-item">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="2" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label"><div class="van-address-item__name">李四1310000000</div><div class="van-address-item__address">浙江省杭州市拱墅区莫干山路 50 号</div></span></div>
</div><i class="van-icon van-icon-edit van-address-item__edit" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
</div>
<div class="van-address-list__disabled-text">以下地址超出配送范围</div>
<div class="van-cell-group van-hairline--top-bottom">
<div class="van-cell van-address-item van-address-item--disabled van-address-item--unswitchable">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="3" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label"><div class="van-address-item__name">王五1320000000</div> <div class="van-address-item__address">浙江省杭州市滨江区江南大道 15 号</div></span></div>
</div>
<i class="van-icon van-icon-edit van-address-item__edit" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
</div>
</div> <button class="van-button van-button--danger van-button--large van-button--square van-address-list__add"><span class="van-button__text">新增地址</span></button>
<div class="van-cell van-address-item van-address-item--disabled van-address-item--unswitchable">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="3" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label"><div class="van-address-item__name">王五1320000000</div><div class="van-address-item__address">浙江省杭州市滨江区江南大道 15 号</div></span></div>
</div><i class="van-icon van-icon-edit van-address-item__edit" style="color:undefined;font-size:undefined;">
<!----></i>
</div><button class="van-button van-button--danger van-button--large van-button--square van-address-list__add"><span class="van-button__text">新增地址</span></button>
</div>
</div>
</div>

View File

@ -48,6 +48,8 @@ Set `columns-num` with 2, you'll have a 2 level picker.
| item-height | Option height | `Number` | `44` |
| loading | Whether to show loading prompt | `Boolean` | `false` |
| visible-item-count | Count of visible columns | `Number` | `5` |
| confirm-button-text | Text of confirm button | `String` | `Confirm` |
| cancel-button-text | Text of cancel button | `String` | `Cancel` |
### Event

View File

@ -41,13 +41,6 @@ export default sfc({
displayColumns() {
return this.columns.slice(0, +this.columnsNum);
},
listeners() {
return {
...this.$listeners,
change: this.onChange
};
}
},
@ -186,18 +179,25 @@ export default sfc({
},
render(h) {
const on = {
...this.$listeners,
change: this.onChange
};
return (
<Picker
ref="picker"
class={bem()}
show-toolbar
value-key="name"
showToolbar
valueKey="name"
title={this.title}
loading={this.loading}
columns={this.displayColumns}
item-height={this.itemHeight}
visible-item-count={this.visibleItemCount}
{...{ on: this.listeners }}
itemHeight={this.itemHeight}
visibleItemCount={this.visibleItemCount}
cancelButtonText={this.cancelButtonText}
confirmButtonText={this.confirmButtonText}
{...{ on }}
/>
);
}

View File

@ -46,6 +46,8 @@ Vue.use(Area);
| loading | 是否显示加载状态 | `Boolean` | `false` | - |
| item-height | 选项高度 | `Number` | `44` | - |
| visible-item-count | 可见的选项个数 | `Number` | `5` | - |
| confirm-button-text | 确认按钮文字 | `String` | `确认` | 1.5.3 |
| cancel-button-text | 取消按钮文字 | `String` | `取消` | 1.5.3 |
### Event

View File

@ -8,16 +8,13 @@ exports[`renders demo correctly 1`] = `
<!---->
</div>
</a> <a class="van-badge van-hairline">
<div class="van-badge__text">标签名称
<div class="van-info van-badge__info">8</div>
<div class="van-badge__text">标签名称<div class="van-info van-badge__info">8</div>
</div>
</a> <a class="van-badge van-hairline">
<div class="van-badge__text">标签名称
<div class="van-info van-badge__info">99</div>
<div class="van-badge__text">标签名称<div class="van-info van-badge__info">99</div>
</div>
</a> <a class="van-badge van-hairline">
<div class="van-badge__text">标签名称
<div class="van-info van-badge__info">99+</div>
<div class="van-badge__text">标签名称<div class="van-info van-badge__info">99+</div>
</div>
</a></div>
</div>

View File

@ -8,9 +8,9 @@ exports[`renders demo correctly 1`] = `
<div><button class="van-button van-button--primary van-button--normal van-button--plain"><span class="van-button__text">朴素按钮</span></button> <button class="van-button van-button--danger van-button--normal van-button--plain"><span class="van-button__text">朴素按钮</span></button></div>
<div><button disabled="disabled" class="van-button van-button--primary van-button--normal van-button--disabled"><span class="van-button__text">禁用状态</span></button> <button disabled="disabled" class="van-button van-button--danger van-button--normal van-button--disabled"><span class="van-button__text">禁用状态</span></button></div>
<div><button class="van-button van-button--primary van-button--normal van-button--loading">
<div class="van-loading van-loading--circular van-loading" style="color:;width:20px;height:20px;"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading" style="color:;width:20px;height:20px;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
</button> <button class="van-button van-button--danger van-button--normal van-button--loading">
<div class="van-loading van-loading--circular van-loading" style="color:;width:20px;height:20px;"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading" style="color:;width:20px;height:20px;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
</button></div>
<div><button class="van-button van-button--primary van-button--normal van-button--square"><span class="van-button__text">方形按钮</span></button> <button class="van-button van-button--danger van-button--normal van-button--round"><span class="van-button__text">圆形按钮</span></button></div>
<div><button class="van-button van-button--default van-button--large"><span class="van-button__text">大号按钮</span></button> <button class="van-button van-button--default van-button--normal"><span class="van-button__text">普通按钮</span></button> <button class="van-button van-button--default van-button--small"><span class="van-button__text">小型按钮</span></button> <button class="van-button van-button--default van-button--mini"><span class="van-button__text">迷你按钮</span></button></div>

View File

@ -64,11 +64,7 @@
}
&__bottom {
position: absolute;
bottom: 0;
left: 0;
width: 100%;
line-height: 18px;
line-height: 20px;
}
&__price {

View File

@ -4,15 +4,12 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-card">
<div class="van-card__header"><a class="van-card__thumb"><img src="//img.yzcdn.cn/upload_files/2017/07/02/af5b9f44deaeb68000d7e4a711160c53.jpg" class="van-card__img">
</a>
<div class="van-card__header"><a class="van-card__thumb"><img src="//img.yzcdn.cn/upload_files/2017/07/02/af5b9f44deaeb68000d7e4a711160c53.jpg" class="van-card__img"></a>
<div class="van-card__content">
<div class="van-card__title">2018秋冬新款男士休闲时尚军绿飞行夹克秋冬新款男</div>
<div class="van-card__desc van-ellipsis">描述信息</div>
<div class="van-card__bottom">
<div class="van-card__price">¥ 2.00</div>
<div class="van-card__num">x 2</div>
</div>
</div>
@ -21,8 +18,7 @@ exports[`renders demo correctly 1`] = `
</div>
<div>
<div class="van-card">
<div class="van-card__header"><a class="van-card__thumb"><img src="//img.yzcdn.cn/upload_files/2017/07/02/af5b9f44deaeb68000d7e4a711160c53.jpg" class="van-card__img">
<span class="van-tag van-tag--mark van-card__tag" style="background-color:#f44;">标签</span></a>
<div class="van-card__header"><a class="van-card__thumb"><img src="//img.yzcdn.cn/upload_files/2017/07/02/af5b9f44deaeb68000d7e4a711160c53.jpg" class="van-card__img"><span class="van-tag van-tag--mark van-card__tag" style="background-color:#f44;">标签</span></a>
<div class="van-card__content">
<div class="van-card__title">2018秋冬新款男士休闲时尚军绿飞行夹克秋冬新款男</div>
<div class="van-card__desc van-ellipsis">描述信息</div>

View File

@ -14,12 +14,6 @@ export default sfc({
arrowDirection: String
},
computed: {
arrowIcon() {
return this.arrowDirection ? `arrow-${this.arrowDirection}` : 'arrow';
}
},
methods: {
onClick() {
this.$emit('click');
@ -49,8 +43,9 @@ export default sfc({
this.icon && <Icon class={bem('left-icon')} name={this.icon} />
);
const arrowIcon = this.arrowDirection ? `arrow-${this.arrowDirection}` : 'arrow';
const RightIcon = slots['right-icon'] || (
this.isLink && <Icon class={bem('right-icon')} name={this.arrowIcon} />
this.isLink && <Icon class={bem('right-icon')} name={arrowIcon} />
);
return (

View File

@ -5,123 +5,81 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-cell-group van-hairline--top-bottom">
<div class="van-cell">
<div class="van-cell__title"><span>单元格</span>
</div>
<div class="van-cell__title"><span>单元格</span></div>
<div class="van-cell__value"><span>内容</span></div>
</div>
<div class="van-cell">
<div class="van-cell__title"><span>单元格</span>
<div class="van-cell__label">描述信息</div>
</div>
<div class="van-cell__value"><span>内容</span></div>
</div>
</div>
</div>
<div>
<div class="van-cell van-cell--large">
<div class="van-cell__title"><span>单元格</span>
</div>
<div class="van-cell__title"><span>单元格</span></div>
<div class="van-cell__value"><span>内容</span></div>
</div>
<div class="van-cell van-cell--large">
<div class="van-cell__title"><span>单元格</span>
<div class="van-cell__label">描述信息</div>
</div>
<div class="van-cell__value"><span>内容</span></div>
</div>
</div>
<div>
<div class="van-cell"><i class="van-icon van-icon-location-o van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__title"><span>单元格</span>
</div>
<div class="van-cell__title"><span>单元格</span></div>
<div class="van-cell__value"><span>内容</span></div>
</div>
</div>
<div>
<div class="van-cell">
<div class="van-cell__value van-cell__value--alone"><span>内容</span></div>
</div>
</div>
<div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>单元格</span>
</div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>单元格</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>单元格</span>
</div>
<div class="van-cell__value"><span>内容</span></div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>单元格</span></div>
<div class="van-cell__value"><span>内容</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>单元格</span>
</div>
<div class="van-cell__value"><span>内容</span></div>
<i class="van-icon van-icon-arrow-down van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>单元格</span></div>
<div class="van-cell__value"><span>内容</span></div><i class="van-icon van-icon-arrow-down van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
</div>
<div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>单元格</span>
</div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>单元格</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>单元格</span>
</div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>单元格</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
</div>
<div>
<div class="van-cell van-cell--clickable"><i class="van-icon van-icon-shop-o van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__title"><span class="custom-text">单元格</span> <span class="van-tag" style="background-color:#f44;">标签</span>
</div>
<div class="van-cell__value"><span>内容</span></div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span class="custom-text">单元格</span> <span class="van-tag" style="background-color:#f44;">标签</span></div>
<div class="van-cell__value"><span>内容</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-cell van-cell--clickable"><i class="van-icon van-icon-location-o van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__title"><span>单元格</span>
</div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>单元格</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-cell">
<div class="van-cell__title"><span>单元格</span>
</div>
<i class="custom-icon van-icon van-icon-search" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>单元格</span></div><i class="custom-icon van-icon van-icon-search" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
</div>

View File

@ -0,0 +1,21 @@
import { use } from '../utils';
const [sfc, bem] = use('checkbox-group');
export default sfc({
props: {
max: Number,
value: Array,
disabled: Boolean
},
watch: {
value(val) {
this.$emit('change', val);
}
},
render(h) {
return <div class={bem()}>{this.$slots.default}</div>;
}
});

View File

@ -1,25 +0,0 @@
<template>
<div :class="b()">
<slot />
</div>
</template>
<script>
import create from '../utils/create';
export default create({
name: 'checkbox-group',
props: {
max: Number,
value: Array,
disabled: Boolean
},
watch: {
value(val) {
this.$emit('change', val);
}
}
});
</script>

View File

@ -1,36 +1,10 @@
<template>
<div :class="b()">
<div
:class="b('icon', [shape, { disabled: isDisabled, checked }])"
@click="toggle"
>
<slot
name="icon"
:checked="checked"
>
<icon
name="success"
:style="iconStyle"
/>
</slot>
</div>
<span
v-if="$slots.default"
:class="b('label', [labelPosition, { disabled: isDisabled }])"
@click="toggle('label')"
>
<slot />
</span>
</div>
</template>
<script>
import create from '../utils/create';
import { use } from '../utils';
import Icon from '../icon';
import findParent from '../mixins/find-parent';
export default create({
name: 'checkbox',
const [sfc, bem] = use('checkbox');
export default sfc({
mixins: [findParent],
props: {
@ -49,9 +23,7 @@ export default create({
computed: {
checked: {
get() {
return this.parent
? this.parent.value.indexOf(this.name) !== -1
: this.value;
return this.parent ? this.parent.value.indexOf(this.name) !== -1 : this.value;
},
set(val) {
@ -119,6 +91,36 @@ export default create({
}
}
}
},
render(h) {
const CheckIcon = this.$scopedSlots.icon ? (
this.$scopedSlots.icon({ checked: this.checked })
) : (
<Icon name="success" style={this.iconStyle} />
);
const Label = this.$slots.default && (
<span
class={bem('label', [this.labelPosition, { disabled: this.isDisabled }])}
onClick={() => {
this.toggle('label');
}}
>
{this.$slots.default}
</span>
);
return (
<div class={bem()}>
<div
class={bem('icon', [this.shape, { disabled: this.isDisabled, checked: this.checked }])}
onClick={this.toggle}
>
{CheckIcon}
</div>
{Label}
</div>
);
}
});
</script>

View File

@ -5,22 +5,19 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">复选框</span>
<!----></i></div><span class="van-checkbox__label">复选框</span>
</div>
</div>
<div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--disabled"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label van-checkbox__label--disabled">
<!----></i></div><span class="van-checkbox__label van-checkbox__label--disabled">
复选框
</span>
</div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--disabled van-checkbox__icon--checked"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label van-checkbox__label--disabled">
<!----></i></div><span class="van-checkbox__label van-checkbox__label--disabled">
复选框
</span>
</div>
@ -28,15 +25,14 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;border-color:#07c160;background-color:#07c160;">
<!---->
<!----></i></div> <span class="van-checkbox__label">
<!----></i></div><span class="van-checkbox__label">
自定义颜色
</span>
</div>
</div>
<div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><img src="https://img.yzcdn.cn/public_files/2017/10/13/793c77793db8641c4c325b7f25bf130d.png"></div> <span class="van-checkbox__label">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><img src="https://img.yzcdn.cn/public_files/2017/10/13/793c77793db8641c4c325b7f25bf130d.png"></div><span class="van-checkbox__label">
自定义图标
</span>
</div>
@ -45,22 +41,19 @@ exports[`renders demo correctly 1`] = `
<div class="van-checkbox-group">
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">
<!----></i></div><span class="van-checkbox__label">
复选框 a
</span>
</div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">
<!----></i></div><span class="van-checkbox__label">
复选框 b
</span>
</div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">
<!----></i></div><span class="van-checkbox__label">
复选框 c
</span>
</div>
@ -70,22 +63,19 @@ exports[`renders demo correctly 1`] = `
<div class="van-checkbox-group">
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">
<!----></i></div><span class="van-checkbox__label">
复选框 a
</span>
</div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">
<!----></i></div><span class="van-checkbox__label">
复选框 b
</span>
</div>
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">
<!----></i></div><span class="van-checkbox__label">
复选框 c
</span>
</div>
@ -95,43 +85,31 @@ exports[`renders demo correctly 1`] = `
<div class="van-checkbox-group">
<div class="van-cell-group van-hairline--top-bottom">
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>复选框a</span>
</div>
<div class="van-cell__title"><span>复选框a</span></div>
<div class="van-cell__value">
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div>
<!---->
</div>
</div>
</div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>复选框b</span>
</div>
<div class="van-cell__title"><span>复选框b</span></div>
<div class="van-cell__value">
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div>
<!---->
</div>
</div>
</div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>复选框c</span>
</div>
<div class="van-cell__title"><span>复选框c</span></div>
<div class="van-cell__value">
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div>
<!---->
</div>
</div>
</div>
</div>
</div>

View File

@ -1,41 +1,16 @@
<template>
<div
:class="b()"
:style="style"
>
<svg viewBox="0 0 1060 1060">
<path
:class="b('hover')"
:style="hoverStyle"
:d="path"
/>
<path
:class="b('layer')"
:style="layerStyle"
:d="path"
/>
</svg>
<slot>
<div
v-text="text"
:class="b('text')"
/>
</slot>
</div>
</template>
<script>
import create from '../utils/create';
import { use } from '../utils';
import { raf, cancel } from '../utils/raf';
import { BLUE, WHITE } from '../utils/color';
const [sfc, bem] = use('circle');
const PERIMETER = 3140;
const PATH = 'M 530 530 m -500, 0 a 500, 500 0 1, 1 1000, 0 a 500, 500 0 1, 1 -1000, 0';
function format(rate) {
return Math.min(Math.max(rate, 0), 100);
}
export default create({
name: 'circle',
export default sfc({
props: {
text: String,
value: Number,
@ -70,11 +45,6 @@ export default create({
}
},
beforeCreate() {
this.perimeter = 3140;
this.path = 'M 530 530 m -500, 0 a 500, 500 0 1, 1 1000, 0 a 500, 500 0 1, 1 -1000, 0';
},
computed: {
style() {
return {
@ -84,8 +54,8 @@ export default create({
},
layerStyle() {
let offset = this.perimeter * (100 - this.value) / 100;
offset = this.clockwise ? offset : this.perimeter * 2 - offset;
let offset = (PERIMETER * (100 - this.value)) / 100;
offset = this.clockwise ? offset : PERIMETER * 2 - offset;
return {
stroke: `${this.color}`,
strokeDashoffset: `${offset}px`,
@ -109,7 +79,7 @@ export default create({
this.startRate = this.value;
this.endRate = format(this.rate);
this.increase = this.endRate > this.startRate;
this.duration = Math.abs((this.startRate - this.endRate) * 1000 / this.speed);
this.duration = Math.abs(((this.startRate - this.endRate) * 1000) / this.speed);
if (this.speed) {
cancel(this.rafId);
this.rafId = raf(this.animate);
@ -131,6 +101,17 @@ export default create({
this.rafId = raf(this.animate);
}
}
},
render(h) {
return (
<div class={bem()} style={this.style}>
<svg viewBox="0 0 1060 1060">
<path class={bem('hover')} style={this.hoverStyle} d={PATH} />
<path class={bem('layer')} style={this.layerStyle} d={PATH} />
</svg>
{this.$slots.default || (this.text && <div class={bem('text')}>{this.text}</div>)}
</div>
);
}
});
</script>

View File

@ -1,19 +1,8 @@
<template>
<component
:is="tag"
:class="b({ [span]: span, [`offset-${offset}`]: offset })"
:style="style"
>
<slot />
</component>
</template>
import { use } from '../utils';
<script>
import create from '../utils/create';
export default create({
name: 'col',
const [sfc, bem] = use('col');
export default sfc({
props: {
span: [Number, String],
offset: [Number, String],
@ -32,6 +21,14 @@ export default create({
const padding = `${this.gutter / 2}px`;
return this.gutter ? { paddingLeft: padding, paddingRight: padding } : {};
}
},
render(h) {
const { span, offset } = this;
return (
<this.tag class={bem({ [span]: span, [`offset-${offset}`]: offset })} style={this.style}>
{this.$slots.default}
</this.tag>
);
}
});
</script>

View File

@ -1,50 +1,13 @@
<template>
<div :class="[b(), { 'van-hairline--top': index }]">
<cell
v-bind="$props"
:class="b('title', { disabled, expanded })"
@click="onClick"
>
<slot
name="title"
slot="title"
/>
<slot
name="icon"
slot="icon"
/>
<slot name="value" />
<slot
name="right-icon"
slot="right-icon"
/>
</cell>
<div
v-if="inited"
v-show="show"
ref="wrapper"
:class="b('wrapper')"
@transitionend="onTransitionEnd"
>
<div
ref="content"
:class="b('content')"
>
<slot />
</div>
</div>
</div>
</template>
<script>
import { use, isDef } from '../utils';
import { raf } from '../utils/raf';
import create from '../utils/create';
import Cell from '../cell';
import CellMixin from '../mixins/cell';
import FindParent from '../mixins/find-parent';
export default create({
name: 'collapse-item',
const [sfc, bem] = use('collapse-item');
const CELL_SLOTS = ['title', 'icon', 'right-icon'];
export default sfc({
mixins: [CellMixin, FindParent],
props: {
@ -73,7 +36,7 @@ export default create({
},
currentName() {
return this.isDef(this.name) ? this.name : this.index;
return isDef(this.name) ? this.name : this.index;
},
expanded() {
@ -144,6 +107,38 @@ export default create({
this.$refs.wrapper.style.height = null;
}
}
},
render(h) {
const Title = (
<Cell
class={bem('title', { disabled: this.disabled, expanded: this.expanded })}
onClick={this.onClick}
{...{ props: this.$props }}
>
{this.$slots.value}
{CELL_SLOTS.map(slot => h('template', { slot }, this.$slots[slot]))}
</Cell>
);
const Content = this.inited && (
<div
v-show={this.show}
ref="wrapper"
class={bem('wrapper')}
onTransitionend={this.onTransitionEnd}
>
<div ref="content" class={bem('content')}>
{this.$slots.default}
</div>
</div>
);
return (
<div class={[bem(), { 'van-hairline--top': this.index }]}>
{Title}
{Content}
</div>
);
}
});
</script>

View File

@ -1,18 +1,8 @@
<template>
<div
:class="b()"
class="van-hairline--top-bottom"
>
<slot />
</div>
</template>
import { use } from '../utils';
<script>
import create from '../utils/create';
export default create({
name: 'collapse',
const [sfc, bem] = use('collapse');
export default sfc({
props: {
accordion: Boolean,
value: [String, Number, Array]
@ -34,6 +24,9 @@ export default create({
this.$emit('change', name);
this.$emit('input', name);
}
},
render(h) {
return <div class={[bem(), 'van-hairline--top-bottom']}>{this.$slots.default}</div>;
}
});
</script>

View File

@ -3,14 +3,10 @@
exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-hairline--top-bottom van-collapse">
<div class="van-collapse van-hairline--top-bottom">
<div class="van-collapse-item">
<div class="van-cell van-cell--clickable van-collapse-item__title van-collapse-item__title--expanded">
<div class="van-cell__title"><span>有赞微商城</span>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>有赞微商城</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-collapse-item__wrapper">
@ -19,37 +15,23 @@ exports[`renders demo correctly 1`] = `
</div>
<div class="van-collapse-item van-hairline--top">
<div class="van-cell van-cell--clickable van-collapse-item__title">
<div class="van-cell__title"><span>有赞零售</span>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>有赞零售</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<!---->
</div>
<div class="van-collapse-item van-hairline--top">
<div disabled="disabled" class="van-cell van-cell--clickable van-collapse-item__title van-collapse-item__title--disabled">
<div class="van-cell__title"><span>有赞美业</span>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell van-cell--clickable van-collapse-item__title van-collapse-item__title--disabled">
<div class="van-cell__title"><span>有赞美业</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<!---->
</div>
</div>
</div>
<div>
<div class="van-hairline--top-bottom van-collapse">
<div class="van-collapse van-hairline--top-bottom">
<div class="van-collapse-item">
<div class="van-cell van-cell--clickable van-collapse-item__title van-collapse-item__title--expanded">
<div class="van-cell__title"><span>有赞微商城</span>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>有赞微商城</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-collapse-item__wrapper">
@ -58,56 +40,36 @@ exports[`renders demo correctly 1`] = `
</div>
<div class="van-collapse-item van-hairline--top">
<div class="van-cell van-cell--clickable van-collapse-item__title">
<div class="van-cell__title"><span>有赞零售</span>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>有赞零售</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<!---->
</div>
<div class="van-collapse-item van-hairline--top">
<div class="van-cell van-cell--clickable van-collapse-item__title">
<div class="van-cell__title"><span>有赞美业</span>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>有赞美业</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<!---->
</div>
</div>
</div>
<div>
<div class="van-hairline--top-bottom van-collapse">
<div class="van-collapse van-hairline--top-bottom">
<div class="van-collapse-item">
<div class="van-cell van-cell--clickable van-collapse-item__title">
<div class="van-cell__title">
<div>有赞微商城<i class="van-icon van-icon-question-o" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
</div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<!---->
</div>
<div class="van-collapse-item van-hairline--top">
<div class="van-cell van-cell--clickable van-collapse-item__title"><i class="van-icon van-icon-shop-o van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__title"><span>有赞零售</span>
</div>
<div class="van-cell__value"> </div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>有赞零售</span></div>
<div class="van-cell__value"><span>内容</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<!---->
</div>
</div>
</div>

View File

@ -121,4 +121,3 @@ export default {
| icon | 自定义`icon` |
| title | 自定义`title` |
| right-icon | 自定义右侧按钮,默认是`arrow` |

View File

@ -0,0 +1,46 @@
import { use } from '../utils';
import Cell from '../cell';
const [sfc, bem, t] = use('contact-card');
export default sfc({
props: {
tel: String,
name: String,
addText: String,
editable: {
type: Boolean,
default: true
},
type: {
type: String,
default: 'add'
}
},
methods: {
onClick(event) {
if (this.editable) {
this.$emit('click', event);
}
}
},
render(h) {
const { type } = this;
return (
<Cell
center
border={false}
class={bem([type])}
isLink={this.editable}
icon={type === 'edit' ? 'contact' : 'add-square'}
onClick={this.onClick}
>
{type === 'add'
? this.addText || t('addText')
: [<div>{`${t('name')}${this.name}`}</div>, <div>{`${t('tel')}${this.tel}`}</div>]}
</Cell>
);
}
});

View File

@ -1,46 +0,0 @@
<template>
<cell
center
:border="false"
:class="b([type])"
:is-link="editable"
:icon="type === 'edit' ? 'contact' : 'add-square'"
@click="onClick"
>
<template v-if="type === 'add'">{{ addText || $t('addText') }}</template>
<template v-else>
<div>{{ $t('name') }}{{ name }}</div>
<div>{{ $t('tel') }}{{ tel }}</div>
</template>
</cell>
</template>
<script>
import create from '../utils/create';
export default create({
name: 'contact-card',
props: {
tel: String,
name: String,
addText: String,
editable: {
type: Boolean,
default: true
},
type: {
type: String,
default: 'add'
}
},
methods: {
onClick(event) {
if (this.editable) {
this.$emit('click', event);
}
}
}
});
</script>

View File

@ -4,77 +4,47 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-cell van-cell--center van-cell--borderless van-cell--clickable van-contact-card van-contact-card--add"><i class="van-icon van-icon-add-square van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__value van-cell__value--alone">添加联系人</div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__value van-cell__value--alone">添加联系人</div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div name="popup-slide-bottom" class="van-popup van-popup--bottom" style="display:none;">
<div class="van-contact-list">
<div class="van-radio-group">
<div class="van-cell-group van-hairline--top-bottom">
<div class="van-cell van-cell--clickable">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="0" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label"><div class="van-contact-list__name">张三13000000000</div></span></div>
</div>
<i class="van-icon van-icon-edit van-contact-list__edit" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
</div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__value van-cell__value--alone">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="0" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label"><div class="van-contact-list__name">张三13000000000</div></span></div>
</div><i class="van-icon van-icon-edit van-contact-list__edit" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
</div> <button class="van-button van-button--danger van-button--large van-button--square van-contact-list__add"><span class="van-button__text">新建联系人</span></button>
</div><button class="van-button van-button--danger van-button--large van-button--square van-contact-list__add"><span class="van-button__text">新建联系人</span></button>
</div>
</div>
<div name="popup-slide-bottom" class="van-popup van-popup--bottom" style="display:none;">
<div class="van-contact-edit">
<div class="van-cell-group van-hairline--top-bottom">
<div maxlength="30" placeholder="请填写姓名" class="van-cell van-field">
<div class="van-cell__title"><span>张三</span>
</div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" maxlength="30" placeholder="请填写姓名" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
</div>
</div>
<div placeholder="请填写电话" class="van-cell van-field">
<div class="van-cell__title"><span>电话</span>
</div>
<div class="van-cell__value">
<div class="van-field__body"><input type="tel" placeholder="请填写电话" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
</div>
<div maxlength="30" placeholder="请填写姓名" class="van-cell van-field">
<div class="van-cell__title"><span>张三</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input maxlength="30" placeholder="请填写姓名" value="" class="van-field__control"></div>
</div>
</div>
<div class="van-contact-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button>
<!---->
<div placeholder="请填写电话" class="van-cell van-field">
<div class="van-cell__title"><span>电话</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input placeholder="请填写电话" value="" class="van-field__control"></div>
</div>
</div>
<div class="van-contact-edit__buttons"><button class="van-button van-button--danger van-button--normal van-button--block"><span class="van-button__text">保存</span></button></div>
</div>
</div>
</div>
<div>
<div class="van-cell van-cell--center van-cell--borderless van-contact-card van-contact-card--edit"><i class="van-icon van-icon-contact van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__value van-cell__value--alone">
<div>张三:张三</div>
<div>电话13000000000</div>
</div>
</div>
</div>
</div>

View File

@ -2,8 +2,6 @@
exports[`ContactList render 1`] = `
<div class="van-contact-list">
<div class="van-radio-group">
<div class="van-cell-group van-hairline--top-bottom"></div>
</div> <button class="van-button van-button--danger van-button--large van-button--square van-contact-list__add"><span class="van-button__text">新建联系人</span></button>
<div class="van-radio-group"></div><button class="van-button van-button--danger van-button--large van-button--square van-contact-list__add"><span class="van-button__text">新建联系人</span></button>
</div>
`;

View File

@ -95,6 +95,8 @@ describe('ContactEdit', () => {
const deleteButton = wrapper.findAll('.van-button').at(1);
deleteButton.trigger('click');
await later();
document.querySelector('.van-dialog__confirm').click();
await later();

View File

@ -0,0 +1,130 @@
import { use } from '../utils';
import Button from '../button';
import Field from '../field';
import Toast from '../toast';
import Dialog from '../dialog';
import validateMobile from '../utils/validate/mobile';
const [sfc, bem, t] = use('contact-edit');
const defaultContact = {
tel: '',
name: ''
};
export default sfc({
props: {
isEdit: Boolean,
isSaving: Boolean,
isDeleting: Boolean,
contactInfo: {
type: Object,
default: () => ({ ...defaultContact })
},
telValidator: {
type: Function,
default: validateMobile
}
},
data() {
return {
data: {
...defaultContact,
...this.contactInfo
},
errorInfo: {
name: false,
tel: false
}
};
},
watch: {
contactInfo(val) {
this.data = {
...defaultContact,
...val
};
}
},
methods: {
onFocus(key) {
this.errorInfo[key] = false;
},
getErrorMessageByKey(key) {
const value = this.data[key].trim();
switch (key) {
case 'name':
return value ? '' : t('nameEmpty');
case 'tel':
return this.telValidator(value) ? '' : t('telInvalid');
}
},
onSave() {
const isValid = ['name', 'tel'].every(item => {
const msg = this.getErrorMessageByKey(item);
if (msg) {
this.errorInfo[item] = true;
Toast(msg);
}
return !msg;
});
if (isValid && !this.isSaving) {
this.$emit('save', this.data);
}
},
onDelete() {
Dialog.confirm({
message: t('confirmDelete')
}).then(() => {
this.$emit('delete', this.data);
});
}
},
render(h) {
const { data, errorInfo } = this;
const onFocus = name => () => this.onFocus(name);
return (
<div class={bem()}>
<Field
v-model={data.name}
clearable
maxlength="30"
label={t('name')}
placeholder={t('nameEmpty')}
error={errorInfo.name}
onFocus={onFocus('name')}
/>
<Field
v-model={data.tel}
clearable
type="tel"
label={t('tel')}
placeholder={t('telEmpty')}
error={errorInfo.tel}
onFocus={onFocus('tel')}
/>
<div class={bem('buttons')}>
<Button
block
type="danger"
text={t('save')}
loading={this.isSaving}
onClick={this.onSave}
/>
{this.isEdit && (
<Button block text={t('delete')} loading={this.isDeleting} onClick={this.onDelete} />
)}
</div>
</div>
);
}
});

View File

@ -1,134 +0,0 @@
<template>
<div :class="b()">
<cell-group>
<field
v-model="data.name"
maxlength="30"
:label="$t('name')"
:placeholder="$t('nameEmpty')"
:error="errorInfo.name"
@focus="onFocus('name')"
/>
<field
v-model="data.tel"
type="tel"
:label="$t('tel')"
:placeholder="$t('telEmpty')"
:error="errorInfo.tel"
@focus="onFocus('tel')"
/>
</cell-group>
<div :class="b('buttons')">
<van-button
block
type="danger"
:text="$t('save')"
:loading="isSaving"
@click="onSave"
/>
<van-button
v-if="isEdit"
block
:text="$t('delete')"
:loading="isDeleting"
@click="onDelete"
/>
</div>
</div>
</template>
<script>
import Field from '../field';
import VanButton from '../button';
import Toast from '../toast';
import Dialog from '../dialog';
import validateMobile from '../utils/validate/mobile';
import create from '../utils/create';
const defaultContact = {
id: '',
tel: '',
name: ''
};
export default create({
name: 'contact-edit',
components: {
Field,
VanButton
},
props: {
isEdit: Boolean,
isSaving: Boolean,
isDeleting: Boolean,
contactInfo: {
type: Object,
default: () => ({ ...defaultContact })
},
telValidator: {
type: Function,
default: validateMobile
}
},
data() {
return {
data: {
...this.defaultContact,
...this.contactInfo
},
errorInfo: {
name: false,
tel: false
}
};
},
watch: {
contactInfo(val) {
this.data = val;
}
},
methods: {
onFocus(key) {
this.errorInfo[key] = false;
},
getErrorMessageByKey(key) {
const value = this.data[key].trim();
switch (key) {
case 'name':
return value ? '' : this.$t('nameEmpty');
case 'tel':
return this.telValidator(value) ? '' : this.$t('telInvalid');
}
},
onSave() {
const isValid = ['name', 'tel'].every(item => {
const msg = this.getErrorMessageByKey(item);
if (msg) {
this.errorInfo[item] = true;
Toast(msg);
}
return !msg;
});
if (isValid && !this.isSaving) {
this.$emit('save', this.data);
}
},
onDelete() {
Dialog.confirm({
message: this.$t('confirmDelete')
}).then(() => {
this.$emit('delete', this.data);
});
}
}
});
</script>

View File

@ -0,0 +1,60 @@
import { use } from '../utils';
import Icon from '../icon';
import Cell from '../cell';
import Button from '../button';
import Radio from '../radio';
import RadioGroup from '../radio-group';
const [sfc, bem, t] = use('contact-list');
export default sfc({
props: {
value: null,
list: Array,
addText: String
},
render(h) {
return (
<div class={bem()}>
<RadioGroup
value={this.value}
onInput={event => {
this.$emit('input', event);
}}
>
{this.list.map((item, index) => (
<Cell key={item.id} isLink>
<Radio
name={item.id}
onClick={() => {
this.$emit('select', item, index);
}}
>
<div class={bem('name')}>{`${item.name}${item.tel}`}</div>
</Radio>
<Icon
slot="right-icon"
name="edit"
class={bem('edit')}
onClick={() => {
this.$emit('edit', item, index);
}}
/>
</Cell>
))}
</RadioGroup>
<Button
square
size="large"
type="danger"
class={bem('add')}
text={this.addText || t('addText')}
onClick={() => {
this.$emit('add');
}}
/>
</div>
);
}
});

View File

@ -1,60 +0,0 @@
<template>
<div :class="b()">
<radio-group
:value="value"
@input="$emit('input', $event)"
>
<cell-group>
<cell
v-for="(item, index) in list"
:key="item.id"
is-link
>
<radio
:name="item.id"
@click="$emit('select', item, index)"
>
<div :class="b('name')">{{ item.name }}{{ item.tel }}</div>
</radio>
<icon
slot="right-icon"
name="edit"
:class="b('edit')"
@click="$emit('edit', item, index)"
/>
</cell>
</cell-group>
</radio-group>
<van-button
square
size="large"
type="danger"
:class="b('add')"
:text="addText || $t('addText')"
@click="$emit('add')"
/>
</div>
</template>
<script>
import Radio from '../radio';
import VanButton from '../button';
import RadioGroup from '../radio-group';
import create from '../utils/create';
export default create({
name: 'contact-list',
components: {
Radio,
VanButton,
RadioGroup
},
props: {
value: null,
list: Array,
addText: String
}
});
</script>

View File

@ -67,7 +67,7 @@ export default {
id: 1,
discount: 0,
denominations: 150,
originCondition: 0,
condition: '无使用门槛\n最多优惠12元',
reason: '',
value: 150,
name: this.$t('coupon.name'),

View File

@ -108,7 +108,7 @@ export default {
| name | Name | `String` |
| discount | Discount | `Number` |
| denominations | Denominations | `Number` |
| originCondition | Condition | `Number` |
| condition | Condition | `String` |
| startAt | Start time (Timestmap, unit second) | `Number` |
| endAt | End time (Timestmap, unit second) | `Number` |
| description | Description | `String` |

View File

@ -4,11 +4,8 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-cell van-cell--clickable van-coupon-cell">
<div class="van-cell__title"><span>优惠券</span>
</div>
<div class="van-cell__value"><span>2张可用</span></div>
<i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-cell__title"><span>优惠券</span></div>
<div class="van-cell__value"><span>2张可用</span></div><i class="van-icon van-icon-arrow van-cell__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<!---->

View File

@ -2,22 +2,16 @@
exports[`coupon cell 1`] = `
<div class="van-cell van-cell--clickable van-coupon-cell">
<div class="van-cell__title"><span>优惠券</span>
</div>
<div class="van-cell__value"><span>使用优惠</span></div>
<i class="van-icon van-icon-arrow van-cell__right-icon">
<!---->
<div class="van-cell__title"><span>优惠券</span></div>
<div class="van-cell__value"><span>使用优惠</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
<!----></i>
</div>
`;
exports[`coupon cell 2`] = `
<div class="van-cell van-cell--clickable van-coupon-cell">
<div class="van-cell__title"><span>优惠券</span>
</div>
<div class="van-cell__value van-coupon-cell--selected"><span>-¥1.00</span></div>
<i class="van-icon van-icon-arrow van-cell__right-icon">
<!---->
<div class="van-cell__title"><span>优惠券</span></div>
<div class="van-cell__value van-coupon-cell--selected"><span>-¥1.00</span></div><i class="van-icon van-icon-arrow van-cell__right-icon">
<!----></i>
</div>
`;
@ -25,16 +19,11 @@ exports[`coupon cell 2`] = `
exports[`render coupon list 1`] = `
<div class="van-coupon-list">
<div class="van-cell van-cell--borderless van-field van-coupon-list__field">
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="text" placeholder="请输入优惠码" maxlength="20" class="van-field__control">
<!---->
<!---->
<div class="van-field__body"><input placeholder="请输入优惠码" maxlength="20" class="van-field__control">
<div class="van-field__button"><button disabled="disabled" class="van-button van-button--danger van-button--small van-button--disabled van-coupon-list__exchange"><span class="van-button__text">兑换</span></button></div>
</div>
<!---->
</div>
</div>
<div class="van-tabs van-tabs--line van-coupon-list__tab">
<div class="van-tabs__wrap van-hairline--top-bottom">
@ -70,9 +59,7 @@ exports[`render coupon list 1`] = `
<p>有效期2017.03.10 - 2017.12.30</p>
<div class="van-checkbox van-coupon__corner">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><i class="van-icon van-icon-success">
<!---->
<!----></i></div>
<!---->
</div>
</div>
</div>
@ -136,8 +123,7 @@ exports[`render coupon list 1`] = `
<!---->
</div>
</div>
</div>
<button class="van-button van-button--default van-button--large van-coupon-list__close"><span class="van-button__text">不使用优惠</span></button>
</div><button class="van-button van-button--default van-button--large van-coupon-list__close"><span class="van-button__text">不使用优惠</span></button>
</div>
`;

View File

@ -36,7 +36,7 @@ const coupon = {
available: 1,
discount: 0,
denominations: 150,
originCondition: 0,
condition: '无使用门槛\n最多优惠12元',
reason: '',
value: 150,
name: '优惠券名称',
@ -113,7 +113,7 @@ export default {
| name | 优惠券名称 | `String` |
| discount | 折扣0为满减券88=>8.8折 | `Number` |
| denominations | 面值0为折扣券单位分 | `Number` |
| originCondition | 满减条件0为无门槛满XX元可用单位分 | `Number` |
| condition | 满减条件 | `String` |
| startAt | 卡有效开始时间 (时间戳, 单位秒) | `Number` |
| endAt | 卡失效日期 (时间戳, 单位秒) | `Number` |
| description | 描述信息,优惠券可用时展示 | `String` |

View File

@ -60,7 +60,7 @@ export default sfc({
<div class={bem('content')}>
<div class={bem('head')}>
<h2 domPropsInnerHTML={this.faceAmount} />
<p>{this.conditionMessage}</p>
<p>{this.coupon.condition || this.conditionMessage}</p>
</div>
<div class={bem('body')}>
<h2>{coupon.name}</h2>

View File

@ -39,7 +39,8 @@
}
&__head {
min-width: 90px;
position: relative;
min-width: 95px;
h2 {
color: @red;
@ -49,6 +50,10 @@
font-size: 50%;
}
}
p {
white-space: pre-wrap;
}
}
&__body {

View File

@ -1,66 +1,14 @@
<template>
<picker
ref="picker"
:title="title"
:columns="columns"
:item-height="itemHeight"
:show-toolbar="showToolbar"
:visible-item-count="visibleItemCount"
:confirm-button-text="confirmButtonText"
:cancel-button-text="cancelButtonText"
@change="onChange"
@confirm="onConfirm"
@cancel="$emit('cancel')"
/>
</template>
<script>
import { use, range } from '../utils';
import Picker from '../picker';
import create from '../utils/create';
import { range } from '../utils';
import PickerMixin from '../mixins/picker';
import { times, padZero, isValidDate, getTrueValue, getMonthEndDay } from './utils';
const [sfc, bem] = use('datetime-picker');
const currentYear = new Date().getFullYear();
function isValidDate(date) {
return Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date.getTime());
}
function padZero(val) {
return `00${val}`.slice(-2);
}
function times(n, iteratee) {
let index = -1;
const result = Array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
function getTrueValue(formattedValue) {
if (!formattedValue) return;
while (isNaN(parseInt(formattedValue, 10))) {
formattedValue = formattedValue.slice(1);
}
return parseInt(formattedValue, 10);
}
function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}
export default create({
name: 'datetime-picker',
export default sfc({
mixins: [PickerMixin],
components: {
Picker
},
props: {
value: null,
minHour: Number,
@ -110,7 +58,10 @@ export default create({
watch: {
value(val) {
val = this.correctValue(val);
const isEqual = this.type === 'time' ? val === this.innerValue : val.valueOf() === this.innerValue.valueOf();
const isEqual =
this.type === 'time'
? val === this.innerValue
: val.valueOf() === this.innerValue.valueOf();
if (!isEqual) {
this.innerValue = val;
@ -145,8 +96,14 @@ export default create({
];
}
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary('max', this.innerValue);
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary('min', this.innerValue);
const { maxYear, maxDate, maxMonth, maxHour, maxMinute } = this.getBoundary(
'max',
this.innerValue
);
const { minYear, minDate, minMonth, minHour, minMinute } = this.getBoundary(
'min',
this.innerValue
);
const result = [
{
@ -306,10 +263,7 @@ export default create({
if (this.type === 'time') {
const pair = value.split(':');
values = [
formatter('hour', pair[0]),
formatter('minute', pair[1])
];
values = [formatter('hour', pair[0]), formatter('minute', pair[1])];
} else {
values = [
formatter('year', `${value.getFullYear()}`),
@ -331,6 +285,26 @@ export default create({
this.$refs.picker.setValues(values);
});
}
},
render(h) {
const props = {};
Object.keys(PickerMixin.props).forEach(key => {
props[key] = this[key];
});
return (
<Picker
class={bem()}
ref="picker"
columns={this.columns}
onChange={this.onChange}
onConfirm={this.onConfirm}
onCancel={() => {
this.$emit('cancel');
}}
{...{ props }}
/>
);
}
});
</script>

View File

@ -0,0 +1,29 @@
export function isValidDate(date) {
return Object.prototype.toString.call(date) === '[object Date]' && !isNaN(date.getTime());
}
export function padZero(val) {
return `00${val}`.slice(-2);
}
export function times(n, iteratee) {
let index = -1;
const result = Array(n);
while (++index < n) {
result[index] = iteratee(index);
}
return result;
}
export function getTrueValue(formattedValue) {
if (!formattedValue) return;
while (isNaN(parseInt(formattedValue, 10))) {
formattedValue = formattedValue.slice(1);
}
return parseInt(formattedValue, 10);
}
export function getMonthEndDay(year, month) {
return 32 - new Date(year, month - 1, 32).getDate();
}

124
packages/dialog/Dialog.js Normal file
View File

@ -0,0 +1,124 @@
import { use } from '../utils';
import Button from '../button';
import Popup from '../mixins/popup';
const [sfc, bem, t] = use('dialog');
export default sfc({
mixins: [Popup],
props: {
title: String,
message: String,
callback: Function,
className: [String, Object, Array],
beforeClose: Function,
messageAlign: String,
confirmButtonText: String,
cancelButtonText: String,
showCancelButton: Boolean,
showConfirmButton: {
type: Boolean,
default: true
},
overlay: {
type: Boolean,
default: true
},
closeOnClickOverlay: {
type: Boolean,
default: false
}
},
data() {
return {
loading: {
confirm: false,
cancel: false
}
};
},
methods: {
handleAction(action) {
if (this.beforeClose) {
this.loading[action] = true;
this.beforeClose(action, state => {
if (state !== false) {
this.onClose(action);
}
this.loading[action] = false;
});
} else {
this.onClose(action);
}
},
onClose(action) {
this.$emit('input', false);
this.$emit(action);
this.callback && this.callback(action);
}
},
render(h) {
if (!this.shouldRender) {
return;
}
const { title, message, messageAlign } = this;
const children = this.$slots.default;
const Title = title && (
<div class={bem('header', { isolated: !message && !children })}>{title}</div>
);
const Content = (children || message) && (
<div class={bem('content')}>
{children || (
<div
domPropsInnerHTML={message}
class={bem('message', { 'has-title': title, [messageAlign]: messageAlign })}
/>
)}
</div>
);
const hasButtons = this.showCancelButton && this.showConfirmButton;
const ButtonGroup = (
<div class={['van-hairline--top', bem('footer', { buttons: hasButtons })]}>
<Button
v-show={this.showCancelButton}
size="large"
class={bem('cancel')}
loading={this.loading.cancel}
text={this.cancelButtonText || t('cancel')}
onClick={() => {
this.handleAction('cancel');
}}
/>
<Button
v-show={this.showConfirmButton}
size="large"
class={[bem('confirm'), { 'van-hairline--left': hasButtons }]}
loading={this.loading.confirm}
text={this.confirmButtonText || t('confirm')}
onClick={() => {
this.handleAction('confirm');
}}
/>
</div>
);
return (
<transition name="van-dialog-bounce">
<div v-show={this.value} class={[bem(), this.className]}>
{Title}
{Content}
{ButtonGroup}
</div>
</transition>
);
}
});

View File

@ -1,118 +0,0 @@
<template>
<transition name="van-dialog-bounce">
<div
v-show="value"
:class="[b(), className]"
>
<div
v-if="title"
v-text="title"
:class="b('header', { isolated: !message && !$slots.default })"
/>
<div
:class="b('content')"
v-if="message || $slots.default"
>
<slot>
<div
v-if="message"
v-html="message"
:class="b('message', { 'has-title': title, [messageAlign]: messageAlign })"
/>
</slot>
</div>
<div
class="van-hairline--top"
:class="b('footer', { 'buttons': showCancelButton && showConfirmButton })"
>
<van-button
v-show="showCancelButton"
size="large"
:class="b('cancel')"
:loading="loading.cancel"
:text="cancelButtonText || $t('cancel')"
@click="handleAction('cancel')"
/>
<van-button
v-show="showConfirmButton"
size="large"
:class="[b('confirm'), { 'van-hairline--left': showCancelButton && showConfirmButton }]"
:loading="loading.confirm"
:text="confirmButtonText || $t('confirm')"
@click="handleAction('confirm')"
/>
</div>
</div>
</transition>
</template>
<script>
import create from '../utils/create';
import VanButton from '../button';
import Popup from '../mixins/popup';
export default create({
name: 'dialog',
components: {
VanButton
},
mixins: [Popup],
props: {
title: String,
message: String,
callback: Function,
className: [String, Object, Array],
beforeClose: Function,
messageAlign: String,
confirmButtonText: String,
cancelButtonText: String,
showCancelButton: Boolean,
showConfirmButton: {
type: Boolean,
default: true
},
overlay: {
type: Boolean,
default: true
},
closeOnClickOverlay: {
type: Boolean,
default: false
}
},
data() {
return {
loading: {
confirm: false,
cancel: false
}
};
},
methods: {
handleAction(action) {
if (this.beforeClose) {
this.loading[action] = true;
this.beforeClose(action, state => {
if (state !== false) {
this.onClose(action);
}
this.loading[action] = false;
});
} else {
this.onClose(action);
}
},
onClose(action) {
this.$emit('input', false);
this.$emit(action);
this.callback && this.callback(action);
}
}
});
</script>

View File

@ -38,6 +38,7 @@
<van-dialog
v-model="show"
show-cancel-button
:lazy-render="false"
:before-close="beforeClose"
>
<van-field

View File

@ -14,36 +14,21 @@ exports[`renders demo correctly 1`] = `
高级用法
</span></button>
<div name="van-dialog-bounce" class="van-dialog" style="display:none;">
<!---->
<div class="van-dialog__content">
<div placeholder="请输入用户名" class="van-cell van-field">
<div class="van-cell__title"><span>用户名</span>
</div>
<div class="van-cell__title"><span>用户名</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="请输入用户名" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入用户名" value="" class="van-field__control"></div>
</div>
</div>
<div placeholder="请输入密码" class="van-cell van-field">
<div class="van-cell__title"><span>密码</span>
</div>
<div class="van-cell__title"><span>密码</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="password" placeholder="请输入密码" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入密码" value="" class="van-field__control"></div>
</div>
</div>
</div>
<div class="van-hairline--top van-dialog__footer van-dialog__footer--buttons"><button class="van-button van-button--default van-button--large van-dialog__cancel"><span class="van-button__text">取消</span></button> <button class="van-button van-button--default van-button--large van-dialog__confirm van-hairline--left"><span class="van-button__text">消息确认</span></button></div>
<div class="van-hairline--top van-dialog__footer van-dialog__footer--buttons"><button class="van-button van-button--default van-button--large van-dialog__cancel"><span class="van-button__text">取消</span></button><button class="van-button van-button--default van-button--large van-dialog__confirm van-hairline--left"><span class="van-button__text">消息确认</span></button></div>
</div>
</div>
</div>

View File

@ -9,10 +9,11 @@ test('Dialog function call', async () => {
Dialog.close();
Dialog.alert('1');
await later();
const callback = jest.fn();
const dialog = document.querySelector('.van-dialog');
await later();
expect(dialog.style.display).toEqual('');
Dialog.close();
@ -33,6 +34,7 @@ test('Dialog function call', async () => {
test('before close', () => {
const wrapper = mount(DialogVue, {
propsData: {
value: true,
beforeClose: (action, done) => done(false)
}
});

View File

@ -1,84 +1,11 @@
<template>
<cell
:icon="leftIcon"
:title="label"
:center="center"
:border="border"
:is-link="isLink"
:required="required"
:class="b({
error,
disabled: $attrs.disabled,
[`label-${labelAlign}`]: labelAlign,
'min-height': type === 'textarea' && !autosize
})"
>
<slot
name="left-icon"
slot="icon"
/>
<slot
name="label"
slot="title"
/>
<div :class="b('body')">
<textarea
v-if="type === 'textarea'"
v-bind="$attrs"
v-on="listeners"
ref="input"
:class="b('control', inputAlign)"
:value="value"
:readonly="readonly"
/>
<input
v-else
v-bind="$attrs"
v-on="listeners"
ref="input"
:class="b('control', inputAlign)"
:type="type"
:value="value"
:readonly="readonly"
>
<icon
v-if="showClear"
name="clear"
:class="b('clear')"
@touchstart.prevent="onClear"
/>
<div
v-if="$slots.icon || icon"
:class="b('icon')"
@click="onClickIcon"
>
<slot name="icon">
<icon :name="icon" />
</slot>
</div>
<div
v-if="$slots.button"
:class="b('button')"
>
<slot name="button" />
</div>
</div>
<div
v-if="errorMessage"
v-text="errorMessage"
:class="b('error-message')"
/>
</cell>
</template>
<script>
import create from '../utils/create';
import { use, isObj, isDef } from '../utils';
import Icon from '../icon';
import Cell from '../cell';
import CellMixin from '../mixins/cell';
import { isObj } from '../utils';
export default create({
name: 'field',
const [sfc, bem] = use('field');
export default sfc({
inheritAttrs: false,
mixins: [CellMixin],
@ -118,7 +45,9 @@ export default create({
computed: {
showClear() {
return this.clearable && this.focused && this.value !== '' && this.isDef(this.value) && !this.readonly;
return (
this.clearable && this.focused && this.value !== '' && isDef(this.value) && !this.readonly
);
},
listeners() {
@ -146,7 +75,7 @@ export default create({
let { value } = target;
const { maxlength } = this.$attrs;
if (this.type === 'number' && this.isDef(maxlength) && value.length > maxlength) {
if (this.type === 'number' && isDef(maxlength) && value.length > maxlength) {
value = value.slice(0, maxlength);
target.value = value;
}
@ -179,7 +108,8 @@ export default create({
this.onIconClick && this.onIconClick();
},
onClear() {
onClear(event) {
event.preventDefault();
this.$emit('input', '');
this.$emit('clear');
},
@ -188,7 +118,8 @@ export default create({
if (this.type === 'number') {
const { keyCode } = event;
const allowPoint = String(this.value).indexOf('.') === -1;
const isValidKey = (keyCode >= 48 && keyCode <= 57) || (keyCode === 46 && allowPoint) || keyCode === 45;
const isValidKey =
(keyCode >= 48 && keyCode <= 57) || (keyCode === 46 && allowPoint) || keyCode === 45;
if (!isValidKey) {
event.preventDefault();
}
@ -226,6 +157,55 @@ export default create({
input.style.height = height + 'px';
}
}
},
render(h) {
const { type, labelAlign, $slots: slots } = this;
const inputProps = {
ref: 'input',
class: bem('control', this.inputAlign),
domProps: {
value: this.value
},
attrs: {
...this.$attrs,
readonly: this.readonly
},
on: this.listeners
};
const Input = type === 'textarea' ? <textarea {...inputProps} /> : <input {...inputProps} />;
return (
<Cell
icon={this.leftIcon}
title={this.label}
center={this.center}
border={this.border}
isLink={this.isLink}
required={this.required}
class={bem({
error: this.error,
disabled: this.$attrs.disabled,
[`label-${labelAlign}`]: labelAlign,
'min-height': type === 'textarea' && !this.autosize
})}
>
{h('template', { slot: 'icon' }, slots['left-icon'])}
{h('template', { slot: 'title' }, slots.label)}
<div class={bem('body')}>
{Input}
{this.showClear && <Icon name="clear" class={bem('clear')} onTouchstart={this.onClear} />}
{(slots.icon || this.icon) && (
<div class={bem('icon')} onClick={this.onClickIcon}>
{slots.icon || <Icon name={this.icon} />}
</div>
)}
{slots.button && <div class={bem('button')}>{slots.button}</div>}
</div>
{this.errorMessage && <div class={bem('error-message')}>{this.errorMessage}</div>}
</Cell>
);
}
});
</script>

View File

@ -5,133 +5,80 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-cell-group van-hairline--top-bottom">
<div placeholder="请输入用户名" class="van-cell van-field">
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="text" placeholder="请输入用户名" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入用户名" value="" class="van-field__control"></div>
</div>
</div>
</div>
</div>
<div>
<div class="van-cell-group van-hairline--top-bottom">
<div placeholder="请输入用户名" class="van-cell van-cell--required van-field">
<div class="van-cell__title"><span>用户名</span>
</div>
<div class="van-cell__title"><span>用户名</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="请输入用户名" value="" class="van-field__control">
<!---->
<div class="van-field__body"><input placeholder="请输入用户名" value="" class="van-field__control">
<div class="van-field__icon"><i class="van-icon van-icon-question-o" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div>
<!---->
</div>
<!---->
</div>
</div>
<div placeholder="请输入密码" class="van-cell van-cell--required van-field">
<div class="van-cell__title"><span>密码</span>
</div>
<div class="van-cell__title"><span>密码</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="password" placeholder="请输入密码" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入密码" value="" class="van-field__control"></div>
</div>
</div>
</div>
</div>
<div>
<div class="van-cell-group van-hairline--top-bottom">
<div disabled="disabled" class="van-cell van-field"><i class="van-icon van-icon-contact van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__title"><span>用户名</span>
</div>
<div class="van-cell__title"><span>用户名</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" disabled="disabled" value="输入框已禁用" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input disabled="disabled" value="输入框已禁用" class="van-field__control"></div>
</div>
</div>
</div>
</div>
<div>
<div class="van-cell-group van-hairline--top-bottom">
<div placeholder="请输入用户名" class="van-cell van-field van-field--error">
<div class="van-cell__title"><span>用户名</span>
</div>
<div class="van-cell__title"><span>用户名</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="请输入用户名" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入用户名" value="" class="van-field__control"></div>
</div>
</div>
<div placeholder="请输入手机号" class="van-cell van-field">
<div class="van-cell__title"><span>手机号</span>
</div>
<div class="van-cell__title"><span>手机号</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="请输入手机号" value="1365577" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<div class="van-field__body"><input placeholder="请输入手机号" value="1365577" class="van-field__control"></div>
<div class="van-field__error-message">手机号格式错误</div>
</div>
</div>
</div>
</div>
<div>
<div class="van-cell-group van-hairline--top-bottom">
<div placeholder="请输入留言" rows="1" class="van-cell van-field">
<div class="van-cell__title"><span>留言</span>
</div>
<div class="van-cell__title"><span>留言</span></div>
<div class="van-cell__value">
<div class="van-field__body"><textarea placeholder="请输入留言" rows="1" class="van-field__control"></textarea>
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><textarea placeholder="请输入留言" rows="1" class="van-field__control"></textarea></div>
</div>
</div>
</div>
</div>
<div>
<div class="van-cell-group van-hairline--top-bottom">
<div placeholder="请输入短信验证码" class="van-cell van-cell--center van-field">
<div class="van-cell__title"><span>短信验证码</span>
</div>
<div class="van-cell__title"><span>短信验证码</span></div>
<div class="van-cell__value">
<div class="van-field__body"><input type="text" placeholder="请输入短信验证码" value="" class="van-field__control">
<!---->
<!---->
<div class="van-field__body"><input placeholder="请输入短信验证码" value="" class="van-field__control">
<div class="van-field__button"><button class="van-button van-button--primary van-button--small"><span class="van-button__text">
发送验证码
</span></button></div>
</div>
<!---->
</div>
</div>
</div>
</div>

View File

@ -2,46 +2,25 @@
exports[`clearable 1`] = `
<div class="van-cell van-field">
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="text" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input class="van-field__control"></div>
</div>
</div>
`;
exports[`clearable 2`] = `
<div class="van-cell van-field">
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="text" class="van-field__control"> <i class="van-icon van-icon-clear van-field__clear">
<!---->
<!----></i>
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input class="van-field__control"><i class="van-icon van-icon-clear van-field__clear">
<!----></i></div>
</div>
</div>
`;
exports[`render textarea 1`] = `
<div class="van-cell van-field">
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><textarea class="van-field__control" style="height: auto;"></textarea>
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><textarea class="van-field__control" style="height: auto;"></textarea></div>
</div>
</div>
`;

View File

@ -0,0 +1,39 @@
import { use } from '../utils';
import Button from '../button';
import RouterLink from '../mixins/router-link';
const [sfc, bem] = use('goods-action-big-btn');
export default sfc({
mixins: [RouterLink],
props: {
text: String,
primary: Boolean,
loading: Boolean,
disabled: Boolean
},
methods: {
onClick(event) {
this.$emit('click', event);
this.routerLink();
}
},
render(h) {
return (
<Button
square
class={bem()}
size="large"
loading={this.loading}
disabled={this.disabled}
type={this.primary ? 'danger' : 'warning'}
onClick={this.onClick}
>
{this.$slots.default || this.text}
</Button>
);
}
});

View File

@ -1,43 +0,0 @@
<template>
<van-button
square
:class="b()"
size="large"
:loading="loading"
:disabled="disabled"
:type="primary ? 'danger' : 'warning'"
@click="onClick"
>
<slot>{{ text }}</slot>
</van-button>
</template>
<script>
import create from '../utils/create';
import VanButton from '../button';
import RouterLink from '../mixins/router-link';
export default create({
name: 'goods-action-big-btn',
mixins: [RouterLink],
components: {
VanButton
},
props: {
text: String,
primary: Boolean,
loading: Boolean,
disabled: Boolean
},
methods: {
onClick(event) {
this.$emit('click', event);
this.routerLink();
}
}
});
</script>

View File

@ -0,0 +1,32 @@
import { use } from '../utils';
import Icon from '../icon';
import RouterLink from '../mixins/router-link';
const [sfc, bem] = use('goods-action-mini-btn');
export default sfc({
mixins: [RouterLink],
props: {
text: String,
info: [String, Number],
icon: String,
iconClass: String
},
methods: {
onClick(event) {
this.$emit('click', event);
this.routerLink();
}
},
render(h) {
return (
<div class={[bem(), 'van-hairline']} onClick={this.onClick}>
<Icon class={[bem('icon'), this.iconClass]} info={this.info} name={this.icon} />
{this.$slots.default || this.text}
</div>
);
}
});

View File

@ -1,39 +0,0 @@
<template>
<div
:class="b()"
class="van-hairline"
@click="onClick"
>
<icon
:class="[b('icon'), iconClass]"
:info="info"
:name="icon"
/>
<slot>{{ text }}</slot>
</div>
</template>
<script>
import create from '../utils/create';
import RouterLink from '../mixins/router-link';
export default create({
name: 'goods-action-mini-btn',
mixins: [RouterLink],
props: {
text: String,
info: [String, Number],
icon: String,
iconClass: String
},
methods: {
onClick(event) {
this.$emit('click', event);
this.routerLink();
}
}
});
</script>

View File

@ -0,0 +1,9 @@
import { use } from '../utils';
const [sfc, bem] = use('goods-action');
export default sfc({
render(h) {
return <div class={bem()}>{this.$slots.default}</div>;
}
});

View File

@ -1,13 +0,0 @@
<template>
<div :class="b()">
<slot />
</div>
</template>
<script>
import create from '../utils/create';
export default create({
name: 'goods-action'
});
</script>

View File

@ -4,26 +4,21 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-goods-action">
<div class="van-hairline van-goods-action-mini-btn"><i class="van-icon van-icon-chat-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i> 客服</div>
<div class="van-hairline van-goods-action-mini-btn"><i class="van-icon van-icon-cart-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i> 购物车</div> <button class="van-button van-button--warning van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">加入购物车</span></button> <button class="van-button van-button--danger van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">立即购买</span></button>
<div class="van-goods-action-mini-btn van-hairline"><i class="van-icon van-icon-chat-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!----></i>客服</div>
<div class="van-goods-action-mini-btn van-hairline"><i class="van-icon van-icon-cart-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!----></i>购物车</div> <button class="van-button van-button--warning van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">加入购物车</span></button> <button class="van-button van-button--danger van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">立即购买</span></button>
</div>
</div>
<div>
<div class="van-goods-action">
<div class="van-hairline van-goods-action-mini-btn"><i class="van-icon van-icon-chat-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i> 客服</div>
<div class="van-hairline van-goods-action-mini-btn"><i class="van-icon van-icon-cart-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!---->
<div class="van-goods-action-mini-btn van-hairline"><i class="van-icon van-icon-chat-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!----></i>客服</div>
<div class="van-goods-action-mini-btn van-hairline"><i class="van-icon van-icon-cart-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<div class="van-info">5</div>
</i> 购物车</div>
<div class="van-hairline van-goods-action-mini-btn"><i class="van-icon van-icon-shop-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i> 店铺</div> <button class="van-button van-button--warning van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">加入购物车</span></button> <button class="van-button van-button--danger van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">立即购买</span></button>
</i>购物车</div>
<div class="van-goods-action-mini-btn van-hairline"><i class="van-icon van-icon-shop-o van-goods-action-mini-btn__icon" style="color:undefined;font-size:undefined;">
<!----></i>店铺</div> <button class="van-button van-button--warning van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">加入购物车</span></button> <button class="van-button van-button--danger van-button--large van-button--square van-goods-action-big-btn"><span class="van-button__text">立即购买</span></button>
</div>
</div>
</div>

44
packages/icon/index.js Normal file
View File

@ -0,0 +1,44 @@
import { use } from '../utils';
import Info from '../info';
import isSrc from '../utils/validate/src';
const [sfc] = use('icon');
export default sfc({
props: {
name: String,
size: String,
color: String,
info: [String, Number],
classPrefix: {
type: String,
default: 'van-icon'
}
},
computed: {
isSrc() {
return isSrc(this.name);
}
},
render(h) {
return (
<i
class={[
this.classPrefix,
this.isSrc ? 'van-icon--image' : `${this.classPrefix}-${this.name}`
]}
style={{
color: this.color,
fontSize: this.size
}}
{...{ on: this.$listeners }}
>
{this.$slots.default}
{this.isSrc && <img src={name} />}
<Info info={this.info} />
</i>
);
}
});

View File

@ -1,52 +0,0 @@
<template>
<i
v-on="$listeners"
:class="[classPrefix, isSrc ? 'van-icon--image' : `${classPrefix}-${name}`]"
:style="style"
>
<slot />
<img
v-if="isSrc"
:src="name"
>
<van-info :info="info" />
</i>
</template>
<script>
import Info from '../info';
import create from '../utils/create-basic';
import isSrc from '../utils/validate/src';
export default create({
name: 'icon',
components: {
[Info.name]: Info
},
props: {
name: String,
size: String,
color: String,
info: [String, Number],
classPrefix: {
type: String,
default: 'van-icon'
}
},
computed: {
style() {
return {
color: this.color,
fontSize: this.size
};
},
isSrc() {
return isSrc(this.name);
}
}
});
</script>

View File

@ -1,53 +1,10 @@
<template>
<transition name="van-fade">
<div
v-if="value"
:class="[b(), className]"
@touchstart="onWrapperTouchStart"
@touchend="onWrapperTouchEnd"
@touchcancel="onWrapperTouchEnd"
>
<div
v-if="showIndex"
:class="b('index')"
>
{{ active + 1 }}/{{ count }}
</div>
<swipe
ref="swipe"
:loop="loop"
indicator-color="white"
:initial-swipe="startPosition"
:show-indicators="showIndicators"
@change="onChange"
>
<swipe-item
v-for="(item, index) in images"
:key="index"
>
<img
:class="b('image')"
:src="item"
:style="index === active ? imageStyle : null"
@touchstart="onTouchStart"
@touchmove="onTouchMove"
@touchend="onTouchEnd"
@touchcancel="onTouchEnd"
>
</swipe-item>
</swipe>
</div>
</transition>
</template>
<script>
import create from '../utils/create';
import { use, range } from '../utils';
import Popup from '../mixins/popup';
import Touch from '../mixins/touch';
import Swipe from '../swipe';
import SwipeItem from '../swipe-item';
import { range } from '../utils';
const [sfc, bem] = use('image-preview');
const MAX_ZOOM = 3;
const MIN_ZOOM = 1 / 3;
@ -60,16 +17,9 @@ function getDistance(touches) {
);
}
export default create({
name: 'image-preview',
export default sfc({
mixins: [Popup, Touch],
components: {
Swipe,
SwipeItem
},
props: {
images: Array,
asyncClose: Boolean,
@ -110,10 +60,6 @@ export default create({
},
computed: {
count() {
return this.images.length;
},
imageStyle() {
const { scale } = this;
const style = {
@ -262,6 +208,56 @@ export default create({
this.moveX = 0;
this.moveY = 0;
}
},
render(h) {
if (!this.value) {
return;
}
const { active, images } = this;
const Index = this.showIndex && (
<div class={bem('index')}>{`${active + 1}/${images.length}`}</div>
);
const Images = (
<Swipe
ref="swipe"
loop={this.loop}
indicator-color="white"
initial-swipe={this.startPosition}
show-indicators={this.showIndicators}
onChange={this.onChange}
>
{images.map((item, index) => (
<SwipeItem>
<img
class={bem('image')}
src={item}
style={index === active ? this.imageStyle : null}
onTouchstart={this.onTouchStart}
onTouchmove={this.onTouchMove}
onTouchend={this.onTouchEnd}
onTouchcancel={this.onTouchEnd}
/>
</SwipeItem>
))}
</Swipe>
);
return (
<transition name="van-fade">
<div
class={[bem(), this.className]}
onTouchstart={this.onWrapperTouchStart}
onTouchend={this.onWrapperTouchEnd}
onTouchcancel={this.onWrapperTouchEnd}
>
{Index}
{Images}
</div>
</transition>
);
}
});
</script>

View File

@ -2,9 +2,7 @@
exports[`render image 1`] = `
<div class="van-image-preview" name="van-fade">
<div class="van-image-preview__index">
1/3
</div>
<div class="van-image-preview__index">1/3</div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 0px; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 0px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/1.png" class="van-image-preview__image"></div>
@ -18,9 +16,7 @@ exports[`render image 1`] = `
exports[`zoom 1`] = `
<div class="van-image-preview" name="van-fade">
<div class="van-image-preview__index">
1/3
</div>
<div class="van-image-preview__index">1/3</div>
<div class="van-swipe">
<div class="van-swipe__track" style="width: 300px; transform: translateX(0px);">
<div class="van-swipe-item" style="width: 100px; height: 100%; transform: translateX(0px);"><img src="https://img.yzcdn.cn/1.png" class="van-image-preview__image" style="transform: scale3d(2, 2, 1) translate(0px, NaNpx);"></div>

13
packages/info/index.js Normal file
View File

@ -0,0 +1,13 @@
import { use, isDef } from '../utils';
const [sfc, bem] = use('info');
export default sfc({
props: {
info: [String, Number]
},
render(h) {
return isDef(this.info) && <div class={bem()}>{this.info}</div>;
}
});

View File

@ -1,19 +0,0 @@
<template>
<div
v-if="isDef(info)"
v-text="info"
:class="b()"
/>
</template>
<script>
import create from '../utils/create-basic';
export default create({
name: 'info',
props: {
info: [String, Number]
}
});
</script>

View File

@ -1,34 +1,11 @@
<template>
<div :class="b()">
<slot />
<div
v-if="loading"
:class="b('loading')"
>
<slot name="loading">
<loading :class="b('loading-icon')" />
<span
v-text="loadingText || $t('loading')"
:class="b('loading-text')"
/>
</slot>
</div>
<div
v-if="finished && finishedText"
v-text="finishedText"
:class="b('finished-text')"
/>
</div>
</template>
<script>
import create from '../utils/create';
import { use } from '../utils';
import utils from '../utils/scroll';
import Loading from '../loading';
import { on, off } from '../utils/event';
export default create({
name: 'list',
const [sfc, bem, t] = use('list');
export default sfc({
model: {
prop: 'loading'
},
@ -108,9 +85,7 @@ export default create({
reachBottom = scroller.scrollHeight - targetBottom < this.offset;
} else {
const elBottom =
utils.getElementTop(el) -
utils.getElementTop(scroller) +
utils.getVisibleHeight(el);
utils.getElementTop(el) - utils.getElementTop(scroller) + utils.getVisibleHeight(el);
reachBottom = elBottom - scrollerHeight < this.offset;
}
@ -128,6 +103,24 @@ export default create({
(bind ? on : off)(this.scroller, 'scroll', this.check);
}
}
},
render(h) {
return (
<div class={bem()}>
{this.$slots.default}
{this.loading && (
<div class={bem('loading')}>
{this.$slots.loading || [
<Loading class={bem('loading-icon')} />,
<span class={bem('loading-text')}>{this.loadingText || t('loading')}</span>
]}
</div>
)}
{this.finished && this.finishedText && (
<div class={bem('finished-text')}>{this.finishedText}</div>
)}
</div>
);
}
});
</script>

View File

@ -10,10 +10,7 @@ exports[`renders demo correctly 1`] = `
<!---->
<!---->
</div>
<div class="van-list">
<!---->
<!---->
</div>
<div class="van-list"></div>
</div>
</div>
</div>

52
packages/loading/index.js Normal file
View File

@ -0,0 +1,52 @@
import { use } from '../utils';
const [sfc, bem] = use('loading');
const DEFAULT_COLOR = '#c9c9c9';
export default sfc({
props: {
size: String,
type: {
type: String,
default: 'circular'
},
color: {
type: String,
default: DEFAULT_COLOR
}
},
render(h) {
const { color, size, type } = this;
const colorType = color === 'white' || color === 'black' ? color : '';
const style = {
color: color === 'black' ? DEFAULT_COLOR : color,
width: size,
height: size
};
const Spin = [];
if (type === 'spinner') {
for (let i = 0; i < 12; i++) {
Spin.push(<i />);
}
}
const Circular = type === 'circular' && (
<svg class={bem('circular')} viewBox="25 25 50 50">
<circle cx="50" cy="50" r="20" fill="none" />
</svg>
);
return (
<div class={bem([type, colorType])} style={style}>
<span class={bem('spinner', type)}>
{Spin}
{Circular}
</span>
</div>
);
}
});

View File

@ -1,62 +0,0 @@
<template>
<div
:class="b([type, colorType])"
:style="style"
>
<span :class="b('spinner', type)">
<i
v-for="(item, index) in (type === 'spinner' ? 12 : 0)"
:key="index"
/>
<svg
v-if="type === 'circular'"
:class="b('circular')"
viewBox="25 25 50 50"
>
<circle
cx="50"
cy="50"
r="20"
fill="none"
/>
</svg>
</span>
</div>
</template>
<script>
import create from '../utils/create-basic';
const DEFAULT_COLOR = '#c9c9c9';
export default create({
name: 'loading',
props: {
size: String,
type: {
type: String,
default: 'circular'
},
color: {
type: String,
default: DEFAULT_COLOR
}
},
computed: {
colorType() {
const { color } = this;
return color === 'white' || color === 'black' ? color : '';
},
style() {
return {
color: this.color === 'black' ? DEFAULT_COLOR : this.color,
width: this.size,
height: this.size
};
}
}
});
</script>

View File

@ -3,12 +3,12 @@
exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-loading van-loading--circular van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading--white" style="color:white;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading--white" style="color:white;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
</div>
<div>
<div class="van-loading van-loading--spinner van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--spinner"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i> <!----></span></div>
<div class="van-loading van-loading--spinner van-loading--white" style="color:white;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--spinner"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i> <!----></span></div>
<div class="van-loading van-loading--spinner van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--spinner"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
<div class="van-loading van-loading--spinner van-loading--white" style="color:white;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--spinner"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></span></div>
</div>
</div>
`;

53
packages/nav-bar/index.js Normal file
View File

@ -0,0 +1,53 @@
import { use } from '../utils';
import Icon from '../icon';
const [sfc, bem] = use('nav-bar');
export default sfc({
props: {
title: String,
fixed: Boolean,
leftText: String,
rightText: String,
leftArrow: Boolean,
border: {
type: Boolean,
default: true
},
zIndex: {
type: Number,
default: 1
}
},
render(h) {
return (
<div
class={[bem({ fixed: this.fixed }), { 'van-hairline--bottom': this.border }]}
style={{ zIndex: this.zIndex }}
>
<div
class={bem('left')}
onClick={() => {
this.$emit('click-left');
}}
>
{this.$slots.left || [
this.leftArrow && <Icon class={bem('arrow')} name="arrow-left" />,
this.leftText && <span class={bem('text')}>{this.leftText}</span>
]}
</div>
<div class={[bem('title'), 'van-ellipsis']}>{this.$slots.title || this.title}</div>
<div
class={bem('right')}
onClick={() => {
this.$emit('click-right');
}}
>
{this.$slots.right ||
(this.rightText && <span class={bem('text')}>{this.rightText}</span>)}
</div>
</div>
);
}
});

View File

@ -1,74 +0,0 @@
<template>
<div
:class="[b({ fixed }), { 'van-hairline--bottom': border }]"
:style="style"
>
<div
:class="b('left')"
@click="$emit('click-left')"
>
<slot name="left">
<icon
v-if="leftArrow"
:class="b('arrow')"
name="arrow-left"
/>
<span
v-if="leftText"
v-text="leftText"
:class="b('text')"
/>
</slot>
</div>
<div
:class="b('title')"
class="van-ellipsis"
>
<slot name="title">{{ title }}</slot>
</div>
<div
:class="b('right')"
@click="$emit('click-right')"
>
<slot name="right">
<span
v-if="rightText"
v-text="rightText"
:class="b('text')"
/>
</slot>
</div>
</div>
</template>
<script>
import create from '../utils/create';
export default create({
name: 'nav-bar',
props: {
title: String,
fixed: Boolean,
leftText: String,
rightText: String,
leftArrow: Boolean,
border: {
type: Boolean,
default: true
},
zIndex: {
type: Number,
default: 1
}
},
computed: {
style() {
return {
zIndex: this.zIndex
};
}
}
});
</script>

View File

@ -5,20 +5,17 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-nav-bar van-hairline--bottom" style="z-index:1;">
<div class="van-nav-bar__left"><i class="van-icon van-icon-arrow-left van-nav-bar__arrow" style="color:undefined;font-size:undefined;">
<!---->
<!----></i> <span class="van-nav-bar__text">返回</span></div>
<div class="van-ellipsis van-nav-bar__title">标题</div>
<!----></i><span class="van-nav-bar__text">返回</span></div>
<div class="van-nav-bar__title van-ellipsis">标题</div>
<div class="van-nav-bar__right"><span class="van-nav-bar__text">按钮</span></div>
</div>
</div>
<div>
<div class="van-nav-bar van-hairline--bottom" style="z-index:1;">
<div class="van-nav-bar__left"><i class="van-icon van-icon-arrow-left van-nav-bar__arrow" style="color:undefined;font-size:undefined;">
<!---->
<!----></i> <span class="van-nav-bar__text">返回</span></div>
<div class="van-ellipsis van-nav-bar__title">标题</div>
<!----></i><span class="van-nav-bar__text">返回</span></div>
<div class="van-nav-bar__title van-ellipsis">标题</div>
<div class="van-nav-bar__right"><i class="van-icon van-icon-search" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div>
</div>
</div>

View File

@ -0,0 +1,116 @@
import { use } from '../utils';
import Icon from '../icon';
const [sfc, bem] = use('notice-bar');
export default sfc({
props: {
text: String,
mode: String,
color: String,
leftIcon: String,
background: String,
delay: {
type: [String, Number],
default: 1
},
scrollable: {
type: Boolean,
default: true
},
speed: {
type: Number,
default: 50
}
},
data() {
return {
wrapWidth: 0,
firstRound: true,
duration: 0,
offsetWidth: 0,
showNoticeBar: true,
animationClass: ''
};
},
watch: {
text: {
handler() {
this.$nextTick(() => {
const { wrap, content } = this.$refs;
if (!wrap || !content) {
return;
}
const wrapWidth = wrap.getBoundingClientRect().width;
const offsetWidth = content.getBoundingClientRect().width;
if (this.scrollable && offsetWidth > wrapWidth) {
this.wrapWidth = wrapWidth;
this.offsetWidth = offsetWidth;
this.duration = offsetWidth / this.speed;
this.animationClass = bem('play');
}
});
},
immediate: true
}
},
methods: {
onClickIcon() {
this.showNoticeBar = this.mode !== 'closeable';
},
onAnimationEnd() {
this.firstRound = false;
this.$nextTick(() => {
this.duration = (this.offsetWidth + this.wrapWidth) / this.speed;
this.animationClass = bem('play--infinite');
});
}
},
render(h) {
const { mode } = this;
const iconName = mode === 'closeable' ? 'cross' : mode === 'link' ? 'arrow' : '';
const barStyle = {
color: this.color,
background: this.background
};
const contentStyle = {
paddingLeft: this.firstRound ? 0 : this.wrapWidth + 'px',
animationDelay: (this.firstRound ? this.delay : 0) + 's',
animationDuration: this.duration + 's'
};
return (
<div
v-show={this.showNoticeBar}
class={bem({ withicon: mode })}
style={barStyle}
onClick={() => {
this.$emit('click');
}}
>
{this.leftIcon && <Icon class={bem('left-icon')} name={this.leftIcon} />}
<div ref="wrap" class={bem('wrap')}>
<div
ref="content"
class={[bem('content'), this.animationClass, { 'van-ellipsis': !this.scrollable }]}
style={contentStyle}
onAnimationend={this.onAnimationEnd}
onWebkitAnimationEnd={this.onAnimationEnd}
>
{this.$slots.default || this.text}
</div>
</div>
{iconName && <Icon class={bem('right-icon')} name={iconName} onClick={this.onClickIcon} />}
</div>
);
}
});

View File

@ -1,131 +0,0 @@
<template>
<div
v-show="showNoticeBar"
:class="b({ withicon: mode })"
:style="barStyle"
@click="$emit('click')"
>
<icon
v-if="leftIcon"
:class="b('left-icon')"
:name="leftIcon"
/>
<div
ref="wrap"
:class="b('wrap')"
>
<div
ref="content"
:class="[b('content'), animationClass, { 'van-ellipsis': !scrollable }]"
:style="contentStyle"
@animationend="onAnimationEnd"
@webkitAnimationEnd="onAnimationEnd"
>
<slot>{{ text }}</slot>
</div>
</div>
<icon
v-if="iconName"
:class="b('right-icon')"
:name="iconName"
@click="onClickIcon"
/>
</div>
</template>
<script>
import create from '../utils/create';
export default create({
name: 'notice-bar',
props: {
text: String,
mode: String,
color: String,
leftIcon: String,
background: String,
delay: {
type: [String, Number],
default: 1
},
scrollable: {
type: Boolean,
default: true
},
speed: {
type: Number,
default: 50
}
},
data() {
return {
wrapWidth: 0,
firstRound: true,
duration: 0,
offsetWidth: 0,
showNoticeBar: true,
animationClass: ''
};
},
computed: {
iconName() {
return this.mode === 'closeable' ? 'cross' : this.mode === 'link' ? 'arrow' : '';
},
barStyle() {
return {
color: this.color,
background: this.background
};
},
contentStyle() {
return {
paddingLeft: this.firstRound ? 0 : this.wrapWidth + 'px',
animationDelay: (this.firstRound ? this.delay : 0) + 's',
animationDuration: this.duration + 's'
};
}
},
watch: {
text: {
handler() {
this.$nextTick(() => {
const { wrap, content } = this.$refs;
if (!wrap || !content) {
return;
}
const wrapWidth = wrap.getBoundingClientRect().width;
const offsetWidth = content.getBoundingClientRect().width;
if (this.scrollable && offsetWidth > wrapWidth) {
this.wrapWidth = wrapWidth;
this.offsetWidth = offsetWidth;
this.duration = offsetWidth / this.speed;
this.animationClass = this.b('play');
}
});
},
immediate: true
}
},
methods: {
onClickIcon() {
this.showNoticeBar = this.mode !== 'closeable';
},
onAnimationEnd() {
this.firstRound = false;
this.$nextTick(() => {
this.duration = (this.offsetWidth + this.wrapWidth) / this.speed;
this.animationClass = this.b('play--infinite');
});
}
}
});
</script>

View File

@ -4,38 +4,30 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-notice-bar" style="color:undefined;background:undefined;"><i class="van-icon van-icon-volume-o van-notice-bar__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-notice-bar__wrap">
<div class="van-notice-bar__content" style="padding-left:0;animation-delay:1s;animation-duration:0s;">足协杯战线连续第2年上演广州德比战上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
</div>
<!---->
</div>
</div>
<div>
<div class="van-notice-bar" style="color:undefined;background:undefined;">
<!---->
<div class="van-notice-bar__wrap">
<div class="van-notice-bar__content van-ellipsis" style="padding-left:0;animation-delay:1s;animation-duration:0s;">足协杯战线连续第2年上演广州德比战上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
</div>
<!---->
</div>
</div>
<div>
<div class="van-notice-bar van-notice-bar--withicon" style="color:undefined;background:undefined;">
<!---->
<div class="van-notice-bar__wrap">
<div class="van-notice-bar__content" style="padding-left:0;animation-delay:1s;animation-duration:0s;">足协杯战线连续第2年上演广州德比战上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
</div> <i class="van-icon van-icon-cross van-notice-bar__right-icon" style="color:undefined;font-size:undefined;">
<!---->
</div><i class="van-icon van-icon-cross van-notice-bar__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
<div class="van-notice-bar van-notice-bar--withicon" style="color:undefined;background:undefined;">
<!---->
<div class="van-notice-bar__wrap">
<div class="van-notice-bar__content" style="padding-left:0;animation-delay:1s;animation-duration:0s;">足协杯战线连续第2年上演广州德比战上赛季半决赛上恒大以两回合5-3的总比分淘汰富力。</div>
</div> <i class="van-icon van-icon-arrow van-notice-bar__right-icon" style="color:undefined;font-size:undefined;">
<!---->
</div><i class="van-icon van-icon-arrow van-notice-bar__right-icon" style="color:undefined;font-size:undefined;">
<!----></i>
</div>
</div>

43
packages/notify/Notify.js Normal file
View File

@ -0,0 +1,43 @@
import { use } from '../utils';
import PopupMixin from '../mixins/popup';
import { RED, WHITE } from '../utils/color';
const [sfc, bem] = use('notify');
export default sfc({
mixins: [PopupMixin],
props: {
message: [String, Number],
color: {
type: String,
value: WHITE
},
background: {
type: String,
value: RED
},
duration: {
type: Number,
value: 3000
},
lockScroll: {
type: Boolean,
default: false
}
},
render(h) {
const style = {
color: this.color,
background: this.background
};
return (
<transition name="van-slide-down">
<div v-show={this.value} class={bem()} style={style}>
{this.message}
</div>
</transition>
);
}
});

View File

@ -1,51 +0,0 @@
<template>
<transition name="van-slide-down">
<div
v-show="value"
v-text="message"
:class="b()"
:style="style"
/>
</transition>
</template>
<script>
import Popup from '../mixins/popup';
import create from '../utils/create';
import { RED, WHITE } from '../utils/color';
export default create({
name: 'notify',
mixins: [Popup],
props: {
message: [String, Number],
color: {
type: String,
value: WHITE
},
background: {
type: String,
value: RED
},
duration: {
type: Number,
value: 3000
},
lockScroll: {
type: Boolean,
default: false
}
},
computed: {
style() {
return {
color: this.color,
background: this.background
};
}
}
});
</script>

View File

@ -0,0 +1,52 @@
import { use } from '../utils';
const [sfc, bem] = use('key');
export default sfc({
props: {
type: Array,
text: [String, Number]
},
data() {
return {
active: false
};
},
computed: {
className() {
const types = this.type.slice(0);
this.active && types.push('active');
return bem(types);
}
},
methods: {
onFocus() {
this.active = true;
this.$emit('press', this.text);
},
onBlur(event) {
event.preventDefault();
event.stopPropagation();
this.active = false;
}
},
render(h) {
const { onBlur } = this;
return (
<i
class={['van-hairline', this.className]}
onTouchstart={this.onFocus}
onTouchmove={onBlur}
onTouchend={onBlur}
onTouchcancel={onBlur}
>
{this.text}
</i>
);
}
});

View File

@ -1,48 +0,0 @@
<template>
<i
v-text="text"
:class="['van-hairline', className]"
@touchstart.stop.prevent="onFocus"
@touchmove="onBlur"
@touchend="onBlur"
@touchcancel="onBlur"
/>
</template>
<script>
import create from '../utils/create';
export default create({
name: 'key',
props: {
type: Array,
text: [String, Number]
},
data() {
return {
active: false
};
},
computed: {
className() {
const types = this.type.slice(0);
this.active && types.push('active');
return this.b(types);
}
},
methods: {
onFocus() {
this.active = true;
this.$emit('press', this.text);
},
onBlur() {
this.active = false;
}
}
});
</script>

View File

@ -1,63 +1,11 @@
<template>
<transition :name="transition ? 'van-slide-up' : ''">
<div
v-show="show"
:style="style"
:class="b([theme])"
@touchstart.stop
@animationend="onAnimationEnd"
@webkitAnimationEnd="onAnimationEnd"
>
<div
v-if="title || showTitleClose"
:class="b('title')"
class="van-hairline--top"
>
<span v-text="title" />
<span
:class="b('close')"
v-if="showTitleClose"
v-text="closeButtonText"
@click="onClose"
/>
</div>
<div :class="b('body')">
<key
v-for="key in keys"
:key="key.text"
:text="key.text"
:type="key.type"
@press="onPressKey"
/>
</div>
<div
v-if="theme === 'custom'"
:class="b('sidebar')"
>
<key
:text="deleteText"
:type="['delete', 'big', 'gray']"
@press="onPressKey"
/>
<key
:text="closeButtonText"
:type="['blue', 'big']"
@press="onPressKey"
/>
</div>
</div>
</transition>
</template>
<script>
import create from '../utils/create';
import { use } from '../utils';
import Key from './Key';
export default create({
name: 'number-keyboard',
components: { Key },
const [sfc, bem, t] = use('number-keyboard');
const CLOSE_KEY_TYPE = ['blue', 'big'];
const DELETE_KEY_TYPE = ['delete', 'big', 'gray'];
export default sfc({
props: {
show: Boolean,
title: String,
@ -129,28 +77,15 @@ export default create({
);
break;
case 'custom':
keys.push(
{ text: 0, type: ['middle'] },
{ text: this.extraKey }
);
keys.push({ text: 0, type: ['middle'] }, { text: this.extraKey });
break;
}
return keys;
},
style() {
return {
zIndex: this.zIndex
};
},
showTitleClose() {
return this.closeButtonText && this.theme === 'default';
},
deleteText() {
return this.deleteButtonText || this.$t('delete');
return this.deleteButtonText || t('delete');
}
},
@ -180,7 +115,7 @@ export default create({
this.$emit(this.show ? 'show' : 'hide');
},
onPressKey(text) {
onPress(text) {
if (text === '') {
return;
}
@ -193,6 +128,47 @@ export default create({
this.$emit('input', text);
}
}
},
render(h) {
const { theme, onPress, closeButtonText } = this;
const showTitleClose = closeButtonText && theme === 'default';
return (
<transition name={this.transition ? 'van-slide-up' : ''}>
<div
v-show={this.show}
style={{ zIndex: this.zIndex }}
class={bem([theme])}
onTouchstart={event => {
event.stopPropagation();
}}
onAnimationend={this.onAnimationEnd}
onWebkitAnimationEnd={this.onAnimationEnd}
>
{(this.title || showTitleClose) && (
<div class={[bem('title'), 'van-hairline--top']}>
<span>{this.title}</span>
{showTitleClose && (
<span class={bem('close')} onClick={this.onClose}>
{closeButtonText}
</span>
)}
</div>
)}
<div class={bem('body')}>
{this.keys.map(key => (
<Key key={key.text} text={key.text} type={key.type} onPress={onPress} />
))}
</div>
{theme === 'custom' && (
<div class={bem('sidebar')}>
<Key text={this.deleteText} type={DELETE_KEY_TYPE} onPress={onPress} />
<Key text={closeButtonText} type={CLOSE_KEY_TYPE} onPress={onPress} />
</div>
)}
</div>
</transition>
);
}
});
</script>

View File

@ -6,18 +6,16 @@ exports[`renders demo correctly 1`] = `
弹出默认键盘
</span></button>
<div name="van-slide-up" class="van-number-keyboard van-number-keyboard--default" style="z-index:100;">
<div class="van-hairline--top van-number-keyboard__title"><span></span> <span class="van-number-keyboard__close">完成</span></div>
<div class="van-number-keyboard__title van-hairline--top"><span></span><span class="van-number-keyboard__close">完成</span></div>
<div class="van-number-keyboard__body"><i class="van-hairline van-key">1</i><i class="van-hairline van-key">2</i><i class="van-hairline van-key">3</i><i class="van-hairline van-key">4</i><i class="van-hairline van-key">5</i><i class="van-hairline van-key">6</i><i class="van-hairline van-key">7</i><i class="van-hairline van-key">8</i><i class="van-hairline van-key">9</i><i class="van-hairline van-key van-key--gray">.</i><i class="van-hairline van-key">0</i><i class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
<!---->
</div>
</div>
<div><button class="van-button van-button--default van-button--normal"><span class="van-button__text">
弹出自定义键盘
</span></button>
<div name="van-slide-up" class="van-number-keyboard van-number-keyboard--custom" style="z-index:100;display:none;">
<!---->
<div class="van-number-keyboard__body"><i class="van-hairline van-key">1</i><i class="van-hairline van-key">2</i><i class="van-hairline van-key">3</i><i class="van-hairline van-key">4</i><i class="van-hairline van-key">5</i><i class="van-hairline van-key">6</i><i class="van-hairline van-key">7</i><i class="van-hairline van-key">8</i><i class="van-hairline van-key">9</i><i class="van-hairline van-key van-key--middle">0</i><i class="van-hairline van-key">.</i></div>
<div class="van-number-keyboard__sidebar"><i class="van-hairline van-key van-key--delete van-key--big van-key--gray">删除</i> <i class="van-hairline van-key van-key--blue van-key--big">完成</i></div>
<div class="van-number-keyboard__sidebar"><i class="van-hairline van-key van-key--delete van-key--big van-key--gray">删除</i><i class="van-hairline van-key van-key--blue van-key--big">完成</i></div>
</div>
</div>
</div>

36
packages/overlay/index.js Normal file
View File

@ -0,0 +1,36 @@
import { use } from '../utils';
const [sfc, bem] = use('overlay');
export default sfc({
props: {
zIndex: Number,
visible: Boolean,
className: String,
customStyle: Object
},
render(h) {
const style = {
zIndex: this.zIndex,
...this.customStyle
};
return (
<transition name="van-fade">
<div
v-show={this.visible}
style={style}
class={[bem(), this.className]}
onTouchmove={event => {
event.preventDefault();
event.stopPropagation();
}}
onClick={event => {
this.$emit('click', event);
}}
/>
</transition>
);
}
});

View File

@ -1,34 +0,0 @@
<template>
<transition name="van-fade">
<div
v-show="visible"
class="van-overlay"
:class="className"
:style="style"
@touchmove.prevent.stop
@click="$emit('click', $event)"
/>
</transition>
</template>
<script>
export default {
name: 'overlay',
props: {
zIndex: Number,
visible: Boolean,
className: String,
customStyle: Object
},
computed: {
style() {
return {
zIndex: this.zIndex,
...this.customStyle
};
}
}
};
</script>

View File

@ -1,43 +1,12 @@
<template>
<ul :class="b({ simple: !isMultiMode })">
<li
v-text="prevText || $t('prev')"
class="van-hairline"
:class="[b('item', { disabled: value === 1 }), b('prev')]"
@click="selectPage(value - 1)"
/>
<li
v-for="page in pages"
v-text="page.text"
class="van-hairline"
:class="[b('item', { active: page.active }), b('page')]"
@click="selectPage(page.number)"
/>
<li
v-if="!isMultiMode"
:class="b('page-desc')"
>
<slot name="pageDesc">{{ pageDesc }}</slot>
</li>
<li
v-text="nextText || $t('next')"
class="van-hairline"
:class="[b('item', { disabled: value === computedPageCount }), b('next')]"
@click="selectPage(value + 1)"
/>
</ul>
</template>
import { use } from '../utils';
<script>
import create from '../utils/create';
const [sfc, bem, t] = use('pagination');
function makePage(number, text, active) {
return { number, text, active };
}
export default create({
name: 'pagination',
export default sfc({
props: {
value: Number,
prevText: String,
@ -60,24 +29,16 @@ export default create({
},
computed: {
isMultiMode() {
return this.mode === 'multi';
},
computedPageCount() {
count() {
const count = this.pageCount || Math.ceil(this.totalItems / this.itemsPerPage);
return Math.max(1, count);
},
pageDesc() {
return this.value + '/' + this.computedPageCount;
},
pages() {
const pages = [];
const pageCount = this.computedPageCount;
const pageCount = this.count;
if (!this.isMultiMode) {
if (this.mode !== 'multi') {
return pages;
}
@ -125,21 +86,56 @@ export default create({
watch: {
value: {
handler(page) {
this.selectPage(page || this.value);
this.select(page || this.value);
},
immediate: true
}
},
methods: {
selectPage(page) {
page = Math.max(1, page);
page = Math.min(this.computedPageCount, page);
select(page) {
page = Math.min(this.count, Math.max(1, page));
if (this.value !== page) {
this.$emit('input', page);
this.$emit('change', page);
}
}
},
render(h) {
const { value } = this;
const simple = this.mode !== 'multi';
const onSelect = value => () => {
this.select(value);
};
return (
<ul class={bem({ simple })}>
<li
class={[bem('item', { disabled: value === 1 }), bem('prev'), 'van-hairline']}
onClick={onSelect(value - 1)}
>
{this.prevText || t('prev')}
</li>
{this.pages.map(page => (
<li
class={[bem('item', { active: page.active }), bem('page'), 'van-hairline']}
onClick={onSelect(page.number)}
>
{page.text}
</li>
))}
{simple && (
<li class={bem('page-desc')}>{this.$slots.pageDesc || `${value}/${this.count}`}</li>
)}
<li
class={[bem('item', { disabled: value === this.count }), bem('next'), 'van-hairline']}
onClick={onSelect(value + 1)}
>
{this.nextText || t('next')}
</li>
</ul>
);
}
});
</script>

View File

@ -4,32 +4,30 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<ul class="van-pagination">
<li class="van-hairline van-pagination__item van-pagination__item--disabled van-pagination__prev">上一页</li>
<li class="van-hairline van-pagination__item van-pagination__item--active van-pagination__page">1</li>
<li class="van-hairline van-pagination__item van-pagination__page">2</li>
<li class="van-hairline van-pagination__item van-pagination__page">3</li>
<li class="van-hairline van-pagination__item van-pagination__page">4</li>
<li class="van-hairline van-pagination__item van-pagination__page">5</li>
<!---->
<li class="van-hairline van-pagination__item van-pagination__next">下一页</li>
<li class="van-pagination__item van-pagination__item--disabled van-pagination__prev van-hairline">上一页</li>
<li class="van-pagination__item van-pagination__item--active van-pagination__page van-hairline">1</li>
<li class="van-pagination__item van-pagination__page van-hairline">2</li>
<li class="van-pagination__item van-pagination__page van-hairline">3</li>
<li class="van-pagination__item van-pagination__page van-hairline">4</li>
<li class="van-pagination__item van-pagination__page van-hairline">5</li>
<li class="van-pagination__item van-pagination__next van-hairline">下一页</li>
</ul>
</div>
<div>
<ul size="small" class="van-pagination van-pagination--simple">
<li class="van-hairline van-pagination__item van-pagination__item--disabled van-pagination__prev">上一页</li>
<li class="van-pagination__item van-pagination__item--disabled van-pagination__prev van-hairline">上一页</li>
<li class="van-pagination__page-desc">1/12</li>
<li class="van-hairline van-pagination__item van-pagination__next">下一页</li>
<li class="van-pagination__item van-pagination__next van-hairline">下一页</li>
</ul>
</div>
<div>
<ul class="van-pagination">
<li class="van-hairline van-pagination__item van-pagination__item--disabled van-pagination__prev">上一页</li>
<li class="van-hairline van-pagination__item van-pagination__item--active van-pagination__page">1</li>
<li class="van-hairline van-pagination__item van-pagination__page">2</li>
<li class="van-hairline van-pagination__item van-pagination__page">3</li>
<li class="van-hairline van-pagination__item van-pagination__page">...</li>
<!---->
<li class="van-hairline van-pagination__item van-pagination__next">下一页</li>
<li class="van-pagination__item van-pagination__item--disabled van-pagination__prev van-hairline">上一页</li>
<li class="van-pagination__item van-pagination__item--active van-pagination__page van-hairline">1</li>
<li class="van-pagination__item van-pagination__page van-hairline">2</li>
<li class="van-pagination__item van-pagination__page van-hairline">3</li>
<li class="van-pagination__item van-pagination__page van-hairline">...</li>
<li class="van-pagination__item van-pagination__next van-hairline">下一页</li>
</ul>
</div>
</div>

View File

@ -9,7 +9,6 @@ exports[`renders demo correctly 1`] = `
<div class="van-cell__label">描述信息</div>
</div>
<div class="van-cell__value"><span>状态</span></div>
</div>
<div class="van-panel__content">
<div>内容</div>
@ -24,7 +23,6 @@ exports[`renders demo correctly 1`] = `
<div class="van-cell__label">描述信息</div>
</div>
<div class="van-cell__value"><span>状态</span></div>
</div>
<div class="van-panel__content">
<div>内容</div>

View File

@ -15,9 +15,7 @@ exports[`renders demo correctly 1`] = `
<div class="van-password-input__info">密码为 6 位数字</div>
</div>
<div name="van-slide-up" class="van-number-keyboard van-number-keyboard--default" style="z-index:100;">
<!---->
<div class="van-number-keyboard__body"><i class="van-hairline van-key">1</i><i class="van-hairline van-key">2</i><i class="van-hairline van-key">3</i><i class="van-hairline van-key">4</i><i class="van-hairline van-key">5</i><i class="van-hairline van-key">6</i><i class="van-hairline van-key">7</i><i class="van-hairline van-key">8</i><i class="van-hairline van-key">9</i><i class="van-hairline van-key van-key--gray"></i><i class="van-hairline van-key">0</i><i class="van-hairline van-key van-key--gray van-key--delete">删除</i></div>
<!---->
</div>
</div>
</div>

View File

@ -86,7 +86,7 @@ exports[`renders demo correctly 1`] = `
<div class="van-picker">
<!---->
<div class="van-picker__loading">
<div class="van-loading van-loading--circular van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading" style="color:#c9c9c9;width:undefined;height:undefined;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
</div>
<div class="van-picker__columns" style="height:220px;">
<div class="van-picker-column column1" style="height:220px;">

View File

@ -28,7 +28,7 @@ exports[`change head content when pulling down 3`] = `
<div class="van-pull-refresh__head">
<!---->
<div class="van-pull-refresh__loading">
<div class="van-loading van-loading--circular van-loading" style="color: rgb(201, 201, 201);"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div> <span>释放即可刷新...</span>
<div class="van-loading van-loading--circular van-loading" style="color: rgb(201, 201, 201);"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div> <span>释放即可刷新...</span>
</div>
</div>
</div>
@ -41,7 +41,7 @@ exports[`change head content when pulling down 4`] = `
<div class="van-pull-refresh__head">
<!---->
<div class="van-pull-refresh__loading">
<div class="van-loading van-loading--circular van-loading" style="color: rgb(201, 201, 201);"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div> <span>释放即可刷新...</span>
<div class="van-loading van-loading--circular van-loading" style="color: rgb(201, 201, 201);"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div> <span>释放即可刷新...</span>
</div>
</div>
</div>

View File

@ -4,18 +4,18 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="demo-radio-group van-radio-group">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label">单选框 1</span></div>
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="2" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label">单选框 2</span></div>
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label">单选框 1</span></div>
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="2" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label">单选框 2</span></div>
</div>
</div>
<div>
<div class="demo-radio-group van-radio-group">
<div class="van-radio van-radio--disabled"><span class="van-radio__input"><input type="radio" disabled="disabled" value="1" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label">单选框 1</span></div>
<div class="van-radio van-radio--disabled"><span class="van-radio__input"><input type="radio" disabled="disabled" value="2" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label">单选框 2</span></div>
<div class="van-radio van-radio--disabled"><span class="van-radio__input"><input type="radio" disabled="disabled" value="1" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label">单选框 1</span></div>
<div class="van-radio van-radio--disabled"><span class="van-radio__input"><input type="radio" disabled="disabled" value="2" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"><!----></i></span> <span class="van-radio__label">单选框 2</span></div>
</div>
</div>
<div>
<div class="demo-radio-group van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:#07c160;font-size:undefined;"> <!----> <!----></i></span> <span class="van-radio__label">
<div class="demo-radio-group van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:#07c160;font-size:undefined;"><!----></i></span> <span class="van-radio__label">
单选框
</span></div>
</div>
@ -23,24 +23,20 @@ exports[`renders demo correctly 1`] = `
<div class="van-radio-group">
<div class="van-cell-group van-hairline--top-bottom">
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>单选框1</span>
</div>
<div class="van-cell__title"><span>单选框1</span></div>
<div class="van-cell__value">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span>
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="1" checked="checked" class="van-radio__control"> <i class="van-icon van-icon-checked" style="color:undefined;font-size:undefined;"><!----></i></span>
<!---->
</div>
</div>
</div>
<div class="van-cell van-cell--clickable">
<div class="van-cell__title"><span>单选框2</span>
</div>
<div class="van-cell__title"><span>单选框2</span></div>
<div class="van-cell__value">
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="2" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"> <!----> <!----></i></span>
<div class="van-radio"><span class="van-radio__input"><input type="radio" value="2" class="van-radio__control"> <i class="van-icon van-icon-circle" style="color:undefined;font-size:undefined;"><!----></i></span>
<!---->
</div>
</div>
</div>
</div>
</div>

View File

@ -4,56 +4,35 @@ exports[`renders demo correctly 1`] = `
<div>
<div>
<div class="van-rate"><i data-index="0" class="van-icon van-icon-star van-rate__item" style="color:#ffd21e;font-size:20px;">
<!---->
<!----></i><i data-index="1" class="van-icon van-icon-star van-rate__item" style="color:#ffd21e;font-size:20px;">
<!---->
<!----></i><i data-index="2" class="van-icon van-icon-star van-rate__item" style="color:#ffd21e;font-size:20px;">
<!---->
<!----></i><i data-index="3" class="van-icon van-icon-star-o van-rate__item" style="color:#c7c7c7;font-size:20px;">
<!---->
<!----></i><i data-index="4" class="van-icon van-icon-star-o van-rate__item" style="color:#c7c7c7;font-size:20px;">
<!---->
<!----></i></div>
</div>
<div>
<div class="van-rate"><i data-index="0" class="van-icon van-icon-like van-rate__item" style="color:#ffd21e;font-size:20px;">
<!---->
<!----></i><i data-index="1" class="van-icon van-icon-like van-rate__item" style="color:#ffd21e;font-size:20px;">
<!---->
<!----></i><i data-index="2" class="van-icon van-icon-like van-rate__item" style="color:#ffd21e;font-size:20px;">
<!---->
<!----></i><i data-index="3" class="van-icon van-icon-like-o van-rate__item" style="color:#c7c7c7;font-size:20px;">
<!---->
<!----></i><i data-index="4" class="van-icon van-icon-like-o van-rate__item" style="color:#c7c7c7;font-size:20px;">
<!---->
<!----></i></div>
</div>
<div>
<div class="van-rate"><i data-index="0" class="van-icon van-icon-star van-rate__item" style="color:#07c160;font-size:25px;">
<!---->
<!----></i><i data-index="1" class="van-icon van-icon-star van-rate__item" style="color:#07c160;font-size:25px;">
<!---->
<!----></i><i data-index="2" class="van-icon van-icon-star van-rate__item" style="color:#07c160;font-size:25px;">
<!---->
<!----></i><i data-index="3" class="van-icon van-icon-star van-rate__item" style="color:#07c160;font-size:25px;">
<!---->
<!----></i><i data-index="4" class="van-icon van-icon-star-o van-rate__item" style="color:#ceefe8;font-size:25px;">
<!---->
<!----></i><i data-index="5" class="van-icon van-icon-star-o van-rate__item" style="color:#ceefe8;font-size:25px;">
<!---->
<!----></i></div>
</div>
<div>
<div class="van-rate"><i data-index="0" class="van-icon van-icon-star van-rate__item" style="color:#bdbdbd;font-size:20px;">
<!---->
<!----></i><i data-index="1" class="van-icon van-icon-star van-rate__item" style="color:#bdbdbd;font-size:20px;">
<!---->
<!----></i><i data-index="2" class="van-icon van-icon-star-o van-rate__item" style="color:#bdbdbd;font-size:20px;">
<!---->
<!----></i><i data-index="3" class="van-icon van-icon-star-o van-rate__item" style="color:#bdbdbd;font-size:20px;">
<!---->
<!----></i><i data-index="4" class="van-icon van-icon-star-o van-rate__item" style="color:#bdbdbd;font-size:20px;">
<!---->
<!----></i></div>
</div>
</div>

View File

@ -5,18 +5,10 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-search" style="background:#f2f2f2;">
<div placeholder="请输入搜索关键词" class="van-cell van-cell--borderless van-field"><i class="van-icon van-icon-search van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" placeholder="请输入搜索关键词" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入搜索关键词" value="" class="van-field__control"></div>
</div>
</div>
<!---->
</div>
@ -25,18 +17,10 @@ exports[`renders demo correctly 1`] = `
<form action="/">
<div class="van-search van-search--show-action" style="background:#f2f2f2;">
<div placeholder="请输入搜索关键词" class="van-cell van-cell--borderless van-field"><i class="van-icon van-icon-search van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" placeholder="请输入搜索关键词" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入搜索关键词" value="" class="van-field__control"></div>
</div>
</div>
<div class="van-search__action">
<div>取消</div>
@ -47,18 +31,10 @@ exports[`renders demo correctly 1`] = `
<div>
<div class="van-search van-search--show-action" style="background:#f2f2f2;">
<div placeholder="请输入搜索关键词" class="van-cell van-cell--borderless van-field"><i class="van-icon van-icon-search van-cell__left-icon" style="color:undefined;font-size:undefined;">
<!---->
<!----></i>
<div class="van-cell__value van-cell__value--alone">
<div class="van-field__body"><input type="search" placeholder="请输入搜索关键词" value="" class="van-field__control">
<!---->
<!---->
<!---->
</div>
<!---->
<div class="van-field__body"><input placeholder="请输入搜索关键词" value="" class="van-field__control"></div>
</div>
</div>
<div class="van-search__action">
<div>

View File

@ -14,7 +14,6 @@ exports[`renders demo correctly 1`] = `
<div class="van-hairline van-step van-step--horizontal van-step--process">
<div class="van-step__title" style="color:#07c160;">商家接单</div>
<div class="van-step__circle-container"><i class="van-icon van-icon-checked" style="color:#07c160;font-size:undefined;">
<!---->
<!----></i></div>
<div class="van-step__line"></div>
</div>
@ -41,7 +40,6 @@ exports[`renders demo correctly 1`] = `
<p>2016-07-12 12:40</p>
</div>
<div class="van-step__circle-container"><i class="van-icon van-icon-checked" style="color:#f44;font-size:undefined;">
<!---->
<!----></i></div>
<div class="van-step__line"></div>
</div>

View File

@ -24,7 +24,7 @@ exports[`renders demo correctly 1`] = `
<!---->
<div class="van-submit-bar__bar">
<div class="van-submit-bar__text"><span>合计:</span> <span class="van-submit-bar__price">¥ 30.50</span></div> <button class="van-button van-button--danger van-button--large van-button--square van-button--loading">
<div class="van-loading van-loading--circular van-loading" style="color:;width:20px;height:20px;"><span class="van-loading__spinner van-loading__spinner--circular"> <svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
<div class="van-loading van-loading--circular van-loading" style="color:;width:20px;height:20px;"><span class="van-loading__spinner van-loading__spinner--circular"><svg viewBox="25 25 50 50" class="van-loading__circular"><circle cx="50" cy="50" r="20" fill="none"></circle></svg></span></div>
</button>
</div>
</div>
@ -40,8 +40,7 @@ exports[`renders demo correctly 1`] = `
<div class="van-submit-bar__bar">
<div class="van-checkbox">
<div class="van-checkbox__icon van-checkbox__icon--round van-checkbox__icon--checked"><i class="van-icon van-icon-success" style="color:undefined;font-size:undefined;">
<!---->
<!----></i></div> <span class="van-checkbox__label">全选</span>
<!----></i></div><span class="van-checkbox__label">全选</span>
</div>
<div class="van-submit-bar__text"><span>合计:</span> <span class="van-submit-bar__price">¥ 30.50</span></div> <button class="van-button van-button--danger van-button--large van-button--square"><span class="van-button__text">提交订单</span></button>
</div>

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