企业网站建设实例,网店运营推广,珠海建站网站,山东圣大建设集团网站前端代码审查#xff08;Code Review#xff09; 针对目录结构、SCSS规范、JS规范、Vue规范 可参照官方给出的风格指南#xff08;Code Review#xff09; 具体实践规范
1、POST/PUT/DELETE 请求按钮需要添加 loading 状态#xff0c;防止重复提交。 建议使用 Element UI…前端代码审查Code Review 针对目录结构、SCSS规范、JS规范、Vue规范 可参照官方给出的风格指南Code Review 具体实践规范
1、POST/PUT/DELETE 请求按钮需要添加 loading 状态防止重复提交。 建议使用 Element UI 提供的button 组件的loading属性或者自己封装一个 loading 状态的按钮组件。 el-button typeprimary :loadingloading clickhandleSubmit 提交 /el-button2、模板上超过两个的判断条件写成方法或者computed
!--bad--
templatet-table v-ifsatus1orderStatus2isShowTable/
/template
!--good--
templatet-table v-ifisChangeAvailiable/
/template
scriptcomputed: {isChangeAvailiable() {return (this.satus1this.orderStatus2this.isShowTable);},},
/script
3、可选链访问数组/对象元素
//bad
cosnt obj {}
cosnt b obj.a obj.a.b
console.log(b) // undefined
//good
cosnt obj {}
cosnt b obj?.a?.b
console.log(b) // undefined4、定时器及时清理
mounted () {this.timer setInterval(() {...}, 1000)
}
destroyed () {if (this.timer) {clearInterval(this.timer)}
}5、window/body上的监听事件–需要解绑
mounted() {window.addEventListener(resize, this.fun)
}
beforeDestroy () {window.removeEventListener(resize, this.fun);
}6、async await 结合使用(调用接口)
export default {created() {this.getOrderNo()},methods:{async getOrderNo() {const res await this.$api.getOrderNo()if(res.success){// 成功处理}}}
}7、使用try…catch…时–错误代码需要提示
try {// 成功处理
} catch (error) {// 处理异常的代码this.$message.error(error.message)
}8、函数有很多参数需要封装成一个对象
// bad---这个方式参数就必须按顺序传递
const getUserInfo (name,age,sex,mobile,hobby) {// 函数逻辑
}
// good
const getUserInfo (userInfo) {// 函数逻辑const {name,age,sex,mobile,hobby} userInfo
}9、简化switch case判断
// bad
const counter (state0,action){switch (action.type) {case ADD:return state 1case MINUS:return state - 1default:return state}
}
// good
const counter (state0,action){const step{ADD:1,MINUS:-1}return state (step[action.type] ?? 0)
}10、判断条件过多需要提取出来
// bad
const checkGameStatus (){if(status0||(satuas1isEnd1)||(isEnd2)){// 调用}
}
// good
const isGaneOver (){return (status0||(satuas1isEnd1)||(isEnd2))
}
const checkGameStatus (){if(isGameOver()){// 调用}
}
11、if 判断嵌套—错误前置
// bad
const publishPost (post){if(isLoggenIn){if(post){if(isPostValid()){doPublishPost(post)}else{throw new Error(文章不合法)}}else{throw new Error(文章不能为空)}}else{throw new Error(用户未登录)}
}
// good
const publishPost (post){if(!isLoggenIn){throw new Error(用户未登录)}if(!post){throw new Error(文章不能为空)}if(!isPostValid()){throw new Error(文章不合法)}doPublishPost(post)
}// bad
const createElement (item){if(item.typeball){cosnt div document.createElement(div)div.className balldiv.style.backgroundColor item.colorreturn div}else if(item.typeblock){const div document.createElement(div)div.className blockdiv.style.backgroundColor item.colorreturn div}else if(item.typesquare){const div document.createElement(div)div.className squarediv.style.backgroundColor item.colorreturn div}else{throw new Error(未知元素类型)}
}// good
cosnt createElement (item){const validTypes [ball, block, image]if(!validTypes.includes(item.type)){throw new Error(未知元素类型)}cosnt div document.createElement(div)div.className item.typediv.style.backgroundColor item.colorreturn div
}
// bad
let commodity {phone: 手机,computer: 电脑,television: 电视,gameBoy: 游戏机,
}function price(name) {if (name commodity.phone) {console.log(1999)} else if (name commodity.computer) {console.log(9999)} else if (name commodity.television) {console.log(2999)} else if (name commodity.gameBoy) {console.log(3999)}
}
price(手机) // 1999
// good
const commodity new Map([[phone, 1999],[computer, 9999],[television, 2999],[gameBoy, 3999],
])const price (name) {return commodity.get(name)
}
price(phone) // 1999
补充常规的—目录结构规范 项目根目录下创建 src 目录src 目录下创建 api 目录、assets 目录、components 目录、directive 目录、router 目录、store 目录、utils 目录、views 目录。 1、api 目录存放所有页面API。 建议将每个页面的API封装成一个单独的js文件文件名与页面名称相同防止增删查改接口命名重复并且都放在api下的modules目录下。 import request from /utils/request
export function afterSaleApplyRefund(data) {return request({url: /web/refundApplyOrder/applyRefund,method: put,data})
}
export function getStoreList(params) {return request({url: /webWaterStore/getMarkStoreTree,method: get,params})
}
....建议API目录下新建index.js文件用于统一导出所有API,在main.js引入并将api挂载到vue的原型上Vue.prototype.$api api在页面直接使用this.$api.xxx调用接口。 WebPack自动加载配置API(使用require.context)
// 自动加载api
const commonApiObj {}
const finalObj {}
const modulesApi require.context(./modules, true, /\.js$/)
modulesApi.keys().forEach(key {const newKey key.replace(/(\.\/|\.js)/g, )commonApiObj[newKey] require(./modules/${newKey})
})
Object.values(commonApiObj).map(x Object.assign(finalObj, x))
// console.log(所有业务接口--, finalObj)
export default {...finalObj
}Vite自动加载配置API(使用import.meta.globEager) (注册全局api方法 )instance.config.globalProperties.$api api; // 自动导入modules
const files: any import.meta.globEager(./modules/*.ts);
let modules: any {};
// eslint-disable-next-line typescript-eslint/no-unused-vars
Object.entries(files).forEach(([k, v]) {Object.assign(modules, v);
});
export default {...modules
};// useApi
import { ComponentInternalInstance, getCurrentInstance } from vue;
export default function useApi() {const { appContext } getCurrentInstance() as ComponentInternalInstance;const proxy appContext.config.globalProperties;return {proxy};
}
//页面使用
script setup langts
import useApi from /hooks/useApi;
const { proxy } useApi();
const getData async () {const res await proxy.$api.xxx(接口名);if (res.success) {...}
}
/script2、assets 目录存放静态资源如图片、字体、公共scss等。
3、components 目录存放公共组件(store也可以如下方式自动导入)。 建议将公共组件拆分为基础组件(baseComponents)和业务组件(pageComponents)基础组件存放一些通用的组件如按钮、输入框、表格等业务组件存放与具体业务相关的组件如用户管理组件、权限管理组件等。 基础组件命名方式大驼峰如TTable;业务组件命名方式是小驼峰如importExcel。 组件文件夹下必须包含index.vue文件index.vue文件中必须包含组件的name属性name属性值必须与组件文件夹名一致。 基础组件复用性高通常情况都是全局注册 components 目录下的index.js–全局导入
import Vue from vue
// 全局自动注册baseComponents下的基础组件
const requireComponent require.context(./baseComponents, true, /\.vue$/)
// 找到组件文件夹下以.vue命名的文件如果文件名为index那么取组件中的name作为注册的组件名
requireComponent.keys().forEach(filePath {const componentConfig requireComponent(filePath)const fileName validateFileName(filePath)const componentName fileName.toLowerCase() index? capitalizeFirstLetter(componentConfig.default.name): fileNameVue.component(componentName, componentConfig.default || componentConfig)
})
//首字母大写
function capitalizeFirstLetter (str) {return str str.charAt(0).toUpperCase() str.slice(1)
}
// 对符合xx/xx.vue组件格式的组件取组件名
function validateFileName (str) {return /^\S\.vue$/.test(str) str.replace(/^\S\/(\w)\.vue$/, (rs, $1) capitalizeFirstLetter($1))
}全局注册main.js
import /components/index.js // 全局基础组件注入页面组件使用
templatedivt-table/t-table/div
/template4、utils 目录存放公共方法如全局loading,axios封装正则校验等。
axios封装request.js
import axios from axios
import { Notification, MessageBox, Message } from element-ui
import store from /store
import { getToken } from /utils/authexport default function (config) {// 创建axios实例const service axios.create({// baseURL: process.env.VUE_APP_BASE_API,baseURL: process.env.VUE_APP_BASE_API ,// 超时 btimeout: 50000})// request拦截器service.interceptors.request.use(config {getToken() (config.headers[Authorization] getToken())localStorage.getItem(store_id) (config.headers[Store-Id] localStorage.getItem(store_id))config.headers[Content-Type] config.headers[Content-Type] || application/json// 8080if (config.type file) {config.headers[content-type] application/multipart/form-data} else if (config.type form) {config.headers[Content-type] application/x-www-form-urlencoded}if (config.method.toLowerCase() get) {config.data true}return config},error {console.log(error)Promise.reject(error)})// 响应拦截器service.interceptors.response.use(res {const code res.data.codeif (code 401) {MessageBox.confirm(登录状态已过期您可以继续留在该页面或者重新登录,系统提示, {confirmButtonText: 重新登录,cancelButtonText: 取消,type: warning}).then(() {store.dispatch(FedLogOut).then(() {if (!window.__POWERED_BY_QIANKUN__) {// 为了重新实例化vue-router对象 避免buglocation.reload()} else {window.location.href /}})})} else if (code ! 200) {Notification.error({title: res.data.msg})return Promise.reject(error)} else {return res.data}},error {console.log(err error)Message({message: error.message,type: error,duration: 5 * 1000})return Promise.reject(error)})return service(config)
}
相关文章
基于ElementUi再次封装基础组件文档 基于ant-design-vue再次封装基础组件文档 vue3ts基于Element-plus再次封装基础组件文档