前端开发调试-管理端vue3脚手架

103 阅读4分钟

背景

项目伊始阶段或者在接手新项目,了解前端基本架构了解前端脚手架需要具备什么能力很重要。一个好的脚手架会提供完备的能力,助力开发者日常codeing。

介绍

以下介绍是在多年开发中,总结下来关于管理端较为完备的脚手架能力清单。基于create-vue创建的脚手架进行描述、增加我们日常开发可能需要用的功能。对于脚手架更底层的组成,需要自己去一一了解、翻查。想要学习到更多知识的前端初学者更需要去了解现成脚手架各个底层能力才能更好地驾驭、使用、完善属于自己的业务脚手架。

脚手架搭建介绍

  • 现成脚手架 (vue)

    vue 脚手架选型: vue + vue-router + elementPlus + pinia + axios + ts

    使用以下命令:官网

    npm create vue@latest
    

    根据提示选择对应的模块

  • 环境变量

    Vue脚手架: vite 环境变量定义 官网介绍

    环境变量(local、dev、test、uat、prod)

    image.png

    vite 默认加载.env、.env.local 文件。.env.[mode] 只在指定模式下加载。 mode 指定模式命令为 vite --mode

    vite默认防止意外地将一些环境变量泄漏到客户端,只有以 VITE_ 为前缀的变量才会暴露给经过 vite 处理的代码

  • 全局变量

vue 教授架在变量的配置方式都一样,在加载环境文件中定义变量。

vite 环境变量文件配置例子(.env[mode])

NODE_ENV=test
# Whether to open mock
VITE_USE_MOCK = true

# public path
VITE_PUBLIC_PATH = /

# Delete console
VITE_DROP_CONSOLE = true
    
# proxy config
VITE_PROXY = [["/api","http://localhost:8080"],["/upload","http://localhost:9090"]]

vite.config.ts

// https://vitejs.dev/config/
export default defineConfig(({ command, mode }) => {
  const env = loadEnv(mode, process.cwd(), '')
  const viteEnv = wrapperEnv(env);
  const { VITE_PORT,VUE_APP_ENV } = viteEnv;
  return {
    plugins: [vue()],
    resolve: {
      alias: {
        
      }
    },
    server: {
      port: VITE_PORT,
      proxy: {

      },
    },
    define: {
        // 全局变量
      __APP_ENV__: JSON.stringify(VUE_APP_ENV)
    }
  }
})

  • 全局状态

    vue脚手架可以选择全局状态管理,在组合式api的项目里面推荐使用 Pinia, Pinia 是 Vue 的专属状态管理库,它允许你跨组件或页面共享状态。

    注意:状态可以分为全局状态、页面状态、组件状态,划分好状态层级,并将状态在合适的层级维护

  • 页面状态缓存 (keep-alive) vue提供了组件 keep-alive,在多个组件间动态切换时缓存被移除的组件实例

    <template> 
        <router-view v-slot="{ Component }"> 
            <keep-alive> 
                <component :is="Component" v-if="$route.meta.keepAlive"/> 
            </keep-alive> 
            <component :is="Component" v-if="!$route.meta.keepAlive"/> 
        </router-view> 
    </template>
    
    
    {
        path: "/demo",
        name: "demo",
        meta: {
            keepAlive: true //设置页面是否需要使用缓存
        },
        component: () => import("@/views/demo.vue")
    }
    
  • 逻辑封装

    vue脚手架请求封装 (axios) 脚手架提供请求统一处理文件路径 src/service/index.ts

    请求拦截

        // 请求拦截
        axios.interceptors.request.use((config): AxiosRequestConfig<unknown> => {
          return config
        })
    

    请求拦截统一处理请求中的必须传参、headers。如:默认接口拼接参数、请求请求头(headers) Content-Type 、统一鉴权token、全局loading等处理

    响应拦截

       // 错误处理
       const errorHandler = (error: any) => {
         const { response } = error
         if (response && response.status) {
           const { status } = response
           if (status < 400) {
             // 一些操作
           } else if (status < 500) {
             // ...一些操作
           } else {
             // 一些操作
           }
    
           return response
         }
       }
       
      // 响应拦截
       axios.interceptors.response.use(
         (res) => {
           return res
         },
         (error) => {
           errorHandler(error)
           return error
         }
       )
    

    响应拦截错误处理处理业务错误报错包括且不限于: 未登录、登录失效、后端异常、接口404、接口失败约定

    响应拦截统一处理非异常情况后端接口返回正常,但是业务需要特殊处理部分逻辑。如:统一处理后端返回数据流,处理图片流,音频流等

  • 组件封装

    脚手架提供统一业务组件路径:src/components。组件封装包含且不限于:布局组件、菜单组件、头部栏组件、页面缓存标签组件、页面内容组件、表单组件、查询条件组件、表格组件、编辑表格组件、带查询条件表格组件、 内容描述组件等

  • 业务封装

    vue: 组合式api

    统一封装业务流程包含且不限于:登录流程、客户端缓存(storage、IndexdDB、cookies)、页面keepAlive声明周期与系统中定制的业务功能等

  • module 封装 (实验)

    以页面模块为封装模型统一封装接口模型,统一接口模型有一下优势:

    1、抽取service层,分层管理

    2、提高接口复用性、拓展性、可维护

    3、service模块可按需注入页面

    4、模板化接口层,代码生成

    const useOptionsMemberInfo = () => {
     const memberList = reactive({});
     const memberDetail = reactive({})
     const getMemberInfoList = async (payload) => {
         try {
           const { result, code } = await service({
             url: API.getMemberByPage,
             method: 'GET',
             payload,
           });
           if(code === 0){
             Object.assign(memberList,result)
           }
         } catch (error) {
           console.log(error)
         }
     };
     const getMemberDetail = async (payload) => {
       try {
         const { result, code } = await service({
           url: API.getMemberDetail,
           method: 'GET',
           payload,
         });
         if(code === 0){
           Object.assign(memberDetail,result)
         }
       } catch (error) {
         console.log(error)
       }
    };
     const delMember = async (payload) => {
       try {
         const { result, code } = await service({
           url: API.delMember,
           method: 'POST',
           payload,
         });
         if(code === 0){
           // message 删除成功
         }
       } catch (error) {
         console.log(error)
       }
     };
     const addMember = async (payload) => {
       try {
         const { result, code } = await service({
           url: API.addMember,
           method: 'POST',
           payload,
         });
         if(code === 0){
           // message 新增成功
         }
       } catch (error) {
         console.log(error)
       }
     };
     const upadteMember = async (payload) => {
       try {
         const { result, code } = await service({
           url: API.upadteMember,
           method: 'POST',
           payload,
         });
         if(code === 0){
           // message 新增成功
         }
       } catch (error) {
         console.log(error)
       }
     };
     return {
       memberList,
       memberDetail,
       getMemberInfoList,
       delMember,
       addMember,
       upadteMember,
       getMemberDetail
     };
    };
    
    export default useOptionsMemberInfo;
    
  • utils功能单元封装

    统一封装业务流程包含且不限于:字符加密解密工具、处理js精度问题的加减乘除计算工具、url处理工具、图片base64文件处理工具、输入表单校验正则工具、时间处理工具

  • 文件格式规范

    参考文章 前端代码规范