Vue3+TypeScript+Django Rest Framework 搭建个人博客(三):博客管理后台(2)

一个完整的网站都是有前台和管理后台组成的,前台用来给真正的用户浏览和使用,后台用来给管理员管理网站内容,配置各种功能和数据等。博客的管理后台就是用来承载创建博客,发布博客,查看留言,管理博客用户这些功能的子系统。

大家好,我是落霞孤鹜,上一篇我们已经实现了管理后台的后端接口部分,这一章我们开始搭建博客的管理后台的前端,实现对博客网站的管理功能。

一、前端界面开发

一个管理后台的功能,一般都需要从最基础的业务对象的管理开始,在我们的博客网站上,业务对象间的依赖依次是用户、标签、分类、文章、评论、点赞、留言、首页统计。

基于这个依赖关系,我们的后台管理功能也按照这样的逻辑顺序进行构建。然后在构建每一个业务对象的管理页面时,按照TypeAPIComponentViewRoute顺序进行组织和代码编写。

src/views下创建两个文件夹adminclient,并把上一个章节中创建的Login.vue 移动到admin文件夹,把Home.vue 文件移动到client下。

1.1 菜单管理

1.1.1 Admin.vue

管理后台的功能需要一个独立的菜单导航功能,因此在src/views/admin下新增Admin.vue文件,用于完成左侧的菜单导航,代码如下:







3.1.2 Dashboard.vue

为了接下来的开发能很好的开展,我们先处理管理后台的默认页面Dashboard, 在src/views/admin 下创建文件Dashboard.vue,编写代码:




3.1.3 添加路由

src/router/index.ts下调整代码如下:

import {createRouter, createWebHistory, RouteRecordRaw} from "vue-router";
import Home from "../views/client/Home.vue";

const routes: Array = [
    {
        path: "/",
        name: "Home",
        component: Home,
        meta: {}
    },
    {
        path: "/login/",
        name: "Login",
        component: () =>
            import("../views/admin/Login.vue")
    },
    {
        path: '/admin',
        name: 'Admin',
        component: () => import("../views/admin/Admin.vue"),
        children: [
            {
                path: '/admin/',
                name: 'Dashboard',
                component: () => import("../views/admin/Dashboard.vue"),
            },
            {
                path: '/admin/dashboard',
                name: 'AdminDashboard',
                component: () => import("../views/admin/Dashboard.vue"),
            },
        ]
    },
]

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes,
});


export default router;

1.2 用户管理

1.2.1 Type

在我们处理登录和注册的时候,已经完成了用户的类型定义,也即User 的interface定义,这里增加所有返回结果的定义,用于管理接口返回的数据结构。在src/types/index.ts文件中代码如下:

export interface User {
    id: number,
    username: string,
    email: string,
    avatar: string | any,
    nickname: string | any,
    is_active?: any,
    is_superuser?: boolean,
    created_at?: string,
}


export interface ResponseData {
    count: number;
    results?: any;
    detail?: string;
}

1.2.2 API

这里要编写用户管理相关的接口,列表查询、启用、禁用、详情查看。在src/api/service.ts编写如下代码:

import { User, ResponseData } from "../types"


export function getUserDetail(userId: number) {
    return request({
        url: '/user/' + userId + '/',
        method: 'get',
    }) as unknown as User
}

export function saveUser(method: string, data: User) {
    // @ts-ignore
    return request({
        url: '/user/' + data.id + '/',
        method,
        data,
    }) as unknown as ResponseData
}

1.2.3 Component

在查看用户详情时,我们需要一个抽屉,展示用户的详细信息,因此在src/components下创建文件UserDetail.vue,编写代码如下:






1.2.4 View

在用户管理中,我们通过一个表格,分页展示所有的用户信息,并通过表格的操作列,提供查看详情、启用、禁用功能。

src/utils/index.ts 下增加方法timestampToTime

export function timestampToTime(timestamp: Date | any, dayMinSecFlag: boolean) {    const date = new Date(timestamp);    const Y = date.getFullYear() + "-";    const M =        (date.getMonth() + 1 < 10            ? "0" + (date.getMonth() + 1)            : date.getMonth() + 1) + "-";    const D =        date.getDate() < 10 ? "0" + date.getDate() + " " : date.getDate() + " ";    const h =        date.getHours() < 10 ? "0" + date.getHours() + ":" : date.getHours() + ":";    const m =        date.getMinutes() < 10            ? "0" + date.getMinutes() + ":"            : date.getMinutes() + ":";    const s =        date.getSeconds() < 10 ? "0" + date.getSeconds() : date.getSeconds();    if (!dayMinSecFlag) {        return Y + M + D;    }    return Y + M + D + h + m + s;}

src/views/admin下新增文件User.vue,引用UserDetail组件,具体代码如下:






1.2.5 Router

有了一个新的页面,我们需要定义route来完成路由跳转。在src/route/index.ts 文件中编写如下代码:

import {createRouter, createWebHistory, RouteRecordRaw} from "vue-router";
import Home from "../views/client/Home.vue";

const routes: Array = [
    {
        path: "/",
        name: "Home",
        component: Home,
        meta: {}
    },
    {
        path: "/login/",
        name: "Login",
        component: () =>
            import("../views/admin/Login.vue")
    },
    {
        path: '/admin',
        name: 'Admin',
        component: () => import("../views/admin/Admin.vue"),
        children: [
            {
                path: '/admin/',
                name: 'Dashboard',
                component: () => import("../views/admin/Dashboard.vue"),
            },
            {
                path: '/admin/dashboard',
                name: 'AdminDashboard',
                component: () => import("../views/admin/Dashboard.vue"),
            },
            {
                path: '/admin/user',
                name: 'UserManagement',
                component: () => import("../views/admin/User.vue"),
            },
        ]
    },
]

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes,
});


export default router;

1.3 标签管理

主要是为了方便灵活的给文章标记类型,所以才有标签管理,标签的属性很简单,就是一个名称。

1.3.1 Type

src/types/index.ts文件中增加代码如下:

export interface Tag {
    id: number,
    name: string,
    created_at: string,
    modified_at: string,
}

export interface TagList {
    count: number,
    results: Array | any
}

1.3.2 API

这里要编写标签管理相关的接口,列表查询、新增、修改、删除。在src/api/service.ts编写如下代码:

export function getTagList(params: any) {
    return request({
        url: '/tag/',
        method: 'get',
        params,
    }) as unknown as TagList
}

export function saveTag(method: string, data: Tag) {
    let url = '/tag/'
    if (['put', 'patch'].includes(method)) {
        url += data.id + '/'
    }
    // @ts-ignore
    return request({
        url,
        method,
        data,
    }) as unknown as ResponseData
}

export function addTag(data: Tag) {
    return request({
        url: '/tag/',
        method: 'post',
        data,
    }) as unknown as ResponseData
}

export function deleteTag(id: number) {
    return request({
        url: '/tag/' + id + '/',
        method: 'delete',
    }) as unknown as ResponseData
}

1.3.3 Component

提供一个新增和修改标签的弹框组件,因此在src/components下创建文件TagEditDialog.vue,编写代码如下:






1.3.4 View

通过表格管理标签,实现对标签的新增,修改,删除和列表查看,在src/views/admin下新增文件Tag.vue文件,编写如下代码:






1.3.5Router

定义route来完成路由跳转。在src/route/index.ts 文件中新增代码:

import {createRouter, createWebHistory, RouteRecordRaw} from "vue-router";
import Home from "../views/client/Home.vue";

const routes: Array = [
    {
        path: "/",
        name: "Home",
        component: Home,
        meta: {}
    },
    {
        path: "/login/",
        name: "Login",
        component: () =>
            import"../views/admin/Login.vue")
    },
    {
        path: '/admin',
        name: 'Admin',
        component: () => import("../views/admin/Admin.vue"),
        children: [
            {
                path: '/admin/',
                name: 'Dashboard',
                component: () => import("../views/admin/Dashboard.vue"),
            },
            {
                path: '/admin/dashboard',
                name: 'AdminDashboard',
                component: () => import("../views/admin/Dashboard.vue"),
            },
            {
                path: '/admin/user',
                name: 'UserManagement',
                component: () => import("../views/admin/User.vue"),
            },
            {
                path: '/admin/tag',
                name: 'Tag',
                component: () => import("../views/admin/Tag.vue"),
            },
        ]
    },
]

const router = createRouter({
    history: createWebHistory(import.meta.env.BASE_URL),
    routes,
});


export default router;

你可能感兴趣的:(Vue3+TypeScript+Django Rest Framework 搭建个人博客(三):博客管理后台(2))