【代码结构】页面函数的布置

160 阅读5分钟

在一个页面文件内避免不了各种各样功能的函数,而当页面功能复杂起来,函数的个数也会随着增加。随意的放置函数虽然不会对功能的实现产生影响,但在维护的时候却会十分痛苦。

你是否遇到过在一个几千行的代码里上下求索,只为了搞懂一个功能的函数调用路径?又是否在重构代码时面对眼花缭乱的函数名称不知如何取舍?

面对这些问题,如何去排布这些函数,让维护代码时能够最快的理解函数,以及定位到相关功能的函数就显得尤为重要。

函数的分类

tip:以下主要以 vue 页面文件为例。 对于前端页面而言,依照函数的作用可以大致划分为以下几类。

  1. 生命周期函数。例如:created,mounted...
  2. 初始重置函数,通常是页面一开始就会执行的函数,对一些对象进行默认赋值等等。
  3. 消息触发函数。例如:父子组件的事件传递,页面间的事件传递。这里之所以称之为消息,而不是事件,主要是为了在功能上与由用户主动触发的那些事件做一个区分。
  4. 数据查询函数。例如:获取订单列表数据,获取用户信息...
  5. 交互事件函数。例如:点击事件,滑动事件...
  6. 业务处理函数。可以说除了以上的函数之外,大多都是业务处理函数了。

函数的放置

在上一篇【从最简单的命名开始】的最后有提到过函数的命名,这里用常见的个人资料页面例子来阐述。 tip:命名是相对主观性的事情,以下命名仅供参考。

<template>
    ...
</template>
export default {
    data() {
        return {
            userInfo: {
                'nickname': '',
                'birthday': '',
                'gender': '',
                'phone': '',
                'phoneHide' '',
            },
        }
    },

    mounted: function () {
        this.setUserInfoDefault()
        this.queryUserInfo()
    },

    methods: {
        // message - 消息触发函数
        messageRefreshPage: functio () {
            this.queryUserInfo()
        },

        // set - 初始重置函数
        setUserInfoDefault: function () {
            this.userInfo = {
                'nickname': '',
                'birthday': '2020-01-01',
                'gender': '男',
                'phone': '',
                'phoneHide' '',
            },
        },

        // query - 数据查询函数
        queryUserInfo: function () {
            this.userInfo = requestResultData
            this.hidePhone()
        },

        // 业务处理函数
        hidePhone: function () {
            this.userInfo.phoneHide = '180****0000'
        },

        dateFormat: function () {
            this.userInfo.birthday = '2020/01/01'
        },

        // on - 交互事件函数
        onSelectBirthday: function (selectData) {
            this.userInfo.birthday = selectData
        },

        onSelectGender: function (selectData) {
            this.userInfo.gender = selectData
        },
    }
}

示例代码中的函数放置位置是有规则的,不是随意的,整体上按照页面的「自然逻辑」来布置。例如一个页面,需要从创建,请求数据,填充数据,用户交互,数据更新,最终销毁等等,这就是「自然逻辑」。

首先,生命周期函数优先,它们最先运行,那么放在代码的最前面就自然的告诉维护代码的开发人员,页面在一开始做了哪些动作。

一般的,不要在 created,mounted 中去写具体的某些功能代码。而是将要做的事情写到一个函数里,取一个恰当的名字来表述。就像上面的 mounted 函数中调用了两个函数,setUserInfoDefault 和 queryUserInfo,一目了然就知道在页面初始时先设置默认值,再查询具体数值。页面越复杂,这种做法的优势就越明显。 ps:曾经维护过一个项目,原先开发把 created 放在了文件最后,就一行代码。以至于我还纳闷了几分钟,怎么没有周期函数页面也能调用接口拿到数据

其次,是消息类函数。为什么要把消息类函数放在最前面呢?主要是为了让维护人员知晓当前页面有哪些现成的事件函数可以调用。比如刷新页面,列表加载更多等等,这种影响比较大的,重要的函数要优先知晓。如果放在最后,有可能维护人员在前面已经找到要修改的代码开始修改,而忽略了后面的消息类函数。这其实就像声明全局变量一样,最好都是在开头,类似一种告知。

接着就是一些页面的初始重置函数,数据查询函数,这些函数大多会在页面开始时就执行,沿着页面「自然逻辑」就会读到这些代码,符合从上至下的阅读习惯。注意示例中的 hidePhone 和 dateFormat,它们是业务处理函数,通常跟随在调用它们的函数后面。

如果将其放到了调用函数前面,会疑惑这函数哪里用到?必须要往下看时才会发现在 queryUserInfo 中被调用了。可这时要了解 hidePhone 的详细逻辑又要返回到上方去阅读,就造成了一种上下求索的阅读方式。同样的,hidePhone 也不宜放到离 queryUserInfo 跨级的位置,比如 onSelectGender 函数后面,一样也会造成阅读困难。

最后是些事件函数,因为影响范围小,不是非常重要。通常只有当维护人员需要修改某个操作功能的时候才会去寻找对应的函数,所以它们被放置在最后。

好了,函数的放置技巧就是以上这些,总结一下:

  1. 按照页面的「自然逻辑」来布置。通常生命周期函数放最前面,后面跟着自定义函数。
  2. 函数依照影响范围,重要程度排序。
  3. 拥有关联的函数放在一起,且被调用函数放在调用函数之后。 当你每个页面都依照这样去布置函数的时候,会发现维护起来相当轻松。至少能够快速的定位功能代码块,而不必去猜测和寻找。