How to package components in component development

Since React, Vue and other front-end frameworks have been widely used in the market, component development has gradually become the mainstream front-end development method. Today I will share with you how we should package components in our usual development. Mainly from the following three aspects to explain to you:

  • what is a component
  • Why split components
  • How to split components

what is a component

Encapsulation of functions and ui styles, a function or a ui style is a component, navigation bar, banner, footer, etc. These functions and styles are all components.
Different frameworks classify components slightly differently. For example, some people divide react components into functional components, stateless components and stateful components, presentation components and container components, etc.; some people Vue components into global components. , local components, functional (stateless) components, normal (stateful) components, dynamic components, normal (non-dynamic) components, asynchronous components, normal (non-asynchronous) components, recursive components, normal (non-recursive) components. But essentially they are all the same. Since we are currently using the vue framework, all today's sharing is mainly for the analysis of vue components.

1. Classification by component registration method: vue divides components into global components and local components

Global components: Components registered globally using Vue.component ( in our projects, they are generally registered uniformly in the utils file )

Vue.component("my-component-name", {
  /****/
});

clipboard.png

Partial components: imported separately through components on the page in use ( in general, it is recommended to use the method of importing components on demand )

clipboard (1).png

2. Classification according to whether the component has its own state: it can be divided into functional (stateless) components and ordinary (stateless) components

Functional style: add functional to html or template tags written in jsx syntax. Generally, a stateless (no responsive data) component can be registered as a functional component ( it does not manage any state, does not listen to any state passed to it, and has no life cycle method. In fact, it is just a accepting some props function, so the rendering overhead is much lower, which can improve some performance to a certain extent )
jsx syntax:

<script>
  import OtherComponent from "./other";
  export default {
    name: "FunctionComponent",
    functional: true,
    components: {
      OtherComponent
    },
    props: {
      title: {
        type: String,
        required: true
      }
    },
    render(h, { props }) {
      const { title } = props;
      return (
        <div>
          <p> 我是函数式组件</p>
          <p>props {title}</p>
          <OtherComponent otherInfo={title} title="我是函数式组件的其他组件" />
        </div>
      );
    }
  };
</script>

The template tag marks functional:

<template functional>
  <div>
    {
   
   { props.title }}
    <p>
      otherInfo {
   
   { props.otherInfo }}
    </p>
  </div>
</template>
<script>
  export default {
    functional: true,
    props: {
      title: {
        default: "",
        type: String
      },
      otherInfo: {
        default: "",
        type: String
      }
    }
  };
</script>

3. According to whether the component is dynamic or not: it can be divided into dynamic components and ordinary (non-dynamic) components.
Dynamic components: components imported through the component tag plus the is attribute (the attribute value is the name of the imported component)

<template>
  <div>
    <component :is="currentTabComponent"></component>
  </div> 
</template>
export default {
  components: {
    DynamicComponent1
  },
  data() {
    return {
      currentTabComponent: "DynamicComponent1"
    };
  }
};

Generally, dynamic components can be used when switching between many components is required. For example, the following code can be optimized as a dynamic component: ( el-tab-pane part of the code is basically repetitive knowledge and a small amount of data is different. In this case, just You can define the data in the el-tab-pane as an array variable in data, and then loop the el-tab-pane, and the components inside can be replaced with custom components) After optimization: (if the component switching is
clipboard.png
frequent , You can add a keep-alive tag outside the components tag to cache deactivated components, so that you don’t need to recreate and mount the next time you switch components )

<template>
  <el-tabs v-model="activeTab">
    <el-tab-pane v-for="(item) in tabList" :key="item.id" :label="item.name" :name="item.id">
      <component :is="item.components"></component>
    </el-tab-pane>
  </el-tabs>
</template>
<script>
import page1 from "@/views/example/page1";
import page2 from "@/views/example/page2";
import page3 from "@/views/example/page3";
export default {
  name: "tab",
  data() {
    return {
      activeTab: '1',
      tabList: [
        { id: '1', name: "页面1", components: page1 },
        { id: '2', name: "页面2", components: page2 },
        { id: '3', name: "页面3", components: page3 }
      ]
    };
  },
};
</script>

4. According to whether the components are asynchronous or not: it can be divided into asynchronous components and ordinary (non-asynchronous) components . First-screen rendering speed, such as the lazy loading of routes used in our project, and the components introduced in this way locally () => import('./my-async-component') are all asynchronous components )

The way to introduce asynchronous components:

a. Through the factory function

Vue.component('async-example', function (resolve, reject) {
  resolve({
    template: '<div>hello vue !</div>'
  })
})

b. Use together with the code cutting function of webpack:

Vue.component('async-wepack-example', function (resolve) {
  // require会告诉webpack将你的代码切割成多个包,然后通过ajax加载    
  require(['./my-async-component'], resolve)
})

c. via import()

Vue.component('async-wepack-example', () => import('./my-async-component'))
Local components register asynchronous components ( this method is currently commonly used in our projects )
new Vue({
  components: {
    myComponent: () => import('./my-async-component')
  }
})
Advanced Asynchronous Components
const asyncComponent = () => ({
  component:import('./my-async-component.vue'),//需要加载的组件
  delay: 200, // 展示加载时组件的延时时间,默认200毫秒
  error: errorComponent, // 加载失败显示组件
  loading: loadingComponent, // 加载时使用组件
  timeout: 2000 // 超时时间,默认 Infinity(组件加载也超时后则使用加载失败时使用的组件。)
})

5. Classification according to whether the components are circular references: can be divided into recursive components and ordinary (non-recursive) components

Recursive components: Components can call themselves in their own templates ( the value of the name component must be defined, generally used for tree components, sidebar routing components, etc. )

<template>
  <div>
    <ul>
      <li v-for="item in list" :key="item.name">
        <span>{
   
   { item.name }}</span>
        <recursive-component v-if="item.children" :list="item.children" />
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    name: "RecursiveComponent",
    props: {
      list: {
        default: () => [],
        type: Array
      }
    }
  };
</script>

6. In general, in our development, components are divided into ui display components (focusing on the display of ui styles, such as our commonly used element-ui), functional components (do not pay attention to styles, only encapsulate functions), business components, etc.

Why split components

1. Improve development efficiency

Before component development, each of our pages was separate. If we encountered a similar part developed by Zeng Jin when developing a page, we could only copy and paste it to the current page, and then make some changes. If the class is lost, the page may still report an error, and it will take a lot of time to troubleshoot the problem. After componentization, we only need to introduce components for similar parts, without repeated development. To a certain extent, the amount of code is also reduced, which greatly Improve project compilation speed

2. Easy to reuse

A component can be used in multiple places

3. Simplify the debugging steps

When a page has a problem, you can first locate a certain module, and then directly locate a certain component, without having to read all the codes of the entire page and then troubleshoot the problem

4. Improve the maintainability of the entire project

All pages are composed of components, and the coupling between modules is reduced. When deleting and modifying the function of a module, only the components need to be directly modified.

5. Facilitate collaborative development

Each component converges the corresponding business functions in one project without disturbing each other. In a multi-person team, each person is only responsible for his own business module, and the addition, deletion, modification, and query of business functions are limited to his own business module and will not affect other people's business.

How to split components

1. Guaranteed single responsibility.

A component "only does one thing well", and only does the most basic thing well, leaving a gap that can be combined. Outsource as much functionality as possible.

2. The principle of openness and closure.

Open for extension, closed for modification. When there are new business requirements, first consider how to expand. A single component only implements the simplest functions, and more is achieved through expansion rather than modification of components.

3. A single component file should preferably not exceed 200 or 400kb

The pursuit of shortness and conciseness is conducive to debugging and narrowing the scope of troubleshooting

4. Avoid functions with too many parameters. Check the validity of the parameters at the entrance, and check the correctness of the return at the exit

Avoid errors in passing parameters when others use components, resulting in many unpredictable errors.

5. Loose coupling, encapsulated components do not depend on too many other components

When all problems are solved by stacking a bunch of open source codes, firstly, there will be redundancy, and secondly, it is difficult to debug. When one of the modules has a problem, the entire component may be unusable, and complex dependencies will also occur. Things like version conflicts. If you want to rely on components or libraries, you need to rely on stable ones that do not change frequently.

6. No side effects: no dependence, no modification of external variables, internal operations do not affect other components

It can be safely replaced under the condition that the input/output is guaranteed to be unchanged.

7. Extract the essence, some irrelevant things, such as data acquisition, data organization or event processing logic, ideally should be moved into external js or placed in the parent component for processing, the component is only responsible for ui display or function accomplish.

8. Reasonable componentization

Turning large blocks of code into loosely coupled and reusable components does have many advantages, but not all page structures need to be extracted into components, and not all logic parts need to be extracted outside the components. When we actually carry out component extraction work, we need to consider not to over-componentize. Then we can judge according to the following points when deciding whether to extract components:
a. Is there enough page structure/logic to guarantee it? If it's just a few lines of code, you may end up creating more code to separate it.

b. Code duplication (or possible duplication)? If something is used only once, and serves a specific use case that is unlikely to be used elsewhere, it might be better to embed it.

c. Will performance be affected? Changing state/props will cause the component to re-render. When this happens, all you need is to re-render the relevant element nodes obtained after diffing. In larger, tightly coupled components, you may find that state changes cause re-renders in many places where it is not needed, and the app's performance may start to suffer.

Guess you like

Origin blog.csdn.net/engineerllm/article/details/115866881