Merge pull request #93 from chenjiahan/dev

Dialog: support both function call and component call
This commit is contained in:
neverland 2017-08-26 21:18:10 +08:00 committed by GitHub
commit 0348a4d561
27 changed files with 311 additions and 246 deletions

View File

@ -9,33 +9,29 @@
<script> <script>
import { Dialog } from 'packages/index'; import { Dialog } from 'packages/index';
const message = '弹窗内容';
export default { export default {
methods: { methods: {
handleAlertClick() { onClickAlert() {
Dialog.alert({ Dialog.alert({
title: 'alert标题', title: '标题',
message: '弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。' message
}).then((action) => {
console.log(action);
}); });
}, },
handleAlert2Click() { onClickAlert2() {
Dialog.alert({ Dialog.alert({
message: '无标题alert' message
}).then((action) => {
console.log(action);
}); });
}, },
handleConfirmClick() { onClickConfirm() {
Dialog.confirm({ Dialog.confirm({
title: 'confirm标题', title: '标题',
message: '弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。' message
}).then((action) => { }).catch(action => {
console.log(action); console.log(action);
}, (error) => {
console.log(error);
}); });
} }
} }
@ -46,8 +42,6 @@ export default {
### 使用指南 ### 使用指南
`Dialog`和其他组件不同不是通过HTML结构的方式来使用而是通过函数调用的方式。使用前需要先引入它它接受一个数组作为参数数组中的每一项对应了图片链接。
```js ```js
import { Dialog } from 'vant'; import { Dialog } from 'vant';
``` ```
@ -56,30 +50,30 @@ import { Dialog } from 'vant';
#### 消息提示 #### 消息提示
用于提示一些消息,只包含一个确认按钮 用于提示一些消息,只包含一个确认按钮
:::demo 消息提示 :::demo 消息提示
```html ```html
<van-button @click="handleAlertClick">alert</van-button> <van-button @click="onClickAlert">Alert</van-button>
<van-button @click="handleAlert2Click">无标题alert</van-button> <van-button @click="onClickAlert2">无标题 Alert</van-button>
<script> <script>
export default { export default {
methods: { methods: {
handleAlertClick() { onClickAlert() {
Dialog.alert({ Dialog.alert({
title: 'alert标题', title: '标题',
message: '弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。' message: '弹窗内容'
}).then((action) => { }).then(() => {
console.log(action); // on close
}); });
}, },
handleAlert2Click() { onClickAlert2() {
Dialog.alert({ Dialog.alert({
message: '弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。' message: '弹窗内容'
}).then((action) => { }).then(() => {
console.log(action); // on close
}); });
} }
} }
@ -90,23 +84,23 @@ export default {
#### 消息确认 #### 消息确认
用于确认消息,包含取消和确认按钮 用于确认消息,包含取消和确认按钮
:::demo 消息确认 :::demo 消息确认
```html ```html
<van-button @click="handleConfirmClick">confirm</van-button> <van-button @click="onClickConfirm">Confirm</van-button>
<script> <script>
export default { export default {
methods: { methods: {
handleConfirmClick() { onClickConfirm() {
Dialog.confirm({ Dialog.confirm({
title: 'confirm标题', title: '标题',
message: '弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。弹窗提示文字左右始终距离边20PX上下距离20PX文字左对齐。' message: '弹窗内容'
}).then((action) => { }).then(() => {
console.log(action); // on confirm
}, (error) => { }).catch(() => {
console.log(error); // on cancel
}); });
} }
} }
@ -117,19 +111,22 @@ export default {
### 方法 ### 方法
#### Dialog.alert(options) | 方法名 | 参数 | 返回值 | 介绍 |
|-----------|-----------|-----------|-------------|
消息提示时使用该方法。 | Dialog.alert | options | `Promise` | 展示消息提示弹窗 |
| Dialog.confirm | options | `Promise` | 展示消息确认弹窗 |
#### Dialog.confirm(options) | Dialog.close | - | `void` | 关闭弹窗 |
消息确认时使用该方法。
### Options ### Options
| 参数 | 说明 | 类型 | 默认值 | 可选值 | | 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------| |-----------|-----------|-----------|-------------|-------------|
| title | 标题 | `string` | | | | title | 标题 | `String` | | |
| message | 内容 | `string` | | | | message | 内容 | `String` | | |
| confirmButtonText | 确认按钮的文案 | `string` | `确认` | | | showConfirmButton | 是否展示确认按钮 | `Boolean` | `true` | |
| cancelButtonText | 取消按钮的文案 | `string` | `取消` | | | showCancelButton | 是否展示取消按钮 | `Boolean` | `false` | |
| confirmButtonText | 确认按钮的文案 | `String` | `确认` | |
| cancelButtonText | 取消按钮的文案 | `String` | `取消` | |
| overlay | 是否展示蒙层 | `Boolean` | `true` | |
| closeOnClickOverlay | 点击蒙层时是否关闭弹窗 | `Boolean` | `false` | |
| lockOnScroll | 是否禁用背景滚动 | `Boolean` | `true` | |

View File

@ -28,8 +28,8 @@
<script> <script>
import Popup from '../mixins/popup'; import Popup from '../mixins/popup';
import VanIcon from '../icon'; import Icon from '../icon';
import VanLoading from '../loading'; import Loading from '../loading';
export default { export default {
name: 'van-actionsheet', name: 'van-actionsheet',
@ -37,8 +37,8 @@ export default {
mixins: [Popup], mixins: [Popup],
components: { components: {
[VanIcon.name]: VanIcon, [Icon.name]: Icon,
[VanLoading.name]: VanLoading [Loading.name]: Loading
}, },
props: { props: {

View File

@ -5,21 +5,21 @@
</template> </template>
<script> <script>
export default { export default {
name: 'van-badge-group', name: 'van-badge-group',
props: { props: {
// tab key // tab key
activeKey: { activeKey: {
type: [Number, String], type: [Number, String],
default: 0 default: 0
}
},
data() {
return {
badges: []
};
} }
}; },
data() {
return {
badges: []
};
}
};
</script> </script>

View File

@ -51,7 +51,7 @@ export default {
wrapperStyle() { wrapperStyle() {
return { return {
transform: `translate3d(${this.offset}px, 0, 0)` transform: `translate3d(${this.offset}px, 0, 0)`
} };
} }
}, },
@ -72,9 +72,8 @@ export default {
if (direction > 0 && -offset > rightWidth * 0.4 && rightWidth > 0) { if (direction > 0 && -offset > rightWidth * 0.4 && rightWidth > 0) {
this.swipeMove(-rightWidth); this.swipeMove(-rightWidth);
this.resetSwipeStatus(); this.resetSwipeStatus();
}
// left // left
else if (direction < 0 && offset >leftWidth * 0.4 && leftWidth > 0) { } else if (direction < 0 && offset > leftWidth * 0.4 && leftWidth > 0) {
this.swipeMove(leftWidth); this.swipeMove(leftWidth);
this.resetSwipeStatus(); this.resetSwipeStatus();
} else { } else {
@ -114,7 +113,7 @@ export default {
endDrag() { endDrag() {
if (this.swiping) { if (this.swiping) {
this.swipeLeaveTransition(this.offset > 0 ? -1 : 1); this.swipeLeaveTransition(this.offset > 0 ? -1 : 1);
}; };
} }
} }

View File

@ -19,7 +19,7 @@ export default {
name: 'van-datetime-picker', name: 'van-datetime-picker',
components: { components: {
'van-picker': Picker [Picker.name]: Picker
}, },
props: { props: {
@ -270,6 +270,9 @@ export default {
}); });
}, },
setColumnByValues(values) { setColumnByValues(values) {
if (!this.$refs.picker) {
return;
}
const setColumnValue = this.$refs.picker.setColumnValue; const setColumnValue = this.$refs.picker.setColumnValue;
if (this.type === 'time') { if (this.type === 'time') {
setColumnValue(0, values[0]); setColumnValue(0, values[0]);

View File

@ -2,8 +2,10 @@
<transition name="van-dialog-bounce"> <transition name="van-dialog-bounce">
<div class="van-dialog" v-show="value"> <div class="van-dialog" v-show="value">
<div class="van-dialog__header" v-if="title" v-text="title" /> <div class="van-dialog__header" v-if="title" v-text="title" />
<div class="van-dialog__content" v-if="message"> <div class="van-dialog__content">
<div class="van-dialog__message" :class="{ 'van-dialog__message--withtitle': title }" v-html="message" /> <slot>
<div class="van-dialog__message" v-if="message" :class="{ 'van-dialog__message--withtitle': title }" v-html="message" />
</slot>
</div> </div>
<div class="van-dialog__footer" :class="{ 'is-twobtn': showCancelButton && showConfirmButton }"> <div class="van-dialog__footer" :class="{ 'is-twobtn': showCancelButton && showConfirmButton }">
<van-button size="large" class="van-dialog__cancel" v-show="showCancelButton" @click="handleAction('cancel')">{{ cancelButtonText }}</van-button> <van-button size="large" class="van-dialog__cancel" v-show="showCancelButton" @click="handleAction('cancel')">{{ cancelButtonText }}</van-button>
@ -27,33 +29,48 @@ export default {
mixins: [Popup], mixins: [Popup],
props: { props: {
title: {
type: String,
default: ''
},
message: {
type: String,
default: ''
},
showConfirmButton: {
type: Boolean,
default: true
},
showCancelButton: {
type: Boolean,
default: false
},
confirmButtonText: {
type: String,
default: '确认'
},
cancelButtonText: {
type: String,
default: '取消'
},
callback: {
type: Function
},
overlay: { overlay: {
default: true default: true
}, },
closeOnClickOverlay: { closeOnClickOverlay: {
default: true default: false
}, },
lockOnScroll: { lockOnScroll: {
default: true default: true
} }
}, },
data() {
return {
title: '',
message: '',
type: '',
showConfirmButton: true,
showCancelButton: false,
confirmButtonText: '确认',
cancelButtonText: '取消',
callback: null
};
},
methods: { methods: {
handleAction(action) { handleAction(action) {
this.$emit('input', false); this.$emit('input', false);
this.$emit(action);
this.callback && this.callback(action); this.callback && this.callback(action);
} }
} }

View File

@ -1,97 +1,62 @@
import Vue from 'vue'; import Vue from 'vue';
import Dialog from './dialog'; import DialogComponent from './dialog';
const DialogConstructor = Vue.extend(Dialog);
let currentDialog;
let instance; let instance;
let dialogQueue = [];
const defaultCallback = action => { const defaultConfig = {
/* istanbul ignore else */ value: true,
if (currentDialog) { title: '',
if (currentDialog.resolve && action === 'confirm') { message: '',
currentDialog.resolve(action); showCancelButton: false,
} else if (currentDialog.reject && action === 'cancel') { closeOnClickOverlay: false,
currentDialog.reject(action); callback: action => {
} instance[action === 'confirm' ? 'resolve' : 'reject'](action);
} }
}; };
const initInstance = () => { const initInstance = () => {
const DialogConstructor = Vue.extend(DialogComponent);
instance = new DialogConstructor({ instance = new DialogConstructor({
el: document.createElement('div') el: document.createElement('div')
}); });
instance.$on('input', value => { instance.$on('input', value => {
instance.value = value; instance.value = value;
}) });
instance.callback = defaultCallback;
document.body.appendChild(instance.$el);
}; };
const showNextDialog = () => { const Dialog = options => {
if (!instance) { return new Promise((resolve, reject) => {
initInstance(); if (!instance) {
} initInstance();
/* istanbul ignore else */
if (!instance.value && dialogQueue.length > 0) {
currentDialog = dialogQueue.shift();
const { options } = currentDialog;
for (const prop in options) {
/* istanbul ignore else */
if (options.hasOwnProperty(prop)) {
instance[prop] = options[prop];
}
} }
instance.callback = options.callback || defaultCallback; Object.assign(instance, {
instance.value = true; resolve,
document.body.appendChild(instance.$el); reject,
} ...options
};
const DialogBox = options => {
return new Promise((resolve, reject) => { // eslint-disable-line
dialogQueue.push({
options: { ...options },
callback: options.callback,
resolve: resolve,
reject: reject
}); });
showNextDialog();
}); });
}; };
DialogBox.alert = function(options) { Dialog.alert = options => Dialog({
return DialogBox({ ...defaultConfig,
type: 'alert', ...options
title: '', });
message: '',
closeOnClickOverlay: false,
showCancelButton: false,
...options
});
};
DialogBox.confirm = function(options) { Dialog.confirm = options => Dialog({
return DialogBox({ ...defaultConfig,
type: 'confirm', showCancelButton: true,
title: '', ...options
message: '', });
closeOnClickOverlay: true,
showCancelButton: true,
...options
});
};
DialogBox.close = function() { Dialog.close = () => {
instance.value = false; instance.value = false;
dialogQueue = [];
currentDialog = null;
}; };
export default DialogBox; export default Dialog;
export {
Dialog
};

View File

@ -48,15 +48,15 @@
<script> <script>
const VALID_TYPES = ['text', 'number', 'email', 'url', 'tel', 'date', 'time', 'datetime', 'password', 'textarea']; const VALID_TYPES = ['text', 'number', 'email', 'url', 'tel', 'date', 'time', 'datetime', 'password', 'textarea'];
import vanCell from '../cell'; import Cell from '../cell';
import vanIcon from '../icon'; import Icon from '../icon';
export default { export default {
name: 'van-field', name: 'van-field',
components: { components: {
vanCell, [Cell.name]: Cell,
vanIcon [Icon.name]: Icon
}, },
props: { props: {

View File

@ -13,8 +13,8 @@
<script> <script>
import Vue from 'vue'; import Vue from 'vue';
import Popup from '../mixins/popup'; import Popup from '../mixins/popup';
import VanSwipe from '../swipe'; import Swipe from '../swipe';
import VanSwipeItem from '../swipe-item'; import SwipeItem from '../swipe-item';
export default { export default {
name: 'van-image-preview', name: 'van-image-preview',
@ -22,8 +22,8 @@ export default {
mixins: [Popup], mixins: [Popup],
components: { components: {
VanSwipe, [Swipe.name]: Swipe,
VanSwipeItem [SwipeItem.name]: SwipeItem
}, },
props: { props: {

View File

@ -1,12 +1,13 @@
<template> <template>
<div class="van-loading" :class="['van-loading--' + type]"> <div :class="['van-loading', 'van-loading--' + type]">
<span class="van-loading__spinner" :class="['van-loading__spinner--' + type, 'van-loading__spinner--' + color]"></span> <span :class="['van-loading__spinner', 'van-loading__spinner--' + type, 'van-loading__spinner--' + color]"></span>
</div> </div>
</template> </template>
<script> <script>
const VALID_TYPES = ['gradient-circle', 'circle']; const VALID_TYPES = ['gradient-circle', 'circle'];
const VALID_COLORS = ['black', 'white']; const VALID_COLORS = ['black', 'white'];
export default { export default {
name: 'van-loading', name: 'van-loading',
@ -14,16 +15,12 @@ export default {
type: { type: {
type: String, type: String,
default: 'gradient-circle', default: 'gradient-circle',
validator(value) { validator: value => VALID_TYPES.indexOf(value) > -1
return VALID_TYPES.indexOf(value) > -1;
}
}, },
color: { color: {
type: String, type: String,
default: 'black', default: 'black',
validator(value) { validator: value => VALID_COLORS.indexOf(value) > -1
return VALID_COLORS.indexOf(value) > -1;
}
} }
} }
}; };

View File

@ -138,7 +138,7 @@ export default {
if (this.preventScroll) { if (this.preventScroll) {
document.addEventListener('touchstart', this.recordPosition, false); document.addEventListener('touchstart', this.recordPosition, false);
document.addEventListener('touchmove', this.watchTouchMove, false); document.addEventListener('touchmove', this.watchTouchMove, false);
} }
}, },

View File

@ -82,7 +82,7 @@ const PopupManager = {
let domParentNode; let domParentNode;
if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) { if (dom && dom.parentNode && dom.parentNode.nodeType !== 11) {
domParentNode = dom.parentNode domParentNode = dom.parentNode;
} else { } else {
domParentNode = document.body; domParentNode = document.body;
} }

View File

@ -8,7 +8,7 @@
</slot> </slot>
</div> </div>
<div class="van-picker__columns" :class="['van-picker__columns--' + columns.length]"> <div class="van-picker__columns" :class="['van-picker__columns--' + columns.length]">
<picker-column <van-picker-column
v-for="(item, index) in columns" v-for="(item, index) in columns"
:key="index" :key="index"
v-model="values[index]" v-model="values[index]"
@ -17,8 +17,8 @@
:itemHeight="itemHeight" :itemHeight="itemHeight"
:visible-item-count="visibileColumnCount" :visible-item-count="visibileColumnCount"
:value-key="valueKey" :value-key="valueKey"
@columnChange="columnValueChange(index)"> @columnChange="columnValueChange(index)"
</picker-column> />
<div class="van-picker-center-highlight" :style="{ height: itemHeight + 'px', marginTop: -itemHeight / 2 + 'px' }"></div> <div class="van-picker-center-highlight" :style="{ height: itemHeight + 'px', marginTop: -itemHeight / 2 + 'px' }"></div>
</div> </div>
</div> </div>
@ -33,7 +33,7 @@ export default {
name: 'van-picker', name: 'van-picker',
components: { components: {
PickerColumn [PickerColumn.name]: PickerColumn
}, },
props: { props: {

View File

@ -20,14 +20,14 @@
</template> </template>
<script> <script>
import VanIcon from '../icon'; import Icon from '../icon';
import Clickoutside from '../utils/clickoutside'; import Clickoutside from '../utils/clickoutside';
export default { export default {
name: 'van-search', name: 'van-search',
components: { components: {
VanIcon [Icon.name]: Icon
}, },
props: { props: {

View File

@ -30,7 +30,7 @@ export default {
name: 'van-steps', name: 'van-steps',
components: { components: {
'van-icon': Icon [Icon.name]: Icon
}, },
props: { props: {

View File

@ -13,9 +13,9 @@ export default {
}, },
destroyed() { destroyed() {
const index = this.$parent.swipes.indexOf(this) const index = this.$parent.swipes.indexOf(this);
if (index > -1) { if (index > -1) {
this.$parent.swipes.splice(index, 1) this.$parent.swipes.splice(index, 1);
} }
} }
}; };

View File

@ -61,27 +61,27 @@ export default {
}).on('autoPlay', function(dist, isEnd) { }).on('autoPlay', function(dist, isEnd) {
scroll.movePage(dist.x, isEnd); scroll.movePage(dist.x, isEnd);
}); });
this.dummy = dummy this.dummy = dummy;
}, },
watch: { watch: {
swipes(value) { swipes(value) {
if (this.autoPlay && value.length > 1) { if (this.autoPlay && value.length > 1) {
this.dummy.initMove() this.dummy.initMove();
} else { } else {
this.dummy.clearMove() this.dummy.clearMove();
} }
this.scroll.update(); this.scroll.update();
return value return value;
}, },
autoPlay(value) { autoPlay(value) {
if (value && this.swipes.length > 1) { if (value && this.swipes.length > 1) {
this.dummy.initMove() this.dummy.initMove();
} else { } else {
this.dummy.clearMove() this.dummy.clearMove();
} }
return value return value;
} }
}, },

View File

@ -8,22 +8,12 @@
</template> </template>
<script> <script>
import VanLoading from '../loading'; import Loading from '../loading';
/**
* van-switch
* @module components/switch
* @desc 开关
* @param {boolean} [value=false] - 开关状态
* @param {boolean} [disabled=false] - 禁用
* @param {boolean} [loading=false] - loading状态
*
* @example
* <van-switch :checked="true" :disabled="false"></van-switch>
*/
export default { export default {
name: 'van-switch', name: 'van-switch',
components: { components: {
'van-loading': VanLoading [Loading.name]: Loading
}, },
props: { props: {
value: Boolean, value: Boolean,

View File

@ -192,7 +192,7 @@
const translate = swipeState.startTranslateLeft + deltaX; const translate = swipeState.startTranslateLeft + deltaX;
/* istanbul ignore else */ /* istanbul ignore else */
if (translate > 0 || (translate * -1) > this.maxTranslate ) return; if (translate > 0 || (translate * -1) > this.maxTranslate) return;
translateUtil.translateElement(el, translate, null); translateUtil.translateElement(el, translate, null);
}, },
@ -200,7 +200,7 @@
end: () => { end: () => {
this.isSwiping = false; this.isSwiping = false;
} }
}) });
}, },
doOnValueChange() { doOnValueChange() {

View File

@ -12,9 +12,7 @@
props: { props: {
type: { type: {
type: String, type: String,
validator: function (val) { validator: val => ~ALLOW_TYPE.indexOf(val)
return ~ALLOW_TYPE.indexOf(val);
}
}, },
mark: Boolean, mark: Boolean,
plain: Boolean plain: Boolean

View File

@ -20,8 +20,8 @@
</template> </template>
<script> <script>
import vanLoading from '../loading'; import Icon from '../icon';
import vanIcon from '../icon'; import Loading from '../loading';
const TOAST_TYPES = ['text', 'html', 'loading', 'success', 'fail']; const TOAST_TYPES = ['text', 'html', 'loading', 'success', 'fail'];
const DEFAULT_STYLE_LIST = ['success', 'fail']; const DEFAULT_STYLE_LIST = ['success', 'fail'];
@ -37,8 +37,8 @@ export default {
name: 'van-toast', name: 'van-toast',
components: { components: {
'van-loading': vanLoading, [Icon.name]: Icon,
'van-icon': vanIcon [Loading.name]: Loading
}, },
props: { props: {
type: { type: {

View File

@ -11,7 +11,6 @@
font-size: 16px; font-size: 16px;
text-align: center; text-align: center;
outline: 0; outline: 0;
overflow: hidden;
-webkit-appearance: none; -webkit-appearance: none;
&::after { &::after {

View File

@ -42,9 +42,10 @@
overflow: hidden; overflow: hidden;
&.is-twobtn { &.is-twobtn {
display: flex;
.van-button { .van-button {
width: 50%; flex: 1;
float: left;
} }
.van-dialog__cancel { .van-dialog__cancel {
@ -63,7 +64,10 @@
} }
&__confirm { &__confirm {
color: #00C000; &,
&:active {
color: #00C000;
}
} }
&-bounce-enter { &-bounce-enter {

View File

@ -1,5 +1,8 @@
require('packages/vant-css/src/index.css'); require('packages/vant-css/src/index.css');
// hack for test touch event
window.ontouchstart = {};
// 读取配置文件,判断运行单个测试文件还是所有测试文件 // 读取配置文件,判断运行单个测试文件还是所有测试文件
const testsReq = require.context('./specs', true, /\.spec$/); const testsReq = require.context('./specs', true, /\.spec$/);
if (process.env.TEST_FILE) { if (process.env.TEST_FILE) {

View File

@ -1,5 +1,20 @@
import DatetimePicker from 'packages/datetime-picker'; import DatetimePicker from 'packages/datetime-picker';
import { mount } from 'avoriaz'; import { mount } from 'avoriaz';
import { triggerTouch } from '../utils';
const dragHelper = (el, position) => {
triggerTouch(el, 'touchstart', 0, 0);
triggerTouch(el, 'touchmove', 0, position / 4);
triggerTouch(el, 'touchmove', 0, position / 3);
triggerTouch(el, 'touchmove', 0, position / 2);
triggerTouch(el, 'touchmove', 0, position);
triggerTouch(el, 'touchend', 0, position);
};
const testTime = '10:00';
const testDate = new Date('2017/03/10 10:00');
const minDate = new Date('2000/01/01 00:00');
const maxDate = new Date('3000/01/01 00:00');
describe('DatetimePicker', () => { describe('DatetimePicker', () => {
let wrapper; let wrapper;
@ -7,36 +22,117 @@ describe('DatetimePicker', () => {
wrapper && wrapper.destroy(); wrapper && wrapper.destroy();
}); });
it('create a datetime picker', () => { it('create a time picker', () => {
const date = new Date();
wrapper = mount(DatetimePicker, { wrapper = mount(DatetimePicker, {
attachToDocument: true,
propsData: { propsData: {
type: 'datetime', type: 'time',
value: date value: testTime
} }
}); });
expect(wrapper.data().innerValue.getTime()).to.equal(date.getTime()); expect(wrapper.vm.innerValue).to.equal(testTime);
}); });
it('create a date picker', () => { it('create a date picker', () => {
const date = new Date();
wrapper = mount(DatetimePicker, { wrapper = mount(DatetimePicker, {
attachToDocument: true,
propsData: { propsData: {
type: 'date', type: 'date',
value: date value: testDate
} }
}); });
expect(wrapper.data().innerValue.getTime()).to.equal(date.getTime()); expect(wrapper.vm.innerValue.getTime()).to.equal(testDate.getTime());
}); });
it('create a time picker', () => { it('create a datetime picker', () => {
const time = '10:00';
wrapper = mount(DatetimePicker, { wrapper = mount(DatetimePicker, {
attachToDocument: true,
propsData: { propsData: {
type: 'time', type: 'datetime',
value: time value: testDate
} }
}); });
expect(wrapper.data().innerValue).to.equal(time); expect(wrapper.vm.innerValue.getTime()).to.equal(testDate.getTime());
});
it('drag time picker', (done) => {
wrapper = mount(DatetimePicker, {
attachToDocument: true,
propsData: {
type: 'time',
value: testTime
}
});
const [hour, minute] = wrapper.find('.van-picker-column-wrapper');
dragHelper(hour, -50);
dragHelper(minute, -50);
setTimeout(() => {
expect(wrapper.vm.innerValue).to.equal('5:05');
done();
}, 10);
});
it('drag date picker', (done) => {
wrapper = mount(DatetimePicker, {
attachToDocument: true,
propsData: {
type: 'date',
value: testDate,
minDate,
maxDate
}
});
setTimeout(() => {
const [year, month, day] = wrapper.find('.van-picker-column-wrapper');
dragHelper(year, -50);
dragHelper(month, -50);
dragHelper(day, -50);
setTimeout(() => {
const newYear = wrapper.vm.innerValue.getFullYear();
const newMonth = wrapper.vm.innerValue.getMonth() + 1;
const newDay = wrapper.vm.innerValue.getDate();
expect(newYear).to.equal(2022);
expect(newMonth).to.equal(8);
expect(newDay).to.equal(15);
done();
}, 10);
}, 10);
});
it('drag datetime picker', (done) => {
wrapper = mount(DatetimePicker, {
attachToDocument: true,
propsData: {
type: 'datetime',
value: testDate,
minDate,
maxDate
}
});
setTimeout(() => {
const [year, month, day, hour, minute] = wrapper.find('.van-picker-column-wrapper');
dragHelper(year, -50);
dragHelper(month, -50);
dragHelper(day, -50);
dragHelper(hour, -50);
dragHelper(minute, -50);
setTimeout(() => {
const newYear = wrapper.vm.innerValue.getFullYear();
const newMonth = wrapper.vm.innerValue.getMonth() + 1;
const newDay = wrapper.vm.innerValue.getDate();
const newHour = wrapper.vm.innerValue.getHours();
const newMinute = wrapper.vm.innerValue.getMinutes();
expect(newYear).to.equal(2022);
expect(newMonth).to.equal(8);
expect(newDay).to.equal(15);
expect(newHour).to.equal(15);
expect(newMinute).to.equal(5);
done();
}, 10);
}, 10);
}); });
}); });

View File

@ -3,11 +3,6 @@ import Vue from 'vue';
describe('Dialog', () => { describe('Dialog', () => {
afterEach(() => { afterEach(() => {
const el = document.querySelector('.van-dialog');
if (!el) return;
if (el.parentNode) {
el.parentNode.removeChild(el);
}
Dialog.close(); Dialog.close();
}); });
@ -28,30 +23,32 @@ describe('Dialog', () => {
}, 500); }, 500);
}); });
it('create a confirm dialog', () => { it('create a confirm dialog', (done) => {
Dialog.confirm({ Dialog.confirm({
title: 'title', title: 'title',
message: 'message' message: 'message'
}).catch((action) => {
expect(action).to.equal('cancel');
done();
}); });
expect(document.querySelector('.van-dialog')).to.exist; expect(document.querySelector('.van-dialog')).to.exist;
setTimeout(() => {
document.querySelector('.van-dialog__cancel').click();
}, 500);
}); });
it('create a confirm dialog with callback', (done) => { it('create a confirm dialog with callback', (done) => {
let dialogAction;
Dialog.confirm({ Dialog.confirm({
title: 'title',
message: 'message',
callback: (action) => { callback: (action) => {
dialogAction = action; expect(action).to.equal('cancel');
done();
} }
}); });
expect(document.querySelector('.van-dialog')).to.exist;
setTimeout(() => { setTimeout(() => {
document.querySelector('.van-dialog__cancel').click(); document.querySelector('.van-dialog__cancel').click();
expect(dialogAction).to.equal('cancel');
done();
}, 500); }, 500);
}); });
}); });

View File

@ -62,7 +62,7 @@ export function triggerTouch(wrapper, eventName, x, y) {
radiusX: 2.5, radiusX: 2.5,
radiusY: 2.5, radiusY: 2.5,
rotationAngle: 10, rotationAngle: 10,
force: 0.5, force: 0.5
}; };
const event = document.createEvent('CustomEvent'); const event = document.createEvent('CustomEvent');