school-of-website-engineering / heimatoutiao Goto Github PK
View Code? Open in Web Editor NEW头条新闻-移动端vue项目,基于Vue2.x的移动端h5项目,使用vant组件库
Home Page: http://sowe.social/Heimatoutiao
License: Apache License 2.0
头条新闻-移动端vue项目,基于Vue2.x的移动端h5项目,使用vant组件库
Home Page: http://sowe.social/Heimatoutiao
License: Apache License 2.0
每个属性声明后面都要加分号。
原则:整体到局部,外部到内部,重要属性优先
.element {
display: block;
float: left;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 100;
margin: 0 100px;
padding: 50px; // padding习惯写到margin后面
width: 100px;
height: 100px;
border: 1px solid #e5e5e5;
border-radius: 3px;
font: normal 13px "Helvetica Neue", sans-serif;
color: #333;
text-align: center;
line-height: 1.5;
background-color: #f5f5f5;
opacity: 1;
}
命名方式:小驼峰
命名规范:前缀名词
// bad
let setCount = 10;
// good
let maxCount = 10;
命名方式:全部大写
命名规范:多个单词时使用分隔符**_**
// bad
const serverErrorCode = {
success: 200,
repeat: 444,
};
// good
const SERVER_ERROR_CODE = {
SUCCESS: 200,
REPEAT: 444,
};
命名方式:小驼峰
命名规范:前缀动词
// bad
function wordClass() {}
// good
function saveWordClass() {}
常用动词:can、has、is、load、get、set
命名方式:大驼峰
命名规范:前缀名词
// bad
class person {}
// good
class Person {}
单行
// 单行注释,注意前面的空格
let maxCount = 123;
多行
/**
* 多行注释
* /
确定条件不允许时,尽早返回。经典使用场景:校验数据
// bad
if (condition1) {
if (condition2) {
...
}
}
// good
if (!condition1) return
if (!condition2) return
...
使用常量进行自解释
// bad
type: 1; // 1代表新增 2代表修改
// good
const MODIFY_TYPE = {
ADD: 1,
EDIT: 2,
};
type: MODIFY_TYPE.ADD;
尽可能简洁表达式
// bad
if (name === "") {
}
if (collection.length > 0) {
}
if (notTrue === false) {
}
// good
if (!name) {
}
if (collection.length) {
}
if (notTrue) {
}
对于相同变量或表达式的多值条件,用 switch 代替 if。
// bad
let type = typeof variable;
if (type === "object") {
// ......
} else if (type === "number" || type === "boolean" || type === "string") {
// ......
}
// good
switch (typeof variable) {
case "object":
// ......
break;
case "number":
case "boolean":
case "string":
// ......
break;
}
逻辑复杂时,建议使用变量名自解释,而不是晦涩难懂的简写。
// bad
function(value) {
return !helpers.req(value) || this.entity.entVocabularyEntries.filter(item => item.vocabularyEntryName === value).length < 2
}
// good
function(value) {
let entVocabularyList = this.entity.entVocabularyEntries
let repeatCount = entVocabularyList.filter(item => item.vocabularyEntryName === value).length
return !helpers.req(value) || repeatCount < 2
}
遵循单一职责的基础上,可以把逻辑隐藏在函数中,同时使用准确的函数名自解释。
// bad
if (modifyType === MODIFY_TYPE.ADD) {
batchVariableAPI(data).then(() => {
this.closeModal()
this.$toast.show('添加变量成功')
})
} else {
updateVariableAPI(data).then(() => {
this.closeModal()
this.$toast.show('修改变量成功')
})
}
// good
modifyType === MODIFY_TYPE.ADD ? this._insertVariable(data) : this._updateVariable(data)
_insertVariable() {
batchVariableAPI(data).then(() => this._successOperation('添加变量成功'))
}
_updateVariable() {
updateVariableAPI(data).then(() => this._successOperation('修改变量成功'))
}
_successOperation(toastMsg) {
this.closeModal()
this.$toast.show(toastMsg)
}
统一小写,多个单词作为文件名使用分隔符 -
// bad
EntityList.vue;
entityList.vue;
// good
entity - list.vue;
和父组件紧密耦合的子组件应该以父组件名作为前缀命名
// bad
components/
|- todo-list.vue
|- todo-item.vue
└─ todo-button.vue
// good
components/
|- todo-list.vue
|- todo-list-item.vue
└─ todo-list-item-button.vue
在单文件组件中没有内容的组件应该是自闭合的
<!-- bad -->
<u-input></u-input>
<!-- good -->
<u-input />
用 **:**表示 v-bind: ,用 **@**表示 v-on
<!-- bad -->
<input v-bind:value="value" v-on:input="onInput" />
<!-- good -->
<input :value="value" @input="onInput" />
组件的 data 必须是一个函数,并且建议在此不使用箭头函数
// bad
export default {
data: () => ({
foo: "bar",
}),
};
// good
export default {
data() {
return {
foo: "bar",
};
},
};
小驼峰命名。内容尽量详细,至少有默认值
// bad
greeting-text: String
// good
greetingText: { type: String, default: ''}
顺序原则:重要属性放前面
顺序依据:依次指令->props属性-> 事件->dom属性(class有标记作用,除外)
分行规则:放在一行,重要内容较多时,可放置 2 ~ 3 行
<!-- bad -->
<u-select
class="select"
size="s"
@select="searchEntity($event, row)"
@blur="searchEntity($event, row)"
v-model="row.variableId"
:list="variableList" />
<!-- good -->
<u-select v-model="row.variableId" :list="variableList" size="s"
@select="searchEntity($event, row)" @blur="searchEntity($event, row)" class="select" />
export default {
name: "",
/*1. Vue扩展 */
extends: "", // extends和mixins都扩展逻辑,需要重点放前面
mixins: [],
components: {},
/* 2. Vue数据 */
props: {},
model: { prop: "", event: "" }, // model 会使用到 props
data() {
return {};
},
computed: {},
watch: {}, // watch 监控的是 props 和 data,有必要时监控computed
/* 3. Vue资源 */
filters: {},
directives: {},
/* 4. Vue生命周期 */
created() {},
mounted() {},
destroy() {},
/* 5. Vue方法 */
methods: {}, // all the methods should be put here in the last
};
顺序保持一致,且标签之间留有空行。template 第一层级下四个空格,script 和 style 第一层级都不加空格
<template>
<div></div>
</template>
<script>
export default {}
</script>
<style>
.app {}
</style>
原则:同等类型的放一起,优先放 mixins 和 components 等 UI 资源。忌随意放置
// bad
import { getAllEntityList, getVariableGroup } from "@/server/api";
import { helpers } from "vuelidate/lib/validators";
import { getRepeatLine } from "@/utils/common";
import { CloseModalMixin, InvalidCheckMixin } from "@/components/common/mixins";
import VSearchSelect from "@/components/variable/v-search-select";
import EModifyModal from "@/components/entity/e-modify-modal";
import { MODIFY_MODAL_TYPE } from "@/utils/config";
import { botIdLoc, custIdLoc } from "@/utils/locs";
// good
import { CloseModalMixin, InvalidCheckMixin } from "@/components/common/mixins";
import VSearchSelect from "@/components/variable/v-search-select";
import EModifyModal from "@/components/entity/e-modify-modal";
import { getAllEntityList, getVariableGroup } from "@/server/api";
import { helpers } from "vuelidate/lib/validators";
import { MODIFY_MODAL_TYPE } from "@/utils/config";
import { getRepeatLine } from "@/utils/common";
import { botIdLoc, custIdLoc } from "@/utils/locs";
data 数据是连接 View 和 Modal 的基础,当 ViewModal 复杂时,建议进行注释并分组。另外,当 data 过于复杂时应考虑优化重构。
// bad
data() {
return {
isOpenModal: false,
list: [],
groupList: [],
searchParams: { groupId: '', searchParam: '', searchType: '' },
pageParam: { currentPage: 1, pageSize: 50 },
totalCount: 0,
groupId: '',
typeList: [],
defaultType: 'paramName'
}
}
// good
data() {
return {
variableList: [],
groupList: [],
typeList: [],
/*
* 查询参数
* 组与组之间通过空行区分
*/
searchParams: { groupId: '', searchParam: '', searchType: '', currentPage: 1, pageSize: 50 },
totalCount: 0,
defaultType: '',
isOpenModal: false
}
}
.eslintrc.js 规则:
module.exports = {
//root: true 用于指定它是最顶层的配置,即它在任何情况下都会被采用,而不会被继承覆盖
root: true,
//env 指定代码运行的环境
env : {
browser: true,
node : true,
es2021 : true,
es6 : true
},
//extends 指定继承的配置
extends: ["plugin:vue/essential"],
//plugins 指定使用的插件
plugins: ["@typescript-eslint"],
// parserOptions 指定解析器选项
parserOptions: { parser: "babel-eslint" },
plugins : ["vue"],
// rules 指定自定义的规则
rules : {
eqeqeq : "off",
curly : "error",
quotes : ["error", "double"],
"arrow-parens" : 0,
"generator-star-spacing" : 0,
"no-unused-vars" : "warn",
"no-debugger" : process.env.NODE_ENV === "production" ? "error" : "off",
indent : [2, 4, { SwitchCase: 1 }],
"space-before-function-paren": ["error", "never"],
"no-constant-condition" : ["warn"],
"no-empty" : ["off"],
"comma-spacing" : ["error", { after: true }],
"key-spacing" : [
"error",
{
singleLine: {},
multiLine : { align: "colon" }
}
],
"object-curly-newline" : ["error", { multiline: true }],
"array-bracket-newline": ["error", { multiline: true }],
curly : ["error", "all"],
quotes : ["error", "double"],
indent : ["error", "tab"],
"brace-style" : ["error", "stroustrup", { allowSingleLine: false }],
"space-infix-ops" : ["error"],
"comma-dangle" : ["warn", "never"]
},
//overrides 指定某些文件的指定规则 */
overrides: [
{
files: ["*.vue"],
rules: { "vue/multi-word-component-names": 0 }
}
]
};
/*
eqeqeq:关闭此规则,允许使用==和!=进行比较。
curly:要求使用大括号将代码块括起来。
quotes:要求使用双引号。
arrow-parens:允许省略箭头函数参数的括号。
generator-star-spacing:允许在生成器函数中省略星号和其周围的空格no-unused-vars:警告末使用的变量。
no-debugger:如果当前环境是production,则报错,否则关闭此规则。indent:要求缩进为2或4个空格,switch语句的case子句需要缩进一次.space-before-function-paren:要求在函数定义中不要使用空格。
o-constant-condition:警告不要使用永远为真或永远为假的条件。no-empty:关闭此规则,允许空块。
comma-spacing:要求在逗号后面使用空格。
key-spacing:要求在对象字面量中使用空格,并且在多行对象字面量中对齐冒号。object-curly-newline:要求在多行对象字面量中使用换行符。
array-bracket-newline:要求在多行数组字面量中使用换行符。curly:要求在所有情况下使用大括号。
quotes:要求使用双引号。
indent:要求使用制表符进行缩进。
brace-style:要求使用Stroustrup 风格的大括号,不允许单行大括号。space-infix-ops:要求在中缀操作符两侧使用空格。
comma-dangle:警告不要在未尾使用逗号。
*/
.eslintignore 规则:
# /node_modules/* and /bower_components/* ignored by default
# Ignore built files except build/index.js
build/*
!build/index.js
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.