前端总结之Control

前言

为了调试Auth后端,写了一个Vue的前端,结合以前写的文章,对Vue为代表的前端做一个总结,内容分为:

  • Control
  • View与Data
  • Element组件
  • CSS

本文是Control部分,这里是整个工程的结构,包括router、Layout、Navigation、interceptor等内容。

Router

整个前端框架是通过router结合在一起的,在router中注册各种路由(route),当访问这些路由时,引向相应的页面。Router是整个前端的控制核心。

在router的使用上,简单情况下,可以是固定的routes,但更多情况下是动态的routes,可以根据角色、权限的不同来显示不同的页面。

  • 首先声明asyncRoutes路由,并设置该路由所需要的权限
  • 然后在store中存储用户拥有的权限
  • 接着在router的拦截器(beforeEach)中进行对比,通过router.addRoutes()将复合的route注册进router。对比的结果也可以放到store中。
  • 最后还需要根据这些动态的route生成相应的Navigation。

Layout

Layout是Router的一部分,它是所有(或一部分)页面的共同的部分。

代码如下:

const routes: Array<RouteRecordRaw> = [
  {
    path: "/",
    redirect: "/dashboard",
  },
  {
    path: "/",
    name: "Layout",
    component: Layout,
    children: [
      {
        path: "/dashboard",
        name: "Dashboard",
        meta: {
          title: "首页",
        },
        component: () => import("../views/Dashboard.vue"),
      },
      {
        path: "/org",
        name: "Org",
        meta: {
          title: "组织管理",
        },
        component: () => import("../views/Org.vue"),
      }
        //... More...
        ]
  }

这里通过在父route上加componet的形式,使子route继承了这些公共的组件。

当然,这些公共组件也需要对嵌入其中的子compont留出空间,通过route-view来嵌入相应子组件,示例:

<template>
    <Header></Header>
    <Sidebar></Sidebar>
    <div class="content-box" :class="{'content-collapse': isCollapse}">
        <router-view v-slot="{ Component }">
            <transition name="move" mode="out-in">
                <keep-alive>
                    <component :is="Component"></component>
                </keep-alive>
            </transition>
        </router-view>
    </div>
</template>

公共的组件可以包括但不限于:header、sidebar(Navigation)、breadcrumb等等内容

Navigation

Navigation是一个网站很重要的一个方面,从位置上,可以是侧栏导航,也可以是顶部导航;从层级上有1层、2层、3层多种形式, 可以参考element-plus导航建议

导航渲染的就是route注册的路由,这样对于动态的route,从store中获取它们会更方便一些。示例:

<template>
    <div class="sidebar">
        <el-menu class="sidebar-el-menu" :default-active="onRoutes" :collapse="isCollapse" router>
            <template v-for="item in routes">

                <template v-if="!item.subs">
                    <el-menu-item :index="item.index" :key="item.index">
                        <el-icon>
                            <component :is="item.icon"></component>
                        </el-icon>
                        <template #title>{{ item.title }}</template>
                    </el-menu-item>
                </template>

                <template v-else>

                    <el-sub-menu :index="item.index"  :key="item.index">
                        <template #title>
                            <el-icon>
                                <component :is="item.icon"></component>
                            </el-icon>
                            <span>{{ item.title }}</span>
                        </template>

                        <template v-for="subItem in item.subs"  :key="subItem.index">
                            <el-menu-item :index="subItem.index">
                             {{ subItem.title }}
                            </el-menu-item>
                        </template>
                    </el-sub-menu>
                </template>
            </template>
        </el-menu>
    </div>
</template>

Interceptor

router的拦截

每个内部跳转时,都进行调用

router.beforeEach((to, from, next) => {
  // ...
})

router.afterEach((to, from) => {
  // ...
})

这个next是一个导航,确保 next 函数在任何给定的导航守卫中都被严格调用一次。

以上为全局的,每个路由还有可以有。

const router = new VueRouter({
  routes: [
    {
      path: '/foo',
      component: Foo,
      beforeEnter: (to, from, next) => {
        // ...
      }
    }
  ]
})

axios的拦截

axios的拦截是通过service.interceptors.requestservice.interceptors.response来完成的,在访问前的request拦截中,可以增加公共的Header,在返回的response拦截中,可以结果,尤其是错误进行相应的处理。

service.interceptors.request.use(
  (config) => {
    // 这里可以对request的header加点料
    return config;
  },
  (error) => {
    console.log(error);
    return Promise.reject();
  }
);

service.interceptors.response.use(
  (response: AxiosResponse<any>) => {
    const { data, config } = response;
    if (response.status === 200) {
     	// 正确放回的处理...
    } else {
      Promise.reject();
    }
  },
  (error) => {
    const { response, message } = error;
    // 错误返回的处理...
);

总结

前端控制的核心是Router,通过Router组织全部的页面。Router中配置公共的Layout,一个重要的Layout就是Navigation。与后端类似,这里也有拦截器,最常用的是Router渲染时的拦截,以及axios访问后端的拦截。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×