preface

The purpose of this series of articles is to show readers how to build their own component libraries that are more flexible for different businesses and scenarios. For now, you must know the basics of vue.js and have read the common components of the Element component library.

Why build your own Element component library?

Let’s look at an example

When we use the Element library, we must call the el-xxx component and render it on the page based on the code Element introduces. Think about the problem. What if, at this point, there is a new requirement that the front-end needs to change the style of this component? Do we use style penetrations to make changes one by one? You might think of using global styles for overwriting, but I’m personally opposed to using global styles because it’s very bad for reading code and managing it later.

To take an extreme example, now you have 100 tables, and now the product manager says to you, “We’re going to dynamically change the height of all our tables based on the screen size.” You might be blindfolded, because the code in the Element library is hard to change, and even if you did, it wouldn’t work on someone else (hence the fact that each el-Select component is independent). Let’s move on to the next image:

In this figure, we can see that the el-Select component is preceded by an X-Select component. In this component, since we defined it ourselves, we can modify it any way we want. In the future, even if the component changes, we can directly change in x-select, all the previous components change.

Summary: Wrapping Element’s component library by itself means that there is an upper layer of wrapping, a single bundle of components, and a unified exit. We can customize according to our team and business to meet front-end customization and rapid development.

Key knowledge (must)

To build a component library, we definitely need to use communication between components. Components generally use parent-child communication, parent-child communication, non-parent component communication (using BUS or Vuex), dependency injection communication (simply, ancestor component to descendant component communication). Here we will briefly introduce the parent to child communication, child to parent communication (if there is a better explanation, welcome to the comment section).

Parent communicates to child props

Parent communicates with child. We just need to add the parameters to be passed on the instance of the subcomponent of the parent component, and then declare in the props property of the subcomponent to receive. A simple little demo is as follows:

ArticleList is our parent component and editArticle is our child component. We use an instance of the editArticle component in the articleList parent and pass the articleInfo argument. We then receive at props in the editArticle component.

It’s not that hard to read, but for those of you who haven’t seen props written this way, you’re probably using arrays. Array writing is simpler, but there are no configurable items. Object writing is recommended.

// Array writing, simple but no configurable items
props: ['articleInfo']
Copy the code
// propA, propB... To illustrate
props : { 
    // Must be a numeric type
    propA: Number.// Must be a string or number type
    propB : [String.Number].// Boolean, if not defined, the default value is true
    propC: { 
        type : Boolean.default : true
    }
    // Number, and must pass
    propD: { 
        type: Number.required: true
    }
    // If it is an array or object, the default value must be a function to return
    propE: { 
        type : Array.default : function () { 
            return[]; }}// Define a validation function
    propF: { 
        validator: function (value) { 
            return value > 10; }}}Copy the code

In fact, it is not difficult for those who have a little Vue foundation to understand these knowledge, but there are also some points that need to pay attention to.

  1. If possible, the props value should be read-only only. When we modify the props value, Vue will report an error. When we modify the Object value, Vue will not detect that you have modified it, but this is avoided (unless you do so intentionally). We’re going to use the variables in data to receive the props value. If it’s an Object value, we need to make a deep copy. Slice is recommended for arrays and Object.assign is recommended for objects.
  2. Parent-child communication is not completed immediately. Sometimes, after the parent communicates with the child, we call the value in the child component by ref immediately, but it does not take effect. In fact, the communication takes some time, and we need to wait. We can use $nextTick or setTimeout to wait, but the difference between the two is irrelevant.

The child corresponded to the parent emit

The child uses $emit() to emit events. The parent uses $on() to emit events for the child. The parent can also use v-ON on the child’s custom tag to emit custom events. Last little demo:

Here, we define a btnForm component in the assnDetails component that uses V-on to monitor custom events Submit and Reset.

The first method cancel triggers the reset custom event, and the second method apply triggers the submit custom event. (Currently cancel and apply are triggered by button clicking on this page. You can also set others, which is not important here).

After the custom event is triggered, the parent component receives it and executes the corresponding method. For example, the method that triggers the custom event submit is applyAssn (as shown in the figure).

Child to parent communication makes sense a few times, but it’s important to note that custom events don’t have the same name as native events like Click.

$attrs, $listeners

  • $attrs

This property gets all the properties passed by the parent component

  • $listeners

This property retrieves all events passed by the parent component

A demo can see all:

This is a button component we defined, but we also want to use the Element button component related things, but the Element button component properties and events are very many, we have trouble passing one by one, is there any way to do it once and for all? The $listeners are designed to solve this problem by dropping attributes and events set on our custom components to the Element component. We can also intercept it, give it default values, and so on. This is a property that we’re going to use a lot later on.

subsequent

This is a new series by the author, aiming to share their own experience of packaging components, welcome to discuss. Also check out the follow-up…