Original link: github.com/func-star/b…

Introduction to the

Before we begin, let’s briefly review the history of the front end. In the very early stages, we could only write js/ CSS naked, and as the project progressed we could see a lot of repetitive code. In this context, jQuery and Bootstrap emerged as The Times required. The component design ideas shown in jQuery and Bootstrap can be seen in many component libraries later, and also bring upgrades to project development. Then came MVVM domination, and the idea of componentization began to spread like a virus across the front end.

Componentization is more of an idea, an exercise in code reuse and functional abstraction by front-end engineers. The ultimate goal is efficiency improvement and project optimization.

Being lazy is one of the virtues of engineers.

Component planning stage

  • customized
  • scalability
  • internationalization

customized

Customization here can be understood as component skin, but it is not just about color. Many mature component libraries in the industry support such customization. Two examples:

The Ant Design component library, for example, exposes a number of style variables that access parties can override to customize their own components. Because Ant Design uses a Less preprocessor, the project must also support Less compilation.

@primary-color: #1890ff; // Global primary color
@link-color: #1890ff; / / the link color
@success-color: #52c41a; / / success
@warning-color: #faad14; / / warning color
@error-color: #f5222d; / / error@font-size-base: 14px; Rgba (0, 0, 0, 0.85); // @text-color: rgba(0, 0, 0, 0.65); Rgba (0, 0, 0,.45); Rgba (0, 0, 0,.25); // invalid color @border-radius-base: 4px; // component/float layer rounded @border-color-base:#d9d9d9; / / border color@box-shadow-base: 0 2px 8px rgba(0, 0, 0, 0.15); // Float shadowCopy the code

That’s the way I’ve always done it.

Fusion Design Central Platform component library, which can be said to be tailored for customization. It sorts out more than 1,000 configuration rules, allowing users to match a set of rules to their own requirements through a visual interface. These rules and variables are eventually converted into Sass/Less variables, which are then compiled and dynamically rendered into the component. The advantage of this approach is that you don’t have to look at what’s behind a bunch of rules and variables. But high coupling is also a serious problem.

With the enhancement of browser native capabilities, CSS Variable compatibility has reached production environment standards. The ability to configure style variables can also be achieved with calc().

We can draw on the Design ideas of Fusion Design to provide a visual configuration platform for access parties, and generate a set of style variables that meet the requirements of access parties. However, they are no longer configuration variables of Less, but CSS variables that are supported by native methods, and finally become a separate theme package. At the same time, the environment dependence of the preprocessor and the intrusion of style variables in the component are solved.

scalability

Extensibility and customization are repetitions here, not from the style variable perspective. Extensibility is a very important consideration for the core capabilities of component libraries. In order to cope with the changeable functional requirements of the business side, the access side will have high requirements for scalability when choosing the component library. The extensibility of a set of component libraries can generally be measured in terms of:

  • Is the component’s API comprehensive enough
  • Whether there is a clear component composition relationship, whether the granularity of components is fine enough
  • Whether the component provides full lifecycle hooks
– Is the component’s API comprehensive enough

For developers, the library of components they choose to plug into is like a general supermarket, ideally you have what I want and what I don’t. Users can extend personalized business components from components at a low cost.

– Whether there is a clear component composition relationship and whether the component granularity is fine enough

For example, I now want a time picker component (DatePicker), but the DatePicker in the component library does not meet my business needs. At this point, I need to re-implement a DatePicker, which would be expensive to implement myself. If you combine components from existing components in a component library, you can greatly reduce development costs.

Therefore, it is particularly important to sort out the combination relations between components. I generally divide components into four types: basic components, capability components, composite components and business components, and then form a complete set of component libraries through component combination, which will be introduced later.

– Whether the component provides full lifecycle hooks

Component lifecycles are rarely used in real-world scenarios, but are not redundant. Consumers can know when components are mounted and unmounted, and can execute business logic on nodes where components are more subdivided.

internationalization

This is an important factor in promoting open source components, as Ant Design Vue offers packages in 36 languages.

Component design stage

  • Verify the composition relationship between components
  • Customize global CSS variables
  • Custom consistent apis
  • Internationalization is component-based or configuration based

Verify the composition relationship between components

In order to achieve high scalability, atomic design theory is an appropriate guide. Atomic design theory holds that pages should be composed and decomposed, just as components can be composed and decomposed. For example, complex components (composite components) can be broken down into combinations of capability components, which in turn can be broken down into infrastructure components, which in turn can be combined with business scenarios to become business components.

Let’s take the DateSelect (time selector component) as an example. A DateSelect can be split into a DatePicker (time scroll selector) and a Popup (pop-up layer component), while a DatePicker component can be composed of multiple pickers (pop-up layer component), In turn, Picker can be developed based on Hammer (gesture library), and Popup can be extended based on Mask (Mask component).

Customize global CSS variables

Not only do components have combinatorial reuse relationships, style variables are also required. To ensure that all components have a consistent style, we need to maintain a global list of style variables, such as font color, font size, and so on. All components then define private style variables based on this global common variable.

:root{
    --namespace-common-color: '# 333'; --namespace-common-font-size-sm: 12px; --namespace-common-font-size-md: 14px; --namespace-common-font-size-lg: 16px; . } .namespace-date-select { .date-select-confirm, .date-select-cancel { color: var(--namespace-common-color); font-size: var(--namespace-common-font-size-sm); }... }...Copy the code

Custom consistent apis

The development of a complete library of components is often coordinated by several people, and in this case, it is easy to have different API names for the same function. For example, the cancellation event in Dialog uses onCancel, while the cancellation event in DateSelect uses Cancel. While this will not affect the operation of the component library, it will appear to be quite irregular, with no component design and review phase. In addition, the access side will be very confused when it is officially used, and the use cost will increase accordingly.

OnMount: component mounting onWillMount: component unmounting onShow: display an event onHide: hide an event onCancel: cancel an event onConfirm: confirm an event onDelete: delete an event...Copy the code

Internationalization is component-based or configuration based

Support for internationalization varies among the many component libraries in the community. If you want to build a component library for internal use, internationalization can be ignored.

There are some differences between component configuration-based internationalization and global configuration-based internationalization. If you want to support multiple languages in your component library (for example, component A in Chinese and component B in English), then choosing component-based configuration is much easier. If this level of support is not required, then global configuration is much easier

Component implementation phase

  • Identify the component’s private API and private style variables
  • Method or event
  • Component quality assurance
  • .

Identify the component’s private API and private style variables

In order to allow users to customize the style of components, variable extraction is needed to extract as many style variables as possible for each component, and users can modify the style of components flexibly.

:root{ --date-select-font-size: var(--namespace-common-font-size-sm); --date-select-color: var(--namespace-common-color); . } .namespace-date-select { .date-select-confirm, .date-select-cancel { color: var(--date-select-color); font-size: var(--date-select-font-size); }... }...Copy the code

Method or event

This can be a headache in both daily and component development. Method callbacks or events usually do what we want, and it’s a bit tricky when to use methods and when to use events.

Let’s analyze the pros and cons of both.

Let’s take a look at the callback method. For example, if you submit a query form and click the query button you need to refresh the list. We need to pass the callback method to refresh the list to the query form for the interface to call when it returns. It is certainly very convenient to use on simple parent-child components. However, when the nesting of components is complex, you may need to communicate between sibling components, or even between unrelated components, which can become painful because the callback method’s pass link becomes long. To sum up, its biggest characteristic is that the link is very clear and easy to locate the method source, but when the relationship between components becomes complicated, it becomes difficult to maintain.

Now let’s look at events. Unlike methods, events don’t need to pass methods between components; they just need to define a listening key and fire at the right point in time. Can be seen that it can better solve the above proposed of the complex relationship between components of the scene, but the question it is, you define the project after too many events will become difficult to maintain, because it’s not like the callback method has clear transitive relation, we have a problem you can’t even positioning, abuse is very terrible one thing.

When developing a component, method passing is preferable to events for simpler parent-child components. For composite components with very complex nested relationships, events are recommended.

Component quality assurance

Committed to creating an excellent open source component library, the quality of components need to have a certain pursuit and requirements. There are several ways to ensure component quality

  1. Design review prior to component development
  2. Unit test coverage
  3. Cross review

Component maintenance phase

  • Hair version of the specification
  • .

Hair version of the specification

Each release should have an ISSURE and branch association, in which the revision points and optimization points of the release should be recorded, along with the corresponding development leader.