preface

I’ve talked a lot about air-UI components, including multilingualism, theme customization, builds, and more. But in fact, a component library contains so many components, in the development of time, will inevitably encounter a lot of strange problems, this section on the development of these components, encountered some problems, and how to solve. (While much of the element-UI component logic is reused, there are other pitfalls.)

Compatible with JSX syntax

JSX syntax error:

const wrap = (
  <div
    ref="wrap"
    style={ style }
    onScroll={ this.handleScroll }
    class={[this.wrapClass, 'air-scrollbar__wrap', gutter? ' ': 'air-scrollbar__wrap--hidden-default']}
  >
    { [view] }
  </div>
);
Copy the code

Babelrc is not compatible with JSX, so the plugins should be added to the transform-vue-jsx array

"plugins": ["transform-runtime"."transform-vue-jsx"].Copy the code

Then install the corresponding dependency:

"babel-plugin-syntax-jsx": "^ 6.18.0"."babel-plugin-transform-vue-jsx": "^ 3.7.0".Copy the code

That will do.

Later, I found that the original VUE-CLI installation project configuration had JSX compatible syntax, but I removed it at that time, resulting in an error, so I added it again.

The Transition class cannot be triggered

There is also a curious case that the transition class has failed to trigger custom methods using the same code as element-UI in the collapse-transition component. I found many ways to solve the problem, and I do not know whether it is related to the vue version. Finally, I used another way to deal with it:

export default {
  name: 'AirCollapseTransition'.functional: true,
  render(h, { children }) {
    let transitionModel = new Transition();
    const data = {
      on: {
        beforeEnter: transitionModel.beforeEnter,
        enter: transitionModel.enter,
        afterEnter: transitionModel.afterEnter,
        beforeLeave: transitionModel.beforeLeave,
        leave: transitionModel.leave,
        afterLeave: transitionModel.afterLeave
      }
    };
    By zachke const data = {on: new Transition()}; by Zachke const data = {on: new Transition()}; * /
    return h('transition', data, children); }};Copy the code

A situation where CSS styles overwrite each other

There is a problem that SCSS in index. SCSS can not be arranged randomly. For example, if you put @import “./date-picker. SCSS “after @import “./cascader-panel. SCSS”, you will get CSS priority overwritten (the same goes for element-UI) :

This is because they all have @import “./scrollbar” CSS. If the data-picker was introduced later, it would cause the el-Scrollbar__warp to overwrite the el-Cascader-minu__wrap class again at the same level, causing the interface to fail:

So when writing SCSS, be careful about overwriting each other, because BEM rules usually have only one layer, and if this component is referenced by other components, priority overwriting can occur.

The inline – block

There was a very strange problem with the time-picker demo code that looked like this:

<template>
  <air-time-picker
    is-range
    v-model="value1"
    range-separator="To"
    start-placeholder="Start time"
    end-placeholder="End time"
    placeholder="Select time range">
  </air-time-picker>
  <air-time-picker
    is-range
    arrow-control
    v-model="value2"
    range-separator="To"
    start-placeholder="Start time"
    end-placeholder="End time"
    placeholder="Select time range">
  </air-time-picker></template>
<script>
  export default {
    data() {
      return {
        value1: [new Date(2016.9.10.8.40), new Date(2016.9.10.9.40)].value2: [new Date(2016.9.10.8.40), new Date(2016.9.10.9.40)]}}}</script>
Copy the code

Then CSS is set to 50% width each by default:

But it’s split into two lines:

One line at 49%, two lines at 50%. And the element-UI setting to 50% does not make two lines. And I checked, CSS is all the same, there is no overwrite problem?? I didn’t see anything until I set a background color:

There was a gap between them. Inline-block is the cause of inline-block. Gaps occur because an inline-block is inline externally and a block internally. Inline resolves successive whitespace to a single space (as in the following example, a trailing newline space between two divs). It used to be written like this:

So a newline between two divs becomes a space. So just get rid of the newline and write it as one line:

After that, set it to 50% and you’re good. Of course, this is only a problem in the development environment, packaging because of compression, so the space will be compressed out, so it is normal.

provide/inject

This is not a bug, but when I looked at the element-UI source code, I found this feature quite useful. In particular, linkage between forms and form components. It’s all done through these two. Specific document :provide/inject, the document is also very clear:

Provide and Inject are mainly used when developing high-level plug-in/component libraries. Not recommended for use in normal application code.

Simply put, the parent component provides variables through provider, and the child component injects variables through inject.

It is important to note that the provider can inject data as long as it invokes inject, no matter how deep the subcomponent is. Rather than being limited to fetching data only from the prop property of the current parent component.

Here’s an example from air-UI:

The air-form component provides the provider property:

  provide() {
    return {
      elForm: this
    };
  },
Copy the code

Then air-form-item imports the elForm object with the Inject attribute, while providing its own elFormItem object:

  provide() {
    return {
      elFormItem: this
    };
  },

  inject: ['elForm'].Copy the code

Air-form-item vue {air-checkbox, air-button, air-input}}

    inject: {
      elForm: {
        default: ' '
      },
      elFormItem: {
        default: ' '}},Copy the code

We can then associate a form or form-item with some calculated properties:

    computed: {
      _elFormItemSize() {
        return (this.elFormItem || {}).elFormItemSize;
      },
      validateState() {
        return this.elFormItem ? this.elFormItem.validateState : ' ';
      },
      needStatusIcon() {
        return this.elForm ? this.elForm.statusIcon : false;
      },
      isDisabled() {
        return this.isGroup
          ? this._checkboxGroup.disabled || this.disabled || (this.elForm || {}).disabled || this.isLimitDisabled
          : this.disabled || (this.elForm || {}).disabled;
      },
Copy the code

This can be associated with the status of the form.

conclusion

Since the element-UI code comes first, the logic for the same components of Air-UI doesn’t need to be changed much to be honest. Of course, you have to climb out of the pit. By now, the overall framework of AIR-UI is pretty good. In addition to the continued development of some components that Element-UI does not have, there are certainly some missing components, such as:

  1. Webpack to upgrade to 4.x
  2. Upgrade vUE version to 3.x
  3. True load on demand optimization
  4. Ts definition file development
  5. Granularity refinement of various theme customization, as well as the corresponding design specification documents

In particular, the fifth point, in fact, we are continuing to do, from theme customization, and then to the corresponding UI design specification, and then let the UI out of the diagram, strictly in accordance with this design specification. Of course, my lovely team members contributed to this. In fact, after I built the first version of AIR-UI, they were responsible for the development of new components, theme customization and design specifications, and I became a hands-off manager again. Thank you to Zhijie, Han Han, Hong Xin, Hao Yu, Yun Yi for continuing to add to and optimize the AIR-UI component library.


Series of articles:

  • Air-ui (1) — Why do I need to build an Element UI component
  • Self-built VUE component AIR-UI (2) — Take a look at the Element UI project
  • Self-built VUE component AIR-UI (3) – CSS development specification
  • Air-ui (4) — Air-UI environment setup and directory structure
  • Air-ui (5) — Create the first vUE component, Button
  • Self-built VUE component AIR-UI (6) – Creates built-in service components
  • Build vUE component AIR-UI (7) – Create command component
  • Self-built VUE component AIR-UI (8) — Implementation part introduces components
  • Build your own VUE component air-UI (9) — document with Vuepress
  • Air-ui (10) — Vuepress Documentation (Advanced version)
  • Vue Component Air-UI (11) — Vuepress Documentation (Crawl version)
  • Self-built VUE component AIR-UI (12) — Internationalization mechanism
  • Self-built VUE Component AIR-UI (13) — Internationalization Mechanism (Advanced Version)
  • Self-built VUE component AIR-UI (14) — Packaged Build (Dev and Dist)
  • Self-built VUE component AIR-UI (15) — Theme customization
  • Self-built VUE component AIR-UI (16) – Packages to build pub tasks
  • Build your own VUE component AIR-UI (17) – Develop a pit crawl and summary