一、统一的编辑器
-
使用统一的编辑器VScode最新版;
-
使用一致的插件扩展,目前4个
image.png
-
使用相同的编辑器设置
其中部分需要自定义一下配置,修改setting.json,复制一下代码到setting文件
{
"files.associations": {
"*.vue": "vue",
"*.wpy": "vue",
"*.wxml": "html",
"*.wxss": "css"
},
"emmet.triggerExpansionOnTab": true,
"emmet.syntaxProfiles": {
"vue-html": "html",
"vue": "html"
},
"files.autoSave": "off",
"vetur.completion.scaffoldSnippetSources": {
},
"vetur.format.defaultFormatterOptions": {
"prettier": {
"semi": true,
"singleQuote": true
},
"wrap_attributes": "force-aligned"
},
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"vetur.format.defaultFormatter.js": "vscode-typescript",
"vetur.format.defaultFormatter.html": "js-beautify-html",
"vetur.validation.template": false
}
- 格式化代码,遵从ESlint规范
文件必选格式化才能提交。
二、命名规范
统一要求:
- 取名字用单词,不用拼音;
- 取名尽量和内容功能相近
- 尽量要简单明确
类型 | 描述 | 举例 |
---|---|---|
文件夹 | 小写开头,驼峰法 | relatedProduct |
Js文件 | 小写开头,驼峰法 | accountApi.js |
样式文件 | 小写开头,驼峰法 | categoryFloor.scss |
Vue文件 | 大写开头,驼峰法 | ShopHeader.vue |
标签Class命名 | 全小写,“-“链接单词 | btn-submit-disable |
静态文件命名 | 全小写,“-”链接单词 | logo-mini.jpg |
方法名 | 小写开头,驼峰法 | getAllCategories(){} |
三、VUE文件使用规范
- template方法和钩子函数按照 先模板属性,后模板函数,再钩子函数的顺序,如下所示:
<script>
import '@/styles/components/category/catelog.scss';
const prefix = 'cpt-category';
export default {
name: 'XXX',
components: {},
props: {},
data () {
return {
prefix
};
},
computed: {},
methods: {},
watch: {},
created () {},
mounted () {},
updated () {},
destroyed () {}
};
</script>
2.组件 中便签class命名使用前缀
根节点class命名必须使用前缀, 内容中的class命名可选
- components组件前缀使用 cpt 开头:cpt-category
- pages组件前缀使用 page 开头:page-home
template块:
<template>
<div :class="[prefix, `${prefix}-wrap`]">
<div>
内容
</div>
</div>
</template>
script块:
<script>
const prefix = 'cpt-category';
export default {
name: 'XXX',
components: {},
props: {},
data () {
return {
prefix
};
}
};
- 样式文件适应scss语言,scoped
不建议在此处写样式,请在对应的styles目录下建对应组件的样式,从外部引入;
当然不管在哪里写都应该遵循样式规范,具体规则请看样式规范。
<style lang="scss" scoped>
</style>
四、样式使用规范
- 使用scss语言规范;
- 必须使用嵌套写法
- 组件的样式文件,根标签class必须使用前缀prefix, 前缀和Vue文件配合使用
@import "@/styles/base.scss";
$prefix: 'cpt-category-floor';
.#{$prefix} {
.container {
}
}
- 组件样式文件必须引入base.scss
使用系统定义好的变量,尤其是颜色,必须使用变量,不能自己随意写颜色;
五、vuex使用规范
全局引入了vuex,因此在组件中使用;
引入的方式:
import { mapState, mapActions } from 'vuex';
- 在computed中引入state/getter,先map在写其他计算属性
computed: {
...mapState({
loginUserInfo: state => state.loginUserInfo
}),
...mapGetters({
defaultColor: 'getDefaultColor',
})
}
- 在methods中引入actions/mutAction,先map在写其他方法
computed: {
methods: {
...mapActions({
getCategoryGroups: 'getCategoryGroups'
}),
...mapMutations({
reloadGameList: 'SET_ReloadGameListFlag'
}),
showDetail () {
this.panelVisible = true;
}
}
六、API请求使用规范
- 接口有统一的错误处理机制,未登录检测;自动带授权token
- 接口定义在api文件夹对应模块下
// Account API
import ajax from './_ajax';
const baseUrl = '/api/account';
const api = {};
api.login = function (params) {
return ajax.post(baseUrl + '/login', params);
};
api.logout = function () {
return ajax.post(baseUrl + '/logout');
};
api.register = function (params) {
return ajax.post(baseUrl + '/register', params);
};
api.resetPassword = function (params) {
return ajax.post(baseUrl + '/resetPassword', params);
};
api.getCountryCode = function () {
return ajax.get(baseUrl + '/getCountryCode');
};
export default api;
- 所有接口的出入都要经过vuex的action,不要直接在VUE文件调用定义api
actions.js定义登录操作
// 用户登录
export const login = ({ commit }, data) => {
return new Promise((resolve, reject) => {
accountApi.login(data).then(result => {
if (result.Success) {
storage.setItem({ name: 'local_loginInfo', value: result.Data, expires: 86400000 });
commit('SET_USER_LOGIN_INFO', result.Data);
}
resolve(result);
}).catch((error) => {
console.log('error:', error);
resolve(false);
});
});
};
// 获取前端分类
export const getCategoryGroups = ({ commit }) => {
return productApi.getCategoryGroups();
};
七、文件引用规范
- 文件引入有相对和绝对两种方式, 两者都可,建议使用绝对
- 相对:../../styles/main.css, 是从当前文件所在目录为起点开始计算的
- 绝对:@/styles/main.css,根据src目录为起点开始计算的
- 引入static下的静态文件,直接引入,也可使用相对地址方式
<img class="logo-img" src="/static/img/logo.jpg"/>
八、 IconFont使用规范
待完善
九、EventBus使用
- 引入;
import EventBus, { EventName } from '@/utils/EventBus';
- 新增加监听
EventBus.$on(EventName.product.onCompareProductClick, (dataInfo) => {
this.deal(dataInfo);
});
- 触发事件
EventBus.$emit(EventName.product.onCompareProductClick);
- 销毁组件时关闭监听
beforeDestroy() {
EventBus.$off(EventName.product.onCompareProductClick);
}
- 所有的事件命名必须全部定义在EventName对象中;规范示例如下:
const EventName = {
nav: {
onNav: 'on-nav',
onSubNavChange: 'on-subnav-change'
},
product: {
onCompareProductClick: 'on-compare-product-click'
}
};
十、storage的使用
- 引入;
import storage from '@/utils/storage';
- 保存,可传递过期时间(毫秒,optional)
storage.setItem({ name: 'key', value: data, expires: 86400000 });
- 获取
storage.getItem('key');
- 移除
storage.removeItem(name);
- 清除所有
storage.clear();
十一、性能优化
- v-if 和 v-show选择调用
- 循环必须为item设置唯一key值
- 细分vuejs组件
- 减少watch的数据
- 路由懒加载
- 图片懒加载
- 数据懒加载、分页加载
- 多使用iconfont而不是图片
- 骨架屏加载
- loading效果/分块异步加载
- 防止重复点击
- 及时移除注册的事件监听
- 及时移除定时器
- 及时移除Eventbus监听
- CDN加速
- SSR(服务端渲染)
网友评论