開發者生存技能 - 代碼規範篇

團隊項目,良好的代碼習慣很是重要。 如下爲本人開發項目中的代碼習慣,或許對你有所幫助

WHY?

  • 團隊項目不是一我的在寫代碼,本身寫代碼爽了,也要讓別人看着清晰
  • 減小bug處理,方便bug查找解決,提升開發效率,減小沒必要要的精力消耗
  • 方便後期維護

HOW?

基本準則

  • 代碼縮進嚴格統一,要麼都是2空格,要麼都是4空格,禁止一切空格交叉使用致使代碼不對齊,看着頭痛的狀況出現
  • 禁止代碼斷層(完整代碼塊內出現多餘的空行)
  • 註釋必須寫
  • 非工程化項目中css禁止在html代碼中書寫
  • 註銷無用的代碼一概刪掉
  • 便於開發的代碼,例如console.log()alert()在開發完成後一概刪掉

HTML

  • 寫註釋javascript

    若是代碼量少還看的清楚,可是代碼量多了,看大量沒有註釋的代碼就沒那麼輕鬆,因此註釋要寫上
    <!-- yes -->
    <!-- 下一步 -->
    <div class="btn-group df-jcc">
      <button class="next-step cp">下一步</button>
      <button class="submit cp">提交</button>
      <button class="exit cp">退出</button>
    </div>
    
    <!-- 提示 -->
    <div class="prompt-layer">
      <div class="title df-aic df-jcc">
        <h3>舒適提示</h3>
      </div>
      <div class="prompt-content">
        <img src="xxx.png" alt="xxx">
        <p class="ac"></p>
      </div>
    </div>
    
    
    <!-- no -->
    <div class="btn-group df-jcc">
      <button class="next-step cp">下一步</button>
      <button class="submit cp">提交</button>
      <button class="exit cp">退出</button>
    </div>
    <div class="prompt-layer">
      <div class="title df-aic df-jcc">
        <h3>舒適提示</h3>
      </div>
      <div class="prompt-content">
        <img src="xxx.png" alt="xxx">
        <p class="ac"></p>
      </div>
    </div>
  • 標籤合理使用css

    <!-- 頭部 -->
    <header></header>
    <!-- 主內容 -->
    <main></main>
    <!-- 尾部 -->
    <footer></footer>
    <!-- 按鈕 -->
    <button></button>
    <!-- 導航 -->
    <nav></nav>
    <!-- 標題 h1-h6 -->
    <h3></h3>
    
    ......
    <!-- yes -->
    <button class="btn"></button>
    
    <!-- no -->
    <div class="btn"></div>
  • 標籤classid命名語義化html

    頭部: class="header"
    尾部: footer
    導航: nav
    側邊欄: sidebar
    標籤頁: tab
    菜單: menu
    ......
    <!-- yes -->
    <div class="sidebar"></div>
    
    <!-- no -->
    <div class="left"></div>
  • 標籤屬性值使用""包裹,不要使用''java

    <!-- yes -->
    <footer class="footer"></footer>
    
    <!-- no -->
    <footer class='footer'></footer>
  • 標籤屬性書寫順序web

    class
    id
    data-*
    src, type, href, value
    title, alt
    <!-- yes -->
    <a class="" id="" data-val="" href=""></a>
    
    <!-- no -->
    <a id="" href="" class="" data-val=""></a>
  • 禁止代碼斷層,出現多餘的空行形成代碼可讀性不好json

    <!-- yes -->
    <div class="point-type df bg-white mb-20 p-20-30 border-e5">
      <div class="text-title">
          <h3></h3>
      </div>
      <nav class="flex-1">
        <ul class="clearfix"></ul>
      </nav>
    </div>
    
    <!-- very poor -->
    <div class="point-type df bg-white mb-20 p-20-30 border-e5">
    
      <div class="text-title">
      
          <h3></h3>
      </div>
      
      <nav class="flex-1">
        <ul class="clearfix"></ul>
        
      </nav>
    </div>

CSS

  • 項目初始化樣式reset.cssantd

    *{-webkit-box-sizing: content-box; -moz-box-sizing: content-box; box-sizing: content-box;}
    body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td { margin:0; padding:0;}
    body { color:rgba(51,51,51,0.8); font-size:14px; font-family: "Arial","Microsoft YaHei","黑體","宋體",sans-serif; }
    td,th,caption { font-size:14px; }
    h1, h2, h3, h4, h5, h6 { font-weight:normal; font-size:100%; }
    address, caption, cite, code, dfn, em, strong, th, var { font-style:normal; font-weight:normal;}
    a { color:#555; text-decoration:none; }
    a:hover { text-decoration: none; }
    img { border:none; vertical-align: middle}
    ol,ul,li { list-style:none; }
    i{font-style: normal;}
    input, textarea, select, button { font:14px "Arial","Microsoft YaHei","黑體","宋體",sans-serif;}
    input,button{border: none; outline: none;}
    input[type=checkbox], input[type=radio]{margin: 0;}
    table { border-collapse:collapse; }
    html {overflow-y: scroll;}
    p{margin: 0;}
    .clearfix:after {content: "."; display: block; height:0; clear:both; visibility: hidden;}
    .clearfix { *zoom:1; }/*公共類*/
  • 項目自定義公用樣式統一放在某一指定css根據自身習慣決定,如下是我編寫css習慣app

    • 將一些常常使用到的樣式統一放到public.css文件中,避免重複書寫
    /* 
     * public.css
     */
     
    .fl {
        float: left;
    }
    .fr {
        float: right;
    }
    .ac {
        text-align: center;
    }
    .ar {
        text-align: right;
    }
    .df {
        display: -webkit-flex;
        display: flex;
    }
    .df-aic {
        display: -webkit-flex;
        display: flex;
        align-items: center;
    }
    .df-jcc {
        display: -webkit-flex;
        display: flex;
        justify-content: center;
    }
    .flex-1 {
        flex: 1;
    }
    .bs {
        -webkit-box-sizing: border-box;
        -moz-box-sizing: border-box;
        box-sizing: border-box;
    }
    .cp {
        cursor: pointer;
    }
    .bg-white {
        background-color: #fff;
    }
    .w100 {
        width: 100%;
    }
    .h100 {
        height: 100%;
    }
    .mb-20 {
        margin-bottom: 20px;
    }
    
    ......
    • 其餘公用樣式統一放到base.css
    /* 
     * base.css
     * 凡是多個頁面會同時使用到的樣式所有放入該文件中 
     */
     
    body {
        background-color: #f9f9fb;
    }
    .container {
        width: 1280px;
        margin: auto;
        padding: 0 15px;
    }
    
    /* 頭部 */
    header {}
    
    /* 主內容 */
    main {}
    
    /* 尾部 */
    footer {}
    
    /* 搜索 */
    .search {}
    
    /* checkbox */
    input[type="checkbox"] {
        width: 20px;
        height: 20px;
        -webkit-appearance:none;
        background: url("xxx.png") no-repeat center;
    }
    input[type="checkbox"]:checked {
         background: url("xxx.png") no-repeat center;
    }
    
    ......
  • 寫註釋async

    某一區塊代碼的樣式寫好註釋,好比 headerfooter列表搜索返回頂部 ...
    /* yes */
    /* header */
    header {}
    
    /* footer */
    footer {}
    
    /* 返回頂部 */
    .go-top {}
    
    /* no */
    header {}
    footer {}
    .go-top {}
  • css書寫順序ide

    • 文本位置樣式
      float,position,left,top,display,z-index...
    • 文本寬高,邊距
      width,height,padding,margin...
    • 文本內容顏色,大小
      color,line-height,font-size,text-align...
    • 文本背景,邊框
      background,border...
    • 其餘
      border-radius,transform,transiton...
    /* yes */
    nav ul li {
        float: left;
        width: 90px;
        height: 32px;
        margin: 10px;
        padding: 0 20px 0 10px;
        font-size: 18px;
        text-align: right;
        border: 1px solid #eee;
        border-radius: 4px;
    }
    
    /* no */
    nav ul li {
        margin: 10px;
        text-align: right;
        border: 1px solid #eee;
        width: 90px;
        height: 32px;
        padding: 0 20px 0 10px;
        float: left;
        font-size: 18px;
        border-radius: 4px;
    }
  • padding margin寫法

    /* 只有一個值的狀況 */
    .title {
         margin-left: 10px;
    }
    
    /* 多值狀況 */
    /* yes */
    .title {
        margin: 0 20px 10px;
    }
    
    /* no */
    .title {
        margin-top: 0;
        margin-right: 20px;
        margin-left: 20px;
        margin-bottom: 10px;
    }
  • css選擇器兩邊各保留一個空格

    /* yes */
    label + input {
        margin-left: 10px;
    }
    nav > ul > li {
        margin-left: 10px;
    }
    
    /* no */
    label+input {
        margin-left: 10px;
    }
    nav>ul>li {
        margin-left: 10px;
    }

JavaScript

  • 寫註釋

    • 整功能模塊註釋
    /**
     *   列表篩選
     *   @param {Array} xxxxx              保存所選省份
     *   @param {String} xxxxxxxxxx        保存所選年代
     *   @method xxxx                      保存所選部分,用於篩選
     *   @method xxxx                      刪除篩選中所選條件
     *   ......
     */
    • 整功能模塊內部小功能代碼註釋也須要寫
    // 列表分頁
    xxxx
    
    // 重置篩選條件
    xxxx
  • 駝峯命名

    /* yes */
    let searchVal = '';
    function getUserInfo() {}
    
    /* no */
    let searchval = '';
    function getuserinfo() {}
    ......
  • 加空格讓代碼更優雅

    • = == === > < % + * / , ...

      /* yes */
      const name = 'yuci';
      const userArr = ['a', 'b', 'c'];
      if (i === 0) {
          // do
      }
      for (let i = 0, len = arr.length; i < len; i++) {
          // do
      }
      
      /* no */
      const name='yuci';
      const userArr=['a','b','c'];
      if(i===0){
          // do
      }
      for(let i=0,len=arr.length;i<len;i++){
          // do
      }
      ......
    • if else for while switch try catch function ...

      /* yes */
      if (i === 0) {
          // do
      } else {
          // do
      }
      try {
          // do
      } catch {
          // do
      }
      switch (dataSort) {
          // do
      }
      for (let i = 0, len = arr.length; i < len; i++) {
          // do
      }
      const fn = username => {
          // do
      }
      function fn() {
          // do
      }
      
      /* no */
      if(i===0){
          // do
      }else{
          // do
      }
      for(let i=0,len=arr.length;i<len;i++){
          // do
      }
      switch(dataSort){
          // do
      }
      const fn=username=>{
          // do
      }
      function fn(){
          // do
      }
      ......
    • 對象 : 右邊加上一個空格

      /* yes */
      const user = {
          name: 'xxx',
          age: 'xxx'
      }
      this.state = {
            username: ''
      }
      this.setState({
            username: 'yucihent'
      })
      
      /* no */
      const user = {
          name:'xxx',
          age:'xxx'
      }
      ......
  • 禁止代碼斷層(可讀性很是差)

    /* yes */
    let fetchData = async (url, method, data) => {
        let options;
        let dataStr = '';
        const headers = {
          'Accept': 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded'
        };
        // get 請求
        if (method === 'get') {
            if (typeof data === 'object') {
                Object.keys(data).forEach(key => {
                    dataStr += `${key}=${data[key]}&`
                });
                if (dataStr) {
                    dataStr = dataStr.substring(0, dataStr.length - 1)
                };
                url = `${url}?${dataStr}`;
            }
            options = {
                method: 'GET',
                headers,
            }
        } else {
            let formData = new FormData();
            for (let key in data) {
                formData.append(key, data[key])
            }
            options = {
                method: 'POST',
                body: formData
            }
        }
        let response = await fetch(url, options);
        let res = await response.json();
        return res;
    }
    
    /* very poor very poor very poor */
    let fetchData = async (url, method, data) => {
        let options;
        let dataStr = '';
        const headers = {
          'Accept': 'application/json',
          'Content-Type': 'application/x-www-form-urlencoded'
        };
        // get 請求
        if (method === 'get') {
            if (typeof data === 'object') {
                Object.keys(data).forEach(key => {
                    dataStr += `${key}=${data[key]}&`
                });
                
                if (dataStr) {
                    dataStr = dataStr.substring(0, dataStr.length - 1)
                    
                };
                url = `${url}?${dataStr}`;
    
            }
            options = {
                method: 'GET',
                headers,
            }
        } else {
            let formData = new FormData();
            
            for (let key in data) {
                formData.append(key, data[key])
                
            }
            options = {
                method: 'POST',
                body: formData
            }
    
    
        }
        
        let response = await fetch(url, options);
        let res = await response.json();
        return res;
    
    
    }
  • 一行代碼不要過多

    /* yes */
    import {
        List,
        InputItem,
        WingBlank,
        WhiteSpace,
        Button,
        Radio,
        Toast
    } from 'antd-mobile'
    
    /* no */
    import { List, InputItem, WingBlank, WhiteSpace, Button, Radio, Toast } from 'antd-mobile'
  • 使用'',而非""

    /* yes */
    import HelloWorld from './components/HelloWorld'
    methods: {
        delItem(index) {
            this.$emit('delItem', index)
        }
    }
    
    /* no */
    import HelloWorld from "./components/HelloWorld"
    methods: {
        delItem(index) {
            this.$emit("delItem", index)
        }
    }
  • 簡潔清晰

    • 模板字符串替代 ++ 字符串拼接
    • 結構賦值

      /* yes */
      this.state = {
          name: 'xxx',
          age: 'xxx'
      }
      const { name, age } = this.state;
      
      /* no */
      const name = this.state.name;
      const age = this.state.age;
    • 屬性名屬性值相同簡寫

      /* yes */
      components: {
          Header,
          Footer
      }
      
      /* no */
      components: {
          Header: Header,
          Footer: Footer
      }
    • 函數

      /* yes */
      methods: {
          delItem(index) {
              this.$emit('delItem', index)
          }
      }
      
      /* no */
      methods: {
          delItem: function(index) {
              this.$emit('delItem', index)
          }
      }

      ......

結束語

上述內容爲我在項目中看見過的代碼規範問題以及本人編碼習慣的總結,不可能適用每位開發者,但大部分編碼風格應該是合大衆口味,但願能幫助到你們

嘮叨一句

團隊合做的一個黃金定則: 別人看你的代碼就像看本身代碼同樣,良好的代碼習慣 很是重要 很是重要 很是重要
相關文章
相關標籤/搜索