Directory structure, code format ESLint +pretty, and Git hooks

Full project address: vuE3-element-plus

Experience address: http://8.135.1.141/vue3-admin-plus

Series entry:

  • True fragrance law! Take you to use vuE3 + VITE2 to lift backstage (entrance)

preface

Eslint +pretty: How to use Git hooks

The directory structure

├ ─ ─. Husky// Git hook├ ─ ─ dist// Package directory├ ─ ─ the mock// Project mock data├ ─ ─ the SRC/ / the source code│ ├ ─ ─ API// All requests│ ├ ─ ─ assetsStatic resources such as theme fonts│ ├ ─ ─ the components// Global common components│ ├ ─ ─ directive// Global directives│ ├ ─ ─ hooks/ / the hooks│ ├ ─ ─ filtres/ / the global filter│ ├ ─ ─ the ICONS// Project all SVG ICONS│ ├ ─ ─ the router// Route correlation│ ├ ─ ─ store// Global Store management│ ├ ─ ─ styles// Global style│ ├ ─ ─ utils// Global public method│ ├ ─ ─ views// view│ ├ ─ ─ App. Vue// Entry page│ ├ ─ ─ the main js// entry load component initialization etc│ ├ ─ ─ mockProdServer. Js// Production environment│ └ ─ ─ permission. Js// Permission management│ └ ─ ─ Settings. Js// Global static page configuration (whether to display sidebars, etc.)├ ─ ─ editorconfig// Editor properties configuration├ ─ ─. Env. Build// Generate environment configuration when packaging (can be specified by --mode)├ ─ ─. Env. Build - serve// Package development environment configuration (can be specified by --mode)├ ─ ─. Env. Serve - dev// Development environment configuration at development time (can be specified by --mode)├ ─ ─. Env. Serve - prod// Build environment configuration at development time (can be specified by --mode)└ ─ ─ eslintignore// eslint ignores items└ ─ ─. Eslintrc. Js/ / eslint configuration└ ─ ─ gitignore// git ignores items└ ─ ─ prettierrc/ / pretty configuration└ ─ ─ index. HTML// Main entry file when packing└ ─ ─ jsconfig. Json// The configuration when using the js language. For example, the editor can be configured to recognize "@" and so on└ ─ ─ package. Json// package.json└ ─ ─ vite. Config. Js/ / vite configuration
Copy the code

Here’s a quick look at SRC

API: Request interface encapsulation

If the interface is used twice or more, encapsulate the interface to the API. However, it is not recommended to encapsulate all interfaces, which would add complexity to the code. The more complex the code, the more difficult it is to bug and develop, which is not conducive to later maintenance

Assets: resource directory

Some static files such as images, JSON data files, etc

Components: Generic component directory

First let’s look at the role of the encapsulation component:

1. Encapsulation: encapsulation of views, data, and change logic. 2. Reuse: pass properties through propsCopy the code

We looked at the role of encapsulation components above, encapsulating business logic and reuse. If you don’t have the above two components, don’t wrap them too much. Wrapping too many components can make development more difficult, so it is recommended to only wrap the same business logic in a page if it has been used more than twice or more times.

This directory is primarily used as a wrapper for global generic components (such as Tinymce). You are advised to encapsulate components in layout that are used several times in a business scenario

In short, do not package what components to this directory, the final component too many, not easy to find, not easy to maintain

hooks

Hook is a new feature in VUe3 that encapsulates business logic. Compared with general utils, it has more use of state management (REF, Reactive) and life cycle. It can be said that it has more soul than the previous API

icons

The SVG image directory uses the Viet-plugin-svG-icons plug-in to encapsulate multiple SVG images

By default, images from the common and Nav-bar directories are read, which can be configured in viteSvgIcons in viet.config. js

vite.config.js

viteSvgIcons({
  // config svg dir that can config multi
  iconDirs: [path.resolve(process.cwd(), 'src/icons/common'), path.resolve(process.cwd(), 'src/icons/nav-bar')].// appoint svg icon using mode
  symbolId: 'icon-[dir]-[name]'
}),
Copy the code

SVG ICONS in common and nav-bar are configured for packaging by default. It can be modified and amplified if necessary

Official configuration document: Vite-plugin-SVG-icons

How to use

Icon-class is the file name of SVG

<template> <div> <div> SVG -icon Example </div> < SVG -icon icon-class="dashboard" class="dashboard" /> </div> </template>Copy the code

If you need to add an SVG, go to the Internet and download it (such as the icon on iconfont). You need the image at the end of the SVG and put it in the appropriate directory

mixins

Mix files, often used state or method can be mixed

Commonmixin.js users get basic information such as environment variables, time date points (today, nearly three days), deferred execution method sleepMixin, etc

import { getCurrentInstance} from 'vue'
const{proxy} = getCurrentInstance() proxy.todayTimemixin --> get today's date proxy.sleepmixin (3000).then() --> execute then after 3S delayCopy the code

elementMixin.js

Element – plus related. Message prompt, confirm confirmation, relevant validation encapsulation formRulesMixin, etc

Proxy. Message ("elementMixin") --> prompt message //formRulesMixin formRulesMixin. <template> < EL-form :model="subForm" :rules="formRulesMixin"> <el-form-item label=" brand name" Prop ="name" :rules=" formRulesmixin.isnotnull "> <el-input V-model =" subform.name "class=" widthpx-150" placeholder=" placeholder" /> </el-form-item> </el-form> <template> <script setup> let subForm = reactive({ name: '' }) </script>Copy the code

routerMixin.js

The router. Route push, Repalce,back and other route jump methods, and related parameter transfer encapsulation,

//routerDemoF.vue
proxy.routerPushMixin('routerDemoS', { name: 'routerDemoS' })
//RouterDemoS.vue
onMounted(() = > {
  //get page pass url data
  console.log(proxy.queryParamsMixin)
  //
})

Copy the code
All methods and properties named in the global mix are named mixin to distinguish them from normal methods

router

A configuration can generate you want to route and page, here mainly introduces the configuration and use of routesRoute configuration parameters in the complete (take the keep-alive route configuration in the project as an example)

{
    /* Path,component,redirect: vue-router itself */
    path: '/writing-demo'.component: Layout,
    redirect: '/writing-demo/keep-alive'./* meta: alwaysShow-> default:false; True: displays parent when there is a child element; False: Do not display parent when there is a child element hidden-> default:false; True: Hides the current TAB in the sidebar, including its children; * /
    meta: { title: 'Writing Demo'.icon: 'eye-open' },
    alwaysShow: true.hidden:false
    children: [{path: 'keep-alive'.component: () = > import('@/views/example/keep-alive'),
         /* name-> Route name; Keep-alive Specifies the name of the cache. */ is recommended
        name: 'KeepAlive'.//cachePage: cachePage when page enter, default false
        //leaveRmCachePage: remove cachePage when page leave, default false
         CachePage ->default:false; True -> The initial page load is cached; leaveRmCachePage->default:false; ActiveMenu: To select the sidebar item, for example, the list page jumps to the details page (set to Hidden). If you want to highlight the list page, you can set activeMenu:" Link to the list page "*/
        meta: { title: 'Keep-Alive'.cachePage: true.leaveRmCachePage: false}}, {path: 'router-demo-f'.name: 'routerDemoF'.hidden: true.component: () = > import('@/views/example/keep-alive/RouterDemoF.vue'),
        meta: { title: 'RouterDemo-F'.activeMenu: '/writing-demo/keep-alive'}}},Copy the code

store

Added auto-import modules, which automatically imports index.js by adding a new file to the Module folder

Let’s take a look at the core code index.js

import { createStore } from 'vuex'
import getters from './getters'

/ * import. Meta. GlobEager: vite2 official provide API * * / read the file
const modulesFiles = import.meta.globEager('./modules/*.js')
let modules = {}
for (const path in modulesFiles) {
  /* Use path.replace to get the file name: app **/
  const moduleName = path.replace(/(.*\/)*([^.]+).*/gi.'$2')
  /* modulesFiles[path]. Default: Fetch the content of the read file **/
  modules[moduleName] = modulesFiles[path].default
}
console.log('modules', modules)
/* * modules {app: {... }, permission: {... }, tagsView: {... }, user: {... }} app: {namespaced: true, state: {... }, mutations: {... }, actions: {... } permission: {namespaced: true, state: {... }, mutations: {... }, actions: {... }} tagsView: {namespaced: true, state: {... }, mutations: {... }, actions: {... }} user: {namespaced: true, state: {... }, mutations: {... }, actions: {... }} __proto__: Object * */
export default createStore({
  modules,
  getters
})
Copy the code

Read the above writing method is not feeling, very sweet!!

styles

Provides some common CSS layouts, such as Flex layout, margin, padding, etc., can improve our development efficiency

SCSS: Animation related, like close and open animations in the sidebar

Elemenet-style-overflow. SCSS: Sets and resets the element-plus style, as in:

elemenet-style-overflow.scss .elODialogModalBodyH60vh { .el-dialog__body { min-height: 60vh; max-height: 70vh; }} use in dialog (reset height of el-dialog__body) <div class="elODialogModalBodyH60vh"> <el-dialog> <div Class ="detail-container-item">DBC file name </div> </el-dialog> </div>Copy the code

To avoid global style contamination, it is recommended to add one more layer to the reset, such as: ElODialogModalBodyH60vh, add div parent in the outer layer, add class (elODialogModalBodyH60vh) to reset, so as to avoid global pollution, but also to modify the effect of element native style

Variable. SCSS: global variable file

This file is configured globally in the viet.config. js file, and can be used directly without application

vite.config.js
css: {
  preprocessorOptions: {
    //define global scss variable
    scss: {
      additionalData: `@import "@/styles/variables.scss"; `}}},Copy the code

Scss-suger. SCSS: Flex, margin, padding Use good, page style do not have to write

Introduce how to use, experience what is really sweet!!

//flex
.rowSCRow -> flex-direction: row; S: specifies the main axis layout. S indicates context-content: flex-start. C: Set the layout mode in the cross axis direction. C means align-items: center..rowSSRowSE, columnSS,.columnSCsimilar//margin
mb-1: margin-bottom:10px;
mbPx-1:margin-bottom:1px; 1 mt - 1, Mr, ml is similar - 1Copy the code

using demo

<div class="widthPC-100"> <! - parallel layout - > < div class = "rowSS" > < div > 1 < / div > < div > 2 < / div > < / div > <! - centered layout - > < div class = "rowCC mt - 2" > < div > 3 < / div > < div > 4 < / div > < / div > <! - centered layout - > < div class = "columnCC mt - 2" > < div > 3 < / div > < div > 4 < / div > < / div > < / div >Copy the code

Variable-to-js. SCSS: Export CSS to js usage file (more on that later)

utils

General utility class

Auth.js: API for manipulating tokens. The previous JS-cookie (jS-cookie problem in electron) has been removed and localStorage has been used

Axiosreq.js: Axios requests encapsulation

Bus.js: used for information transfer in irrelevant components in VUe3, similar to new bus() in VUe2;

Getpagetitle.js: API for assembling title;

Validate.js: Some common validates

.env.build,.env.serve-dev,.env.serve-prod, package.json

//.env.serve-devVariables must start with VITE_APP_. Import. Meta. import.meta.env.VITE_APP_BASE_URL VITE_APP_ENV = 'serve' VITE_APP_BASE_URL = 'http:/ / 8.135.1.141 / micro - service - API '
VITE_APP_BASE_WS_URL = ''

//package.json
"scripts": {
   // Use --mode to specify your configuration file and run VITE_APP_xx to get the variables you set
  "dev": "vite --mode serve-dev --host"."build": "vite build --mode build"."build:serve": "vite build --mode build-serve"."serve": "vite preview --mode build"."preview": "yarn run build && vite preview "."lint": "eslint --ext .js,.jsx,.vue,.ts,.tsx src --fix"."prepare": "husky install"
},
Copy the code

Eslint Pretty Hook introduction

Eslint: Code quality verification

 // .eslintrc.js
 extends: [
    'plugin:vue/vue3-essential'.'eslint:recommended'.'@vue/typescript/recommended'.// The pretty plugin is configured for ESLint. Using pretty formatting will comply with esLint's verification rules
    '@vue/prettier'.'@vue/prettier/@typescript-eslint'
  ]
Copy the code

Prettier: Code formatting

{
    // Use TAB indentation, false by default
    "useTabs": false.// TAB indent size, default is 2
    "tabWidth": 2.// The newline length defaults to 80
    "printWidth": 120.// Strings use single quotes
    "singleQuote": true.// Whether to place a comma after the last element of an object or array (as in ES5)
    "trailingComma": "none".// Print Spaces in the object by default true
    // true: { foo: bar }
    // false: {foo: bar}
    "bracketSpacing": true.// Automatically add semicolons at the end of each line; False - > don't add
    "semi": false.// Formatting plug-in Prettier, formatting, end tag > next line
    "htmlWhitespaceSensitivity": "ignore"
}
Copy the code

When vscode or webstrom saves, format code automatically while prettier is used

After setting it up, you will find a different development experience

Git hook: git life hook function, which executes the shell script before committing

//pre-commit# push run before eslint check yarn run lint | | echo exit;Copy the code