头图
The essence of the starting point is to learn vue3, vite, typescript, and create a set of enterprise management background menu permission control, routing control, component design, network asynchronous components, hook meaning, construction compilation, and design patterns, and learn new technologies for yourself. Cognition and insights are also a summary of one’s mastery of previous knowledge points

New Project

Since the starting point is running vite, of course we have to install vite first

Vite requires Node.js version >= 12.0.0

# 安装vite
npm init vite@latest 

# npm 6.x
npm init vite@latest my-vue-app --template vue # 拉取模板 -- 官网提供更多模板选择

# npm 7+, 需要额外的双横线:
npm init vite@latest my-vue-app -- --template vue # 拉取模板 -- 官网提供更多模板选择

Official Document-How to install vite

After the project is installed, there will be three common configuration commands in package.json

{
    "scripts": {
        "dev": "vite",
        // 启动开发服务器,别名:`vite dev`,`vite serve`
        "build": "vite build",
        // 为生产环境构建产物
        "preview": "vite preview"
        // 本地预览生产构建产物
    }
}

Start service

# 安装依赖
npm install 

# 启动服务
npm run dev 

The above port 3000 appears without accident, that is, visit http://localhost:3000/

project address

🎉🎉🎉🎉🎉GitHub

Project preview

🎉🎉🎉🎉🎉 online preview

vue-vite-admin-ts

Build the layout

In src/main.js

import {createApp} from 'vue'
import App from './App.vue'
import router from '@/packages/router'
import setupInit from '@/packages/base/index'
import mitt from "mitt";

const app = createApp(App)
app.provide("$mitt", mitt());
setupInit(app)
router.isReady().then(() => {
    app.mount('#app')
})
  • Mitt is a global communication that replaces Vue2's EventBus. It is a small and active third-party message publish/subscribe JavaScript library. The official document is not related to the framework, so this React and Vue can be used.

packages/layout/index.vue final layout file


<template>
    <a-layout style="height: 100%">
        <Slider/>
        <a-layout :style="{marginLeft}" class="layout" :class="layoutClassName">
            <HeaderTop/>
            <HeaderProcess/>
            <LayoutContainer/>
        </a-layout>
    </a-layout>
</template>
<script lang="ts">
import {defineComponent, computed} from 'vue';
import Slider from './slider.vue'
import HeaderTop from './headerTop.vue'
import HeaderProcess from './headerProcess.vue'
import LayoutContainer from './layoutContainer.vue'
import {themeHook} from '@/packages/hook'
import {useStore} from "vuex";

export default defineComponent({
    components: {
        Slider,
        HeaderTop,
        HeaderProcess,
        LayoutContainer
    },
    setup() {
        const {layoutClassName} = themeHook()
        const store = useStore();
        const marginLeft = computed(() => store.state.app.themeConfig.menuMaxWidth + 'px')
        return {
            layoutClassName,
            marginLeft
        }
    }
});
</script>

Routing introduction

Vue Router4 is the official router of Vue.js. It is deeply integrated with the core of Vue.js, making it easy to build single-page applications with Vue.js. Features include:

  • Nested route map
  • Dynamic routing
  • Modular, component-based routing configuration
  • Routing parameters, queries, wildcards
  • Show the transition effect provided by the transition system of Vue.js
  • Detailed navigation control
  • Automatically activate links to CSS classes
  • HTML5 history mode or hash mode
  • Customizable scrolling behavior
  • Correct encoding of URL

For specific documents, please see packages/router/index.ts

import {createRouter, createWebHashHistory, createWebHistory, RouteRecordRaw, RouterOptions} from 'vue-router'
import {routerMode} from '@/packages/config';
import {App} from 'vue';
import {setupRouterGuard} from '@/packages/router/guard'
import {setupBeforeStore} from "@/packages/router/beforeStore";
import {setAddRoute} from '@/packages/router/addRoute'

// 定义路由
const routes: Array<RouteRecordRaw> = [
    {
        path: "/",
        name: "admin",
        component: () => import('@/packages/layout/index.vue'),
        children: [
            {path: '', redirect: 'home'},
            {
                path: '/home', name: 'home', meta: {title: '首页'},
                component: () => import('@/packages/views/home/index.vue')
            },
        ]
    },
    {
        path: "/login", name: 'login', meta: {title: '登录'},
        component: () => import('@/packages/views/login/index.vue'),
    },
    {
        path: "/test", name: 'test', meta: {title: '测试页面'},
        component: () => import('@/packages/views/test/index.vue'),
    },
    {
        path: '/404',
        component: () => import('@/packages/views/error/404.vue'),
    },
    {
        path: '/:catchAll(.*)*', // 不识别的path自动匹配404
        redirect: '/404',
    },
]

// 实列化router
const router = createRouter({
    history: routerMode === 'history' ? createWebHistory() : createWebHashHistory(),
    routes
})


router.beforeEach((to: any, from: any, next: any) => {
    setupBeforeStore()
    setupRouterGuard(to, from, next)
});

const setupRouter = (app: App) => {
    setAddRoute(app, router)
    app.use(router)
}

export default router;
export {
    setupRouter
}

Vuex

Vuex4 is a state management mode + library specially developed for Vue.js applications. It uses centralized storage management to manage the state of all components of the application, and uses corresponding rules to ensure that the state changes in a predictable manner

For specific documents, please see packages/store/index.ts

import type {App} from 'vue';
import {createStore} from 'vuex'
import user from './user'
import app from './app'
import {setAddStore} from "@/packages/store/addStore";


const store: any = createStore({
    modules: {
        user,
        app
    }
})


const setupStore = (app: App) => {
    setAddStore(app, store)
    app.use(store)
}

export {
    setupStore
}
export default store;

axios

Axios is a promise-based HTTP library that can be used in browsers and node.js,

  • Create XMLHttpRequests from the browser
  • Create http request from node.js
  • Support Promise API
  • Intercept request and response
  • Convert request data and response data
  • Cancel request
  • Automatically convert JSON data
  • Client supports defense against XSRF

The code here should also have response interception, request interception, but not pasted out, please see packages/http/request.ts , automatic reconnection, error return, encapsulating common request usage methods


const post = (url: string, params, config) => {
    return http.post(rewriteUrl(url), params, config)
}

const get = (url: string, params, config) => {
    return http.get(rewriteUrl(url), {params: params, ...config})
}


const all = (request: Array<any>) => {
    return axios.all(request)
}


const upload = (url: string, params) => {
    let config = {
        headers: {
            "Content-Type": "multipart/form-data",
        },
    };
    return http.post(rewriteUrl(url), params, config);
};


const download = (url: string, params, config) => {
    return axios({
        method: "post",
        url: rewriteUrl(url), //后端下载接口地址
        responseType: "blob", // 设置接受的流格式
        data: {
            ...params,
        },
        params: {
            ...params
        }
    }).then((res: any) => {
        handleExport(res.data, config.fileName);
    })
};


export {
    post,
    get,
    all,
    upload,
    download,
}

Catalog Introduction

egg

Provide basic services, edit the main menu, dynamically load routing, complete additions, deletions, and changes. Please see egg/app/controller/home.js

cd /vue-vite-admin-ts/egg
npm install // 安装egg.js所需要的依赖
npm run dev // 开发模式 
npm run serve // 服务模式

After obtaining the project, open egg/config/config.default.js and fill in your own data name in the username

config.sequelize = {
    dialect: 'mysql',
    host: '127.0.0.1',
    port: 3306,
    username: 'xxxx', // 数据库用户名
    password: '**123456**', // 数据库密码
    database: 'egg',
    define: { // model的全局配置
        timestamps: true, // 添加create,update,delete时间戳
        paranoid: false, // 添加软删除
        freezeTableName: true, // 防止修改表名为复数
        underscored: false // 防止驼峰式字段被默认转为下划线
    }
}

mock directory

It is well known that Mock.js has swept the front end because of two important features:

  • Rich data types: support the generation of random text, numbers, Boolean values, dates, mailboxes, links, pictures, colors, etc.
  • Intercept Ajax requests: You can intercept Ajax requests without modifying the existing code and return simulated response data. Safe and convenient
Mock.mock("/api/yxs/notice", 'post', () => {
    const data = Mock.mock({
        "array|5": [
            {
                id: "@id", // 随机id
                text: "@cword(10)", // 随机文本
                createTime: "@datetime(MM-dd HH:mm:ss)",
            }
        ]
    })
    // 指定规则统一数据格式
    const result: resData = {
        code: 1,
        message: '请求成功',
        data: data.array,
    }
    return result;
})

Use mock, just import it in the main.js file

src

Place the source directory

├── src                                 // 源码目录
    |────packages                           // 应用主资源
    |──assets                               // 图片等资源
    |──base                                 // 基础配置
    |──common                               // 处理公共函数
    |──components                           // 全局组件
    |──config                               // 配置入口
    |──extend                               // 扩展目录
    |──hook                                 // 放置钩子函数
    |──http                                 // 网络请求
    |──layout                               // 布局
    |──plugin                               // 插件
    |──router                               // 路由
    |──service                              // 请求接口
    |──store                                // 数据存储
    |──style                                // 样式入口
    |──theme                                // 主题
    |──utils                                // 公共工具方法
    |──views                                // 页面组件
    |──install.ts                           // 应用入口文件
    |──App.vue                              // 入口组件
    |──main.ts                              // 默认应用文件(lib.html)

typings directory

Placed in the typescript environment for development, global variables, to avoid the editor prompting errors

export {};
declare global {
    declare interface Window {
        __app__: any,
        $: any,
        less: any
    }
}

File introduction

.editorconfig

editorconfig is a configuration file used to maintain a consistent coding style for multiple developers across different editors and IDEs. The editorconfig project consists of a file format that defines an encoding style and a set of text editor plug-ins. The editor plug-ins read the file and format the specified file with the defined style.
The editorconfig file is user-friendly and can work well with the version control system

root = true

[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

.eslintignore

eslin check code filter file

/examples
/html
/lib/*
/public

/test
/mock
/egg/*
/dist
/typings
*.sh
node_modules

iconfont.*
*.md
*.scss
*.woff
*.ttf
vite.config.ts

.eslintrc.js

In the development process of JavaScript for more than 20 years, many lint tools have appeared. Here are three mainstream lint tools.

  • JSLint
  • JSHint
  • ESLint

ESLint is known as the next-generation JS Linter tool. It is inspired by PHP Linter, which parses the source code into an AST, and then checks the AST to determine whether the code conforms to the rules. ESLint uses esprima to parse the source code into
AST, then you can use any rules to detect whether the AST meets expectations, which is also the reason for ESLint's high scalability

module.exports = {
    rules: {
        // 缩进 4 空格
        "indent": [2, 4],

        // 禁止空格和 tab 的混合缩进
        'no-mixed-spaces-and-tabs': 1,

        // 禁用 debugger
        'no-debugger': 1,

        // 禁止不必要的布尔转换
        'no-extra-boolean-cast': 1,

        // 强制所有控制语句使用一致的括号风格
        'curly': 1,

        // 禁止使用多个空格c
        'no-multi-spaces': 1,

        // 要求在函数标识符和其调用之间有空格
        'func-call-spacing': 1,

        // 关闭 强制在函数括号内使用一致的换行
        'function-paren-newline': 0,

        // 强制隐式返回的箭头函数体的位置
        'implicit-arrow-linebreak': 1,

        // 强制在对象字面量的属性中键和值之间使用一致的间距
        'key-spacing': 1,

        // 强制在关键字前后使用一致的空格
        'keyword-spacing': 1,

        // 要求调用无参构造函数时有圆括号
        'new-parens': 1,

        // 禁止出现多行空行
        'no-multiple-empty-lines': 1,

        // 不检查后面是否有分号
        'semi': 0,

        // 要求操作符周围有空格
        'space-infix-ops': 1,

        //数组中不允许出现空位置
        'no-sparse-arrays': 2,

        // 不允许有声明后未使用的变量或者参数
        'no-unused-vars': 'off',

        'vue/script-setup-uses-vars': 'off',  // 如果使用 script-setup 可開啟

        'vue/component-definition-name-casing': 'off' // 驼峰命名
    },
}

.huskyrc

Husky can prevent wrong git commit, git push and more woof!

Mainly used to check whether the code is submitted and prevent the team from appearing irregular code

// package.json
{
  "husky": {
        "hooks": {
            "pre-commit": "lint-staged"
        }
    },
    "lint-staged": {
        "*.{vue, ts}": [
            "eslint --quiet",
            "git add"
        ]
    },
}
git commit -m '测试提交' 

.npmrc

.npmrc, can be understood as npm running cnfiguration, that is, npm runtime configuration file

Create a new .npmrc file in the root directory of the project, and configure it in the format of key=value. For example, to configure the source of npm as Taobao source, set the proxy

registry = https://registry.npmjs.org/

Of course you can set it manually

config set registry https://registry.npm.taobao.org

.prettierrc

vsCode uses the prettier extension, combined with the .prettierrc configuration file to format the code

module.exports = {
    // 一行最多 100 字符
    printWidth: 100,
    // 使用 4 个空格缩进
    tabWidth: 4,
    // 不使用缩进符,而使用空格
    useTabs: false,
    // 行尾不需要有分号
    semi: false,
    // 使用单引号
    singleQuote: true,
    // 对象的 key 仅在必要时用引号
    quoteProps: 'as-needed',
    // jsx 不使用单引号,而使用双引号
    jsxSingleQuote: false,
    // 尾随逗号
    trailingComma: 'all',
    // 大括号内的首尾需要空格
    bracketSpacing: true,
    // jsx 标签的反尖括号需要换行
    jsxBracketSameLine: false,
    // 箭头函数,只有一个参数的时候,也需要括号
    arrowParens: 'always',
    // 每个文件格式化的范围是文件的全部内容
    rangeStart: 0,
    rangeEnd: Infinity,
    // 不需要写文件开头的 @prettier
    requirePragma: false,
    // 不需要自动在文件开头插入 @prettier
    insertPragma: false,
    // 使用默认的折行标准
    proseWrap: 'preserve',
    // 根据显示样式决定 html 要不要折行
    htmlWhitespaceSensitivity: 'css',
    // 换行符使用 lf
    endOfLine: 'lf',
}

Prettier used to format the code, keeping the semicolon, single and double quotation marks in the code uniform.

ESLint mainly used to check the syntax errors of JavaScript code, and can also play a role in standardizing the code format.

In daily development, we have to use both Prettier and ESLint. Use ESLint to check possible syntax errors in the code, use Prettier to adjust the code format

[t]sconfig.json

{
    "compilerOptions": {
        "baseUrl": "./",
        "paths": {
            "@/*": [
                "src/*"
            ],
            "__ROOT__/*": [
                "*"
            ]
        }
    },
    "exclude": [
        "node_modules"
    ]
}

The configuration editor presses ctrl+mouse and slides to the path, it will automatically prompt to the file directory

vite.config.js

For specific configuration, please see the official document https://cn.vitejs.dev/config/

export default defineConfig(({command, mode}) => {
    if (command === 'serve') {
        return {
            // dev 独有配置
        }
    } else {
        // command === 'build'
        return {
            // build 独有配置
        }
    }
})

Finished function

✅ Use Vue 3

✅ Use Vuex 4.x

✅ Use Vue-router 4.x

✅ Based on Vite 2.6

✅ Based on Ant Design Vue

✅ Overall framework responsive layout

✅ Project switching

✅ User login interception, user logout

✅ Breadcrumb navigation + multiple layout effects

✅ Based on background permissions, button permissions design

✅ Menu navigation + multiple layouts

✅ Built-in iconfont font icons, automatically generated components

✅ Package post, get, all, upload, download based on axios

✅ http error reconnect

✅ Component permission instruction package

✅ tsx builds global components

✅ http network component (new feature of vue3)

✅ Menu management, including adding, deleting, modifying, and checking, the menu is cached, whether it is fixed, whether it is hidden (but displayed), whether it is hidden or not, waiting for specific functions, view the document

✅ Contains rich text editor, file printing, chart preview, animation components, status details components, etc.

✅ Support multi-page applications

✅ Support iframe embedded

✅ Page refresh

✅ Full screen of the page

✅ Right-click menu package

✅ Scroll bar optimization

✅ Skeleton screen component preview

✅ Deep traversal, search, and irregular search based on the package loadsh

✅ Global communication based on mitt

✅ Solve tens of thousands table rendering based on vxe-table

✅ Mock data

✅ Egg.js back-end service, see the documentation for specific operations

✅ sequelize model addition, deletion, modification and investigation

✅ Eslint code check

✅ Development editor global configuration

✅ Package compression processing Gzip


羊先生
1.9k 声望821 粉丝