preface

Hello, everyone! I’m Lin.

Today I want to share with you the encapsulation of components. In the process of developing business requirements, we may come across a completely new business requirement, or we may come across an existing feature to iterate over a new one.

Clearly, it is worth thinking about how to design a new business requirement value.

Also, it’s worth thinking about developing iterations on the basis of an existing feature.

Instead of just command+ C and command+v!

This article is also a summary of how I design components for requirements.

Writing summary is not easy, if there is a better design and thought, look forward to a collision.

Need & Thinking

Draft requirements:

When I got the requirements draft, I first saw that the cascading components of the Elemental-UI didn’t fit the business, and it was relatively cumbersome to retrofit on top of that. So eventually I decided to encapsulate a cascade myself.

Next, I thought about the functions to be realized according to the requirements as follows:

1. Users can select by search category.

2. Users can expand the category and click to select. (ps: Click on the first panel to expand all the first level panels of its children)

3. Initialize the state. By default, all nodes of the first node will be expanded.

4. Supports positive and negative node selection.

5. Each search box on the panel controls the search on the panel.

How to implement requirements

Once you have a clear idea of what you want to implement, what I think you should do is not rush to write code, but do a deeper analytical thinking.

I’m going to start with the data structure, which is a tree. Something like this:

const data=[
	{
    	text: "Guide".id: 2.children: [{text: "Design Principles".id: 2.1.children: [{text: Navigation "1".id: 2.112}, {text: "Navigation 2".id: 2.113}, {text: "Navigation 3".id: 2.114,},],}, {text: "Design Principle 2".id: 2.2.children: [{text: "Navigation 2".id: 2.21,},],},],Copy the code

Given the tree data format, I can see that this requires a recursive component.

But now a key question arises: how does a template render such a data format?

  • Solution 1: When designing this recursive component, we will treat each node as a recursive component. For example, we will iterate over a node, if there is a children attribute, then we will recurse until we stop when the node has no children attribute. And then go through the next node…

  • Solution 2: Split the recursive component into left and right sections. The left side first traverses the nodes of the same level, and the right side renders the data by selecting the nodes of the upper level to control the nodes of the next level. (ps: peer node traversal)

In fact, the bottom line is: do you want to traverse depth or breadth? (PS: The final plan is in question, here is…)

Design components

This is done with a recursive component CascaderItem and a search-filter filterItem component and a parent component Cascader.

Let’s start with the layout

The layout of the draft component is the left and right panels. I developed this component using a Flex layout. I ended up using Scenario 2 to traverse the data rendering. Solution 1 has no problem in the implementation of functions, but there are some defects in the layout, because solution 1 is based on a node node as a panel.

Component templates for Solution 2:

leftThe panel is a loop through peer nodes,rightA part is a component that references itself, so it becomes a recursive component.

Design of component properties

The design of this component’s properties is passed by the props property.

The properties of the recursive component CascaderItem are: Options, level (ps: indicates the current level), changeValToStr, isCheckbox, isInput, and reverseChoice

The parent Cascader component has the following properties: filterable, value (ps: bidirectional binding, which will be discussed later), and iptProps.

The specific meaning of each attribute can be viewed in the source code comments, here no longer do about…

Recursive component implementation ideas

This is controlled by a computed property, showRightItem, to show the panel with hidden child nodes (ps: recursive termination condition). This computation property relies on a selected array of reactive data (ps: selected nodes). The return value of showRightItem is controlled by determining whether the selected level node has the children attribute.

The selected item is passed to the child CascaderItem by the parent Cascader. In this case, I’m passing the properties via select. sync, and when the user clicks on the Node, the update: Selected event is triggered to change the parent’s data.

Capturing user behavior

The update: Selected event is not only triggered when the user clicks on a node. There is some additional logic to handle on this user behavior function. Wait until all the logic is complete before firing an event to notify the parent component.

The logic involved is as follows:

1. Determine whether the user click behavior is selected correctly or unselected.

2. Operate the selected array to delete the data of the next level node. Because the upper level node is switched, the next level node will be deleted to achieve the same effect of switching data view.

3. Whether the selected node has the children attribute? If so, push the first bit of the child to the selected array until the first bit of the child does not have the children attribute.

When the user searches at each level, an INPUT event is triggered. Do data filtering at the current level on this user behavior.

When searching for data below the current level, the data in the panel below the current level is unpredictable. In order to solve the user’s confusion, the searched parent’s data is not associated with the current subpanel’s data (ps: it may stay in the previous node’s child data).

This is controlled by a switch that hides the next panel while the user searches. Wait until the user has decided what to search for.

Ok, so at this point the logic of the recursive component is pretty much complete. Specific implementation can view the source code…

Implementation of the parent component

The parent component is the component that is exposed to the user. It is similar to the total pool to assign tasks to different sub-components. The filterable attribute passed by the user determines whether the recursive component CascaderItem or filterItem is used.

With the idea of high cohesion and low coupling, components expose onChange events and V-Model attributes.

The onChange event is triggered when the selected node changes. The V-Model property implements bidirectional data binding, and the input event is triggered internally to update the data bound to the user in time.

The parent component is similar to the total pool and is also responsible for processing some data. The logic involved is as follows:

1. Initialize the data and add the pathObj and CHECKED properties to the tree data. (Ps: The pathObj property is used to record the relationship between the upper and lower nodes, checked is the checkbox that serves the recursive component)

2. Flatten the tree data to provide total data for search.

3. Initialize the selected array and initialize the SELECTED data based on the value passed in by the user.

Specific data processing logic how to achieve can view the source code and source annotations…

Using Cascader

The diagram below:

Originally wanted to record a small video operation components, but I still do not know which software 😢 ̄□ ̄ | | (ps: more because of lazy 😝) please download the source code experience ha ~

The source address

Cascader

analyse

Meeting business requirements is not difficult, and there may be many ways to accomplish this. I think it’s more the thinking in the development process and how you design is a very important part of writing code from the beginning.

During the development of this component, I had an episode collision with my partner: is it reasonable for the user to select the node data?

How do you understand that? As FAR as I know, the development components are for users to operate. I think whether the selected node data meets the business requirements is a business logic problem at another level, which should be another judgment and encapsulation rules. (Ps: I think we all have our own understanding and ideas.)

Disadvantages: Currently only support single selection function, the component can also develop multiple selection function (PS: there will be time to iterate, please look forward to…)

As a team, it’s inevitable that you’ll need to build on someone else’s code base to implement new functionality. Talk about iterating new requirements over existing functionality. How do you practice this on a daily basis?

conclusion

During the development process, I still felt it was necessary to encapsulate components and design components to add different colors for project management and subsequent iterations.

This brief article is Lin years ago the last summary of the friends of the big dig helpful words hope to reward a star ~

Finally, I wish you all a happy New Year and everything goes well in the New Year