图书馆系统从开发到部署--框架搭建

121 阅读2分钟

前言

书接上文,因为刚开发时的想法有点问题,所以框架也就有点小问题,但是能用。

登录

登录系统的有三种人,游客、读者、管理员。登录的权限判断使用vue-router的全局路由守卫。

router.beforeEach(async(to) => {
  const hasToken = getToken()
  if (hasToken) {
    if (to.path === "/login") {
      return "/"
    } else {
      const hasGetUserInfo = store.getters.roles || []
      if (hasGetUserInfo.length) {
        return true
      } else {
        try {
          await store.dispatch("user/getInfo").then(res => {
            const roles = res.data.roles
            store.dispatch("permission/generateRoutes", roles).then((accessedRoutes) => {
              accessedRoutes.map(item => {
                router.addRoute(item)
              })
              router.push(to.path)// hack方法 确保addRoutes已完成
              return true
            })
          })
        } catch (error) {
        }
      }
    }
  } else {
    store.dispatch("permission/initRoutes")
  }
})

逻辑很简单,但是这里需要注意的是,try、catch是无法捕获异步行为的错误的,例如Promise。如果想用的话就要如上使用await

layout

layout由三部分构成,分别是main、navbar、siderbar,下面为预览。 QQ截图20220430170342.png

siderbar

siderbar已经在前面总结过了。

<template>
  <div :class="classObj"
       class="app-wrapper">
    <sidebar class="sidebar-container" />
    <div class="main-container">
      <navbar />
      <app-main />
    </div>
  </div>
</template>

    const classObj = computed(() => {
      return {
        hideSidebar: store.getters.isCollapse,
        openSidebar: !store.getters.isCollapse
      }
    })

这里classObj通过vuex里的isCollapse判断是否折叠siderbar。

AppMain

AppMain这里是vue3的统一写法了,当时用transition和keep-alive时。以后的路由组件都会显示在这里。

<template>
  <section class="app-main">
    <router-view v-slot="{Component}">
      <transition name="fade-transform"
                  mode="out-in">
        <keep-alive :include="[]">
          <component :is="Component" />
        </keep-alive>
      </transition>
    </router-view>
  </section>
</template>

Navbar

Navbar其实并没有什么实际意义,主要就是提供一个breadcrumb和刷新后退的功能,前者官网的教程很详细,稍微说一下刷新功能。

主要是通过一个redirect路由组件来实现,这个组件在别的地方也有用到。

  //redirect.vue
  setup() {
    const route = useRoute()
    const router = useRouter()
    const { params, query } = route
    const { path } = params
    router.replace({ path: "/" + path, query })
  }
  //navbar.vue
    function refresh() {
      router.replace({
        path: "/redirect" + route.fullPath
      })
    }
  //index.js
{
  path: "/redirect",
  component: Layout,
  hidden: true,
  children: [{
    name: "redirect",
    path: "/redirect/:path(.*)",
    component: () =>
      import ("@/views/redirect/index")
  }]
},

path: "/redirect/:path(.*)"会把/redirect后的东西当成params传给redirect组件,当然对应的你在路由传递参数时就不能使用params而是要使用query。

剩下的说白了就是把路径传给redirect组件,然后在redirect里重定向至原页面。

还有需要注意的就是appmain里的include="[]"不能包括redirect组件,否则redirect组件不能正常工作

axios封装

这里也是每次项目直接CV然后微微改动就行的部分。

import axios from "axios"
import store from "@/store"

const service = axios.create({
  baseURL: process.env.NODE_ENV === "development" ? "http://****" : "https://*****",
  timeout: 5000 
})

service.interceptors.request.use(
  config => {
    return config
  },
  error => {
    console.log(error)
    return Promise.reject(error)
  }
)

service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code !== 0) {
      if (response.config.url === "/pay") return response
      return Promise.reject(new Error(res.message || "Error"))
    } else {
      return res
    }
  },
  error => {
    console.log("err" + error) // for debug
    return Promise.reject(error)
  }
)
export default service

结语

写的时候感觉写了很久,事后总结起来感觉好像也就只弄了这么一点点内容而已....