This is the 20th day of my participation in the August More Text Challenge

0 x00 profile

A component Button marks (or encapsulates) an action command that triggers the corresponding business logic in response to a user click. This article will in-depth analysis of the source code, analysis of its implementation principle, patience to read, I believe will help you. Source code implementation see packages/button/ SRC/folder under button.vue, button-group.vue and other components. πŸ”— component document Breadcrumb πŸ”— gitee source code

For more component profiling see πŸ‘‰ πŸ“š Element 2 source profiling Component Overview.


Button component has two parts < button >, < button – group >, component source code is in the packages/button/SRC/folder. Under the project engineering mechanism, each component corresponds to its own folder component-name, defines exported components and extends the install method for them. Each component is built in a separate package based on the CommonJS2 specification, supporting on-demand import.

0x01 button-Group Button group

The button-group.vue component is the container that wraps the button button. The

component creates a

element container with class name el-button-group and provides anonymous slots for distributing content for the Button component to use.

<template>
  <div class="el-button-group">
    <slot></slot>
  </div>
</template>
<script>
  export default {
    name: 'ElButtonGroup'
  };
</script>
Copy the code

0 x02 button component

Template Template content

Component creates a native button element with class name el-button, which consists of loading icon, icon icon, and custom button text.

<template>
  <button
    class="el-button"
    @click="handleClick"
    :disabled="buttonDisabled || loading"
    :autofocus="autofocus"
    :type="nativeType"
    :class="[ type ? 'el-button--' + type : '', buttonSize ? 'el-button--' + buttonSize : '', { 'is-disabled': buttonDisabled, 'is-loading': loading, 'is-plain': plain, 'is-round': round, 'is-circle': circle } ]"
  >
    <i class="el-icon-loading" v-if="loading"></i>
    <i :class="icon" v-if="icon && ! loading"></i>
    <span v-if="$slots.default"><slot></slot></span>
  </button>
</template>
Copy the code

buttonElement root node

  • Listen for the click event, bound to the handleClick callback.

  • The disabled state is determined by calculating the value of the buttonDisabled and button loading state properties.

  • Use the autofocus attribute value to set whether the button has an input focus when the page loads.

  • Native Button type Settings. Button/submit/reset:

    • submit: This button submits form data to the server. This value is the default if no property is specified or if the property is dynamically changed to a null or invalid value.
    • reset: This button resets all components to their original values.
    • button: This button has no default behavior. It can have client-side scripts associated with element events that fire when they occur.
  • Dynamically add styles:

    • According to thetypeAttribute value adds type styleel-button--[primary/success/warning/danger/info/text].
    • According to the calculated propertiesbuttonSizeAdd size stylesel-button--[medium/small/mini] .
    • According to the calculated propertiesbuttonDisabledAnd the proploading,plain 、round 、circleAnd other properties, Settingsis-disabledButton disabled state,is-loadingButton loading state,is-plainPlain button,is-roundRounded button,is-circleCircular button.

Inner element node

  • Loading iconIf:loadingAttribute values fortrue, the button is loaded state. Render a usage nameel-icon-loadingIcon Icon.
  • Icon iconIf:iconProperty sets the icon class name (truthy), and the button is not loaded, render the class name icon.
  • Custom button text: provides anonymous slots<span>Element that is rendered only when the content is distributedv-if="$slots.default".

Set Button properties to generate different Button styles. The recommended order is type -> plain -> round/circle -> size -> Loading -> disabled.

The attributes property

Component prop is defined as follows:

props: {
  type: {
    type: String.default: 'default'
  },
  size: String.icon: {
    type: String.default: ' '
  },
  nativeType: {
    type: String.default: 'button'
  },
  loading: Boolean.disabled: Boolean.plain: Boolean.autofocus: Boolean.round: Boolean.circle: Boolean
},
Copy the code
parameter instructions type An optional value The default value
size size string medium / small / mini
type type string primary / success / warning / danger / info / text
plain Plain button or not boolean false
round Rounded button or not boolean false
circle Circular button or not boolean false
loading Loading status boolean false
disabled Disabled or not boolean false
icon Icon in the name of the class string
autofocus Default focus boolean false
native-type Native Type attribute string button / submit / reset button

Click event

Listen for the component’s click event. When the click triggers the click event, execute the handleClick(evt) method and call this.$emit(‘click’, evt); Trigger the click event on the current instance.

methods: {
  handleClick(evt) {
    // Triggers events on the current instance
    this.$emit('click', evt); }}Copy the code

Calculate attribute

buttonSize

Get the size of the button based on the size attribute, the FormItem calculation attribute elFormItemSize when using the Form Form, and the global attribute this.$element. size when testing the component.

Receive a FormItem instance using the Dependency injection Inject option to get its calculated attribute elFormItemSize.

/ / form - item component
inject: {
  elFormItem: {
    default: ' '}},computed: {
  _elFormItemSize() {
    return (this.elFormItem || {}).elFormItemSize;
  },
  buttonSize() {
    return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size; }},Copy the code

Similarly, the Form-item component uses the Inject option to receive the Form instance, which is used to calculate the element size elFormItemSize, as calculated by the form-item and form’s respective size attribute values.

// packages\form\src\form-item.vue
provide() {
  return {
    elFormItem: this
  };
}, 
inject: ['elForm'].props: { 
  size: String
}, 
computed: { 
  _formSize() {
    return this.elForm.size;
  },
  elFormItemSize() {
    return this.size || this._formSize; }},// packages\form\src\form.vue 
provide() {
  return {
    elForm: this
  };
},

props: { 
  size: String,},Copy the code

buttonDisabled

Used to determine the disabled status of the button, according to the disabled attribute, the Form of the disabled attribute to determine.

inject: {
  elForm: {
    default: ' '}},computed: {
  buttonDisabled() {
    return this.disabled || (this.elForm || {}).disabled; }},Copy the code

Use the Inject option to receive the Form component instance and get its Prop Disabled property.

// packages\form\src\form.vue
provide() {
  return {
    elForm: this
  };
},

props: { 
  disabled: Boolean,},Copy the code

0 x03 πŸ“š reference

“button”,MDN

“依衖注ε…₯”,vuejs.org

0x04 Attention column

This article has been included in the column πŸ‘‡, you can directly follow.