actionsheet code review

This commit is contained in:
陈嘉涵 2017-08-17 14:08:21 +08:00
parent 4a55f341ab
commit 2ba123ed93
4 changed files with 111 additions and 81 deletions

View File

@ -1,40 +1,35 @@
<template> <template>
<transition name="actionsheet-float"> <transition name="van-actionsheet-float">
<div class="van-actionsheet" :class="{ 'van-actionsheet--withtitle': title }" v-show="currentValue"> <div :class="['van-actionsheet', { 'van-actionsheet--withtitle': title }]" v-show="value">
<div class="van-actionsheet__header" v-if="title"> <div class="van-actionsheet__header" v-if="title">
<h3 v-text="title"></h3> <h3 v-text="title" />
<van-icon name="close" @click.stop="currentValue = false"></van-icon> <van-icon name="close" @click.stop="$emit('input', false)" />
</div>
<ul v-if="!title" class="van-actionsheet__list">
<li
v-for="(item, index) in actions"
:key="index"
:class="['van-actionsheet__item', item.className, { 'van-actionsheet__item--loading': item.loading }]"
@click.stop="handleItemClick(item)">
<template v-if="!item.loading">
<span class="van-actionsheet__name">{{ item.name }}</span>
<span class="van-actionsheet__subname" v-if="item.subname">{{ item.subname }}</span>
</template>
<van-loading v-else class="van-actionsheet__loading" type="circle" color="black" />
</li>
</ul>
<div class="van-actionsheet__item van-actionsheet__cancel" @click.stop="$emit('input', false)" v-if="cancelText">{{ cancelText }}</div>
<div class="van-actionsheet__content" v-else>
<slot></slot>
</div> </div>
<template v-if="!title">
<ul class="van-actionsheet__list">
<li
v-for="(item, index) in actions"
:key="index"
class="van-actionsheet__item"
:class="[item.className, item.loading ? 'van-actionsheet__item--loading' : '']"
@click.stop="handleItemClick(item)">
<template v-if="!item.loading">
<span class="van-actionsheet__name">{{ item.name }}</span>
<span class="van-actionsheet__subname" v-if="item.subname">{{ item.subname }}</span>
</template>
<van-loading v-else class="van-actionsheet__loading" type="circle" color="black" />
</li>
</ul>
<a class="van-actionsheet__button" @click.stop="currentValue = false" v-if="cancelText">{{ cancelText }}</a>
</template>
<template v-else>
<div class="van-actionsheet__content">
<slot></slot>
</div>
</template>
</div> </div>
</transition> </transition>
</template> </template>
<script> <script>
import Popup from '../../mixins/popup'; import Popup from '../../mixins/popup';
import VanLoading from '../../loading';
import VanIcon from '../../icon'; import VanIcon from '../../icon';
import VanLoading from '../../loading';
export default { export default {
name: 'van-actionsheet', name: 'van-actionsheet',
@ -42,12 +37,12 @@ export default {
mixins: [Popup], mixins: [Popup],
components: { components: {
VanLoading, [VanIcon.name]: VanIcon,
VanIcon [VanLoading.name]: VanLoading
}, },
props: { props: {
value: {}, value: Boolean,
actions: { actions: {
type: Array, type: Array,
default: () => [] default: () => []
@ -64,32 +59,13 @@ export default {
} }
}, },
data() {
return {
currentValue: this.value
};
},
watch: {
currentValue(val) {
this.$emit('input', val);
},
value(val) {
this.currentValue = val;
}
},
mounted() { mounted() {
if (this.value) { this.value && this.open();
this.currentValue = true;
this.open();
}
}, },
methods: { methods: {
handleItemClick(item) { handleItemClick(item) {
if (item.callback && typeof item.callback === 'function') { if (typeof item.callback === 'function') {
item.callback(item); item.callback(item);
} }
} }

View File

@ -4,26 +4,23 @@
.van-actionsheet { .van-actionsheet {
position: fixed; position: fixed;
width: 100%; left: 0;
top: auto; right: 0;
bottom: 0; bottom: 0;
right: auto; color: $c-black;
left: 50%;
transform: translate3d(-50%, 0, 0);
backface-visibility: hidden;
transition: .2s ease-out; transition: .2s ease-out;
background-color: #e0e0e0; background-color: #e0e0e0;
backface-visibility: hidden;
&--withtitle { &--withtitle {
background-color: $c-white; background-color: $c-white;
} }
&__item { &__item {
line-height: 50px;
height: 50px; height: 50px;
text-align: center; line-height: 50px;
color: $c-black;
font-size: 16px; font-size: 16px;
text-align: center;
position: relative; position: relative;
background-color: $c-white; background-color: $c-white;
@ -33,28 +30,20 @@
} }
&__subname { &__subname {
color: $c-gray-darker;
font-size: 12px; font-size: 12px;
color: $c-gray-darker;
} }
&__loading { &__loading {
margin: 0 auto;
display: inline-block; display: inline-block;
} }
&__button { &__cancel {
display: block;
margin-top: 5px; margin-top: 5px;
line-height: 50px;
color: $c-black;
font-size: 16px;
text-align: center;
background-color: $c-white;
} }
&__header { &__header {
line-height: 44px; line-height: 44px;
color: $c-black;
text-align: center; text-align: center;
position: relative; position: relative;
@ -63,16 +52,16 @@
} }
.van-icon-close { .van-icon-close {
top: 11px;
right: 15px;
position: absolute; position: absolute;
font-size: 22px; font-size: 22px;
line-height: 22px; line-height: 22px;
top: 11px;
right: 15px;
} }
} }
}
.actionsheet-float-enter, &-float-enter,
.actionsheet-float-leave-active { &-float-leave-active {
transform: translate3d(-50%, 100%, 0); transform: translate3d(0, 100%, 0);
}
} }

View File

@ -1,5 +1,6 @@
import ActionSheet from 'packages/actionsheet'; import ActionSheet from 'packages/actionsheet';
import { mount } from 'avoriaz'; import { mount } from 'avoriaz';
import { DOMChecker } from '../utils';
describe('ActionSheet', () => { describe('ActionSheet', () => {
let wrapper; let wrapper;
@ -26,7 +27,13 @@ describe('ActionSheet', () => {
} }
}); });
expect(wrapper.instance().currentValue).to.be.true; DOMChecker(wrapper, {
noStyle: {
'.van-actionsheet': {
display: 'none'
}
}
});
}); });
it('create title type actionsheet', () => { it('create title type actionsheet', () => {
@ -98,8 +105,8 @@ describe('ActionSheet', () => {
} }
}); });
const cancelButton = wrapper.find('.van-actionsheet__button')[0]; const cancelButton = wrapper.find('.van-actionsheet__cancel')[0];
expect(wrapper.contains('.van-actionsheet__button')).to.be.true; expect(wrapper.contains('.van-actionsheet__cancel')).to.be.true;
expect(cancelButton.text()).to.equal('cancel'); expect(cancelButton.text()).to.equal('cancel');
}); });
@ -111,12 +118,24 @@ describe('ActionSheet', () => {
}); });
const eventStub = sinon.stub(wrapper.vm, '$emit'); const eventStub = sinon.stub(wrapper.vm, '$emit');
expect(wrapper.data().currentValue).to.be.false; DOMChecker(wrapper, {
style: {
'.van-actionsheet': {
display: 'none'
}
}
});
wrapper.vm.value = true; wrapper.vm.value = true;
wrapper.update(); wrapper.update();
wrapper.vm.$nextTick(() => { wrapper.vm.$nextTick(() => {
expect(wrapper.data().currentValue).to.be.true; DOMChecker(wrapper, {
noStyle: {
'.van-actionsheet': {
display: 'none'
}
}
});
expect(eventStub.calledWith('input')); expect(eventStub.calledWith('input'));
done(); done();
}); });

46
test/unit/utils.js Normal file
View File

@ -0,0 +1,46 @@
/**
* 按照一定的规则进行匹配
*/
export function DOMChecker(wrapper, rules) {
const { text, count, src, style, noStyle, value } = rules;
if (text) {
Object.keys(text).forEach(key => {
expect(wrapper.find(key)[0].text().trim()).to.equal(text[key]);
});
}
if (count) {
Object.keys(count).forEach(key => {
expect(wrapper.find(key).length).to.equal(count[key]);
});
}
if (src) {
Object.keys(src).forEach(key => {
expect(wrapper.find(key)[0].element.src).to.equal(src[key]);
});
}
if (value) {
Object.keys(value).forEach(key => {
expect(wrapper.find(key)[0].element.value).to.equal(value[key]);
});
}
if (style) {
Object.keys(style).forEach(key => {
Object.keys(style[key]).forEach(prop => {
expect(wrapper.find(key)[0].hasStyle(prop, style[key][prop])).to.equal(true);
});
});
}
if (noStyle) {
Object.keys(noStyle).forEach(key => {
Object.keys(noStyle[key]).forEach(prop => {
expect(wrapper.find(key)[0].hasStyle(prop, noStyle[key][prop])).to.equal(false);
});
});
}
}