V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
vipbic
V2EX  ›  程序员

🎅 🎅 🎅 站在 Vue3 上-构建管理系统 vue-vite-admin-ts

  •  1
     
  •   vipbic · 2021-12-24 19:34:26 +08:00 · 1082 次点击
    这是一个创建于 1090 天前的主题,其中的信息可能已经有所发展或是发生改变。

    出发点的本质是想学习下 vue3 、vite 、typescript 、以及在创建企业管理后台菜单权限控制、路由控制、组件设计、网络异步组件、hook 意义、构建编译、设计模式的集合,对自己使用学习新技术的认知和见解,也是对自己在以往的知识点的掌握做出一个总结

    新建项目

    既然出发点奔着 vite ,当然我们得先安装 vite

    Vite 需要 Node.js 版本 >= 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 # 拉取模板 -- 官网提供更多模板选择
    

    官方文档-如何安装 vite

    项目安装完成后,在 package.json 中会出现三条我们所常见配置命令

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

    启动服务

    # 安装依赖
    npm install 
    
    # 启动服务
    npm run dev 
    

    上述不出意外的出现端口 3000 的端口,即访问 http://localhost:3000/

    项目地址

    🎉🎉🎉🎉🎉GitHub

    项目预览

    🎉🎉🎉🎉🎉在线预览

    vue-vite-admin-ts

    构建布局

    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 是全局通信就是取代 Vue2 的 EventBus ,是一个体积极小的第三方消息发布 /订阅式 JavaScript 库 官方文档是与框架无关的,所以这个 React 、Vue 都可以用

    最终布局文件请看packages/layout/index.vue

    
    <template>
        <a-layout style="height: 100%">
            <Slider/>
            <a-layout :style="{marginLeft}" class="layout" :class="layoutClassName">
                <HeaderTop/>
                <HeaderProcess/>
                <LayoutContainer/>
            </a-layout>
        </a-layout>
    </template>
    

    路由介绍

    Vue Router4 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举。功能包括:

    • 嵌套路由映射
    • 动态路由选择
    • 模块化、基于组件的路由配置
    • 路由参数、查询、通配符
    • 展示由 Vue.js 的过渡系统提供的过渡效果
    • 细致的导航控制
    • 自动激活 CSS 类的链接
    • HTML5 history 模式或 hash 模式
    • 可定制的滚动行为
    • URL 的正确编码

    具体文件请看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 是一个专为 Vue.js 应用程序开发的状态管理模式 + 库。它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化

    具体文件请看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 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中,

    • 从浏览器中创建 XMLHttpRequests
    • 从 node.js 创建 http 请求
    • 支持 Promise API
    • 拦截请求和响应
    • 转换请求数据和响应数据
    • 取消请求
    • 自动转换 JSON 数据
    • 客户端支持防御 XSRF

    此处代码还应有响应拦截,请求拦截,没有粘贴出来,具体请看packages/http/request.ts,自动重连,错误返回,封装了常见的请求使用方式

    
    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,
    }
    

    目录介绍

    egg

    提供基础服务,主要菜单编辑这块,动态加载路由,完整的增删改查,具体代码请看egg/app/controller/home.js

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

    获取项目后,打开 egg/config/config.default.js 请在 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 目录

    众所周知 Mock.js 因为两个重要的特性风靡前端:

    • 数据类型丰富 :支持生成随机的文本、数字、布尔值、日期、邮箱、链接、图片、颜色等。

    • 拦截 Ajax 请求 :不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。安全又便捷

    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;
    })
    

    使用 mock ,只需在 main.js 文件中引入即可

    src

    放置源码目录

    ├── 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 目录

    放置在 typescript 环境中开发,全局变量,避免编辑器提示报错

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

    文件介绍

    .editorconfig

    editorconfig 是用于跨不同的编辑器和 IDE 为多个开发人员维护一致的编码风格的配置文件。editorconfig 项目由定义编码样式的文件格式和一组文本编辑器插件组成,编辑器插件通过读取文件并以已定义的样式格式化指定文件。 editorconfig 文件具有友好的阅读性,且能与版本控制系统配合良好的特点

    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 检查代码过滤文件

    /examples
    /html
    /lib/*
    /public
    
    /test
    /mock
    /egg/*
    /dist
    /typings
    *.sh
    node_modules
    
    iconfont.*
    *.md
    *.scss
    *.woff
    *.ttf
    vite.config.ts
    

    .eslintrc.js

    在 JavaScript 20 多年的发展历程中,也出现过许许多多的 lint 工具,下面就来介绍下主流的三款 lint 工具,

    • JSLint
    • JSHint
    • ESLint

    ESLint 号称下一代的 JS Linter 工具,它的灵感来源于 PHP Linter ,将源代码解析成 AST ,然后检测 AST 来判断代码是否符合规则。ESLint 使用 esprima 将源代码解析吃成 AST ,然后你就可以使用任意规则来检测 AST 是否符合预期,这也是 ESLint 高可扩展性的原因

    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 可以防止错误的 git commit ,git push 和更多 woof !

    主要用于检查代码是否通过在提交,防止团队出现不规范的代码

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

    .npmrc

    .npmrc ,可以理解成 npm running cnfiguration, 即 npm 运行时配置文件

    在项目的根目录下新建 .npmrc 文件,在里面以 key=value 的格式进行配置。比如要把 npm 的源配置为淘宝源, 设置代理

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

    当然你可以手动设置

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

    .prettierrc

    vsCode 使用 prettier 扩展,结合 .prettierrc 配置文件格式化代码

    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 用来格式化代码,保持代码中分号,单双引号等等格式统一。

    ESLint 主要用来校验 JavaScript 代码语法错误,也能起到规范代码格式的作用。

    在日常开发中,我们既要使用 Prettier, 也要使用 ESLint 。用 ESLint 检查代码中可能存在的语法错误, 用 Prettier 调整代码格式

    [t]sconfig.json

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

    配置编辑器按住 ctrl+鼠标滑到路径处,会自动提示到文件目录里面去

    vite.config.js

    具体配置请看官方文档https://cn.vitejs.dev/config/

    export default defineConfig(({command, mode}) => {
        if (command === 'serve') {
            return {
                // dev 独有配置
            }
        } else {
            // command === 'build'
            return {
                // build 独有配置
            }
        }
    })
    
    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1524 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 17:05 · PVG 01:05 · LAX 09:05 · JFK 12:05
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.