Front-end development technical specification

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 ?

Guess you like

Origin blog.csdn.net/z1093541823/article/details/125102169