nitroge / memories

日常学习累积的点点滴滴滴滴点点
7 stars 0 forks source link

项目开发规范和风格指南 #25

Open nitroge opened 2 years ago

nitroge commented 2 years ago

项目开发规范和风格指南

为什么要制定开发规范?

  • 团队编码风格不一,增加了成员之间代码阅读成本,加大了团队协作成本和维护成本
  • 随着团队人员的变化(多人开发一个应用,或者应用更换开发人员),如果缺乏规范,项目可能会变得一团糟,甚至失控
  • 虽然这些细节是小事,不会有体验或者性能上的优化,但是却体现了一个coder和团队的专业程度

    Vue

  • 单文件组件名大小写:要么始终是单词大写开头(PascalCase),要么始终是横线连接(kebab-case)
  • 模板中的组件名大小写:视觉上比更能够和单个单词的HTML元素区别开来
  • 简单的计算属性:应该把复杂计算属性分割为尽可能多的更简单的property
  • props传参的单一性:不要把功能点包裹到一个对象传递,可读性极差
  • 模板中简单的表达式:复杂表达式会让你的模板变得不那么声明式。我们应该尽量描述应该出现的是什么,而非如何计算那个值。
  • 避免使用魔法数字/魔法变量,这种写法写出来的代码晦涩难懂,难以维护,隐藏 BUG 多
  • scoped中的元素选择器:在 scoped 样式中,类选择器比元素选择器更好,因为大量使用元素选择器是很慢的。
  • 变量命名:不要使用缩写,除非每个人都能轻而易举的读懂它的意思
  • 方法命名:当前组件元素抛出的事件用on开头,子组件抛出的事件用handle开头

    JavaScript

    对象键值速记

    
    const lukeSkywalker = 'Luke Skywalker';

// bad const obj = { lukeSkywalker: lukeSkywalker, };

// good const obj = { lukeSkywalker, };

使用对象多个属性时对对象进行结构,数组同
```javascript
// bad
function getFullName(user) {
  const firstName = user.firstName;
  const lastName = user.lastName;

  return `${firstName} ${lastName}`;
}

// good
function getFullName(user) {
  const { firstName, lastName } = user;
  return `${firstName} ${lastName}`;
}

// best
function getFullName({ firstName, lastName }) {
  return `${firstName} ${lastName}`;
}

使用默认参数语法,而不是改变函数参数

// really bad
function handleThings(opts) {
  // No! We shouldn’t mutate function arguments.
  // Double bad: if opts is falsy it'll be set to an object which may
  // be what you want but it can introduce subtle bugs.
  opts = opts || {};
  // ...
}

// good
function handleThings(opts = {}) {
  // ...
}

将变量分配到需要的位置,但将它们放在合理的位置

// bad - unnecessary function call
function checkName(hasName) {
  const name = getName();

  if (hasName === 'test') {
    return false;
  }

  if (name === 'test') {
    this.setName('');
    return false;
  }

  return name;
}

// good
function checkName(hasName) {
  if (hasName === 'test') {
    return false;
  }

  const name = getName();

  if (name === 'test') {
    this.setName('');
    return false;
  }

  return name;
}

对布尔值使用快捷方式,但对字符串和数字使用显式比较。

// bad
if (isValid === true) {
  // ...
}

// good
if (isValid) {
  // ...
}

// bad
if (name) {
  // ...
}

// good
if (name !== '') {
  // ...
}

// bad
if (collection.length) {
  // ...
}

// good
if (collection.length > 0) {
  // ...
}

三元组不应嵌套,通常为单行表达式

// bad
const foo = maybe1 > maybe2
  ? "bar"
  : value1 > value2 ? "baz" : null;

// split into 2 separated ternary expressions
const maybeNull = value1 > value2 ? 'baz' : null;

// good
const foo = maybe1 > maybe2 ? 'bar' : maybeNull;

避免不必要的三元语句

// bad
const foo = a ? a : b;
const bar = c ? true : false;
const baz = c ? false : true;

// good
const foo = a || b;
const bar = !!c;
const baz = !c;

不要使用选择运算符代替控制语句

// bad
!isRunning && startRunning();

// good
if (!isRunning) {
  startRunning();
}

CSS

Use :not() to Apply/Unapply Borders on Navigation

/*bad*/
.nav li {
  border-right: 1px solid #666;
}
.nav li:last-child {
  border-right: none;
}
/*good*/
.nav li:not(:last-child) {
  border-right: 1px solid #666;
}

函数式编程

将程序分解为一些更可重用、更可靠且更易于理解的部分,然后将他们组合起来,形成一个更易推理的程序整体。

// 命令式编程
var arr = [1, 2, 3, 4];
var newArr = [];
for(let i = 0; i < arr.length; i++){
newArr.push(arr[i] + 1);
}
// 函数式编程
var add = x => x+1;
var createArr = function (arr, fn) {
var newArr = [];
for(let i = 0; i < arr.length; i++){
newArr.push(fn(arr[i]));
}
return newArr;
}

纯函数:
纯函数可以保证代码的稳定性,因为相同的输入永远会得到相同结果。不纯的函数可能会带来副作用。 函数副作用 调用函数时除了返回函数值之外,还对主调用函数产生附加的影响,比如修改全局变量或者外部变量,或者修改参数。这可能会带来难以查找的问题并降低代码的可读性。

减少副作用方法:

可变性和不可变性:

方法链:

// For eventloop
const files = [ 'foo.txt ', '.bar', '   ', 'baz.foo' ];
let filePaths = [];

for (let file of files) {
  const fileName = file.trim();
  if(fileName) {
    const filePath = `~/cool_app/${fileName}`;
    filePaths.push(filePath);
  }
}
// filePaths = [ '~/cool_app/foo.txt', '~/cool_app/.bar', '~/cool_app/baz.foo']

// Method chaining
const files = [ 'foo.txt ', '.bar', '   ', 'baz.foo' ];
const filePaths = files
  .map(file => file.trim())
  .filter(Boolean)
  .map(fileName => `~/cool_app/${fileName}`);

// filePaths = [ '~/cool_app/foo.txt', '~/cool_app/.bar', '~/cool_app/baz.foo']

文章推荐

你已经是一个成熟的码农了,这些思维习惯你要有 前端工程师都有哪些靠谱的小工具 css黑魔法小技巧