Merge pull request #4228 from VanMess/better-button

Better button
This commit is contained in:
Aresn 2018-11-02 10:25:47 +08:00 committed by GitHub
commit a25314e846
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 90 additions and 22 deletions

View file

@ -1,27 +1,9 @@
<template> <template>
<a <component :is="tagName" :class="classes" :disabled="disabled" @click="handleClickLink" v-bind="tagProps">
v-if="to"
:class="classes"
:disabled="disabled"
:href="linkUrl"
:target="target"
@click.exact="handleClickLink($event, false)"
@click.ctrl="handleClickLink($event, true)"
@click.meta="handleClickLink($event, true)">
<Icon class="ivu-load-loop" type="ios-loading" v-if="loading"></Icon> <Icon class="ivu-load-loop" type="ios-loading" v-if="loading"></Icon>
<Icon :type="icon" :custom="customIcon" v-if="(icon || customIcon) && !loading"></Icon> <Icon :type="icon" :custom="customIcon" v-if="(icon || customIcon) && !loading"></Icon>
<span v-if="showSlot" ref="slot"><slot></slot></span> <span v-if="showSlot" ref="slot"><slot></slot></span>
</a> </component>
<button
v-else
:type="htmlType"
:class="classes"
:disabled="disabled"
@click="handleClickLink">
<Icon class="ivu-load-loop" type="ios-loading" v-if="loading"></Icon>
<Icon :type="icon" :custom="customIcon" v-if="(icon || customIcon) && !loading"></Icon>
<span v-if="showSlot" ref="slot"><slot></slot></span>
</button>
</template> </template>
<script> <script>
import Icon from '../icon'; import Icon from '../icon';
@ -98,14 +80,34 @@
[`${prefixCls}-ghost`]: this.ghost [`${prefixCls}-ghost`]: this.ghost
} }
]; ];
},
// Point out if it should render as <a> tag
isHrefPattern() {
const {to} = this;
return !!to;
},
tagName() {
const {isHrefPattern} = this;
return isHrefPattern ? 'a' : 'button';
},
tagProps() {
const {isHrefPattern} = this;
if(isHrefPattern) {
const {linkUrl,target}=this;
return {href: linkUrl, target};
} else {
const {htmlType} = this;
return {type: htmlType};
}
} }
}, },
methods: { methods: {
// Ctrl or CMD and click, open in new window when use `to` // Ctrl or CMD and click, open in new window when use `to`
handleClickLink (event, new_window = false) { handleClickLink (event) {
this.$emit('click', event); this.$emit('click', event);
const openInNewWindow = event.ctrlKey || event.metaKey;
this.handleCheckClick(event, new_window); this.handleCheckClick(event, openInNewWindow);
} }
}, },
mounted () { mounted () {

View file

@ -0,0 +1,66 @@
import { createVue, destroyVM } from '../util';
describe('Button.vue', () => {
let vm;
afterEach(() => {
destroyVM(vm);
});
it('should render as <a>', done => {
vm = createVue(`
<Button to="http://www.thinkinfe.tech/">Think in FE</Button>
`);
expect(vm.$el.tagName).to.equal('A');
done();
});
it('should render as <button>', done => {
vm = createVue(`
<Button>Think in FE</Button>
`);
expect(vm.$el.tagName).to.equal('BUTTON');
done();
});
it('handle with `type` attribute', done => {
// should render with `type` attribute
// if it is a <button>
vm = createVue(`
<Button htmlType="reset">Think in FE</Button>
`);
expect(vm.$el.getAttribute('type')).to.equal('reset');
// should't render with `type` attribute
// if it is a <button>
vm = createVue(`
<Button to="http://www.thinkinfe.tech/" htmlType="reset">Think in FE</Button>
`);
expect(vm.$el.getAttribute('type')).to.equal(null);
done();
});
it('should change loading state', done => {
vm = createVue({
template: `
<Button :loading="loading" @click="fetch">Think in FE</Button>
`,
data() {
return {loading: false};
},
methods: {
fetch() {
this.loading = true;
}
}
});
vm.$el.click();
vm.$nextTick(() => {
expect(vm.$el.classList.contains('ivu-btn-loading')).to.equal(true);
const $icons = vm.$el.querySelectorAll('.ivu-icon');
expect($icons.length).to.equal(1);
expect($icons[0].classList.contains('ivu-load-loop')).to.equal(true);
expect($icons[0].classList.contains('ivu-icon-ios-loading')).to.equal(true);
done();
});
});
});