美文网首页web前端
web前端开发规范

web前端开发规范

作者: 侬姝沁儿 | 来源:发表于2017-06-15 15:17 被阅读589次

    前言

    web前端开发规范:这是一个简陋版,不定时更新。

    项目结构:

    vue项目结构

    <pre>
    <code>
    |-- 项目名
    |-- static 开发相关静态文件
    |-- fonts 字体样式的存放目录
    |-- image 全局共用的img图片目录
    |-- js 全局共用的js目录
    |-- other 全局共用的其他文件目录(如果需要,可选)
    |-- ...
    |-- src 开发内容
    |-- api api请求server的目录
    |-- components 全局共用组件的目录
    |-- config 默认配置的目录
    |-- constant.js 共用常量配置文件
    |-- translate.js 翻译配置文件
    |-- fragment.js 配置碎片
    |-- ...
    |-- frame 自定义框架的目录
    |-- doc 用于存放项目文档(如果需要,可选)
    |--mixin vue混合的目录
    |-- page 单页面应用的目录
    |-- 业务目录
    |-- 业务模块
    |-- _js 此业务私有的js
    |-- _img 此业务私有的img(如果需要,可选)
    |-- ...
    |-- 共用模块名 业务私有的共用模块必须使用前缀
    |-- doc 用于存放业务文档(如果需要,可选)
    |-- ...
    |-- routes vue路由的目录
    |-- style 单页面应用样式的目录
    |-- utils 项目工具型函数的存放目录
    |-- custom-methods.js 自定义的共用方法
    |-- validator.js 自定义的验证方法
    |-- ...
    |-- datajson 引入本地json的目录,谁引入则在建立其对应的目录中存放
    |-- fragment 公用碎片
    |-- dep 引入的公共第三方依赖包目录
    </code>
    </pre>

    如果不支持目录,请看图片

    分离、

    结构、样式、行为分离,尽量确保文档和模板只包含 HTML 结构,样式都放到样式表里,行为都放到脚本里。
    功能应用分离:方法该做的事叫给方法做,不要为了便利直接为对象的某个变量进行运算赋值。

    统一注释

    HTML 模块注释:

    <!-- 文章列表列表模块 -->
    <div class="article-list">
    ...
    </div>
    

    HTML 区块注释:

    <!--
    @name: Drop Down Menu
    @description: Style of top bar drop down menu.
    @author: Ashu(Aaaaaashu@gmail.com)
    -->
    

    JS 单行注释:
    在代码上面注释,必须独占一行。// 后跟一个空格,缩进与下一行被注释说明的代码一致。

    JS 后缀注释:
    在一段语句后面后缀进行注释, // 前后都跟一个空格,用于对某个语句的说明。

    this.getBaseDataAfter() // 基础数据请求完成之后执行的方法
    

    JS 多行注释

    /**
     * 函数描述
     * 与此函数相关联引入的其他函数,并说明该函数具体位置以及说明其功能
     * @param {string} p1 参数1的说明
     * @param {string} p2 参数2的说明,比较长
     *     那就换行了.
     * @param {number=} p3 参数3的说明(可选)
     * @return {Object} 返回值描述
     */
    
    

    JS 文件注释
    文件注释用于告诉不熟悉这段代码的读者这个文件中包含哪些东西。 应该提供文件的大体内容, 它的作者, 依赖关系和兼容性信息。如下:

    /**
     * @fileoverview Description of file, its uses and information
     * about its dependencies.
     * @author user@meizu.com (Firstname Lastname)
     * Copyright 2015 Meizu Inc. All Rights Reserved.
     */
    
    

    多进行注释,对于自行定义的一些对象参数必须进行注释说明如下:

    {
              name: null, // 姓名
              mobile: null, // 手机号码
              id_card: null, // 身份证号
              monthly_income_money: '', // 月收入
    }
    

    语义化和命名

    应以功能或内容命名,不以表现形式命名;命名-缩写规范使用业界熟知的或者约定俗成的。常量采用全部大写,单词间下划线分隔的命名方式。变量采用驼峰命名法。全局属性或者引入文件采用$驼峰命名法进行命名。私有属性、变量和方法以下划线 _ 开头。由多个单词组成的 缩写词,在命名中,根据当前命名法和出现的位置,所有字母的大小写与首字母的大小写保持一致。

    var HTML_ENTITY = {}; // 常量
    var loadingModules = {}; // 变量
    var _privateMethod = {}; // 私有属性、变量和方法
    function XMLParser() {}; // 多个单词组成的 缩写词
    

    命名-缩写规范:

    <pre>
    navigation => nav
    header => hd
    description => desc
    button => btn
    previous => prev
    </pre>

    css 命名

    ID、Class :采用命名必须由单词、中划线-连接或数字组成命名。不允许使用拼音(约定俗成的除外,如:youku, baidu),尤其是缩写的拼音、拼音与英文的混合。

    命名-前缀规范:

    选择器必须是以某个前缀开头

    .m-detail .info { sRules; }
    .m-detail .current { sRules; }
    .m-detail .news { sRules; }
    

    <pre>
    <table>
    <thead>
    <tr>
    <th>前缀</th>
    <th>说明</th>
    <th>示例</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <td>g-</td>
    <td>全局通用样式命名,前缀g全称为global,一旦修改将影响全站样式</td>
    <td>g-mod</td>
    </tr>
    <tr>
    <td>m-</td>
    <td>模块命名方式</td>
    <td>m-detail</td>
    </tr>
    <tr>
    <td>ui-</td>
    <td>组件命名方式</td>
    <td>ui-selector</td>
    </tr>
    <tr>
    <td>js-</td>
    <td>所有用于纯交互的命名,不涉及任何样式规则。JSer拥有全部定义权限</td>
    <td>js-switch</td>
    </tr></tbody></table>
    </pre>

    出于性能考量,在没有必要的情况下避免元素选择器叠加 Class、ID 使用。

    JS 命名

    对于不经常使用jquery的项目,在使用jquery的地方必须进行jquery的标注声明:

    /* global $ */
    

    JS 对象或JSON的属性命名:字母小写,多个单词组成时,采用下划线分隔。

    var obj = {
        result_type: '',
        name: '',
        status_show: ''
    }
    

    JS 函数命名:使用动宾短语和驼峰命名法,参数也使用驼峰命名法,可选参数以 opt_ 开头.

    function getStyle(element, opt_child) {}
    

    JS 类:使用名词和Pascal 命名法(与骆驼命名法类似。只不过骆驼命名法是首字母小写,而帕斯卡命名法是首字母大写),类的 方法 / 属性, 使用驼峰命名法。

    function Engine(options) {}
    

    boolean 类型的变量使用 is 或 has 开头。如果在对象中使用is_has_开头

    var isReady = false;
    var hasMoreCommands = false;
    var obj = {
        is_show: false,
        has_name: true
    }
    

    JS 组件命名:文件名和组件名采用中划线-连接命名

    date-range.js // 日期范围选择
    <!-- 视频自定义播放组件 -->
    <video-play></video-play>
    

    操作符始终写在前一行, 以免分号的隐式插入产生预想不到的问题。

    var y = a ?
        longButSimpleOperandB : longButSimpleOperandC;
    if (a === 'string' || 
        s === 'object'
    ) {}
    
    

    接口命名规范:可读性强,见名晓义;尽量不与各个社区已有的习惯冲突;尽量写全。不用缩写,除非是下面列表中约定的;(变量以表达清楚为目标,uglify 会完成压缩体积工作)

    HTML HEAD 模板

    <!DOCTYPE html>
    <html lang="zh-cmn-Hans">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>Style Guide</title>
        <meta name="description" content="不超过150个字符">
        <meta name="keywords" content="">
        <meta name="author" content="name, email@gmail.com">
    
        <!-- 为移动设备添加 viewport -->
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    
        <!-- iOS 图标 -->
        <link rel="apple-touch-icon-precomposed" href="/apple-touch-icon-57x57-precomposed.png">
    
        <link rel="alternate" type="application/rss+xml" title="RSS" href="/rss.xml" />
        <link rel="shortcut icon" href="path/to/favicon.ico">
    </head>
    

    声明顺序

    css声明顺序

    相关属性应为一组,推荐的样式编写顺序

    1. Positioning(定位)
    2. Box model(盒子模型)
    3. Typographic(排版)
    4. Visual(视觉效果,如动画颜色等)
    5. other(其他)
    /* Positioning */
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      left: 0;
      z-index: 100;
    
      /* Box model */
      display: block;
      box-sizing: border-box;
      width: 100px;
      height: 100px;
      padding: 10px;
      border: 1px solid #e5e5e5;
      border-radius: 3px;
      margin: 10px;
      float: right;
      overflow: hidden;
    
      /* Typographic */
      font: normal 13px "Helvetica Neue", sans-serif;
      line-height: 1.5;
      text-align: center;
    
      /* Visual */
      background-color: #f5f5f5;
      color: #fff;
      opacity: .8;
    
      /* Other */
      cursor: pointer;
    

    结构以ESLint为准

    比如缩进,=的前后有空格等都按ESLint为准

    JS语言特性

    [强制] 任何使用this的地方都要说名此this代表谁。

    [强制] 每个 var 只能声明一个变量。一个 var 声明多个变量,容易导致较长的行长度,并且在修改时容易造成逗号和分号的混淆。

    var hangModules = [];
    var missModules = [];
    var visited = {};
    

    [强制] 变量必须 即用即声明,不得在函数或其它形式的代码块起始位置统一声明所有变量。变量声明与使用的距离越远,出现的跨度越大,代码的阅读与维护成本越高。

    [强制] 在 判断中使用类型严格的 ===。

    [建议] 按执行频率排列判断或代码分支的顺序。

    [建议] 如果函数或全局中的 else 块后没有任何语句,可以删除 else。

    function getName() {
        if (name) {
            return name;
        }
    
        return 'unnamed';
    }
    

    [建议] 不要在循环体中包含函数表达式,事先将函数提取到循环体外。因为循环体中的函数表达式,运行过程中会生成循环次数个函数对象。

    function clicker() {
        // ......
    }
    for (var i = 0, len = elements.length; i < len; i++) {
        var element = elements[i];
        addListener(element, "click", clicker);
    }
    

    [建议] 对循环内多次使用的不变值,在循环外用变量缓存。

    var width = wrap.offsetWidth + 'px';
    for (var i = 0, len = elements.length; i < len; i++) {
        var element = elements[i];
        element.style.width = width;
        // ......
    }
    

    [建议] 类型检测优先使用 typeof。对象类型检测使用 instanceof。null 或 undefined 的检测使用 == null。

    // string
    typeof variable === 'string'
    
    // number
    typeof variable === 'number'
    
    // boolean
    typeof variable === 'boolean'
    
    // Function
    typeof variable === 'function'
    
    // Object
    typeof variable === 'object'
    
    // RegExp
    variable instanceof RegExp
    
    // Array
    variable instanceof Array
    
    // null
    variable === null
    
    // null or undefined
    variable == null
    
    // undefined
    typeof variable === 'undefined'
    

    [强制] 字符串开头和结束使用单引号 '。输入单引号不需要按住 shift,方便输入。实际使用中,字符串经常用来拼接 HTML。为方便 HTML 中包含双引号而不需要转义写法。

    [强制] 不允许修改和扩展任何原生对象和宿主对象的原型。

    [建议] 属性访问时,尽量使用 .。

    [建议] 一个函数的长度控制在 50 行以内。将过多的逻辑单元混在一个大函数中,易导致难以维护。一个清晰易懂的函数应该完成单一的逻辑单元。复杂的操作应进一步抽取,通过函数的调用来体现流程。特定算法等不可分割的逻辑允许例外。

    function syncViewStateOnUserAction() {
        if (x.checked) {
            y.checked = true;
            z.value = '';
        }
        else {
            y.checked = false;
        }
    
        if (a.value) {
            warning.innerText = '';
            submitButton.disabled = false;
        }
        else {
            warning.innerText = 'Please enter it';
            submitButton.disabled = true;
        }
    }
    
    // 直接阅读该函数会难以明确其主线逻辑,因此下方是一种更合理的表达方式:
    
    function syncViewStateOnUserAction() {
        syncXStateToView();
        checkAAvailability();
    }
    
    function syncXStateToView() {
        y.checked = x.checked;
    
        if (x.checked) {
            z.value = '';
        }
    }
    
    function checkAAvailability() {
        if (a.value) {
            clearWarnignForA();
        }
        else {
            displayWarningForAMissing();
        }
    }
    

    [建议] 一个函数的参数控制在 6 个以内。

    [建议] 属性在构造函数中声明,方法在原型中声明。

    function TextNode(value, engine) {
        this.value = value;
        this.engine = engine;
    }
    
    TextNode.prototype.clone = function () {
        return this;
    };
    

    相关文章

      网友评论

        本文标题:web前端开发规范

        本文链接:https://www.haomeiwen.com/subject/hqfuqxtx.html