本规范提供了一种统一的编码规范来编写 Vue.js 代码。这使得代码具备以下的特性:javascript
本指南为 De Voorhoede 参考 RiotJS 编码规范 而写。css
this
赋值给 component
变量始终基于模块的方式来构建你的 app,每个子模块只作一件事情。html
Vue.js 的设计初衷就是帮助开发者更好的开发界面模块。一个模块是应用程序中独立的一个部分。vue
每个 Vue 组件(等同于模块)首先必须专一于解决一个 单一的问题 , 独立的 , 可复用的 , 微小的 and 可测试的 。java
若是你的组件作了太多的事或是变得臃肿,请将其拆分红更小的组件并保持单一的原则。通常来讲,尽可能保证每个文件的代码行数不要超过 100 行。也请保证组件可独立的运行。比较好的作法是增长一个单独的 demo 示例。nginx
组件的命名需听从如下原则:git
同时还须要注意:github
app-
前缀做为命名空间 : 若是很是通用的话可以使用一个单词来命名,这样能够方便于其它项目里复用。<!-- 推荐 -->
<app-header></app-header> <user-list></user-list> <range-slider></range-slider> <!-- 避免 --> <btn-group></btn-group> <!-- 虽然简短可是可读性差. 使用 `button-group` 替代 --> <ui-slider></ui-slider> <!-- ui 前缀太过于宽泛,在这里意义不明确 --> <slider></slider> <!-- 与自定义元素规范不兼容 -->
Vue.js 的表达式是 100% 的 Javascript 表达式。这使得其功能性很强大,但也带来潜在的复杂性。所以,你应该尽可能 保持表达式的简单化 。vue-cli
若是你发现写了太多复杂并难以阅读的行内表达式,那么可使用 method 或是 computed 属性来替代其功能。django
<!-- 推荐 --> <template> <h1> {{ `${year}-${month}` }} </h1> </template> <script type="text/javascript"> export default { computed: { month() { return this.twoDigits((new Date()).getUTCMonth() + 1); }, year() { return (new Date()).getUTCFullYear(); } }, methods: { twoDigits(num) { return ('0' + num).slice(-2); } }, }; </script> <!-- 避免 --> <template> <h1> {{ `${(new Date()).getUTCFullYear()}-${('0' + ((new Date()).getUTCMonth()+1)).slice(-2)}` }} </h1> </template>
虽然 Vue.js 支持传递复杂的 JavaScript 对象经过 props 属性,可是你应该尽量的使用原始类型的数据。尽可能只使用 JavaScript 原始类型 (字符串、数字、布尔值) 和 函数。尽可能避免复杂的对象。
组件的每个属性单独使用一个 props,而且使用函数或是原始类型的值。
<!-- 推荐 -->
<range-slider :values="[10, 20]" min="0" max="100" step="5" :on-slide="updateInputs" :on-end="updateResults"> </range-slider> <!-- 避免 --> <range-slider :config="complexConfigObject"></range-slider>
在 Vue.js 中,组件的 props 即 API,一个稳定并可预测的 API 会使得你的组件更容易被其余开发者使用。
组件 props 经过自定义标签的属性来传递。属性的值能够是 Vue.js 字符串( :attr="value"
或v-bind:attr="value"
)或是不传。你须要保证组件的 props 能应对不一样的状况。
验证组件 props 能够保证你的组件永远是可用的(防护性编程)。即便其余开发者并未按照你预想的方法使用时也不会出错。
type
属性 校验类型<template> <input type="range" v-model="value" :max="max" :min="min"> </template> <script type="text/javascript"> export default { props: { max: { type: Number, // 这里添加了数字类型的校验 default() { return 10; }, }, min: { type: Number, default() { return 0; }, }, value: { type: Number, default() { return 4; }, }, }, }; </script>
this
赋值给 component
变量(在 Vue.js 组件上下文中, this
指向了组件实例。所以当你切换到了不一样的上下文时,要确保this
指向一个可用的 component
变量。
换句话说,不要在编写这样的代码 const self = this;
,而是应该直接使用变量 component
。
this
赋值给变量 component
可用让开发者清楚的知道任何一个被使用的地方,它表明的是组件实例。<script type="text/javascript"> export default { methods: { hello() { return 'hello'; }, printHello() { console.log(this.hello()); }, }, }; </script> <!-- 避免 --> <script type="text/javascript"> export default { methods: { hello() { return 'hello'; }, printHello() { const self = this; // 没有必要 console.log(self.hello()); }, }, }; </script>
按照必定的结构组织,使得组件便于理解。
name
属性。借助于 vue devtools 可让你更方便的测试组件结构化
<template lang="html"> <div class="Ranger__Wrapper"> <!-- ... --> </div> </template> <script type="text/javascript"> export default { // 不要忘记了 name 属性 name: 'RangeSlider', // 组合其它组件 extends: {}, // 组件属性、变量 props: { bar: {}, // 按字母顺序 foo: {}, fooBar: {}, }, // 变量 data() {}, computed: {}, // 使用其它组件 components: {}, // 方法 watch: {}, methods: {}, // 生命周期函数 beforeCreate() {}, mounted() {}, }; </script> <style scoped> .Ranger__Wrapper { /* ... */ } </style>
Vue.js 提供的处理函数和表达式都是绑定在 ViewModel 上的,组件的每个事件都应该按照一个好的命名规范来,这样能够避免很多的开发问题,具体可见以下 ** 为何**。
Vue.js 支持组件嵌套,而且子组件可访问父组件的上下文。访问组件以外的上下文违反了 基于模块开发 的 第一原则 。所以你应该尽可能避免使用 this.$parent
。
Vue.js 支持经过 ref
属性来访问其它组件和 HTML 元素。并经过 this.$refs
能够获得组件或 HTML 元素的上下文。在大多数状况下,经过 this.$refs
来访问其它组件的上下文是能够避免的。在使用的的时候你须要注意避免调用了不恰当的组件 API,因此应该尽可能避免使用 this.$refs
。
this.$refs
来实现。this..$ref
而不是 JQuery
, document.getElement*
, document.queryElement
。<!-- 推荐,并未使用 this.$refs -->
<range :max="max" :min="min" @current-value="currentValue" :step="1"></range>
<!-- 使用 this.$refs 的适用状况-->
<modal ref="basicModal"> <h4>Basic Modal</h4> <button class="primary" @click="$refs.basicModal.close()">Close</button> </modal> <button @click="$refs.basicModal.open()">Open modal</button> <!-- Modal component --> <template> <div v-show="active"> <!-- ... --> </div> </template> <script> export default { // ... data() { return { active: false, }; }, methods: { open() { this.active = true; }, hide() { this.active = false; }, }, // ... }; </script>
<!-- 若是可经过 emited 来作则避免经过 this.$refs 直接访问 -->
<template> <range :max="max" :min="min" ref="range" :step="1"></range> </template> <script> export default { // ... methods: { getRangeCurrentValue() { return this.$refs.range.currentValue; }, }, // ... }; </script>
Vue.js 的组件是自定义元素,这很是适合用来做为样式的根做用域空间。能够将组件名做为 css 类的命名空间。
使用组件名做为样式命名的前缀,可基于 BEM 或 OOCSS 范式。同时给style标签加上 scoped 属性。加上 scoped 属性编译后会给组件的 class 自动加上惟一的前缀从而避免样式的冲突。
<style scoped> /* 推荐 */ .MyExample { } .MyExample li { } .MyExample__item { } /* 避免 */ .My-Example { } /* not scoped to component or module name, not BEM compliant */ </style>
使用 Vue.js 组件的过程当中会建立 Vue 组件实例,这个实例是经过自定义属性配置的。为了便于其余开发者使用该组件,对于这些自定义属性即组件API应该在 README.md
文件中进行说明。
README.md
是标准的咱们应该首先阅读的文档文件。代码托管网站 (github/bitbucket/gitlab 等) 会默认在仓库中展现 该文件做为仓库的介绍。在模块目录中添加 README.md
文件:
range-slider/
├── range-slider.vue ├── range-slider.less └── README.md
在 README 文件中说明模块的功能以及使用场景。对于 vue 组件来讲,比较有用的描述是组件的自定义属性即 API 的描述介绍。
range slider 组件可经过拖动的方式来设置一个给定范围内的数值。
该模块使用 noUiSlider 来实现夸浏览器和 touch 功能的支持。
<range-slider>
支持以下的自定义属性:
attribute | type | description |
---|---|---|
min |
Number | 可拖动的最小值. |
max |
Number | 可拖动的最大值. |
values |
Number[] optional | 包含最大值和最小值的数组. 如. values="[10, 20]" . Defaults to [opts.min, opts.max] . |
step |
Number optional | 增长减少的数值单位,默认为 1. |
on-slide |
Function optional | 用户拖动开始按钮或者结束按钮时的回调函数,函数接受 (values, HANDLE) 格式的参数。 如: on-slide={ updateInputs } , component.updateInputs = (values, HANDLE) => { const value = values[HANDLE]; } . |
on-end |
Function optional | 当用户中止拖动时触发的回调函数,函数接受 (values, HANDLE) 格式的参数。 |
如须要自定义 slider 的样式可参考 noUiSlider 文档
添加 index.html
文件做为组件的 demo 示例,并提供不一样配置状况的效果,说明组件是如何使用的。
代码校验能够保持代码的统一性以及追踪语法错误。.vue 文件能够经过使用 eslint-plugin-html
插件来校验代码。你能够经过 vue-cli
来开始你的项目, vue-cli
默认会开启代码校验功能。
为了校验工具可以校验 *.vue
文件,你须要将代码编写在 <script>
标签中,并使,由于校验工具没法理解行内表达式,配置校验工具能够访问全局变量 vue
和组件的 props
。
ESLint 须要经过 ESLint HTML 插件 来抽取组件中的代码。
经过 .eslintrc
文件来配置 ESlint,这样 IED 能够更好的理解校验配置项。 ESlint,这样.
{
"extends": "eslint:recommended", "plugins": ["html"], "env": { "browser": true }, "globals": { "opts": true, "vue": true } }
运行 ESLint
eslint src/**/*.vue
JSHint 能够解析 HTML (使用 --extra-ext
命令参数) 和 抽取代码(使用 --extract=auto
命令参数).
经过 .jshintrc
文件来配置 ESlint,这样 IED 能够更好的理解校验配置项。
{
"browser": true, "predef": ["opts", "vue"] }
运行 JSHint
jshint --config modules/.jshintrc --extra-ext=html --extract=auto modules/
注:JSHint 不接受 vue
扩展名的文件,只支持 html
。
本人demo地址: