Iview was released in version 3.0.0 on July 28 this year, and big upgrades often mean big changes in functionality and interfaces. Although the official website has a long update log, it still seems a bit abstract, so I decided to do a comparison between the old version and the new one and see what features the new version brings to the table.

This article to explain to you, is a very commonly used component – Button

Look at the conclusion

New Button has the following new features:

  1. Supports link mode, which can be configuredtoAttribute to start the
  2. To support independentghostAttributes that are stylistically compatible with otherstypeValue of the compound
  3. Support custom ICONS, please refer to “IView 3.x Upgrade Inventory — Icon”.

Button upgrade is relatively smooth, two points need to be noted:

  1. The new version does not support ittype="ghost", but can be used independentlyghostProperty, so before upgrading, global search is recommendedtype="ghost"The call
  2. Old and newdefaultIt’s a little bit different

Support link mode

Older versions of the Button component simply wrapped a Button label. Button adds a key attribute: TO — Normally, components are rendered as Button tags; If to has a value, the component is rendered as an A tag.

This breaks the semantics of a Button, but it’s handy. In the past, to apply a Button style to a tag, you would have to write class:

<! -- Normal A tag -->
<a class="ivu-btn ivu-btn-primary" href="/foo/bar">This is an A link</a>
<! -- router-link -->
<router-link class="ivu-btn ivu-btn-primary" to="/foo/bar">This is a router-link</router-link>
Copy the code

Although you can reuse Button styles, you lose Button behavior, such as loading, icon, etc. This is no longer a problem with the new version of link mode. The same logic can be written as:

<Button type="primary" to="/foo/bar">Here's a link</Button>
<! -- Final render as -->
<a class="ivu-btn ivu-btn-primary" href="/foo/bar">Here's a link</a>
Copy the code

The value of to attribute can be string or object. Iview preferentially uses vue-Router functions to handle link jumps. If there is no vue-router in the application environment, it degrades to the normal window.location.href = this.to; The call. In addition to to, Button also adds replace and target attributes to supplement the definition of links. The replace attribute has the same semantics as the replace attribute of router-link. The target attribute is the same as the target attribute of the A tag.

In general, in link mode, you can think of Button as a neutered version of a router-link component.

independentghostattribute

The ghost button was once the subject of much discussion, but is now a fairly common design. This design specifies that the background color of the Button must be transparent. There is no font or border style, but older versions of the Button only support ghost in a grey tone:

The new version has made great improvements in this respect, ghost style as an independent class, with other type type as the button font, border color supplement, complement each other, you can see the iView official website provided examples:

Ghost buttons with multiple color values can really improve usability. Once the 1. X version of ANTD also ghost as a type of view, to the 2. X version is also taken out as an independent feature, iView this improvement, it seems that there is a basis, follow the trend.

Unfortunately, iView has also changed the default style, which should be noted by teams with high design requirements:

The problem

All right, features and changes are out of the way, and finally, let’s look at the code. The new Button only has 116 lines of code, but it has a lot to offer:

1. Repeat code

The new Button template looks like this:

<template>
    <a
        v-if="to"
        .>
        <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>
    </a>
    <button
        v-else
        .>
        <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>
Copy the code

Oh, a is exactly the same as button’s wrapped content block. In fact, this piece of code can be isolated into a separate component, reducing duplication.

In addition, the definition of size is also awkward:

. exportdefault{... props: { ... size: { validator (value) {return oneOf(value, ['small'.'large'.'default']);
                },
                default () {
                    return this.$IVIEW.size === ' ' ? 'default' : this.$IVIEW.size; }}... },... };Copy the code

There is nothing wrong with a single component, but you can find 16 identical codes in the code, respectively: AutoComplete, Avatar, ButtonGroup, Cascader, CheckboxGroup, Checkbox, ColorPicker, Picker, InputNumber, Input, RadioGroup, Radio, Se Lect, Spin, Switch, Table… This one can be a mixin, which is a bit of a low grade mistake.

2. Event handling

Older versions of Button simply wrapped the Button tag, so its event handling was very simple. Now that the new version is compatible with link mode, it looks a bit convoluted:

<template>
    <! LinkUrl is an attribute mixed with mixinsLink -->
    <a :href="linkUrl"
        @click.exact="handleClickLink($event, false)"
        @click.ctrl="handleClickLink($event, true)"
        @click.meta="handleClickLink($event, true)">.</a>
    <button . @click="handleClickLink">.</button>
</template>
<script>. exportdefault {
        mixins: [ mixinsLink ],
        ...
        methods: {
            handleClickLink (event, new_window = false) {
                this.$emit('click', event);
                // handleCheckClick is a property mixed in from mixinsLink
                this.handleCheckClick(event, new_window); }}... };</script>
Copy the code

The handleClickLink is bound three times with exact, CTRL and meta modifiers respectively. It is used to simulate the clicking effect of normal A tags. Why not use ctrlKey and metaKey attributes of $Event object? I took a close look at mixinsLink’s code, but unfortunately it was too uneducated to draw reliable conclusions. I did a simple demo to compare the effects of various implementations, but I didn’t see why.

Another problem is the new_window variable. All the other variable names are humped, so it’s a bit awkward to suddenly have an underscore.

3. Expired ghost value

Last but not least, type=”ghost” is now out of date, and the source validator has been modified accordingly.

This error message, a little hard? This could have been done with a deprecated warning, and it would have been easier for the upgrader to figure out what changes to make.

Appendix:

  1. Iview upgrade guide — Icon
  2. Iview upgrade guide – Button