VUE编码规范
<h1>前端开发规范</h1>
<p>[TOC]</p>
<p><div STYLE="page-break-after: always;"></div></p>
<h2>一、概述</h2>
<p>本规范旨在为前端程序的开发者提供规范化最新的指导,可用于程序员个人编译环境以及研发团队集成环境等场合的代码规范化检查。</p>
<p>> <em>不管有多少人共同参与同一项目,一定要确保每一行代码都像是同一个人编写的</em></p>
<h2>二、方针</h2>
<table>
<thead>
<tr>
<th style="text-align: center;">约束等级</th>
<th style="text-align: center;">约束效力</th>
<th style="text-align: center;">强制性</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;"><font color=#f5222d>【强制】</font></td>
<td style="text-align: center;">违反该项将被认为代码存在严重缺陷</td>
<td style="text-align: center;">前端程序团队必须遵守</td>
</tr>
<tr>
<td style="text-align: center;"><font color=#52c41a>【推荐】</font></td>
<td style="text-align: center;">违反该项将被认为代码存在轻微缺陷</td>
<td style="text-align: center;">根据具体产品特性的不同,选择性地遵守</td>
</tr>
<tr>
<td style="text-align: center;"><font color=#1890ff>【参考】</font></td>
<td style="text-align: center;">违反该项可被认为代码存在优化空间</td>
<td style="text-align: center;">从产品持续优化及人员技能提升的角度,参考使用</td>
</tr>
</tbody>
</table>
<h2>三、环境要求</h2>
<ol>
<li>
<p><font color=#f5222d>【强制】</font><a href="https://nodejs.org/">Node.js</a> 14.X 或更高版本,你可以使用 <a href="https://github.com/creationix/nvm">nvm</a> 或 <a href="https://github.com/coreybutler/nvm-windows">nvm-windows </a>在一台电脑中管理多个 Node 版本</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>使用 [Visual Studio Code (VS Code)/Webstorm] 进行代码编写</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>代码提交前使用 VS Code 进行格式化(不要格式引入的外部文件)</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>规定 Tab 大小为 2 个空格,保证在所有环境下获得一致展现</p>
<pre><code class="language-javascript">// settings.json
{
&quot;editor.tabSize&quot;: 2
// ...
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>安装插件 <a href="https://marketplace.visualstudio.com/items?itemName=octref.vetur">Vetur</a>( Vue开发扩展及 Vue 文件代码格式化)</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>安装插件 <a href="https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode">Prettier - Code formatter</a>( CSS / Less / JS 等其他文件代码格式化;Vetur 的格式化基于此插件实现,固可以在所有文件实现统一的格式化)</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>安装插件 <a href="https://marketplace.visualstudio.com/items?itemName=MS-CEINTL.vscode-language-pack-zh-hans">Chinese (Simplified) Language Pack for Visual Studio Code</a> ( VS Code 简体中文语言包)</p>
</li>
<li><font color=#52c41a>【推荐】</font>使用 Chrome 浏览器并安装 <a href="https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd">Vue.js devtools</a> 进行调试</li>
</ol>
<h2>四、编码规范</h2>
<h3>4.1 HTML / Template 编码规范</h3>
<h4>语法</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>缩进使用两个空格代替 Tab</p>
<ul>
<li><em>前端代码层级较深,使用短缩进有利于利用屏幕空间,提升效率</em></li>
<li><em>使用两个空格代替 Tab 可以保证在所有环境下获得一致展现</em></li>
</ul>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;div&gt;
&lt;div&gt;bar&lt;/div&gt;
&lt;/div&gt;
&lt;!-- good --&gt;
&lt;div&gt;
&lt;div&gt;bar&lt;/div&gt;
&lt;/div&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>嵌套元素应当缩进一次(即两个空格),同层级缩进应保持一致</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;div&gt;
&lt;div&gt;bar&lt;/div&gt;
&lt;div&gt;bar&lt;/div&gt;
&lt;/div&gt;
&lt;!-- good --&gt;
&lt;div&gt;
&lt;div&gt;bar&lt;/div&gt;
&lt;div&gt;bar&lt;/div&gt;
&lt;/div&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>对于属性的定义,使用双引号,不要使用单引号</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;input class='a' type=text&gt;
&lt;!-- good --&gt;
&lt;input class=&quot;a&quot; type=&quot;text&quot;&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不要省略可选的结束标签(closing tag)(如<code>&lt;/li&gt;</code> 或 <code>&lt;/body&gt;</code>)</p>
<p><em>省略可选的结束标签,虽不会违反 H5 规范;但可能会造成层级上的困扰,导致代码出现无法预料的问题</em></p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;h1&gt;h1 text
&lt;h2&gt;h2 text
&lt;!-- good --&gt;
&lt;h1&gt;h1 text&lt;/h1&gt;
&lt;h2&gt;h2 text&lt;/h2&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>特殊符号使用 <a href="http://www.w3school.com.cn/html/html_entities.asp">HTML 字符实体</a>(实体名称对大小写敏感),常用如下:</p>
<table>
<thead>
<tr>
<th style="text-align: center;">符号</th>
<th style="text-align: center;">实体编码</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: center;">空格</td>
<td style="text-align: center;">\&nbsp;</td>
</tr>
<tr>
<td style="text-align: center;">©</td>
<td style="text-align: center;">\&copy;</td>
</tr>
<tr>
<td style="text-align: center;">¥</td>
<td style="text-align: center;">\&yen;</td>
</tr>
<tr>
<td style="text-align: center;">®</td>
<td style="text-align: center;">\&reg;</td>
</tr>
<tr>
<td style="text-align: center;">></td>
<td style="text-align: center;">\&gt;</td>
</tr>
<tr>
<td style="text-align: center;"><</td>
<td style="text-align: center;">\&lt;</td>
</tr>
<tr>
<td style="text-align: center;">&</td>
<td style="text-align: center;">\&amp;</td>
</tr>
</tbody>
</table>
</li>
<li>
<p><font color=#f5222d>【强制】</font>td / th 要在 tr 里面,li 要在 ul / ol 里面</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;table&gt;
&lt;td&gt;test&lt;/td&gt;
&lt;/table&gt;
&lt;!-- good --&gt;
&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;test&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>ul / ol 的直接子元素只能是 li,不能包含其他元素</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;ul&gt;
&lt;span&gt;123&lt;/span&gt;
&lt;li&gt;a&lt;/li&gt;
&lt;li&gt;b&lt;/li&gt;
&lt;/ul&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>行内元素里面不可使用块级元素</p>
<p>a 标签是一个行内元素,行内元素里面套了一个 div 的标签,这样可能会导致 a 标签无法正常点击</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;a href=&quot;../test&quot;&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/a&gt;</code></pre>
<p>可以使用如下代码进行修复:</p>
<pre><code class="language-html">&lt;a href=&quot;../test&quot; style=&quot;display: block&quot;&gt;
&lt;div&gt;&lt;/div&gt;
&lt;/a&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不使用自定义标签,会与Vue组件系统的自定义组件冲突</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不使用重复属性,重复的属性只会取第一个</p>
<pre><code class="language-html">&lt;!-- error --&gt;
&lt;input class=&quot;a&quot; type=&quot;text&quot; class=&quot;b&quot;&gt;
&lt;!-- good --&gt;
&lt;input class=&quot;a b&quot; type=&quot;text&quot;&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不要在https的链接里写http的图片</p>
<p><em>只要https的网页请求了一张http的图片,就会导致浏览器地址栏左边的小锁没有了,一般不要写死,写成根据当前域名的协议去加载,用//开头:</em></p>
<pre><code class="language-html">&lt;img src=&quot;//static.chimeroi.com/hello-world.jpg&quot;&gt;</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>不要在自闭合(self-closing)元素的尾部添加斜线( <a href="http://dev.w3.org/html5/spec-author-view/syntax.html#syntax-start-tag">HTML5 规范</a>中说明这是可选的)</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;img src=&quot;logo.png&quot; alt /&gt;
&lt;!-- good --&gt;
&lt;img src=&quot;logo.png&quot; alt&gt;</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>不使用属性设置样式(<code>img</code>, <code>table</code>等元素)</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;img src=&quot;test.jpg&quot; alt width=&quot;400&quot; height=&quot;300&quot;&gt;
&lt;!-- good --&gt;
&lt;img src=&quot;test.jpg&quot; style=&quot;width:400px;height:300px;&quot;&gt;</code></pre>
</li>
<li>
<p><font color=#1890ff>【参考】</font>自定义属性要以data-开头
自己添加的非标准的属性要以data-开头,否则<a href="https://link.juejin.im/?target=https%3A%2F%2Fvalidator.w3.org%2F">w3c validator</a>会认为是不规范的</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;div count=&quot;5&quot;&gt;&lt;/div&gt;
&lt;!-- good --&gt;
&lt;div data-count=&quot;5&quot;&gt;&lt;/div&gt;</code></pre>
</li>
</ol>
<h4>HTML5 doctype</h4>
<p><font color=#f5222d>【强制】</font>为每个 HTML 页面添加标准模式(standard mode)的声明,确保在每个浏览器中拥有一致的展现</p>
<pre><code class="language-html">&lt;!DOCTYPE html&gt;
&lt;html&gt;
...</code></pre>
<h4>语言属性</h4>
<p><font color=#f5222d>【强制】</font>为每个 HTML 页面根元素添加 <a href="http://w3c.github.io/html/semantics.html#the-html-element">lang 属性</a></p>
<p>根据 HTML5 规范:</p>
<p>> 强烈建议为 html 根元素指定 lang 属性,从而为文档设置正确的语言。这将有助于语音合成工具确定其所应该采用的发音,有助于翻译工具确定其翻译时所应遵守的规则等等。</p>
<pre><code class="language-html">&lt;html lang=&quot;zh-CN&quot;&gt;
&lt;!-- ... --&gt;
&lt;/html&gt;</code></pre>
<h4>字符编码</h4>
<p><font color=#f5222d>【强制】</font>通过声明一个明确的字符编码,让浏览器轻松、快速的确定网页内容渲染方式,通常指定为'UTF-8'</p>
<pre><code class="language-html">&lt;html&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;/head&gt;
...</code></pre>
<h4>引入 CSS 和 JavaScript 文件</h4>
<p><font color=#f5222d>【强制】</font>根据 HTML5 规范,在引入 CSS 和 JavaScript 文件时不需要指定 <code>type</code> 属性,因为 <code>text/css</code> 和 <code>text/javascript</code> 分别是它们的默认值</p>
<pre><code class="language-html">&lt;!-- External CSS --&gt;
&lt;link rel=&quot;stylesheet&quot; href=&quot;code_guide.css&quot;&gt;
&lt;!-- In-document CSS --&gt;
&lt;style&gt;
...
&lt;/style&gt;
&lt;!-- External JS --&gt;
&lt;script src=&quot;code_guide.js&quot;&gt;&lt;/script&gt;
&lt;!-- In-document JS --&gt;
&lt;script&gt;
...
&lt;/script&gt;</code></pre>
<h4>减少标签的数量</h4>
<p><font color=#52c41a>【推荐】</font>编写 HTML 代码时,尽量避免多余的层级</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;span class=&quot;avatar&quot;&gt;
&lt;img src=&quot;...&quot;&gt;
&lt;/span&gt;
&lt;!-- good --&gt;
&lt;img class=&quot;avatar&quot; src=&quot;...&quot;&gt;</code></pre>
<h4>属性顺序</h4>
<p><font color=#1890ff>【参考】</font>属性应该按照特定的顺序出现以保证易读性</p>
<ol>
<li><code>class</code></li>
<li><code>id</code></li>
<li><code>name</code></li>
<li><code>data-*</code></li>
<li><code>src</code>, <code>for</code>, <code>type</code>, <code>href</code>, <code>value</code> , <code>max-length</code>, <code>max</code>, <code>min</code>, <code>pattern</code></li>
<li><code>placeholder</code>, <code>title</code>, <code>alt</code></li>
<li><code>aria-*</code>, <code>role</code></li>
<li><code>required</code>, <code>readonly</code>, <code>disabled</code></li>
</ol>
<h4>语义化</h4>
<p><font color=#1890ff>【参考】</font>尽量遵循 HTML 标准和语义,但是不要以牺牲实用性为代价;任何时候都要尽量使用最少的标签并保持最小的复杂度。</p>
<h3>4.2 CSS / Less 编码规范</h3>
<h4>命名</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>类名使用小写字母,以中划线分隔</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>id 采用驼峰式命名</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>less 中的变量、函数、混合等采用驼峰式命名</p>
<pre><code class="language-less">@mainFontColor: #444;
#companyName,
.company-name {
color: @mainFontColor;
}</code></pre>
</li>
</ol>
<h4>语法</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>所有声明语句都应当以分号结尾
<em>最后一条声明语句后面的分号是可选的,但是,如果省略这个分号,你的代码可能更易出错</em></p>
<pre><code class="language-css">/* error */
.selector {
font-size: 15px
color: red
}
/* not good */
.selector {
font-size: 15px;
color: red
}
/* good */
.selector {
font-size: 15px;
color: red;
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>避免为 0 值指定单位,例如,用 <code>margin: 0;</code> 代替 <code>margin: 0px;</code></p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>为选择器中的属性添加双引号,例如,<code>input[type=&quot;text&quot;]</code>;
<a href="http://mathiasbynens.be/notes/unquoted-attribute-values#css">某些情况下是可选的</a>,但是,为了代码的一致性,建议都加上双引号</p>
<pre><code class="language-css">/* not good */
.selector[type=text] {
/* ... */
}
/* good */
.selector[type=&quot;text&quot;] {
/* ... */
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>十六进制值应该全部小写,例如,<code>#f3f6fa</code></p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不出现空的规则(声明块中没有声明语句)</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不要设置太大的z-index(一个正常的系统的层级关系在 10 以内就能完成)</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>多写注释,且多使用句子进行描述而不是词语</p>
<pre><code class="language-css">/* 为了去除输入框和表单点击时的灰色背景 */
input,
form {
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
}</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>不要使用<code>*</code>选择器</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>适当使用<code>:before</code>和<code>:after</code>来画页面的一些视觉上的辅助性元素,如三角形、短的分隔线、短竖线等,可以减少页面上没有用的标签</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>选择器不要超过4层(在 Less 中避免嵌套超过 4 层)</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>用 <code>border: 0;</code> 代替 <code>border: none;</code></p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>使用简写形式的十六进制值,例如,用 <code>#fff</code> 代替 <code>#ffffff</code></p>
</li>
<li><font color=#52c41a>【推荐】</font>对于属性值或颜色参数,省略小于 1 的小数前面的 0 (例如,<code>.5</code> 代替 <code>0.5</code>;<code>-.5px</code> 代替 <code>-0.5px</code>)</li>
</ol>
<h4>代码风格</h4>
<p><em>此处大部分工作将由代码格式化工具完成(参见环境要求),一般无需考虑</em></p>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>缩进使用两个空格代替 Tab</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>为选择器分组时,将单独的选择器单独放在一行</p>
<pre><code class="language-css">/* not good */
.selector, .selector-secondary, .selector[type=text] {
/* ... */
}
/* good */
.selector,
.selector-secondary,
.selector[type=&quot;text&quot;] {
/* ... */
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>声明块的左花括号前添加一个空格</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>声明块的右花括号应当单独成行</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>每条声明语句的 <code>:</code> 后应该插入一个空格</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>每条样式声明应该独占一行</p>
<pre><code class="language-css">/* not good */
.selector {
font-size: 15px; color: red;
}
/* good */
.selector {
font-size: 15px;
color: red;
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>对于以逗号分隔的属性值,每个逗号后面都应该插入一个空格(例如,<code>box-shadow</code>,<code>transition</code>)</p>
<pre><code class="language-css">/* not good */
.selector {
transition: border .2s,color .3s,padding .4s;
}
/* good */
.selector {
transition: border .2s, color .3s, padding .4s;
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font><code>!important</code>前插入一个空格</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>注释:<code>//</code>后插入一个空格,<code>/*</code>后插入一个空格,<code>*/</code>前插入一个空格</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>Less 的操作符,在圆括号中的数学计算表达式的数值、变量和操作符之间均添加一个空格</p>
</li>
<li><font color=#52c41a>【推荐】</font>注释统一用<code>/* */</code>( Less 中也不要用<code>//</code>)</li>
</ol>
<h4>样式兼容性</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>当使用一些较新的 CSS3 语法时,应注意添加浏览器前缀( FAIS 2 打包工具包含 CSS 预处理,固无需考虑此条)</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>不要使用 input 的 <code>line-height</code> 来做垂直居中
设置 <code>line-height</code> 为一个很高的值会导致 Safari 浏览器的输入光标变得巨大 (与 <code>line-height</code> 等高)</p>
<pre><code class="language-css">/* not good */
input {
height: 40px;
line-height: 40px;
}
/* good */
input {
height: 20px;
line-height: 20px;
padding: 10px 0;
}</code></pre>
</li>
</ol>
<h4>选择器权重(样式覆盖)</h4>
<p>> 权重的基本规则:
>
> 1. 相同的权重:以后面出现的选择器为最后规则
> 2. 不同的权重,权重值高则生效
>
> <a href="https://www.w3cplus.com/css/css-specificity-things-you-should-know.html">详细了解</a>权重计算方法</p>
<ol>
<li><font color=#f5222d>【强制】</font>非通用样式使用嵌套方式进行编写,避免影响其他自己不了解样式,造成样式覆盖</li>
<li><font color=#52c41a>【推荐】</font>Vue 中样式谨慎使用 scoped,会影响样式选择器性能,请使用第一点进行特有样式编写</li>
<li><font color=#52c41a>【推荐】</font>样式需要修改时,尽量找到原样式声明进行修改</li>
<li><font color=#f5222d>【强制】</font>无法修改原样式声明时,应通过权重关系,编写权重更高的样式进行覆盖</li>
<li><font color=#f5222d>【强制】</font>不使用<code>!important</code>,除非原样式使用内联样式或<code>!important</code>且无法直接修改</li>
</ol>
<h4>声明简写</h4>
<ol>
<li>
<p><font color=#52c41a>【推荐】</font>当你不确定自己写的属性会否影响到其他属性时,应避免使用简写</p>
<pre><code class="language-css">/* error */
.element {
margin: 0 0 10px;
background: red;
background: url(&quot;image.jpg&quot;);
border-radius: 3px 3px 0 0;
}
/* good */
.element {
margin-bottom: 10px;
background-color: red;
background-image: url(&quot;image.jpg&quot;);
border-top-left-radius: 3px;
border-top-right-radius: 3px;
}</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>当你确定自己的声明不会影响到其他属性时,请使用简写提升代码简洁性</p>
<pre><code class="language-css">/* not good */
.element {
padding-top: 10px;
padding-right: 20px;
padding-bottom: 15px;
padding-left: 20px;
}
/* good */
.element {
padding: 10px 20px 15px;
}</code></pre>
</li>
</ol>
<h4>CSS动画</h4>
<ol>
<li><font color=#52c41a>【推荐】</font>不要使用all属性做动画</li>
</ol>
<p>使用transition做动画的时候不要使用all所有属性,在有一些浏览器上面可能会有一些问题,如下:</p>
<pre><code class="language-css">transition: all 2s linear;</code></pre>
<p>在Safari上面可能会有一些奇怪的抖动,正确的做法是要用哪个属性做动画就写哪个,如果有多个就用隔开,如下代码所示:</p>
<pre><code class="language-css">transition: transform 2s linear, opacity 2s linear;</code></pre>
<ol>
<li><font color=#52c41a>【推荐】</font>位移动画使用 transform 替代 position (提升动画性能)</li>
<li><font color=#52c41a>【推荐】</font>使用 CSS 动画替代 JS 动画</li>
</ol>
<h4>声明顺序</h4>
<p><font color=#1890ff>【参考】</font>相关的属性声明按以下顺序做分组处理,组之间需要有一个空行</p>
<ol>
<li>
<p><strong>Positioning</strong>(影响其他元素和自身位置相关声明)</p>
</li>
<li>
<p><strong>Box model</strong>(自身盒模型相关声明)</p>
</li>
<li>
<p><strong>Typographic</strong>(文本相关声明)</p>
</li>
<li>
<p><strong>Visual</strong>(自身样式)</p>
</li>
<li>
<p><strong>Misc</strong>(其他声明)</p>
<pre><code class="language-css">.declaration-order {
/* Positioning */
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
/* Box-model */
display: block;
float: right;
width: 100px;
height: 100px;
/* Typography */
font: normal 13px &quot;Helvetica Neue&quot;, sans-serif;
line-height: 1.5;
color: #333;
text-align: center;
/* Visual */
background-color: #f5f5f5;
border: 1px solid #e5e5e5;
border-radius: 3px;
/* Misc */
opacity: 1;
}</code></pre>
</li>
</ol>
<h3>4.3 JavaScript 编码规范</h3>
<h4>命名</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>标准变量采用驼峰式命名(考虑与后台交换数据的情况,对象属性可灵活命名)</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>常量全大写,用下划线连接</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>变量名不应过短,要能准确完整地描述该变量所表述的事物</p>
<table>
<thead>
<tr>
<th>不好的变量名</th>
<th>好的变量名</th>
</tr>
</thead>
<tbody>
<tr>
<td>inp</td>
<td>input, priceInput</td>
</tr>
<tr>
<td>day1, day2, param1</td>
<td>today, tomorrow</td>
</tr>
<tr>
<td>id</td>
<td>userId, orderId</td>
</tr>
<tr>
<td>obj</td>
<td>orderData, houseInfos</td>
</tr>
<tr>
<td>tId</td>
<td>removeMsgTimerId</td>
</tr>
<tr>
<td>handler</td>
<td>submitHandler, searchHandler</td>
</tr>
</tbody>
</table>
</li>
<li>
<p><font color=#f5222d>【强制】</font>变量名不要使用计算机术语,如 texareaData,应该取和业务相关的名字,如 leaveMsg</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>变量名的对仗要明确,如 up/down、begin/end、opened/closed、visible/invisible、scource/target</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>变量名使用正确的语法</p>
<p><em>不要使用中文拼音,如 shijianchuo 应改成 timestamp ;</em>
<em>如果是复数的话加 s,或者加上 List,如 orderList、menuItems;</em>
<em>而过去式的加上 ed,如 updated/found 等;</em>
<em>如果正在进行的加上 ing,如 calling;</em></p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>使用临时变量时请结合实际需要进行变量命名</p>
<p><em>有些喜欢取temp和obj之类的变量,如果这种临时变量在两行代码内就用完了,接下来的代码就不会再用了,还是可以接受的,如交换数组的两个元素。但是有些人取了个temp,接下来十几行代码都用到了这个temp,这个就让人很困惑了。所以应该尽量少用temp类的变量</em></p>
<pre><code class="language-javascript">// not good
let temp = 10;
let leftPosition = currentPosition + temp,
topPosition = currentPosition - temp;
// good
let adjustSpace = 10;
let leftPosition = currentPosition + adjustSpace,
topPosition = currentPosition - adjustSpace;</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>波尔变量可以结合实际语境使用 done/found/successs/ok/available/complete 等修饰词</p>
<pre><code class="language-javascript">// good
let ajaxDone = true,
fileFound = false,
resourceUpdated = true;</code></pre>
</li>
<li><font color=#52c41a>【推荐】</font>波尔变量名应使用肯定的布尔变量名,不要使用否定的名词,如 notOk、notReady,因为否定的词取反的时候就会比较奇怪,如 <code>if (!notOk)</code></li>
</ol>
<h4>语法</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>变量不要先使用后声明</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不要声明了变量却不使用</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不要在同个作用域下声明同名变量</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>一个函数作用域中所有的变量声明尽量提到函数首部,可根据代码进行分组,但不允许出现两个连续的变量声明</p>
<pre><code class="language-javascript">// not good
let registerForm = null;
let question = &quot;&quot;;
let calculateResult = 0;
// good
let registerForm = null,
question = &quot;&quot;,
calculateResult = 0;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>为了快速知晓变量类型,声明变量时要赋值</p>
<pre><code class="language-javascript">// not good
let registerForm,
question,
calculateResult;
// good
let registerForm = null,
question = &quot;&quot;,
calculateResult = 0;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>单一函数的返回值类型要确定(如下无法确定该函数的最终返回类型)</p>
<pre><code class="language-javascript">// not good
function calculatePrice(seatCount){
if (seatCount &lt;= 0) {
return &quot;&quot;;
} else {
return seatCount * 79;
}
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>debugger不要出现在提交的代码里</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>使用<code>===</code>代替<code>==</code>,<code>!==</code>代替<code>!=</code>(<code>==</code>会自动进行类型转换,可能会出现奇怪的结果)</p>
<pre><code class="language-javascript">null == undefined //true
'' == '0' //false
0 == '' //true
0 == '0' //true
' \t\r\n ' == 0 //true
new String(&quot;abc&quot;) == &quot;abc&quot; //true
new Boolean(true) == true //true
true == 1 //true</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>使用三目运算代替简单的 if-else</p>
<pre><code class="language-javascript">// not good
let seatDiscount = 100;
if (seat &lt; 5) {
seatDiscount = 90;
} else if(seat &lt; 10) {
seatDiscount = 80;
} else {
seatDiscount = 70;
}
// good
let seatDiscount = seat &lt; 5 ? 90 : seat &lt; 10 ? 80 : 70;</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>使用<code>let</code>定义变量,<code>const</code>定义常量</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>使用箭头函数取代简单的函数</p>
<pre><code class="language-javascript">// not good
let _this = this;
setTimeout(function() {
_this.foo = &quot;bar&quot;;
}, 2000);
// good
setTimeout(() =&gt; this.foo = &quot;bar&quot;, 2000);</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>在必要的地方添加非空判断以提高代码的稳健性</p>
</li>
<li><font color=#52c41a>【推荐】</font>将复杂的函数分解成多个子函数,方便维护和复用</li>
</ol>
<h4>代码风格</h4>
<p>此处大部分工作将由代码格式化工具完成(参见环境要求),一般无需考虑</p>
<ol>
<li><font color=#f5222d>【强制】</font>缩进使用两个空格代替 Tab</li>
<li><font color=#f5222d>【强制】</font>统一使用双引号<code>&quot;&quot;</code>(与 Prettier 默认格式化配置持一致)</li>
<li>
<p><font color=#f5222d>【强制】</font>以下几种情况后需加分号<code>;</code></p>
<ul>
<li>
<p>变量声明</p>
</li>
<li>表达式</li>
<li>return</li>
<li>throw</li>
<li>break</li>
<li>continue</li>
<li>do-while</li>
</ul>
</li>
<li><font color=#f5222d>【强制】</font>以下几种情况<strong>不需要</strong>空格:
<ul>
<li>对象的属性名后</li>
<li>前缀一元运算符后</li>
<li>后缀一元运算符前</li>
<li>函数调用括号前</li>
<li>无论是函数声明还是函数表达式,'('前不要空格</li>
<li>数组的'['后和']'前</li>
<li>对象的'{'后和'}'前</li>
<li>运算符'('后和')'前</li>
</ul></li>
<li><font color=#f5222d>【强制】</font>以下几种情况<strong>需要</strong>空格:
<ul>
<li>二元运算符前后</li>
<li>三元运算符'?:'前后</li>
<li>代码块'{'前</li>
<li>下列关键字前:<code>else</code>, <code>while</code>, <code>catch</code>, <code>finally</code></li>
<li>下列关键字后:<code>if</code>, <code>else</code>, <code>for</code>, <code>while</code>, <code>do</code>, <code>switch</code>, <code>case</code>, <code>try</code>,<code>catch</code>, <code>finally</code>, <code>with</code>, <code>return</code>, <code>typeof</code></li>
<li>单行注释'//'后(若单行注释和代码同行,则'//'前也需要),多行注释'*'后</li>
<li>对象的属性值前</li>
<li>for循环,分号后留有一个空格,前置条件如果有多个,逗号后留一个空格</li>
<li>无论是函数声明还是函数表达式,'{'前一定要有空格</li>
<li>函数的参数之间</li>
</ul></li>
</ol>
<h4>数组、对象</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>对象属性名不需要加引号</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>对象以缩进的形式书写,不要写在一行</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>数组中不要存在空元素</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不要用<code>for in</code>循环数组</p>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>数组、对象最后不要有逗号</p>
<pre><code class="language-javascript">// not good
let a = {
'b': 1
};
let a = { b: 1 };
let a = {
b: 1,
c: 2,
};
// good
let a = {
b: 1,
c: 2
};</code></pre>
</li>
</ol>
<h4>使用 null</h4>
<p><strong><font color=#f5222d>【强制】</font>正确使用 null</strong></p>
<p>>适用场景:
>
>- 初始化一个将来可能被赋值为对象的变量
>- 与已经初始化的变量做比较
>- 作为一个参数为对象的函数的调用传参
>- 作为一个返回对象的函数的返回值</p>
<ol>
<li>
<p>不要用null来判断函数调用时有无传参</p>
</li>
<li>
<p>不要与未初始化的变量做比较</p>
<pre><code class="language-javascript">// not good
function test(a, b) {
if (b === null) {
// not mean b is not supply
// ...
}
}
let a;
if (a === null) {
// ...
}
// good
let a = null;
if (a === null) {
// ...
}</code></pre>
</li>
</ol>
<h4>使用 undefined</h4>
<p><strong><font color=#f5222d>【强制】</font>正确使用 undefined</strong></p>
<ol>
<li>
<p>不要给变量赋值 undefined(undefined 本身就表示一个变量未定义)</p>
</li>
<li>
<p>不要直接使用 undefined 进行变量判断</p>
</li>
<li>
<p>使用<code>typeof</code>和字符串 'undefined' 对变量进行判断</p>
<pre><code class="language-javascript">// not good
if (person === undefined) {
// ...
}
// good
if (typeof person === 'undefined') {
// ...
}</code></pre>
</li>
</ol>
<h4>文档注释</h4>
<p><font color=#1890ff>【参考】</font>各类标签 @param, @method 等请参考 <a href="http://usejsdoc.org/">usejsdoc </a>和 <a href="http://yuri4ever.github.io/jsdoc/">JSDoc Guide</a>;</p>
<p>建议在以下情况下使用:</p>
<ul>
<li>所有常量</li>
<li>所有函数</li>
<li>所有类</li>
</ul>
<pre><code class="language-javascript">/**
* @func
* @desc 一个带参数的函数
* @param {string} a - 参数a
* @param {number} b=1 - 参数b默认值为1
* @param {string} c=1 - 参数c有两种支持的取值&lt;/br&gt;1—表示x&lt;/br&gt;2—表示xx
* @param {object} d - 参数d为一个对象
* @param {string} d.e - 参数d的e属性
* @param {string} d.f - 参数d的f属性
* @param {object[]} g - 参数g为一个对象数组
* @param {string} g.h - 参数g数组中一项的h属性
* @param {string} g.i - 参数g数组中一项的i属性
* @param {string} [j] - 参数j是一个可选参数
*/
function foo(a, b, c, d, g, j) {
// ...
}</code></pre>
<h3>4.4 Vue 组件编码规范</h3>
<h4>命名</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font><strong>组件名</strong>应该始终是多个单词的,根组件 <code>App</code> 除外</p>
<pre><code class="language-javascript">// not good
Vue.component('todo', {
// ...
})
export default {
name: 'Todo',
// ...
}
// good
Vue.component('todo-item', {
// ...
})
export default {
name: 'TodoItem',
// ...
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font><strong>单文件组件</strong>的文件名应该要么始终是单词大写开头( PascalCase ),要么始终是横线连接( kebab-case )</p>
<pre><code class="language-javascript">// not good
components/
|- mycomponent.vue
components/
|- myComponent.vue
// good
components/
|- MyComponent.vue
components/
|- my-component.vue</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>应用特定样式和约定的<strong>基础组件</strong> (也就是展示类的、无逻辑的或无状态的组件) 应该全部以一个特定的前缀开头,比如 Base、App 或 V</p>
<pre><code class="language-javascript">// not good
components/
|- MyButton.vue
|- VueTable.vue
|- Icon.vue
// good
components/
|- BaseButton.vue
|- BaseTable.vue
|- BaseIcon.vue
components/
|- AppButton.vue
|- AppTable.vue
|- AppIcon.vue
components/
|- VButton.vue
|- VTable.vue
|- VIcon.vue</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>只应该拥有单个活跃实例的<strong>单例组件</strong>应该以 The 前缀命名,以示其唯一性</p>
<p>> <em>单例组件不意味着组件只可用于一个单页面,而是每个页面只使用一次。这些组件永远不接受任何 prop,因为它们是为你的应用定制的,而不是它们在你的应用中的上下文。如果你发现有必要添加 prop,那就表明这实际上是一个可复用的组件,只是目前在每个页面里只使用一次</em></p>
<pre><code class="language-javascript">// not good
components/
|- Heading.vue
|- MySidebar.vue
// good
components/
|- TheHeading.vue
|- TheSidebar.vue</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>和父组件<strong>紧密耦合的子组件</strong>应该以父组件名作为前缀命名</p>
<p>> <em>如果一个组件只在某个父组件的场景下有意义,这层关系应该体现在其名字上。因为编辑器通常会按字母顺序组织文件,所以这样做可以把相关联的文件排在一起</em></p>
<pre><code class="language-javascript">// not good
components/
|- TodoList.vue
|- TodoItem.vue
|- TodoButton.vue
components/
|- SearchSidebar.vue
|- NavigationForSearchSidebar.vue
//good
components/
|- TodoList.vue
|- TodoListItem.vue
|- TodoListItemButton.vue
components/
|- SearchSidebar.vue
|- SearchSidebarNavigation.vue</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>组件名应该以高级别的 (通常是一般化描述的) 单词开头,以描述性的修饰词结尾</p>
<pre><code class="language-javascript">// not good
components/
|- ClearSearchButton.vue
|- ExcludeFromSearchInput.vue
|- LaunchOnStartupCheckbox.vue
|- RunSearchButton.vue
|- SearchInput.vue
|- TermsCheckbox.vue
// good
components/
|- SearchButtonClear.vue
|- SearchButtonRun.vue
|- SearchInputQuery.vue
|- SearchInputExcludeGlob.vue
|- SettingsCheckboxTerms.vue
|- SettingsCheckboxLaunchOnStartup.vue</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>组件名应该倾向于完整单词而不是缩写</p>
<pre><code class="language-javascript">// not good
components/
|- SdSettings.vue
|- UProfOpts.vue
// good
components/
|- StudentDashboardSettings.vue
|- UserProfileOptions.vue</code></pre>
</li>
</ol>
<h4>语法</h4>
<ol>
<li>
<p><font color=#f5222d>【强制】</font>组件的 <code>data</code> 必须是一个函数(除了 <code>new Vue</code> 外的任何地方)</p>
<pre><code class="language-javascript">// not good
export default {
data: {
foo: 'bar'
}
}
// good
export default {
data () {
return {
foo: 'bar'
}
}
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font><code>prop</code> 的定义应该尽量详细,至少需要指定其类型</p>
<pre><code class="language-javascript">// not good
// 这样做只有开发原型系统时可以接受
props: ['status']
// good
props: {
status: String
}
// better
props: {
status: {
type: String,
required: true,
validator: function (value) {
return [
'syncing',
'synced',
'version-conflict',
'error'
].indexOf(value) !== -1
}
}
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>为 <code>v-for</code> 设置键值;在组件上总是必须用 <code>key</code> 配合 <code>v-for</code>,以便维护内部组件及其子树的状态</p>
<p>在组件上总是必须用 key 配合 v-for,以便维护内部组件及其子树的状态</p>
</li>
<li>
<p><font color=#f5222d>【强制】</font>不要把 <code>v-if</code>和 <code>v-for</code> 同时用在同一个元素上(大部分时候你可以使用计算属性实现)</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;ul&gt;
&lt;li
v-for=&quot;user in users&quot;
v-if=&quot;user.isActive&quot;
:key=&quot;user.id&quot;
&gt;
{{ user.name }}
&lt;/li&gt;
&lt;/ul&gt;
&lt;!-- good --&gt;
&lt;ul&gt;
&lt;li
v-for=&quot;user in activeUsers&quot;
:key=&quot;user.id&quot;
&gt;
{{ user.name }}
&lt;/li&gt;
&lt;/ul&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font><strong>自闭合组件</strong>在单文件组件、字符串模板和 JSX 中没有内容的组件应该是自闭合的;但在 DOM 模板里不要这样做</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;!-- 在单文件组件、字符串模板和 JSX 中 --&gt;
&lt;MyComponent&gt;&lt;/MyComponent&gt;
&lt;!-- 在 DOM 模板中 --&gt;
&lt;my-component/&gt;
&lt;!-- good --&gt;
&lt;!-- 在单文件组件、字符串模板和 JSX 中 --&gt;
&lt;MyComponent/&gt;
&lt;!-- 在 DOM 模板中 --&gt;
&lt;my-component&gt;&lt;/my-component&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font><strong>模版中的组件名</strong>大小写在单文件组件和字符串模板中组件名应该总是 PascalCase 的;但是在 DOM 模板中总是 kebab-case 的</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;!-- 在单文件组件和字符串模板中 --&gt;
&lt;mycomponent/&gt;
&lt;!-- 在单文件组件和字符串模板中 --&gt;
&lt;myComponent/&gt;
&lt;!-- 在 DOM 模板中 --&gt;
&lt;MyComponent&gt;&lt;/MyComponent&gt;
&lt;!-- good --&gt;
&lt;!-- 在单文件组件和字符串模板中 --&gt;
&lt;MyComponent/&gt;
&lt;!-- 在 DOM 模板中 --&gt;
&lt;my-component&gt;&lt;/my-component&gt;</code></pre>
<p>亦或者</p>
<pre><code class="language-html">&lt;!-- 在所有地方 --&gt;
&lt;my-component&gt;&lt;/my-component&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font><strong>JS/JSX 中的组件名</strong>应该始终是 PascalCase 的</p>
<pre><code class="language-javascript">// not good
Vue.component('myComponent', {
// ...
})
import myComponent from './MyComponent.vue'
export default {
name: 'myComponent',
// ...
}
export default {
name: 'my-component',
// ...
}
// good
Vue.component('MyComponent', {
// ...
})
import MyComponent from './MyComponent.vue'
export default {
name: 'MyComponent',
// ...
}</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font><strong>Prop 名大小写</strong>,在声明 <code>prop</code> 的时候,其命名应该始终使用 camelCase,而在模板和 JSX 中应该始终使用 kebab-case</p>
<pre><code class="language-javascript">// not good
props: {
'greeting-text': String
}
&lt;WelcomeMessage greetingText=&quot;hi&quot;/&gt;
// good
props: {
greetingText: String
}
&lt;WelcomeMessage greeting-text=&quot;hi&quot;/&gt;</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>多个特性的元素应该分多行撰写,每个特性一行(此项 Vetur 插件会自动根据行宽阈值进行自动折行处理,一般无需考虑)</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;img src=&quot;https://vuejs.org/images/logo.png&quot; alt=&quot;Vue Logo&quot;&gt;
&lt;MyComponent foo=&quot;a&quot; bar=&quot;b&quot; baz=&quot;c&quot;/&gt;
&lt;!-- good --&gt;
&lt;img
src=&quot;https://vuejs.org/images/logo.png&quot;
alt=&quot;Vue Logo&quot;
&gt;
&lt;MyComponent
foo=&quot;a&quot;
bar=&quot;b&quot;
baz=&quot;c&quot;
/&gt;</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>组件模板应该只包含简单的表达式,复杂的表达式则应该重构为计算属性或方法</p>
<pre><code class="language-javascript">// not good
{{
fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}}
// good
// 在模板中
{{ normalizedFullName }}
// 复杂表达式已经移入一个计算属性
computed: {
normalizedFullName: function () {
return this.fullName.split(' ').map(function (word) {
return word[0].toUpperCase() + word.slice(1)
}).join(' ')
}
}</code></pre>
</li>
<li>
<p><font color=#52c41a>【推荐】</font>应该把复杂计算属性分割为尽可能多的更简单的属性</p>
<pre><code class="language-javascript">// not good
computed: {
finalPrice: function () {
var basePrice = this.manufactureCost / (1 - this.profitMargin)
return (
basePrice -
basePrice * (this.discountPercent || 0)
)
}
}
// good
computed: {
basePrice: function () {
return this.manufactureCost / (1 - this.profitMargin)
},
discount: function () {
return this.basePrice * (this.discountPercent || 0)
},
finalPrice: function () {
return this.basePrice - this.discount
}
}</code></pre>
</li>
<li>
<p><font color=#f5222d>【强制】</font>非空 HTML 特性值应该始终带引号</p>
<pre><code class="language-html">&lt;!-- not good --&gt;
&lt;input type=text&gt;
&lt;AppSidebar :style={width:sidebarWidth+'px'}&gt;
&lt;!-- good --&gt;
&lt;input type=&quot;text&quot;&gt;
&lt;AppSidebar :style=&quot;{ width: sidebarWidth + 'px' }&quot;&gt;</code></pre>
</li>
<li><font color=#f5222d>【强制】</font>可简写指令需要缩写 (用 <code>:</code> 表示 <code>v-bind:</code> 和用 <code>@</code> 表示 <code>v-on:</code>)</li>
</ol>
<h4>代码风格</h4>
<p><em>此处大部分工作将由代码格式化工具完成(参见环境要求),一般无需考虑</em></p>
<p>具体要求见 4.1 ,4.2,4.3 中代码风格部分</p>
<h4>组件/实例的选项的顺序</h4>
<p><font color=#1890ff>【参考】</font>组件/实例的选项应该有统一的顺序,这是我们推荐的组件选项默认顺序:</p>
<ol>
<li><strong>副作用</strong> (触发组件外的影响)
<ul>
<li><code>el</code></li>
</ul></li>
<li><strong>全局感知</strong> (要求组件以外的知识)
<ul>
<li><code>name</code></li>
<li><code>parent</code></li>
</ul></li>
<li><strong>组件类型</strong> (更改组件的类型)
<ul>
<li><code>functional</code></li>
</ul></li>
<li><strong>模板修改器</strong> (改变模板的编译方式)
<ul>
<li><code>delimiters</code></li>
<li><code>comments</code></li>
</ul></li>
<li><strong>模板依赖</strong> (模板内使用的资源)
<ul>
<li><code>components</code></li>
<li><code>directives</code></li>
<li><code>filters</code></li>
</ul></li>
<li><strong>组合</strong> (向选项里合并属性)
<ul>
<li><code>extends</code></li>
<li><code>mixins</code></li>
</ul></li>
<li><strong>接口</strong> (组件的接口)
<ul>
<li><code>inheritAttrs</code></li>
<li><code>model</code></li>
<li><code>props</code>/<code>propsData</code></li>
</ul></li>
<li><strong>本地状态</strong> (本地的响应式属性)
<ul>
<li><code>data</code></li>
<li><code>computed</code></li>
</ul></li>
<li><strong>事件</strong> (通过响应式事件触发的回调)
<ul>
<li><code>watch</code></li>
<li>生命周期钩子 (按照它们被调用的顺序)
<ul>
<li><code>beforeCreate</code></li>
<li><code>created</code></li>
<li><code>beforeMount</code></li>
<li><code>mounted</code></li>
<li><code>beforeUpdate</code></li>
<li><code>updated</code></li>
<li><code>activated</code></li>
<li><code>deactivated</code></li>
<li><code>beforeDestroy</code></li>
<li><code>destroyed</code></li>
</ul></li>
</ul></li>
<li><strong>非响应式的属性</strong> (不依赖响应系统的实例属性)
<ul>
<li><code>methods</code></li>
</ul></li>
<li><strong>渲染</strong> (组件输出的声明式描述)
<ul>
<li><code>template</code>/<code>render</code></li>
<li><code>renderError</code></li>
</ul></li>
</ol>
<h4>元素特性的顺序</h4>
<p><strong><font color=#1890ff>【参考】</font>元素 (包括组件) 的特性应该有统一的顺序,这是我们为元素特性推荐的默认顺序:</strong></p>
<ol>
<li><strong>定义</strong> (提供组件的选项)
<ul>
<li><code>is</code></li>
</ul></li>
<li><strong>列表渲染</strong> (创建多个变化的相同元素)
<ul>
<li><code>v-for</code></li>
</ul></li>
<li><strong>条件渲染</strong> (元素是否渲染/显示)
<ul>
<li><code>v-if</code></li>
<li><code>v-else-if</code></li>
<li><code>v-else</code></li>
<li><code>v-show</code></li>
<li><code>v-cloak</code></li>
</ul></li>
<li><strong>渲染方式</strong> (改变元素的渲染方式)
<ul>
<li><code>v-pre</code></li>
<li><code>v-once</code></li>
</ul></li>
<li><strong>全局感知</strong> (需要超越组件的知识)
<ul>
<li><code>id</code></li>
</ul></li>
<li><strong>唯一的特性</strong> (需要唯一值的特性)
<ul>
<li><code>ref</code></li>
<li><code>key</code></li>
<li><code>slot</code></li>
</ul></li>
<li><strong>双向绑定</strong> (把绑定和事件结合起来)
<ul>
<li><code>v-model</code></li>
</ul></li>
<li><strong>其它特性</strong> (所有普通的绑定或未绑定的特性)</li>
<li><strong>事件</strong> (组件事件监听器)
<ul>
<li><code>v-on</code></li>
</ul></li>
<li><strong>内容</strong> (覆写元素的内容)
<ul>
<li><code>v-html</code></li>
<li><code>v-text</code></li>
</ul></li>
</ol>
<h4>单文件组件的顶级元素的顺序</h4>
<p><strong><font color=#f5222d>【强制】</font>单文件组件应该总是按照 <code>&lt;template&gt;</code>、<code>&lt;script&gt;</code> 和 <code>&lt;style&gt;</code> 的标签顺序</strong></p>
<pre><code class="language-html">&lt;!-- good --&gt;
&lt;!-- ComponentA.vue --&gt;
&lt;template&gt;...&lt;/template&gt;
&lt;style&gt;/* ... */&lt;/style&gt;
&lt;!-- ComponentB.vue --&gt;
&lt;template&gt;...&lt;/template&gt;
&lt;script&gt;/* ... */&lt;/script&gt;
&lt;style&gt;/* ... */&lt;/style&gt;</code></pre>
<h4>隐性的父子组件通信</h4>
<p><strong><font color=#f5222d>【强制】</font>应该优先通过 prop 和事件进行父子组件之间的通信,而不是 this.$parent 或改变 prop。</strong></p>
<p>一个理想的 Vue 应用是 prop 向下传递,事件向上传递的。遵循这一约定会让你的组件更易于理解。然而,在一些边界情况下 prop 的变更或 <code>this.$parent</code> 能够简化两个深度耦合的组件。</p>
<p>问题在于,这种做法在很多<em>简单</em>的场景下可能会更方便。但请当心,不要为了一时方便 (少写代码) 而牺牲数据流向的简洁性 (易于理解)。</p>
<h4>非 Flux 的全局状态管理</h4>
<p><strong><font color=#f5222d>【强制】</font>应该优先通过 Vuex 管理全局状态,而不是通过 this.$root 或一个全局事件总线。</strong></p>
<p>通过 <code>this.$root</code> 和/或全局事件总线管理状态在很多简单的情况下都是很方便的,但是并不适用于绝大多数的应用。Vuex 提供的不仅是一个管理状态的中心区域,还是组织、追踪和调试状态变更的好工具。</p>