Vue项目命名规范-项目编码优化指北
Author:zhoulujun Date:
命名规范
拼写准确
比如我的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 方法放置顺序
components
filter
props
data
watch
computed
metods
created
activited
mounted
update
beforeRouteUpdate
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