• home > OMD > codeGuide >

    Vue项目命名规范-项目编码优化指北

    Author:zhoulujun Date:

    正确并形象地给函数、变量命名,是程序代码可读性、项目可维护性的保障。作为曾经的java狗,还是习惯给前端加上条条框框。js维护好还要团队遵从约定模式,同理协作


    命名规范

    • 拼写准确

      比如我的confirm与confrim 把函数未执行归咎于代码逻辑问题

    • 使用正常的时态

      • 特别是代码中状态的变量或者函数的命名,比如 onXxxxStarted 表示xxx已经启动了,isConnecting表示正在连接。正确的时态可以给使用者传递准确的信息。

    • 函数和属性的命名是有区别的

      • 如果是函数,建议使用动宾结构

        动宾结构就是 doSomething,这样的函数命名含义明确,比如: openFile, setName, addNumber...

      • 如果是属性命名,建议使用定语+名词

        比如 fileName, maxLength, textSize

    • 不要单词+拼音混合使用

      比如:useJiFen,huKouNumber.. 缺乏美感不说,可读性大幅度降低。

    • 谨慎使用缩写

      除非是约定俗成已经被广泛使用的缩写,否则老老实实用完整拼写。典型的反面例子: count->cnt, manager->mgr password->pwd button->btn。无论我们使用eclipse 或者intellij, 都有很好的自动完成功能,名字长一点没关系的,可读性更重要


    js命名:

    • 变量名、参数名、函数名、方法/属性:必须使用camel命名法


    • 私有(保护)成员:必须以下划线_开头

    • 常量名:必须使用全部大写的下划线命名法,如IS_DEBUG_ENABLED

    • 类名:必须使用pascal命名法

    • 枚举名:必须使用pascal命名法

    • 枚举的属性:必须使用全部大写的下划线命名法

    • 命名空间:必须使用camel命名法

    • 语义:命名同时还需要关注语义,如:

      • 变量名应当使用名词

      • boolean类型的应当使用is、has等起头,表示其类型

      • 函数名应当用动宾短语

      • 类名应当用名词

    HTML命名

    • html 文件名必须使用小写字母

    • 标签名必须使用小写字母

    • 属性名必须使用小写字母

    • 以上名称有多个单词情况下使用中划线分割

    • 属性值必须用双引号包围

    CSS命名

    • css 文件名必须使用小写字母

    • 选择器必须单词全字母小写,多个单词情况下使用中划线分割

    • class选择器必须代表相应模块或部件的内容或功能,不得以样式信息进行命名

    • id 选择器必须保证页面唯一

    • 同一页面,应避免使用相同的 name 与 id

    vue中变量命名规范

    变量命名使用主要集中在data和methods中

    data中更多的是名词与状态布尔类型

    名词:名词太多,大致分为复数、后缀加Arr、加Obj之类作为约定规则

    状态布尔型:

    • 表示是不是,用is+ :如 isEmpty

    • 表示有没有,用has+... : 如 hasClass

    • 表示能不能,用can+... :如 canSubmit

    单词本身的形式(过去式、进行时、将来时):had开头、ing、ed结尾等

    • methods中handle+以下:

    • dd/remove,添加/移除

    • add/delete,添加/删除

    • insert/delete,插入/删除

    • start/stop,开始/停止

    • begin/end,开始/结束

    • send/receive,发送/接收

    • get/set,取出/设置

    • get/release,获取/释放

    • put/get,放入/取出

    • up/down,向上/向下

    • show/hide,显示/隐藏

    • open/close,打开/关闭

    • increment/decrement,增加/减少

    • lock/unlock,锁/解锁

    • next/previous,下一个/前一个

    • create/destroy,创建/销毁

    • min/max,最小/最大

    • visible/invisible,可见/不可见

    • pop/push,出栈/入栈

    • store/query,存储/查询

    结合业务:

    • 表单提交:submit、send

    • 表单增删改查:add、delete、update、search、reset

    • 上传附件:upload

    • 关闭打开弹窗:open/close

    • 检查:check

    method自定义方法命名

    • 动宾短语(good:jumpPage、openCarInfoDialog)(bad:go、nextPage、show、open、login)

    • ajax 方法以 get、post 开头,以 data 结尾(good:getListData、postFormData)(bad:takeData、confirmData、getList、postForm)

    • 事件方法以 on 开头(onTypeChange、onUsernameInput)

    • init、refresh 单词除外

    • 尽量使用常用单词开头(set、get、open、close、jump)

    • 驼峰命名(good: getListData)(bad: get_list_data、getlistData)

    data props 方法注意点

    • 使用 data 里的变量时请先在 data 里面初始化

    • props 指定类型,也就是 type

    • props 改变父组件数据 基础类型用 $emit ,复杂类型直接改

    • ajax 请求数据用上 isLoading、isError 变量

    • 不命名多余数据,现在是详情页、你的数据是 ajax 请求的,那就直接声明一个对象叫 d,而不是每个字段都声明

    • 表单数据请包裹一层 form

    vue 方法放置顺序

    1. components

    2. filter

    3. props

    4. data

    5. watch

    6. computed

    7. metods

    8. created

    9. activited

    10. mounted

    11. update

    12. beforeRouteUpdate

    13. destroy

    注意:

    • 不在 mounted、created 之类的方法写逻辑,在 created 里面监听 Bus 事件

    • 数据请求尽量放在created(数据请求越早越好),如果涉及到需要页面加载完成之后的话就用 mounted。,

    • 不要在 updated 里更新数据

    文件或文件夹的命名

    文件命名规范

    普通文件,统一使用小写字母开头的(camelCase)命名规范。如index.js 、 index.vue,

    虽然有人说,展开node_modules中的项目依赖,会发现,几乎所有的项目文件夹命名都是 kebab-case命名的,使用kebab-case命名的文件夹比camelCase命名的文件夹看起来更清晰

    但是本人推荐的组件命与类 都为PascalCase命名,所以,全局都为驼峰命名好。

    注:文件大小写,windows不敏感,但是git对文件大小敏感啊。

    属于Api的,统一加上Api后缀

    属于类或组件的,使用PascalBase风格

    文件夹命名

    views 文件夹下面是由 以页面为单位的vue文件 或者 模块文件夹 组成的,放在 src 目录之下,与 components、assets 同级

    views 下的文件夹命名

    views 下面的文件夹代表着模块的名字

    • 由名词组成(car、order、cart)

    • 单词只能有一个(good: car order cart)(bad: carInfo carpage)

    • 尽量是名词(good: car)(bad: greet good)

    • 以小写开头(good: car)(bad: Car)

    views 下的 vue 文件命名

    • views 下面的 vue 文件代表着页面的名字

    • 放在模块文件夹之下

    • 只有一个文件的情况下不会出现文件夹,而是直接放在 views 目录下面,如 Login Home

    • 尽量是名词

    • 大写开头,开头的单词就是所属模块名字(CarDetail、CarEdit、CarList)

    • 名字至少两个单词(good: CarDetail)(bad: Car)

    • 常用结尾单词有(Detail、Edit、List、Info、Report)

    • 以 Item 结尾的代表着组件(CarListItem、CarInfoItem)

    Vue组件命名

    之前常听人说,Vue 组件的名称最好不要和原生 HTML 标签相同。为了避免重名,通常会在组件名称前面加上一个前缀

    如 el-button、el-input、el-date-picker等,貌似很有道理。Ant.design,直接大写命名,这样

    • 组件名可以使用原生 HTML 标签名,意味着再也不用较劲脑汁去规避原生 HTML 标签了。

    • 组件都使用了首字母大写标签名,使它们很容易地与原生小写的 HTML 标签区分。

    参考这篇文章,了解下vue组件命名机制《聊聊 Vue 组件命名那些事》,可以了解到

    Vue1.0 组件名以字母开头,后面跟字母、数值或下划线,并且不与 HTML 元素或 Vue 保留标签重名。

    Vue2.0:与1.0基本相同,只是 HTML 标签和 Vue 保留标签范围有些不同:

        区分大小写的表情只有:   

        'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font,' +

         'font-face,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +

         'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view'

    Vue2.0虽然也和react一样,引入了Virtual DOM,理论上,可以和React 那样使用 PascalCase 形式的组件标签,但是

    Vue组件命名需要注意事项

    • 不与 HTML 元素(区分大小写)或 SVG 元素(不区分大小写)重名;

    • 不使用 Vue 保留的 slot 和 component(区分大小写)

    • 不适用Vue内置组件KeepAlive、Transition、TransitionGroup 

    • 不使用非法的标签字符

    基础组件命名

    应用特定样式和约定的基础组件 (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V。

    **反例**
        components/
        |- button.vue
        |- loading.vue
        |- slide.vue
    **正例**
        components/
        |- BaseButton.vue
        |- BaseLoading.vue
        |- BaseSlide.vue

    单个活跃实例的组件

    单个活跃实例的组件应该以 The 前缀命名,以示其唯一性

    这不意味着组件只可用于一个单页面,而是每个页面只使用一次。这些组件永远不接受任何 prop,因为它们是为你的应用定制的,而不是它们在你的应用中的上下文。如果你发现有必要添加 prop,那就表明这实际上是一个可复用的组件,只是目前在每个页面里只使用一次。

    **反例**
        components/
        |- SaleManage.vue
        |- ImportExcel.vue
    **正例**
        components/
        |- TheSaleManage.vue
        |- TheImportExcel.vue

    紧密耦合的组件名

    和父组件紧密耦合的子组件应该以父组件的命名为前缀.如果一个组件只在其父组件某个场景下有意义,这层关系应该体现在组件名上,因为编辑器通常按照首字母顺序组织文件.

    **反例**
        components/
        |- SearchBox.vue
        |- SearchItem.vue
        |- SearchButton.vue
    **正例**
        components/
        |- SearchBox.vue
        |- SearchBoxItem.vue
        |- SearchBoxButton.vue

    组件命中的单词顺序

    组件名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾。

    **反例**
        components/
        |- ClearSearchButton.vue
        |- ExcludeFromSearchInput.vue
        |- LaunchOnStartupCheckbox.vue
        |- RunSearchButton.vue
        |- SearchInput.vue
        |- TermsCheckbox.vue
    **正例**
        components/
        |- SearchButtonClear.vue
        |- SearchButtonRun.vue
        |- SearchInputQuery.vue
        |- SearchInputExcludeGlob.vue
        |- SettingsCheckboxTerms.vue
        |- SettingsCheckboxLaunchOnStartup.vue

    完整单词的组件名

    编辑器中的自动补全已经相当友好,让书写长的组件名的代价已经可以微乎其微,同样的效率更易于理解,何乐而不为?

    **反例**
        components/
        |- soManage.vue
        |- woManage.vue
    **正例**
        components/
        |- SaleOrderManage.vue
        |- WorkOrderManage.vue

    prop的大小写

    在声明时始终采用(camelCase),在模板和 JSX 中应该始终使用( kebab-case)。

    单纯的遵循每个语言的约定。在 JavaScript 中更自然的是 camelCase。而在 HTML 中则是 kebab-case。

    **反例**
    props: {
      'greeting-text': String
    }
    <WelcomeMessage greetingText="hi"/>
    **正例**
    props: {
      greetingText: String
    }
    <WelcomeMessage greeting-text="hi"/>


    代码优化/编码技巧

    使用对象代替 if 及 switch

    在很多情况下,我们经常会遇到循环判断执行赋值操作的场景,一般我们都会使用 if 及 switch 的条件判断,如果符合则执行赋值,不符合则进入下个判断,比如:

    let name = 'lisi';
    let age = 18;
     
    if (name === 'zhangsan') {
     age = 21;
    } else if (name === 'lisi') {
     age = 18;
    } else if (name === 'wangwu') {
     age = 12;
    }
     
    // 或者
    switch(name) {
     case 'zhangsan':
      age = 21;
      break
     case 'lisi':
      age = 18;
      break
     case 'wangwu':
      age = 12;
      break
    }

    这样的写法不仅冗余,而且代码执行效率不高,我们可以使用对象的形式简写:

    let name = 'lisi';
    let obj = {
     zhangsan: 21,
     lisi: 18,
     wangwu: 12
    };
     
    let age = obj[name] || 18;

    以上这种技巧适用于循环判断一次赋值的情况,如果判断过后有较多处理逻辑的还需要使用 if 或 switch 等方法。

    使用 router.beforeEach 来处理跳转前逻辑

    在某些情况下,我们需要在路由跳转前处理一些特定的业务逻辑,比如修改路由跳转、设置 title 等,一般在beforEach 函数里面集中,出理

    注:最后需要调用 next() 方法执行路由跳转。

    使用 v-if 来优化页面加载

    无论是vue还是angular,ng-if v-if, 都是可以优化页面加载

    注:如果涉及到权限问题的代码都需要使用 v-if,而不是 v-show,v-for和v-if永远不要在一个元素上

    路由跳转尽量使用 name 而不是 path

    我们前期配置的路由路径后期难免会进行修改,如果我们页面跳转的地方全是使用的 path,那么我们需要修改所有涉及该 path 的页面,这样不利于项目的维护。而相对于 path,name 使用起来就方便多了,因为其具有唯一性,即使我们修改了 path,还可以使用原来的 name 值进行跳转。

    使用 computed 代替 watch

    它们在功能上还是有所区别的,但是有时候可以实现同样的效果,而 computed 会更胜一筹(在处理多数据联动的情况下,使用 computed 会更加合理一点)。

    • watch:当监测的属性变化时会自动执行对应的回调函数

      watch 监测的是属性值, 只要属性值发生变化,其都会触发执行回调函数来执行一系列操作。

    • computed:计算的属性只有在它的相关依赖发生改变时才会重新求值

      computed 监测的是依赖值,依赖值不变的情况下其会直接读取缓存进行复用,变化的情况下才会重新计算


    使用 setTimeout 代替 setInterval

    为何不用setInterval,因为它可能会带来两个问题:

    • “丢帧”现象

    • 不同定时器的代码的执行间隔比预期小

     setInterval会存在代码的执行间隔比预期小以及 “丢帧” 的现象,原因在于其本身的实现逻辑。

    很多人会认为 setInterval 中第二个时间参数的作用是经过该毫秒数执行回调方法,其实不然,其真正的作用是经过该毫秒数将回调方法放置到队列中去,但是如果队列中存在正在执行的方法,其会等待之前的方法完毕再执行,如果存在还未执行的代码实例,其不会插入到队列中去,也就产生了 “丢帧”

    而 setTimeout 并不会出现这样的现象,因为每一次调用都会产生了一个新定时器,同时在前一个定时器代码执行完之前,不会向队列插入新的定时器代码。

    // 该定时器实际会在 3s 后立即触发下一次回调
    setInterval(() => {
     // 执行完这里的代码需要 2s
    }, 1000);
     
    // 使用 setTimeout 改写,4秒后触发下一次回调
    let doSometing = () => {
     // 执行完这里的代码需要 2s
     setTimeout(doSometing, 1000);
    }
    
    doSometing();

     延伸阅读:对于“不用setInterval,用setTimeout”的理解

    参考文章:

    变量命名规范 https://segmentfault.com/a/1190000014621403

    聊聊 Vue 组件命名那些事 https://cnodejs.org/topic/5816aabdcf18d0333412d323

    Vue的编码技巧与规范使用详解 https://www.jb51.net/article/168642.htm

    代码规范:https://github.com/ecomfe/spec



    转载本站文章《Vue项目命名规范-项目编码优化指北》,
    请注明出处:https://www.zhoulujun.cn/html/Operation/codeGuide/8230.html