工作后总结的前后端协作实践

304 阅读4分钟

在网上看到了很多前后端协作规范的文章,比如约定code的含义,约定请求方法等等。其实这些内容都是比较基础和偏底层的,我们在公司开发需求时,一般都是在已有项目上进行开发,上面提到的很多内容其实已经搭建好了,不需要我们关心。而这篇文章将介绍几个我在工作中真实遇到的几类问题,并给出解决方案。

一、不合理的数据结构导致客户端对数据进行二次加工

需求:

例如在一个BI数据看板的需求中,客户端要按照一定顺序显示库存食物的信息,服务端返回如下结构

data = {
    apple: {
        price: 5,
        type: 'fruit',
        count: 100,
        desc: '苹果'
    },
    orange: {
        price: 10,
        type: 'fruit',
        count: 60,
        desc: '橘子'
    },
    carrot: {
        price: 2,
        type: 'vegetable',
        count: 200,
        desc: '胡萝卜'
    }
}

问题

  1. 服务端返回的是一个对象,客户端不能直接循环,需要对数据进行二次加工,影响性能和用户体验
  2. 客户端需要维护一个显示顺序的数组,导致客户端和服务端都维护了一个食物类型的枚举值。如果需求发生变动,两端都要进行修改

解决方案

服务端直接按照要求的显示顺序返回数据即可

data = [
    {
        name: 'apple',
        price: 5,
        type: 'fruit',
        count: 100,
        desc: '苹果'
    },
    {
        name: 'orange',
        price: 10,
        type: 'fruit',
        count: 60,
        desc: '橘子'
    },
    {
        name: 'carrot',
        price: 2,
        type: 'vegetable',
        count: 200,
        desc: '胡萝卜'
    }
]

二、下拉框,复选框等类似“列表”的展示内容,客户端维护枚举值

需求

下拉框中有若干个选项,用户选择时,客户端将该选项的value作为入参请求数据。服务端返回数据如下:

data = [1, 2, 3]

客户端维护一个枚举值从而进行页面展示

map = {
    1: '苹果',
    2: '香蕉',
    3: '橘子',
}

问题

枚举值由客户端维护,如果未来新增枚举类型,客户端和服务端都要更改

解决方案

客户端返回如下结构

data = [
    {
        label: '苹果',
        value: '1',
    },
    {
        label: '香蕉',
        value: '2',
    },
    {
        label: '橘子',
        value: '3',
    },
]

客户端在进行页面渲染和接口请求时,只需要从data中取出相应字段即可,未来新增类型时,只需要后端改变即可,客户端无需发版

三、 前端从后端返回列表内容中过滤出初始默认值

需求

单选框组件有初始默认值

问题:

服务端返回如下结构,默认选中香蕉

data = [
    {
        label: '苹果',
        value: '1',
    },
    {
        label: '香蕉',
        value: '2',
    },
    {
        label: '橘子',
        value: '3',
    },
]

为了确定初始默认值,客户端会写出如下代码

const initialSelected = data.find(item => item.value === '2')
  1. 魔法数字,一个头两个大!!
  2. 客户端需要对数据进行一次遍历,如果数据量很大,或者宿主机器性能较差,会出现卡顿
  3. 未来业务变动,修改了默认值,客户端需要重新发版

解决办法:

服务端增加默认值字段

data = [
    {
        label: '苹果',
        value: '1',
    },
    {
        label: '香蕉',
        value: '2',
        selected: true,
    },
    {
        label: '橘子',
        value: '3',
    },
]

四、客户端业务判断逻辑过重

需求

某一条记录有三种状态:未编辑(0),已编辑(1),不支持编辑(2) 管理员(admin)有权限对记录进行编辑操作,普通用户(ordinaryUser)无权限 客户端会有四种显示内容:去编辑的按钮,未编辑的文字,已编辑的文字,不支持编辑的文字

问题

为了实现上述需求,客户端会写出如下代码

if (status === '0') {
    if (role === 'admin') {
        return <Button>去编辑</Button>
    } else {
        return <Text>未编辑</Text>
    }
} else if (status === '1') {
    return <Text>已编辑</Text>
} else if (status === '2') {
    return <Text>不支持编辑</Text>
}

解决方案

服务端直接下发显示内容,客户端根据显示内容添加样式即可,例如

data = {
    type: 'Button',
    label: '去编辑'
}

总结

客户端直接与用户接触,因此更注重页面信息的展示,交互效果和用户体验,复杂的业务逻辑还是放在服务端处理比较好。