More articles

preface

Share the practice of recent projects and try to be as clear as possible. The main idea is to convey the ideas of componentization, modularization, decoupling and aggregation. Thought is the foundation, the truth of practice

Current state of front-end development

Front-end from the primitive society JS, JQuery, to now have a lot of excellent tools and frameworks, such as: Webpack, gulp, Parcle, VUE-CLI, React scaffolding, umiJS, etc., as well as the basic framework that allows us to easily build a set of projects with one click, and then support the UI libraries such as Element-UI and ANTD to achieve rapid development, the right time, the right place. Next, Renhe will talk about some problems he found during the journey (personal opinion only).

  1. The use of componentized, modular framework development, the development of the code is still difficult to maintain, there is componentized, modular form, no componentized, modular real
  2. Lack of decoupling thought, but without decoupling there is no aggregation. Coding first and then disassembling, the process itself is a mistake, cannot beThe late optimizationThis excuse is used as a cover
  3. Encapsulated components cannot be used in different scenarios, projects, or scenarios. Encapsulation over and over again
  4. Logic is difficult to reuse, except for tool classes, related business logic is difficult to extract or lack of flexibility (existing technology bottlenecks)
  5. Strong coupling between logic layer and UI layer. With the increase of functional modules, the code volume of logic layer and UI layer increases and becomes difficult to maintain, and general logic cannot be reused
  6. Developer: You are a mature editor, learn to code yourself. Editor: pawn

The more practical problem is that the logic layer is very flexible, and developers have different coding abilities, so ESLint and TSLint become useless tools for checking syntax and coding style. The end result is that the larger the project, the more difficult it is to maintain

To make things

Talking about so many problems makes you feel like a resentful woman. Now that you know the problems, you have to think about how to solve the problems, improve your personal development efficiency and benefit the team

This is what the front end team is already doing, essentially solving the problem of project maintainability, logic reuse, and even once and for all (both active and passive thank you)

The business layer

Front-end development is straightforward and prototype diagrams can be used as a reference to quickly dismantle modules, but the business layer has a lot to do: pull out UI templates, abstract logic, deal with flexible business, and so on

Taking the classic large screen class as an example, it is suitable for the demo of module dismantling. After dismantling the business layer, it is necessary to abstract the basic template into each module. For the basic components provided by the basic library like Element-UI, they can be directly taken to do business encapsulation

The UI layer

UI layer encapsulation is common. Taking Element-UI as an example, we have already wrapped the smallest components, but let’s take a look at the actual development (demo) :

Actual development situation is very terror, terror of the dom may have hundreds of lines, combined with logic & CSS, code of terror, this approach is only componentized form, maintenance degrees will go up at once and have code cleanliness may collapse on the spot (what stuff), read the code must be on the spot of poor ability of collapse (nothing), Buddha system (next)

  • Question to consider: Why is the UI layer so difficult to maintain when using UI libraries?

  • Answer: The basic components only complete the basic functions, and the business is uncertain and rich, the basic components need a lot of assembly to meet the needs of the business, when the developer at the business level does not do module disassembly or cannot do disassembly, UI layer code volume will increase greatly

  • Conclusion: The functionality of the base components needs to be aggregated to form our business base components

Take a look at the encapsulated business code

A comparison of the code above and below shows how much simpler the code is, and how much more is aggregated into its own components

  • The principle of

Only the aggregation of functions, without adulteration of business logic, and the flexibility of business is dealt with at the business layer

Logic layer

A long time ago, logic was mostly just tool class logic, and logic for common scenarios was very difficult to pull out, and vue and React mixins couldn’t handle the complexity and flexibility of the business. While we were still immersed in the fact that Vue 2.x was simpler and easier to use than React, hooks came along and brought about a logic layer reform. To make logic silks and logic combinations more flexible, which is in line with hooks, to make logic layers more flexible and reusable, which is not the benefit of technology. It’s an understanding of decoupling and aggregation during development (based on combinatorial apis or hooks, thanks for the extreme experience of constantly updating the technology)

  • The aggregation

Aggregation is well understood as the aggregation of multiple functions together to make components more powerful and rich for out-of-the-box functionality

  • The decoupling

Compared with aggregation decoupling, it separates the non-strongly correlated logic, saves the state and interface separately, and adds switches in the basic functions to decide whether to turn on the functions

Decoupling is more important than aggregation. Sometimes developers don’t know how to decouple and start developing, and end up with a very bloated component or function. The same goes for decoupling the business layer, which can end up with a very bloated page that is very difficult to maintain. When A new development maintains feature A it is forced to maintain feature B or C or more

  • The principle of
  1. Independent functions are decoupled, while non-basic functions are decoupled
  2. A file only does one thing

Take Table as an example, Table has many functions, and the aggregation and decoupling of logical layer is very important. Now there is a basic Table, editable Table and multi-choice Table, and the basic Table is the core of all my tables, and all functions will be based on this. Other richer functions are determined by the switch mode whether to open, the state and interface of each function are kept independently, when the need to modify the editable Table to find the corresponding useTableEdit function, here extract part of the core code to give you a glance

// useTbale.js
import { reactive, toRefs, ref, onUnmounted } from '@vue/composition-api'
/ / the checkbox - logic
import useTableCheckBox from './useTableCheckBox'
// edit table- logic
import useTableEdit from './useTableEdit'

function useTable({
  checkbox = false,
  edit = false,}) {
  conststate = reactive({... })/ / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert the checkbox multi-select logic start -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
  const {
    currentSelects,
    setCurrentSelects
  } = checkbox ? useTableCheckBox() : {}
  // checkbox related output parameter
  const checkBoxParams = checkbox ? {
    currentSelects,
    setCurrentSelects,
  } : { }
  / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert the checkbox multi-select logic end -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -

  / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert editable table logic start -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -
  const {
    editDatas,
    clearEdits,
    setEditHandle,
  } = edit ? useTableEdit() : {}
  // Edit table related parameters
  const editParams = edit ? {
    editDatas,
    clearEdits,
    setEditHandle
  } : { }
  / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- whether to insert editable table logical end -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -.return{...// checkbox Select multiple states & interfaces. checkBoxParams,// Edit TAB related state & interface. editParams,// Dynamic table header related state & interface. activeColParams, } }export default useTable

Copy the code

When the same function is encountered in the future, only the corresponding interface can be called. Take multi-select table as an example:

// table-checkbox Select select table data for storage
const selectionHandle = vals= > tableApis.selectionChange(vals)
Copy the code

Configuration layer

After encapsulation of the component and logic layer, there will be a lot of configuration. In order to further improve the maintainability of the project, we propose a separate configuration layer, taking the form form as an example:

/ / the UI layer
Form(
  style="margin-left: -15px",
  ref="formRef",
  :formData="formData",
  :formConfig="formConfig",
  :inline="false",
  :labelPosition="'right'",
  :labelWidth="'120px'",
  :formRules="formRules",
  :isShadow="false"
)
/ / logic layer
const {
  formData,
  formConfig,
  formRules,
  loopFormConfig,
  loopFormData,
  submitHandle,
  resetHandle,
  resetFormData,
} = useForm({
  formRef,
  formData: pFormData,
  formConfig: pFormConfig,
  formRules: pFormRules,
})
/ / configuration layers
export const pFormData = { businessTypeCode: null.businessTypeName: null.periodDays: null }
export const pFormConfig = [
  { type: 'input'.key: 'businessTypeCode'.label: 'type ID'.disabled: false },
  { type: 'input'.key: 'businessTypeName'.label: 'Business Type Name'.disabled: false },
  { type: 'input'.key: 'periodDays'.label: 'Set repayment Period (days)'.disabled: false.kind: 'number'}]export const pFormRules = {
  businessTypeCode: [{required: true.message: 'Please enter type ID'.trigger: ['change'.'blur']}],businessTypeName: [{required: true.message: 'Business Type Name'.trigger: ['change'.'blur']}],periodDays: [{required: true.message: 'Please set the repayment period correctly'.trigger: ['change'.'blur'] {},validator: payCycleValidator, trigger: ['change'.'blur']},]}Copy the code

conclusion

What do you do at each level

  • The UI layer

Encapsulate the UI abstracted from the business layer, aggregate functions, and throw necessary actions to facilitate business processing

  • Logic layer
  1. Abstract basic logic & functional logic & auxiliary tools, decouple functional logic and aggregate basic and functional logic
  2. Provide a variety of parameters & callbacks to deal with the flexibility of the business
  3. Add business logic appropriately (for example, default processing of data returned by interfaces or coupling loading into them)
  4. Save state & throw necessary interfaces
  • Configuration layer

Provide various configurations to the UI layer and control the UI layer by controlling the configuration through the logical layer

  • The business layer

Business layer = UI layer + configuration layer + logic layer

But the business layer has more necessary things to do:

  1. Break down the business module and abstract the UI & logic from it
  2. Dealing with business-dependent logic and UI layers that can’t be encapsulated
  3. Extract several business-level hooks when the business is sufficiently complex

conclusion

Subjective initiative is insufficient, external force is dry