前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >总结后台开发经验

总结后台开发经验

作者头像
Innei
发布2021-12-28 11:46:50
7840
发布2021-12-28 11:46:50
举报
文章被收录于专栏:静之森

前些天在边学习边试着写一个后台管理系统,后台的前端是用 Vue + ElementUI 写的,只是一个大体的框架,后端是由 Express 驱动的,数据库是 Mongodb。

后台目前实现了文章、分类的管理以及用户登陆,后端提供了相应的接口。

后端方面

开始写后台之前首先是把前端的大体的界面呈现出来,这里简单的把 Element 官方提供的容器布局拿过来用,并没有太花时间在前端上。然后是后端方面,写路由和数据库操作就不多说了。重要的是路由方面的可复用性。一个接口写一次还好,但是后期可能会用到多次,只是每次的 URI 不同,所以写一套通用接口就必不可少了。可能在刚开始学习的小伙伴并不会注意到这点,导致最后代码越来越冗余,每次改一个地方需要修改多次。

通用接口

以我的后端路由为例,我的后端接口地址挂载在跟地址下的/admin/api下,为了保证以后能用同一个跟地址,所以可以定义一个路由,映射到/admin/api

js

代码语言:javascript
复制
1const app = require('express')()
2app.use('/admin/api', router)

COPY

其次是写一个通用接口,比如查询文章和查询分类接口,其实只是查询的数据库模型不同而已。再比如删除等等。

为了避免通用接口和以后写的其他接口冲突,可以给通用接口加一个前缀,一般为/rest/。那么我们写的全部挂载到 router 上。

js

代码语言:javascript
复制
1app.use('/admin/api/rest/:res', router)

COPY

那么在写接口时如查询接口为GET / ,可以这么去写。

js

代码语言:javascript
复制
1router.get('/', async (req, res) => {
2    if (req.Model.modelName === 'Category') {
3      const isEdit = req.query.edit === 'false' ? false : req.query.edit
4      const cateList = await req.Model.find().populate('parents')
5      if (isEdit) {
6        const index = cateList.findIndex(el => el._id == isEdit)
7        cateList.splice(index, 1)
8      }
9      res.send(cateList)
10      return
11    }
12    const model = await req.Model.find()
13    res.send(model)
14  })

COPY

通用接口是写了,那么还要去获取参数,根据参数去加载相应的模型,这个时候命名规范和文件树结构规范就很重要了。

一般的,后端使用这样的文件树结构。

代码语言:javascript
复制
1├──admin 				//路由相关 外层可以由 router 文件夹包含
2    └── index.js  // 路由入口
3├── middlewares // 中间件存放路径
4    ├── auth.js
5    └── resource.js
6├── models // 模型
7    ├── AdminUser.js
8    ├── Category.js
9    └── Post.js
10├── node_modules 
11    ...
12├── plugins // 插件相关
13    └── db.js
14└── uploads // 上传,静态文件存放

COPY

模型以帕斯卡(pascal)命名法来命名,单数,接口地址以下划线命名法,复数。

比如/posts为接口地址,对应模型为Post.在加载指定模型时使用中间件(inflection 库)来转换单词大小写。

js

代码语言:javascript
复制
1const resource = async (req, res, next) => {
2  const ModelName = require('inflection').classify(req.params.res)
3  req.Model = require(`../models/${ModelName}`) // 处理后挂载到请求体上
4  next()
5}
6
7module.exports = options => {
8  return resource
9}

COPY

使用函数方式导出变量,方便日后重构和扩展功能。

前端方面

前端主要是和后端接口紧密相连。前端一般使用 axios 获取后端接口进行交互。首先引入 axios 模块,挂载到 Vue 原型中,方便日后调用,由于是前端模块化,所以这里也可以做成一个模块,方便日后修改。

我的前端文件树是这样的。

代码语言:javascript
复制
1../admin/src
2├── App.vue  // 主模板
3├── components // 组件
4├── main.js // 主入口
5├── plugins // 插件
6│   ├── axios.js
7│   └── element.js
8├── router.js // 路由入口
9└── views // 视图
10    ├── CreateArticle.vue
11    ├── EditAdminUser.vue
12    ├── EditArticle.vue
13    ├── EditCategory.vue
14    ├── ListAdminUser.vue
15    ├── ListArticle.vue
16    ├── ListCategory.vue
17    ├── Login.vue
18    └── Main.vue

COPY

模块封装

plugins 中自定义 axios 模块。

js

代码语言:javascript
复制
1import axios from 'axios'
2const http = axios.create({
3  baseURL: 'http://localhost:3000/admin/api'
4})
5// ...
6export default http

COPY

把 axios 重新进行一次封装,可以日后方便的引入 axios 的拦截器,等等。在入口文件中,对 axios 和 Vue 进行绑定。

js

代码语言:javascript
复制
1import http from '../plugins/axios'
2Vue.prototype.$http = http

COPY

视图可复用性

比如编辑和新建,视图应该是差不多的,只是获取数据和提交的接口不同,一样的布局不需要写 2 次相同的代码,修改起来也不太好操作。可以使用通过路由在判断,是修改还是新建视图。

以我的路由接口为例,新建为 posts/create,编辑为 posts/edit/5d354bc760840663bd4cf933,很明显编辑中有_id的参数,那么可以通过路由中有没有_id参数判断就行了。在路由中加入 props: true 获取当前的参数。

js

代码语言:javascript
复制
1 children: [
2        // 使用子路由, 父路由中的组件必须要存在 router-view 标签才能显示
3        {
4          path: '/posts/create',
5          component: EditArticle
6        },
7        {
8          path: '/posts/edit/:id',
9          component: EditArticle,
10          props: true
11        },
12		// ....

COPY

由于编辑文章需要提前向后端获取数据,所以可以这么写。

js

代码语言:javascript
复制
1 props: {
2    id: {}
3  },
4 methods: {
5    fetch() {
6      this.$http.get("rest/posts/" + this.$route.params.id).then(res => {
7        this.article = res.data;
8      });
9    },
10    fetchCategory() {
11      this.$http.get("rest/categories").then(res => {
12        this.categories = res.data;
13      });
14    },
15},
16 created() {
17    if (this.id) {
18      this.fetch();
19    }
20    this.fetchCategory();
21  },
22  //...
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 后端方面
    • 通用接口
    • 前端方面
      • 模块封装
        • 视图可复用性
        相关产品与服务
        数据库
        云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档