Naming conventions
project naming
The lowerCamelCase
name is adopted
, and the names in the code cannot be underscored, nor can they be concluded with an underscore or a dollar sign.
bundle;
directory naming
All names are lowerCamelCase in
lowercase
. When there is a plural structure, use plural nomenclature, and abbreviations do not use plurals.
JS
,
CSS
,
HTML
,
PNG
file naming
The lowerCamelCase
name is adopted
, and the names in the code cannot be underscored, nor can they be concluded with an underscore or a dollar sign.
bundle;
naming rigor
1.
It is strictly forbidden to use pinyin and English in the name of the code, and it is not allowed to use Chinese directly. Description: Correct English
Spelling and grammar can make it easy for readers to understand and avoid ambiguity. Note that even pure pinyin naming methods should be avoided;
// good
mallManagementSystem
// bad
mall_management-system / mall-management-system
// good
scripts / styles / components / images / utils / layouts / demoStyles /
demoScripts / img / doc
// bad
script / style / demo_scripts / demo-styles / imgs / docs
// good
renderDom.js / signup.css / index.html / companyLogo.png
// bad
render-dom.js / UserManagement.html
// good
henan / luoyang / rmb
等国际通用的名称,可视同英文。
// bad
DaZhePromotion [
打折
] / getPingfenByName() [
评分
] / int
某变量
= 3
2
、杜绝完全不规范的缩写,避免望文不知义。
HTML
规范
HTML
标签
标签必须合法且闭合、嵌套正确,标签名需
小写
;
标签语法无错误,需要符合语义化;
标签的自定义属性以
data
-
开头,如:
<a href="#" data
-
num='18'></a>
;
除非有特定的功能、组件要求等,禁止随意使用
id
来定义元素样式。
链接
给
<a>
标签加上
title
属性;
<a>
标签的
href
属性必须写上链接地址,暂无的加上
javascript:alert('
敬请期待!
')
;
非本专题的页面间跳转,采用打开新窗口模式:
target="_blank"
。
HTML
类型
推荐使用
HTML5
的文档类型申明:(建议使用
text/html
格式的
HTML
。避免使用
XHTML
。
XHTML
以及它的属性,比如
application/xhtml+xml
在浏览器中的应用支持与优化空间都十分有限)。
缩进
缩进使用
2
个空格(一个
Tab
);
嵌套的节点应该缩进。
语义化标签
// bad
AbstractClass“
缩写
”
命名成
AbsClass
;
condition“
缩写
”
命名成
condi
,此类随意缩写严重降低了代码的可阅读性。
规定字符编码
IE
Compatibility Mode
specify character encoding
doctype
uppercase
// good
<!DOCTYPE html>
<html>
<head>
<meta
http-equiv
=
"X-UA-Compatible"
content
=
"IE=Edge"
/>
<meta
charset
=
"UTF-8"
/>
<title>
Page title
</title>
</head>
<body>
<img
src
=
"images/company-logo.png"
alt
=
"Company"
/>
</body>
</html> There are many new semantic tags in
HTML5
, so semantic tags are used first to avoid a page with
div
or
p
tags.
Quotes
(
html
,
vue
template
)
Use double quotes
(" ")
instead of single quotes
('')
.
CSS
specification
name
ID
and
class
names always use names that reflect the purpose and use of the element, or other generic names, instead of appearance and obscurity
The name.
Attribute writing order
The following sequence is recommended:
Layout positioning properties:
display / position / float / clear / visibility / overflow
// good
<header></header>
<footer></footer>
// bad
<div>
<p></p>
</div>
Class names use lowercase letters, separated by dashes
id
is named in camel case
Variables, functions, mixins and placeholders in scss
and
less
are named in camel case
//
bad
.fw-800
{
font-weight
:
800
;
}
.red
{
color
:
red
;
}
//
good
.heavy
{
font-weight
:
800
;
}
.important
{
color
:
red
;
}
自身属性:
width / height / margin / padding / border / background
文本属性:
color / font / text-decoration / text-align / vertical-align / white- space / break-word
其他属性(
CSS3
):
content / cursor / border-radius / box-shadow / text-shadow /
background:linear-gradient …
选择器
css
选择器中避免使用标签名,从结构、表现、行为分离的原则来看,应该尽量避免
css
中出现
HTML
标签,并且在
css
选择器中出现标签名会存在潜在的问题。
很多前端开发人员写选择器链的时候不使用 直接子选择器(注:直接子选择器和后代选择器的区别)。
Sometimes this can cause painful design problems and sometimes it can be expensive. However, in any case, it is a very
Bad practice.
If you're not writing very general selectors that need to match to the end of
the DOM , you should always consider immediate child selectors.
Use abbreviated attributes as much as possible
.about
{
display
:
block
;
position
:
relative
;
float
:
left
;
over-flow
:
auto
;
width
:
100px
;
height
:
100px
;
margin
:
0 10px
;
padding
:
20px 0
;
background
:
rgba
(
0
,
0
,
0
,
.5
);
border
:
1px
solid
red
;
color
:
#333
;
font-family
:
Arial
,
'Helvetica Neue'
,
Helvetica
,
sans-serif
;
text-align
:
center
;
cursor
:
pointer
;
border-radius
:
10px
;
}
//
good
.content
>
.title
{
font-size
:
2rem
;
}
//
bad
.content .title
{
font-size
:
2rem
;
}
//
good
border-top
:
0
;
font
:
100%
/
1.6
palatino
,
georgia
,
serif
;
padding
:
0 1em 2em
;
//
bad
border-top-style
:
none
;
each selector and attribute on its own line
omit
units after
0
Avoid using
ID
selectors and global tag selectors to prevent polluting global styles
font-family
:
palatino
,
georgia
,
serif
;
font-size
:
100%
;
line-height
:
1.6
;
padding-bottom
:
2em
;
padding-left
:
1em
;
padding-right
:
1em
;
padding-top
:
0
;
//
good
button
{
width
:
100px
;
height
:
50px
;
color
:
#fff
;
background
:
#00a0e9
;
}
//
bad
button
{
width
:
100px
;
height
:
50px
;
color
:
#fff
;
background
:
#00a0e9
;
}
//
good
div
{
padding-bottom
:
0
;
margin
:
0
;
}
//
bad
div
{
padding-bottom
:
0px
;
margin
:
0em
;
}
CSS3
browser private prefix writing
CSS3
browser-private prefixes come first, standard prefixes follow.
Javascript
specification
name
1.
Use lowercase camel case to name
lowerCamelCase
. The name in the code cannot be underlined, nor can it be concluded with an underscore or a dollar sign.
bundle;
2. The name
of
the method
method must be in the form of a verb or a verb
+
noun;
//
good
.header
{
padding-bottom
:
0px
;
margin
:
0em
;
}
//
bad
#header
{
padding-bottom
:
0px
;
margin
:
0em
;
}
.about
{
border-radius
:
10px
;
-webkit-
border-radius
:
10px
;
-moz-
border-radius
:
10px
;
-o-
border-radius
:
10px
;
-ms-
border-radius
:
10px
;
}
// good
localValue
/
getHttpMessage
()
/
inputUserId
// bad
_name
/
name_
/
name$
2
)
Method names, parameter names, member variables, and local variables all use
the lowerCamelCase
style
format, must follow the hump form.
// good
saveShopCarData
/
openShopCarInfoDialog
// bad
save
/
open
/
show
/
go
3.
Hereby explain, adding, deleting, checking and modifying, the following
5
words are used uniformly for details, and other words are not allowed (the purpose is to unify each end)
;
`add / update / delete / detail / get`
Attachment: Verbs commonly used in function methods
:
/**
get
get
/set
settings
add
increase
/remove
delete
create
create
/destory
remove
start
start
/stop
stop
open
open
/close
close
read
read
/write
write
load
load
/save
save
create
create
/destroy
destroy
begin
begins
/end
ends
backup
backup
/restore
recovery
import
import
/export
export
split
/ merge
_
inject
injection
/extract
extraction
attach
/ detach
_
bind
binding
/separate
separation
view view
/
browse
browse
edit
/ modify
_
select
select
/mark
mark
copy
copy
/paste
paste
undo
undo
/redo
redo
insert
insert
/delete
remove
add
join
/append
add
clean
clean up
/clear
clear
index
index
/
sort
find
find
/search
search
,
increase
increase
/decrease
decrease
play
playback
/pause
pause
launch
start
/run
run
compile
compile
/execute
execution
debug
debugging
/trace
tracking
observe
observation
/listen
monitoring
build
build
/publish
release
input
input
/output
output
encode
encoding
/decode
decoding
encrypt
encryption
/decrypt
decryption
compress
compression
/decompress
decompression
pack
packaging
/unpack
unpacking
,
Parse
analysis
/emit
generation
connect
connection
/disconnect
disconnection
,
send
send
/receive
receive
downloaddownload
/ uploadupload
_
refresh
refresh
/synchronize
synchronization
update
update
/revert
recovery
lock
lock
/unlock
unlock
check out
check out
/check in check
in
submit
submit
/commit
delivery
push
push
/pull
pull
expandExpand
/ collapseCollapse
_
begin
start
/end
end
Start
/finish 4. The names of constants are all capitalized, and the words are separated by underscores, and the semantic expression should be complete and clear, and the name should not be too long
.
code format
1.
Use
2
spaces for indentation
;
2.
Insert a blank line between codes with different logic, different semantics, and different businesses to separate them to improve readability.
Note: In any case, there is no need to insert multiple blank lines for separation.
string
Uniformly use single quotes
('')
instead of double quotes
("")
. This is very useful when creating
HTML
strings:
object declaration
1.
Use literal values to create objects
;
enter
to enter
/exit
to exit
abort
to give up
/quit
to leave
obsolete
obsolete
/depreciate
obsolete
collect
collection
/aggregate
collection
**/
// good
const
MAX_STOCK_COUNT
// bad
const
MAX_COUNT
// good
if
(
x
<
y
) {
x
+=
10
;
}
else
{
x
+=
1
;
}
// good
let
str
=
'foo'
;
let
testDiv
=
'<div id="test"></div>'
;
// bad
let
str
=
'foo'
;
let
testDiv
=
"<div id='test'></div>"
;
2.
Use literals instead of object constructors.
brackets
Curly braces are required after the following keywords (even if the content of the code block is only one line):
Conditional judgment and loop up to three layers
If the conditional judgment can be solved by using ternary operators and logical operators, do not use conditional judgment, but remember not to write too long ternary operation
operator. If it exceeds
3
layers, please extract it into a function and write a clear comment.
The conversion name of this
References to the context
this can only
be named
using
'that'
block scope
1.
let
replace var
;
// good
let
user
=
{};
// bad
let
user
=
new
Object
();
// good
var
user
=
{
age
:
0
,
name
:
1
,
city
:
3
};
// bad
var
user
=
new
Object
();
user
.
age
=
0
;
user
.
name
=
0
;
user
.
city
=
0
;
if
,
else
,
for
,
while
,
do
,
switch
,
try
,
catch
,
finally
,
with
// good
if
(
condition
) {
doSomething
();
}
// if
后单行内容时
condition
&&
doSomething
()
// bad
if
(
condition
)
doSomething
();
ES6
提出了两个新的声明变量的命令:
let
和
const
。其中,
let
完全可以取代
var
,因为两者语义相同,
而且
let
没有副作用。
Therefore, it is recommended not to use
the var
command, but to use
the let
command instead.
2.
Global constants and thread safety.
Between
let
and
const , it is recommended to use
const
first
, especially in the global environment. Variables should not be set, only constants should be set.
const
is preferred over
let
for several reasons. One is that
const
can remind people who read the program that this variable should not change; the other is
const
is more in line with the idea of functional programming. The operation does not change the value, but only creates a new value, and this is also conducive to future distributed operations;
The last reason is that the
JavaScript
compiler will
optimize
const , so using more
const will help improve the running efficiency of the program.
Rate, that is to say , the essential difference between
let
and
const
is actually the difference in the internal processing of the compiler.
There are two other advantages of const
declaring constants. One is that people who read the code will immediately realize that this value should not be modified, and the other is to prevent inadvertent
Errors caused by modifying variable values.
All functions should be set as constants.
string
Static strings always use single quotes or backticks, not double quotes. Dynamic strings use backticks.
destructuring assignment
1.
When using array members to assign values to variables, destructuring assignment is preferred;
2.
If the parameter of the function is a member of the object, destructuring assignment is preferred;
// bad
const
a
=
"foobar"
;
const
b
=
'foo'
+
a
+
'bar'
;
// acceptable
const
c
=
`foobar`
;
// good
const
a
=
'foobar'
;
const
b
=
`foo${
a
}bar`
;
const
arr
=
[
1
,
2
,
3
,
4
];
// bad
const
first
=
arr
[
0
];
const
second
=
arr
[
1
];
// good
const
[
first
,
second
]
=
arr
;
// bad
function
getFullName
(
user
) {
const
firstName
=
user
.
firstName
;
const
lastName
=
user
.
lastName
;
3.
If the function returns multiple values, the destructuring assignment of the object is preferred over the destructuring assignment of the array. This makes it easy to add back later
value, and change the order in which the values are returned.
object
1.
For objects defined on a single line, the last member does not end with a comma. Objects defined on multiple lines, the last member ends with a comma;
}
// good
function
getFullName
(
obj
) {
const
{
firstName
,
lastName
}
=
obj
;
}
// best
function
getFullName
({
firstName
,
lastName
}) {}
// bad
function
processInput
(
input
) {
return
[
left
,
right
,
top
,
bottom
];
}
// good
function
processInput
(
input
) {
return
{
left
,
right
,
top
,
bottom
};
}
const
{
left
,
right
}
=
processInput
(
input
);
// bad
const
a
=
{
k1
:
v1
,
k2
:
v2
, };
const
b
=
{
k1
:
v1
,
k2
:
v2
};
// good
const
a
=
{
k1
:
v1
,
k2
:
v2
};
const
b
=
{
k1
:
v1
,
k2
:
v2
,
};
2.
The object should be as static as possible. Once defined, no new attributes can be added at will. If adding attributes is unavoidable, use
Object.assign
method;
// bad
const
a
=
{};
a
.
x
=
3
;
// if reshape unavoidable
const
a
=
{};
Object
.
assign
(
a
, {
x
:
3
});
// good
const
a
=
{
x
:
null
};
a
.
x
=
3
;
3
、如果对象的属性名是动态的,可以在创造对象的时候,使用属性表达式定义;
// bad
const
obj
=
{
id
:
5
,
name
:
'San Francisco'
,
};
obj
[
getKey
(
'enabled'
)]
=
true
;
// good
const
obj
=
{
id
:
5
,
name
:
'San Francisco'
,
[
getKey
(
'enabled'
)]:
true
,
};
4.
In addition, the properties and methods of the object should be expressed in a concise manner as much as possible, so that it is easy to describe and write.
var
ref
=
'some value'
;
// bad
const
atom
=
{
ref
:
ref
,
value
:
1
,
addValue
:
function
(
value
) {
return
atom
.
value
+
value
;
},
};
// good
const
atom
=
{
array
1.
Use the spread operator (
...
) to copy the array;
2.
Use
the Array.from
method to convert an array-like object into an array.
function
1.
Immediate execution functions can be written in the form of arrow functions;
2.
For those occasions where anonymous functions are used as parameters, try to use arrow functions instead. Because this is more concise and binds
this
;
ref
,
value
:
1
,
addValue
(
value
) {
return
atom
.
value
+
value
;
},
};
// bad
const
len
=
items
.
length
;
const
itemsCopy
=
[];
let
i
;
for
(
i
=
0
;
i
<
len
;
i
++
) {
itemsCopy
[
i
]
=
items
[
i
];
}
// good
const
itemsCopy
=
[
...
items
];
const
foo
=
document
.
querySelectorAll
(
'.foo'
);
const
nodes
=
Array
.
from
(
foo
);
//The difference between Array.from and the spread operator
The Array.from method also supports array
-
like objects. The so-called array-like objects have only one essential characteristic, that is, they must have a length property.
Therefore, any
object with a
length attribute can be converted to an array through
the Array . from method, and the spread operator cannot be converted at this time.
Array
.
from
({
length
:
3
});
// [ undefined, undefined, undefined ]
In the above code,
Array
.
from
returns an array with three members, and the value of each position is
undefined
. spread operator conversion
Can't get this object.
(()
=>
{
console
.
log
(
'Welcome to the Internet.'
);
})();
// bad
[
1
,
2
,
3
].
map
(
function
(
x
) {
return
x
*
x
;
});
// good
[
1
,
2
,
3
].
map
((
x
)
=>
{
return
x
*
x
;
});
// best
[
1
,
2
,
3
].
map
(
x
=>
x
*
x
);
3.
The arrow function replaces
Function.prototype.bind
, and
self/_this/that should not be used
to bind
this
;
// bad
const
self
=
this
;
const
boundMethod
=
function
(
...
params
) {
return
method
.
apply
(
self
,
params
);
}
// acceptable
const
boundMethod
=
method
.
bind
(
this
);
// best
const
boundMethod
=
(
...
params
)
=>
method
.
apply
(
this
,
params
);
4.
Arrow functions are recommended for simple, one-line, and non-reusable functions. If the function body is more complicated and the number of lines is larger, you should still
Use the traditional function writing method;
5.
All configuration items should be concentrated in one object and placed in the last parameter. Boolean values cannot be directly used as parameters;
// bad
function
divide
(
a
,
b
,
option
=
false
) {}
// good
function
divide
(
a
,
b
, {
options
=
false
}
=
{}) {}
6. Do not use
the arguments variable
in the function body
, use the rest operator ( ... ) instead. because the rest operator explicitly says that you want
To obtain parameters, and
arguments
is an array-like object, and
the rest
operator can provide a real array;
7.
Use the default value syntax to set the default value of the function parameter.
Map
deconstruction
Pay attention to the distinction between
Object
and
Map
, and only use
Object when simulating real-world entity objects
. If you just need
key: value
The data structure uses
the Map
structure. Because
Map
has a built-in traversal mechanism.
module
ES6
模块语法是
JavaScript
模块的标准写法,坚持使用这种写法,取代
Node.js
的
CommonJS
语
法。
1
、使用
import
取代
require()
;
// bad
function
concatenateAll
() {
const
args
=
Array
.
prototype
.
slice
.
call
(
arguments
);
return
args
.
join
(
''
);
}
// good
function
concatenateAll
(
...
args
) {
return
args
.
join
(
''
);
}
// bad
function
handleThings
(
opts
) {
opts
=
opts
||
{};
}
// good
function
handleThings
(
opts
=
{}) {
// ...
}
let
map
=
new
Map
(
arr
);
for
(
let
key
of
map
.
keys
()) {
console
.
log
(
key
);
}
for
(
let
value
of
map
.
values
()) {
console
.
log
(
value
);
}
for
(
let
item
of
map
.
entries
()) {
console
.
log
(
item
[
0
],
item
[
1
]);
}
// CommonJS
的写法
const
moduleA
=
require
(
'moduleA'
);
const
func1
=
moduleA
.
func1
;
const
func2
=
moduleA
.
func2
;
// ES6
的写法
import
{
func1
,
func2
}
from
'moduleA'
;
2.
Use
export
to replace
module.exports
;
//
How to write commonJS
var
React
=
require
(
'react'
);
var
Breadcrumbs
=
React
.
createClass
({
render
() {
return
<
nav
/ >
;
}
});
module
.
exports
=
Breadcrumbs
;
// ES6
way of writing
import
React
from
'react'
;
class
Breadcrumbs
extends
React
.
Component
{
render
() {
return
<
nav
/ >
;
}
};
export default
Breadcrumbs
;
如果模块只有一个输出值,就使用
export default
,如果模块有多个输出值,除非其中某个输出值特别
重要,否则建议不要使用
export default
,即多个输出值如果是平等关系,
export default
与普通的
export
就不要同时使用。
3
、如果模块默认输出一个函数,函数名的首字母应该小写,表示这是一个工具方法;
function
makeStyleGuide
() {}
export default
makeStyleGuide
;
4
、如果模块默认输出一个对象,对象名的首字母应该大写,表示这是一个配置值对象。
const
StyleGuide
=
{
es6
: {}
};
export default
StyleGuide
;
Vue
writing specification
Component introduction order
When importing components, they should be introduced in the order from global to local, from
vue
to
js
Component names are multiple words
Component names should always consist of multiple words, except for the root component
App
, and
things like
<transition>
,
<component>
Vue
built-in components.
Doing so avoids conflicts with existing and future
HTML
elements
, since all HTML element names are single-word.
component file
As long as there is a build system capable of splicing files, separate each component into files.
When you need to edit a component, or look up the usage of a component, this approach can help you find it more quickly.
<script>
import
{
mapGetters
}
from
'vuex'
;
import
eventBus
from
'../event/eventBus.js'
import
TodoLtem
from
'@/component/todoList.vue'
//
This component is a to-do list
//
Introduce
vue
file
, must carry
the .vue
suffix
import
{
getUserInfo
,
//
Get basic user information
getUserLoginInfo
//
Get login user details
}
from
'@/api/common/userInfo.js'
</script>
// good
app
.
component
(
'todo-item'
, {
// ...
})
export default
{
name
:
'TodoItem'
,
// ...
}
// bad
app
.
component
(
'todo'
, {
// ...
})
export default
{
name
:
'TodoItem'
,
// ...
}
Case of single file component file
单文件组件的文件名应该采用小驼峰命名法
lowerCamelCase
,代码中的命名均不能以下划线、中划线
连接
单文件组件的
name
应采用大驼峰命名法
UpperCamelCase
,
在组件注册时应采用大驼峰命名,组件在
模板中使用时亦采用大驼峰命名
// good
components
/
|-
TodoList
.
vue
|-
TodoItem
.
vue
// bad
app
.
component
(
'TodoList'
, {
// ...
})
app
.
component
(
'TodoItem'
, {
// ...
})
// good
components
/
|-
myComponent
.
vue
// bad
components
/
|-
my
-
component
.
vue
//good
export default
{
name
:
'MyComponent'
}
<template>
<MyComponent> </MyComponent>
</template>
<script>
import
MyComponent
from
'./myComponent.vue'
export default
{
component
:{
MyComponent
}
}
</script>
基础组件名称
应用特定样式和约定的基础组件
(
也就是展示类的、无逻辑的或无状态的组件
)
应该全部以一个特定的前
缀开头,比如
Base
、
App
或
V
。
紧密耦合的组件名称
与父组件紧密耦合的子组件应该以父组件名作为前缀命名。
如果特性元素较多,应该主动换行
// good
components
/
|-
BaseButton
.
vue
|-
BaseTable
.
vue
|-
BaseIcon
.
vue
components
/
|-
AppButton
.
vue
|-
AppTable
.
vue
|-
AppIcon
.
vue
components
/
|-
VButton
.
vue
|-
VTable
.
vue
|-
VIcon
.
vue
// bad
components
/
|-
MyButton
.
vue
|-
VueTable
.
vue
|-
Icon
.
vue
// good
components
/
|-
todoList
.
vue
|-
todoListItem
.
vue
|-
todoListItemButton
.
vue
// bad
components
/
|-
TodoList
.
sight
|
-
TodoItem.vue
_
|
-
TodoButton.vue
_
// good
<MyComponent
foo
=
"a"
bar
=
"b"
baz
=
"c"
foo
=
"a"
Prop
definition
Prop
definition should be as detailed as possible
In the submitted code, the definition of
prop
should be as detailed as possible, at least specifying its type.
Careful
prop
definitions
have two advantages:
They describe
the API of the component
, so the design and usage of the component can be easily understood;
In a development environment, Vue will warn if a malformed
prop
is provided to a component
to help you catch potential
error source.
Set the key value for
v
-
for
Always
use
key with
v - for .
bar
=
"b"
baz
=
"c"
foo
=
"a"
bar
=
"b"
baz
=
"c"
/>
// bad
<MyComponent
foo
=
"a"
bar
=
"b"
baz
=
"c"
foo
=
"a"
bar
=
"b"
baz
=
"c"
foo
=
"a"
bar
=
"b"
baz
=
"c"
foo
=
"a"
bar
=
"b"
baz
=
"c"
/>
// good
props
: {
status
:
String
}
//
better example
props
: {
status
: {
type
:
String
,
required
:
true
,
validator
:
value
=>
{
return
[
'syncing'
,
'synced'
,
'version-conflict'
,
'error'
].
includes
(
value
)
}
}
}
// bad
//
This is only acceptable for prototyping
props
: [
'status'
] must always be
keyed with v - for
on the component
in order to maintain the state of the internal component and its subtree. Even for elements, maintaining predictable
The behavior of testing is also a good practice.
It is forbidden to use the index
of the cycle
as
the key of the component
Avoid
using
v
-
if
and
v
-
for together
(vue2.x)
Never use both v
-
if
and
v
-
for
on the same element
.
Generally we tend to do this in two common situations:
In order to filter items in the list
(
eg
v
-
for="user in users" v
-
if="user.isActive"
)
. In this kind of
情形下,请将
users
替换为一个计算属性
(
比如
activeUsers
)
,返回过滤后的列表。
为了避免渲染本应该被隐藏的列表
(
比如
v
-
for="user in users" v
-
if="shouldShowUsers"
)
。
这种情形下,请将
v
-
if
移动至容器元素上
(
比如
ul
、
ol
)
。
// good
<
ul
>
<
li
v
-
for
=
"todo in todos"
:
key
=
"todo.id"
>
{
{
todo
.
text
}}
<
/li>
<
/ul>
// bad
<
ul
>
<
li v
-
for
=
"todo in todos"
>
{
{
todo
.
text
}}
<
/li>
<
/ul>
<
ul
>
<
li v
-
for
=
"(todo,idx) in todos"
:
key
=
"idx"
>
{
{
todo
.
text
}}
<
/li>
<
/ul>
// good
<ul>
<template
v-for
=
"user in users"
:key
=
"user.id"
>
<li
v-if
=
"user.isActive"
>
{
{ user.name }}
</li>
</template>
</ul>
// bad
<ul>
<li
v-for
=
"user in users"
v-if
=
"user.isActive"
:key
=
"user.id"
>
{
{ user.name }}
sets scope for component styles
For an application, styles
can be global in the
top-level App component and layout components, but should be in all other components.
scoped.
This rule only applies to
single-file components
. You
don't
have to use
scoped
attribute
. Scoping can also be done via
CSS Modules
(
a
class
-based,
BEM
-like strategy
)
or other libraries
/
conventions to implement.
In any case, for component libraries, we should prefer to choose
class
-based strategy instead of
scoped
attribute
.
这会让覆写内部样式变得更容易:使用人类可理解的
class
名称,没有太高的选择器优先级,而且不太
会导致冲突。
模板中使用简单的表达式
组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法。
</li>
</ul>
// good
<template>
<button
class
=
"button button-close"
>
×
</button>
</template>
<!--
使用
`scoped` attribute -->
<style
scoped
>
.button
{
border
:
none
;
border-radius
:
2px
;
}
.button-close
{
background-color
:
red
;
}
</style>
// bad
<template>
<button
class
=
"btn btn-close"
>
×
</button>
</template>
<style>
.btn-close
{
background-color
:
red
;
}
</style>
// good
<template>
<p>
{
{ normalizedFullName }}
</p>
Command abbreviation
Directive abbreviations
(
with
:
for
v
-
bind:
,
@
for
v
-
on:
and
#
for
v
-
slot
)
should either always be used or never
use.
</template>
//
complex expression has been moved into a computed property
computed: {
normalizedFullName: function () {
return this.fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}
}
// bad
<template>
<p>
{
{ fullName.split(' ').map(function (word) { return word[0].toUpperCase() +
word.slice(1) }).join(' ') }}
</p>
</template>
// good
<input
:value
=
"newTodoText"
:placeholder
=
"newTodoInstructions"
>
<input
v-bind:value
=
"newTodoText"
v-bind:placeholder
=
"newTodoInstructions"
>
<input
@input
=
"onInput"
@focus
=
"onFocus"
>
<input
v-on:input
=
"onInput"
v-on:focus
=
"onFocus"
>
<template
v-slot:header
>
<h1>
Here might be a page title
</h1>
</template>
<template
v-slot:footer
>
<p>
Here's some contact info
</p>
</template>
tag order is consistent
Single-file components should always keep the label order as
v-show
and
v-if
options
If at runtime, you need to switch very frequently, use
v-show
; if at runtime, the condition rarely changes, use
v-if
.
Order of component
/ instance options
Options for components
/
instances should have a uniform order.
<template
#header
>
<h1>
Here might be a page title
</h1>
</template>
<template
#footer
>
<p>
Here's some contact info
</p>
</template>
// bad
<input
v-bind:value
=
"newTodoText"
:placeholder
=
"newTodoInstructions"
>
<input
v-on:input
=
"onInput"
@focus
=
"onFocus"
>
<template
v-slot:header
>
<h1>
Here might be a page title
</h1>
</template>
<template
#footer
>
<p>
Here's some contact info
</p>
</template>
// good
<template>
...
</template>
<script>
...
</script>
<style>
...
</style>
// bad
<template>
...
</template>
<style>
...
</style>
<script>
...
</script>
This is the default order we recommend for component options. They are divided into several categories, so you can know that the new
property
should be placed in
where.
1.
Global perception
(
required to be perceived outside the component
)
name
2.
Template compilation options
(
change the way templates are compiled
)
compilerOptions
3.
Template dependency
(
resources used in the template
)
components
directives
4.
Combination
(
merge
property
into options
)
extends
mixins
provide
/
inject
5.
Interface
(
interface of component
)
inheritAttrs
props
emits
expose
6.
Composition
API
(
entry point
to use composition
API
)
setup
7.
本地状态
(
本地的响应式
property)
data
computed
8.
事件
(
通过响应式事件触发的回调
)
watch
生命周期事件
(
按照它们被调用的顺序
)
beforeCreate
created
beforeMount
mounted
beforeUpdate
updated
activated
deactivated
beforeUnmount
unmounted
errorCaptured
renderTracked
renderTriggered
9.
非响应式的
property
(
不依赖响应性系统的实例
property)
methods
10.
渲染
(
组件输出的声明式描述
)
template
/
render
元素
attribute
的顺序
元素
(
包括组件
)
的
attribute
应该有统一的顺序。
This is the default order we recommend for component options. They are divided into several categories, so you can know the newly added custom
attribute
and where the directive should be placed.
1.
Definition
(
provide options for components
)
is
2.
List rendering
(
creating multiple variants of the same element
)
v
-
for
3.
Condition
(
whether the element is rendered
/
displayed
)
v
-
if
v
-
else
-
if
v
-
else
v
-
show
v
-
cloak
4.
Rendering modifiers
(
changing how elements are rendered
)
in
-
for
v
-
once
5.
Global perception
(
required to be perceived outside the component
)
id
6.
唯一性
Attribute
(
需要唯一值的
attribute)
ref
key
7.
双向绑定
(
结合了绑定与事件
)
v
-
model
8.
其他
Attribute
(
所有普通的、绑定或未绑定的
attribute)
9.
事件
(
组件事件监听器
)
v
-
on
10.
内容
(
覆写元素的内容
)
v
-
html
v
-
text
scoped
中的元素选择器
元素选择器应该避免在
scoped
中出现。
在
scoped
样式中,类选择器要比元素选择器更好,因为大量地使用元素选择器是很慢的。
// good
<template>
<button
class
=
"btn btn-close"
>
×
</button>
</template>
<style
scoped
>
.btn-close
{
background-color
:
red
;
Vue Router
specification
Page jump data transfer using routing parameters
Use route lazy loading (lazy loading) mechanism
Naming convention in router
The naming convention of path
and
childrenPoints
adopts the small hump naming convention (try to
keep the directory structure of the
vue file consistent, because the target
The directory and file names are all in humpcase, which makes it easy to find the corresponding file)
**The name
naming convention adopts the big hump naming convention and is
consistent with the
component component name!
(Because
keep-alive
feature,
keep-alive
is cached
according to
the name of
the component , so the two must be highly consistent)
}
</style>
// bad
<template>
<button>
×
</button>
</template>
<style
scoped
>
button
{
background-color
:
red
;
}
</style>
// good
let
id
=
'123'
;
this
.
$router
.
push
({
name
:
'userCenter'
,
query
: {
id
:
id
}
});
// good
{
path
:
'/uploadAttachment'
,
name
:
'UploadAttachment'
,
meta
: {
title
:
'
Upload Attachment
'
},
component
: ()
=>
import
(
'@/view/components/uploadAttachment/index.vue'
)
},
//
Dynamically load the
Vue
project directory specification
Base
All naming in the
vue project must be consistent with the backend naming. For example, permissions: back-end
privilege,
front-end regardless of
router, store,
API
and so on must use
privielege
words!
Catalog description
export const
reload
=
[{
path
:
'/reload'
,
name
:
'Reload'
,
component
:
Main
,
meta
: {
title
:
'
Dynamic Loading
'
,
icon
:
'icon iconfont'
},
children
: [{
path
:
'/reload/smartReloadList'
,
name
:
'SmartReloadList'
,
component
: ()
=>
import
(
'@/views/reload/smartReload/smartReloadList.vue'
)
}]
}
];
src
源码目录
|-- api
所有
api
接口
|-- assets
静态资源,
images, icons, styles
等
|-- components
公用组件
|-- config
配置信息
|-- constants
常量信息,项目所有
Enum,
全局常量等
|-- datas
模拟数据,临时存放
|-- mock
模拟接口,临时存放
|-- router
路由,统一管理
|-- store vuex,
统一管理
|-- themes
自定义样式主题
|-- views
视图目录
| |-- role role
模块名
| |-- |-- roleList.vue role
列表页面
| |-- |-- roleAdd.vue role
新建页面
| |-- |-- roleUpdate.vue role
更新页面
| |-- |-- index.less role
模块样式
| |-- |-- components role
模块通用组件文件夹
| |-- employee employee
模块
api
目录
assets
目录
components
目录
文件、变量命名要与后端保持一致。
此目录对应后端
API
接口,按照后端一个
controller
一个
api js
文件。若项目较大时,可以按
照业务划分子目录,并与后端保持一致。
The method name in
the api should be as semantically consistent as possible with the backend
api url .
Add annotations to each method in the
api , and the annotations
are consistent with the backend swagger documentation.
rear end:
url
:
EmployeeController.java
/employee/add
/employee/delete/{id}
/employee/update
front end:
employee.js
//
add employee
addEmployee: (data) => {
return postAxios('/employee/add', data)
},
//
Update employee information
updateEmployee: (data) => {
return postAxios('/employee/update', data)
},
//
delete employee
deleteEmployee: (employeeId) => {
return postAxios('/employee/delete/' + employeeId)
},
assets
are static resources, which store
images, styles, icons
and other static resources. The naming format of static resources is
kebabCase
|assets
|-- icons
|-- images
| |-- backgroundColor.png
| |-- uploadHeader.png
|-- styles
constants
目录
此目录应按照组件进行目录划分,目录命名为
kebabCase
,组件命名规则也为
kebabCase
|components
|-- errorLog
| |-- index.vue
| |-- index.less
|-- markdownEditor
| |-- index.vue
| |-- index.js
|-- kebabCase
此目录存放项目所有常量,如果常量在
vue
中使用,请使用
vue
-
enum
插件
(
https
:
//www.npmjs.com/package/vue-enum)
目录结构:
|
constants
|--
index
.
js
|--
role
.
js
|--
employee
.
js
例子:
employee
.
js
export const
EMPLOYEE_STATUS
=
{
NORMAL
: {
value
:
1
,
desc
:
'
normal
'
},
DISABLED
: {
value
:
1
,
desc
:
'
disabled
'
},
DELETED
: {
value
:
2
,
desc
:
'
Deleted
'
}
};
export const
EMPLOYEE_ACCOUNT_TYPE
=
{
QQ
: {
value
:
1
,
desc
:
'QQ
login
'
},
WECHAT
: {
value
:
2
,
desc
:
'
WeChat login
'
},
DINGDING
: {
value
:
3
,
desc
:
'
DingTalk login
'
},
router
and
store
directory
views
directory
Notes
annotation requirements
USERNAME
: {
value
:
4
,
desc
:
'
Username password login
'
}
};
export default
{
EMPLOYEE_STATUS
,
EMPLOYEE_ACCOUNT_TYPE
};
These two directories must split the business and cannot be placed in a
js
file.
The router
tries
to be consistent with the structure in
views .
store
recommends splitting different
js
files according to business. When the business is complex, it must be split into different modules
The naming should be consistent with the backend,
router
,
api , etc.
Components in components
should use
pascal-case
rules
|-- views
视图目录
| |-- role role
模块名
| | |-- roleList.vue role
列表页面
| | |-- roleAdd.vue role
新建页面
| | |-- roleUpdate.vue role
更新页面
| | |-- index.less role
模块样式
| | |-- components role
模块通用组件文件夹
| | | |-- roleHeader.vue role
头部组件
| | | |-- roleModal.vue role
弹出框组件
| |-- employee employee
模块
| |-- behaviorLog
行为日志
log
模块
| |-- codeGenerator
代码生成器模块
整理必须加注释的地方
其他
尽量不要手动操作
DOM
因使用
vue
框架,所以在项目开发中尽量使用
vue
的数据驱动更新
DOM
,尽量(不到万不得已)不要
Manually manipulate
DOM
, including: adding, deleting, modifying
dom
elements, changing styles, adding events, etc.
Remove useless code
Due to the use of the
svn
code version tool, the useless code must be deleted in time, for example: some debugging
console
statements,
debugger
, useless code for deprecated functions.
svn
commit specification
note
For the code submitted to
the svn
code base, each
commit
needs to fill in the modifications made by this submission. When there are multiple modifications, use the sequential
table display
code integrity
The code submitted to
the svn
code base must ensure that
it can run normally after
Checkout , and
it is forbidden to prompt the console with an error or warning message.
Submit the code, personal configuration information is prohibited from being uploaded to the
svn
code base to avoid conflicts with co-developers
, and
the baseUrl
of the request
is prohibited in the code
Hard-coded, multi-environment switching, please use
the node
environment configuration to determine which path to use,
you must ensure that
the files in the code base can be packaged after checking out
Work well in every environment
For page comments, the following content needs to be written at the top of the page ()
<!--
des
: The description about this page needs to indicate the function of this page or component
creator
: Creator (the original author of the file can write)
createTime
: Creation time (it can be written by the original author of the file)
-->
For
the method that the page needs to be modified due to requirements or
bugs , the following content also needs to be stated
/*
des
: The description about this change needs to state the reason for this change
updator
: Creator (the author of the modification
--
not the current file author needs to write)
updateTime
: Creation time (the author of the modification)
*/
Instructions for use of public components
The interface js file in the api
directory
must be annotated to describe the function of the interface
The state, mutation, action, etc.
in
the store must be annotated to describe the function of the attribute
When a vue file introduces a component, a note must be added to explain the purpose of the component
When a vue
file introduces a method in
the api
, a note must be added to explain the purpose of the method
For the methods of the vue
file
, comments must be added for each method , and additional comments must be added for complex business processing in the method
The data of the
vue file
,
very common attribute names need to be commented, for example:
tableData/searchForm
does not need to add comments,
scaleEffectKey
needs to add annotations
1.xxx
2.xxx
ignore
//good
service
.
baseURL
=
process
.
env
.
VUE_APP_BASE_URL
;
//bad
service
.
baseURL
=
'http://127.0.0.1:9999'
;
//
Various types of files that do not need to be submitted
.
DS_Store
node_modules
/
dist
.
history
#
Log files
npm
-
debug
.
log
*
yarn
-
debug
.
log
*
yarn
-
error
.
log
*
pnpm
-
debug
.
log
*
#
Editor directories and files
.
idea
.
vscode
*
.
suo
*
.
ntvs
*
*
.
njsproj
*
.
sln
*
.
sw
?