The focus of my work in the last week is to sort out the team norms, and I have also checked and missed a lot of knowledge in the writing process. After removing the part about the company scene, I have this series of articles, which are expected to be written in four parts:

  1. Git specification
  2. Engineering specifications
  3. User experience specification
  4. Naming conventions

Engineering specifications

Project directory

The name of the project directory definition should be clear and legible. For each folder, you can place a readme.md file that describes the important parts and responsibilities. Here is a common example:

├─ public // Static page ├─ scripts // Related Scripts To Configure ├─ SRC // Home Directory ├─ assets // Static Resources ├─ Components ├─ lib // Global Plugin ├─ Router // Router // Router // Router // Router // Router // Router // Router // Router // Router // Router // Router // Router // ├─ views // Page ├─ app.vue // page main entry ├─ main.js // API main entryCopy the code

Here are a few more tips:

  • If there are nested pages, you can define one in SRClayoutUse as a basic view component
  • componentsPlease keep the components in the file generic
  • If views has service components, you can create components in the current directory for use, or perform secondary encapsulation based on global components
  • The page under views is defined in the form of folder. For example, if there is a statistics page, write only one.vueFiles may cause too much content in the file. If multiple files are extracted in views directly.vueIt can lead to structural disunity

utils

For files under utils, keep classifying them by file type. The following uses the utils file of Ant-Design-Pro as an example

The name of the Submit information
Authorized.ts Use @ umijs/[email protected]
authority.ts 🌎 localization: docs translated to english (#7938)
request.ts 🌎 localization: docs translated to english (#7938)
utils.less clean: remove unuse less (#6214)
utils.test.ts feat: @umijs/route-utils replace getAuthorityFromRouter (#7319)
utils.ts 🌎 localization: docs translated to english (#7938)

In your development projects, use libraries like LoDash as a priority, and encapsulate your own methods on top of them. If you really don’t want to do it manually, don’t think about doing it from 0 to 1

VueX

In large projects, VueX splitting is usually based on business. Please do not directly use State, Getter, Mutation, etc., under VueX. Instead, use Module to aggregate related dependencies, and finally integrate them through import.

├─ home // main directory ├─ index.js // VueX state getters action management ├─... ├ ─ index.js // VueX master entry // other files that might existCopy the code

home/index.js

export default {
  namespaced: true.state: () = >({... }),mutations: {... },actions: {... },getters: {... }}Copy the code

index.js

import { createStore } from 'vuex';
import home from './home';

const store = createStore({
  modules: {
    home,
  },
});

export default store;
Copy the code

Router

Routing hierarchy

Route hierarchy is very important. Before Router4, routes are defined in the same order. If the hierarchy is not clear, two problems may occur:

  • It takes half a day to maintain or define new routes
  • It is very difficult to traverse routes information, and it is very troublesome to do permissions and so on

For example, for the above design, the head, content, and footer sections, observe that the rest of the design is basically the same at the top and bottom, but the content area is different.

To develop such a design, you can define a layout component as the basic common structure and write the specific information of the routers

├ ─ ─ the definition of routes / / routes directory ├ ─ ─ home. Js / / homepage ├ ─ ─ the js / / classification ├ ─ ─ the food. The js / / club food ├ ─ ─ brand. Js / / big └ ─ ─ index. The js / / vue ├ ── routes.js // Assign files in the routers directory to the final vue routerCopy the code

routes.js

import layout from '@/layout';
import home from './routes/home';
import type from './routes/type';
import food from './routes/food';
import brand from './routes/brand';

const routes = [
  {
    path: '/'.component: layout,
    children: home,
  },
  {
    path: '/'.component: layout,
    children: type,
  },
  {
    path: '/'.component: layout,
    children: food,
  },
  {
    path: '/'.component: layout,
    children: brand,
  },
];

export default routes;
Copy the code

index.js

import { createRouter, createWebHistory, createWebHashHistory } from 'vue-router';

import routes from './routes';

const router = createRouter({
  routes,
});

// Global navigation guard
router.beforeEach(async (to) => {
  // ...
});

export default router;
Copy the code

Capturing unknown Routes

Unknown routes need to be correctly handled no matter in the middle platform or mobile terminal products. Generally speaking, there are two processing methods, and the specific type of project can be selected:

  1. Directly give a 404 prompt, prompt page does not exist and other information;
  2. Help them redirect to the home page or other pages.
// vue router4
{ path: '/:pathMatch(._)_'.name: 'NotFound'.redirect: { name: 'home'}};// vue router3
{ path: The '*'.name: 'NotFound'.redirect: { name: 'home'}};Copy the code

Route lazy loading

Use lazy loading to save screen time. Lazy loading utilizes webpack code splitting + import() to load dependent JS files only when entering the current route.

  { path: '/'.name: 'home'.component: () = > import(/* webpackChunkName: "home" */ 'views/home/index.vue')}Copy the code

Lazy loading is used for all pages except the parent page that requires children

/* webpackChunkName: “home” */ This comment syntax is unique to Webpack, which is responsible for the file name after the build package

Component Splitting Suggestions

A large project is made up of thousands of sub-components, a bit like Lego. It’s definitely hard to develop a large project directly, but it’s relatively easy to give thousands of sub-components for you to piece together.

Component splitting should follow two principles:

Granularity subdivision

In learning the design pattern, there is a very important word is single responsibility. In principle, a component is responsible for only one thing, which can maximize the reuse of components and facilitate testing and locating problems.

But one of the problems with overly single responsibility components is that the granularity is too fine and the components are fragmented. For example, the autocomplete component, which is a combination of search box + SELECT, can be reused directly because the first two components are just fine.

Another example is the Badge. There is a red dot on the upper right corner of the Badge, which may be a number or an icon. Of course, its responsibilities are very simple. This component cannot be reused in any other scenario because there is no similar scenario that requires the little red dot widget

Consideration of universality

Components can be divided into basic components and business components. When businesses are frequently used repeatedly, general components are usually encapsulated twice. For example, there is a component of search department, which is reused in many views and integrates automatic search + initial loading + automatic next page loading. The final effect is also very convenient to use.

But now suddenly there is a requirement to bottom-tip the search component, does that just change the source code? However, if you change components directly, you also violate the open and close principle

In fact, this example is to think about the suitability of a wide range of components. In the use of third-party components, you will see that they expose a lot of slots, JSX rendering functions, and the ultimate purpose is to deal with a variety of scenarios

A component’s shape (DOM structure) is always variable, but its behavior (logic) is fixed, so one of the secrets of general-purpose components is to give control of the DOM structure to the developer. Components are only responsible for behavior and the most basic DOM structure

Engineering optimization

Optimization is a huge topic, and the approach taken varies from project to project. Here are just a few common approaches

Project optimization

  • CND
  • Gzip, so that the back end supports GZIP compression, the front end also generates Gzip files
  • Compress images in production using webP format
  • Route lazy loading
  • Third-party components are loaded as required
  • Pull away from third-party libraries to avoid being packaged with business component coupling
  • .

Code optimization

  • Reduce manipulation of the DOM if the manipulation aggregates all dom changes together
  • Instead of changing the style directly, change the style to class.
  • Table is not applicable as far as possible, and binding events are in the form of event delegation
  • For animation elements, take them out of the document flow, reducing redrawing and rearrangement
  • .

Optimization of construction process

  • Delete the eslint-loader and use the editor’s built-in ESLint
  • Use catch-loader to speed up resources
  • Deleted from the production environment.mapFile, shortenimportFind the suffix
  • .