The code is not standardized, and my colleagues are in tears. As a front-end, how can I make my code more elegant?


Preface

Front-end development is a field involving multiple technologies and languages, such as HTML, CSS, JavaScript, Vue, etc. In order to make front-end code more elegant and readable, we need to follow some coding standards and best practices to make our code clearer, more meaningful, and easier to understand and communicate. This article will introduce some common front-end coding standards and suggestions, I hope it will be helpful to you.

提示:以下是本篇文章正文内容,下面案例可供参考,如有不同意见可以提出一起探讨

1. How to optimize code?

1. The combined use of if and return and if nesting

Principle: The return statement will terminate the current function and return the value of the current function. Using if+return can greatly improve the readability of the code and avoid using else and elseif to nest if. If you write too much else or else-if, the code will be indented. Ugly and daunting

Before optimization

navurl7() {
    
    
	if (this.hasLogin) {
    
    
		this.rolesData().then((res) => {
    
    
			if (res.data == 3) {
    
    
				uni.navigateTo({
    
    
					url: '/pages/franchisee/index',
				})
			}else {
    
    
				uni.navigateTo({
    
    
					url: '/pages/attractInvestment/index',
				})
			}
		})
	} else {
    
    
		uni.navigateTo({
    
    
			url: '/pages/login/index',
		})
	}
},

Optimized

navurl7() {
    
    
  if (!this.hasLogin) return uni.navigateTo({
    
     url: "/pages/login/index" });
  //符合上述条件,此处代码不会执行
  this.rolesData().then((res) => {
    
    
    if (res.data !== 3) return uni.navigateTo({
    
     url: "/pages/attractInvestment/index" });
    uni.navigateTo({
    
    
      url: "/pages/franchisee/index",
    });
  });
},

2.ES6 async and await

Principle: promise is asynchronous. Using async and await can make the code look synchronous, eliminating the .then step and effectively solving the problem of callback hell. What? What is callback hell, you ask? that is

 this.xxxxx1().then((res1) => {
    
    
   // do something
   this.xxxxx2().then((res2) => {
    
    
     // do something
     this.xxxxx3().then((res3) => {
    
    
       // do something
       this.xxxxx4().then((res4) => {
    
    
         // do something
         this.xxxxx5().then((res5) => {
    
    
           // do something
         });
       });
     });
   });
 });

Before optimization

 navurl7() {
    
    
   if (!this.hasLogin) return uni.navigateTo({
    
     url: "/pages/login/index" });
   this.rolesData().then((res) => {
    
    
     if (res.data !== 3) return uni.navigateTo({
    
     url: "/pages/attractInvestment/index" });
     uni.navigateTo({
    
    
       url: "/pages/franchisee/index",
     });
   });
 },

Optimized

 async navurl7() {
    
    
   if (!this.hasLogin) return uni.navigateTo({
    
     url: "/pages/login/index" });
   let result = await this.rolesData();
   if (result.data !== 3) return uni.navigateTo({
    
     url: "/pages/attractInvestment/index" });
   uni.navigateTo({
    
     url: "/pages/franchisee/index" });
 },

At this time, let’s take a look at the first step. The code has been optimized from 18 lines to 6 lines. The code is easier to read and more concise.

3.ES6 lastIndexOf function

Principle: The lastIndexOf method in Array returns the subscript of the sub-item that meets the conditions. Using this function can simplify the following function code

Before optimization

hotliveClick(id, pic) {
    
    
	plus.share.getServices(function(res){
    
    
		console.log(res)
	    var sweixin = null;  
	    for(var i = 0; i < res.length; i++){
    
      
			var t = res[i];  
			if(t.id == 'weixin'){
    
      
				sweixin = t;  
			}  
		}  
		if(sweixin){
    
      
			sweixin.launchMiniProgram({
    
      
				id: 'gh_7b33e2a22ed9', //这里写你的小程序原始id(以gh开头)
				type: 0, //这里是不同的环境(默认0)
				path:'/page/me/live/live_find/find?id=' + id + '&pic=' + pic //这里是指定页的路径,如需传参直接字符串拼接(首页可以省略)
			});  
        }  
    },function(err){
    
      
        console.log(err);  
    })
}

Optimized

  hotliveClick(id, pic) {
    
    
    plus.share.getServices((res) => {
    
    
    const lastIndex=res.lastIndexOf((v) => v.id === "weixin")
      if (lastIndex===-1) return;
      res[lastIndex].launchMiniProgram({
    
    
        id: "gh_7b33e2a22ed9",
        type: 0,
        path: "/page/me/live/live_find/find?id=" + id + "&pic=" + pic,
      });
    });
  },

4. Avoid nested loops

Principle: It is estimated that when writing code, you are most afraid of encountering this kind of headache loop. Make good use of es6 and avoid nested loops~~

Before optimization

getFlagArrs(m, n) {
    
    
	var flagArrs = [],
		flagArr = [],
		isEnd = false
	for (var i = 0; i < m; i++) {
    
    
		flagArr[i] = i < n ? 1 : 0
	}
	flagArrs.push(flagArr.concat())
	// 当n不等于0并且m大于n的时候进入
	if (n && m > n) {
    
    
		while (!isEnd) {
    
    
			var leftCnt = 0
			for (var i = 0; i < m - 1; i++) {
    
    
				if (flagArr[i] == 1 && flagArr[i + 1] == 0) {
    
    
					for (var j = 0; j < i; j++) {
    
    
						flagArr[j] = j < leftCnt ? 1 : 0
					}
					flagArr[i] = 0
					flagArr[i + 1] = 1
					var aTmp = flagArr.concat()
					flagArrs.push(aTmp)
					if (aTmp.slice(-n).join('').indexOf('0') == -1) {
    
    
						isEnd = true
					}
					break
				}
				flagArr[i] == 1 && leftCnt++
			}
		}
	}
	return flagArrs
},

Optimized

鄙人不才,光看代码没看出想表达什么,只要不出问题,这个代码我是不会动的,如果要动,大概率重构

5.uniapp routing encapsulation

Before optimization

	uni.navigateTo({
    
    
		url: '/pages/order/placeOrderPt?grouponGoodsId=' + that.grouponGoodsId + '&number=' + that.berbox + '&productId='+ that.sku
	})

Optimized

/**
 * 封装uniapp路由hook
 * @returns 路由跳转方法
 */
export const useRouter = () => {
    
    
    /**
     * 把对象转成query格式:aaa=bbb&ccc=ddd
     * @param obj 
     * @returns 
     */
    function mapObjectToQueryString(obj: Object) {
    
    
        if (!obj) return ""
        var str = [];
        for (let p in obj) {
    
    
            if (obj.hasOwnProperty(p)) {
    
    
                str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
            }
        }
        return "&" + str.join("&");
    }
    /**
     * 
     * @param url 跳转地址
     * @param params 跳转参数
     */
    const push = <T>(url: string, params?: T) => {
    
    
        let completeUrl = params ? `${
      
      url}?${
      
      mapObjectToQueryString(params ?? {
      
      })}` : url
        uni.navigateTo({
    
    
            url: completeUrl,
        })
    }
    /**
     * 
     * @param params 跳转参数
     */
    const back = () => {
    
    
        uni.navigateBack({
    
    
            delta: 1
        })
    }
    /**
      * 跳转至某页面,关闭其他所有页面并不能返回
      * @param url 跳转地址
      * @param params 跳转参数
      */
    const replace = <T>(url: string, params?: T) => {
    
    
        let completeUrl = params ? `${
      
      url}?${
      
      mapObjectToQueryString(params ?? {
      
      })}` : url
        uni.redirectTo({
    
    
            url: completeUrl,
        })
    }
    /**
      * 跳转至某页面,关闭其他所有页面并不能返回
      * @param url 跳转地址
      * @param params 跳转参数
      */
    const switchTab = <T>(url: string, params?: T) => {
    
    
        let completeUrl = params ? `${
      
      url}?${
      
      mapObjectToQueryString(params ?? {
      
      })}` : url
        uni.switchTab({
    
    
            url: completeUrl,
        })
    }
    return {
    
     push, replace, switchTab, back }
}
	const router=useRouter()
    router.push("xxxx/xxxx/xxxx",{
    
    id:xxx,name:xxxx,age:xxx,others:xxx})

6.includes solves multi-condition judgments

Principle: Array.includes() receives a value. If any value in the array is the same as the incoming value, it returns true, otherwise it returns false.

Before optimization

 if (props.orginItem.historyType === 2 || props.orginItem.historyType === 3 || props.orginItem.historyType === 5) {
    
    
     // do something
 }

Optimized

   if ([2,3,5].includes(props.orginItem.historyType)) {
    
    
                // do something
       }

7. Simple code can be written line by line

Before optimization

const testArr = someArr.map(item => {
    
    
    return {
    
    
        ...item,
        someKey: item.someKey1 + item.someKey2
    }
})

Optimized

const testArr = someArr.map(item => ({
    
     ...item, someKey: item.someKey1 + item.someKey2 }))

9.Chain calls

example:

const arr = state.totalFlatTree
    .map(v => ({
    
     ...v, checked: !!props.modelValue.includes(v.nodeId) }))
    .filter(v => v.nodeType === 1)
    .sort((a, b) => a.nodeId - b.nodeId)
    .reduce((pre, cur) => `${
      
      pre}${
      
      cur.nodeName}`, "")

10. Reasonably use Boolean conversion rules to make if judgments

Principle: In js, undefined, null, +0, -0, '' (empty string), and NaN are all false when converted to Boolean values.

Assume that the backend gives a condition and the return value is 0 or 1 but does not exclude null.

Before optimization

if(xxx===0){
    
    
    // do something
    // xxx=null时不执行
}
if(xxx===1){
    
    
    // do something
    // xxx=null时不执行
}

Optimized

if(!xxx){
    
    
    // do something
    // xxx=null或者xxx=0时执行
}
if(xxx){
    
    
    // do something
    // xxx=null时不执行
}

11. Unify the options of the selector and write json comments

When writing code in daily life and coming into contact with forms or filters, selectors are basically used. Other modules may also use these options. If you don’t encapsulate them, you will go crazy ctrl+c, ctrl+v, and you may feel that when writing Convenient, but if you need to add some options later, you may miss them if you are not careful.

Most people may be used to writing comments in the // way. There is no smart prompt in the code, but if you use json comments /** */, there will be prompts.

example

// xxxx.ts
/**
 * 事件等级
 */
export const eventLevelOptions = [
    {
    
     label: "全部", value: -1 },
    {
    
     label: "一级事件", value: 1 },
    {
    
     label: "二级事件", value: 2 },
    {
    
     label: "三级事件", value: 3 },
    {
    
     label: "四级事件", value: 4 },
];
/**
 * 初信初访
 */
export const eventFirstTypeOptions = [
    {
    
     label: "初信初访", value: 1 },
    {
    
     label: "重复访", value: 2 },
]

Insert image description here

12. Make reasonable use of hooks to save code volume

Here is an article I wrote before

https://blog.csdn.net/wz9608/article/details/128189567?spm=1001.2014.3001.5502

13. Jump to the page and encapsulate the jump parameters

In daily life, we may use several different functions, which are very similar. We choose to use the same page, such as: adding a form, modifying a form,

Some people may like to copy a few more pages, but when the function is complex, modifications require changing multiple pages, which is very unfriendly. But when writing on the same page, the parameters are afraid of getting mixed up. At this time, we change the jump parameters Make a layer of encapsulation to make it more semantic and write comments

Before optimization

// 跳转之前一个页面
router.push({
    
    path:"xxxx",query:{
    
    type:1}})
// 页面中
if(route.query.type==="1"){
    
    
   //do something
}
if(route.query.type==="2"){
    
    
   //do something
}

Optimized

// xxx.ts
// 这里用的ts枚举类型,js用对象代替即可
/**
 * 事件选择页面模式
 */
export enum TEventSelectMode {
    
    
    /** 重复访 */
    CREATE_AGAIN = "crate_again",
    /** 返回表单 */
    BACK_FORM = "back_form",
    /** 直接关联事件 */
    ABOUT_EVENT = "about_event",
    /** 四级创建 */
    FOUR_CREATE = "four_create"
}
// 跳转之前一个页面
router.push({
    
    path:"xxxx",query:{
    
    mode:TEventSelectMode.CREATE_AGAIN}})
// 页面中
if(route.query.mode===TEventSelectMode.CREATE_AGAIN){
    
    
   //do something
}
if(route.query.mode===TEventSelectMode.BACK_FORM){
    
    
   //do something
}

14.How to write 1000 ifs? Optimize with branches

Before optimization

function dosomethingByName(name: string) {
    
    
            if (name === "xxx") {
    
    
                this.xxx()
            } else if (name === "xxx1") {
    
    
                this.xxx1()
            } else if (name === "xxx2") {
    
    
                this.xxx2()
            } else if (name === "xxx3") {
    
    
                this.xxx3()
            } else if (name === "xxx4") {
    
    
                this.xxx4()
            } else if (name === "xxx5") {
    
    
                this.xxx5()
            } else {
    
    
                this.xxx6()
            }
        }

Optimized

 function dosomethingByName(name: string) {
    
    
     const objcet = {
    
    
         "xxx": () => this.xxx(),
         "xxx1": () => this.xxx1(),
         "xxx2": () => this.xxx2(),
         "xxx3": () => this.xxx3(),
         "xxx4": () => this.xxx4(),
         "xxx5": () => this.xxx5(),
     }
     // || this.xxx6() 相当于else
     objcet[name]() || this.xxx6()
 }

15. Put an end to self-added names

Before optimization

// 某同事在data中定义了这么一串东西
      detailVisible1: false,
      detailVisible2: false,
      detailVisible3: false,
      detailVisible4: false,
      detailVisible5: false,
      detailVisible6: false,
      detailVisible7: false,
      detailVisible8: false,

Optimized

// 建议打上json注解
       /** 预警详情 */
    wraningVisibel: boolean;
    /** 调处详情 */
    mediationDetailVisibel: boolean;
    /** 上报详情 */
    escalationDetailVisibel: boolean;
    /** 研判驳回 */
    judgmentRejectVisibel: boolean

2. Naming specifications

Naming is a headache. Many people come up with all kinds of strange names. Naming is the most basic and important task in programming. A good naming can make the code clearer, more meaningful, and easier to understand and communicate. . Here are some key points of naming conventions:

  • Project naming: all in lowercase, separated by dashes, such as my-project.
  • Directory naming: all in lowercase, separated by dashes. When there is a plural structure, the plural naming method should be used, and the abbreviation does not need to be plural, such as components, assets.
  • File naming: all in lowercase, separated by dashes, such as index.html, main.js, style.css.
  • Variable naming: use lowercase camel case naming method (lowerCamelCase), that is, the first letter of the first word is lowercase, and the first letter of the subsequent words is capitalized, such as userName, isLogin.
  • Constant naming: all capital letters, words separated by underscores, such as MAX_LENGTH, API_URL.
  • Function naming: Use lowercase camel case naming (lowerCamelCase), and it must reflect the function or role of the function, such as getData, handleClick.
  • Class naming: Use Upper CamelCase naming method (UpperCamelCase), that is, the first letter of each word is capitalized, such as User, Product.
  • Component naming: Use Upper CamelCase naming method (UpperCamelCase), and use complete words instead of abbreviations, such as Header, Footer.
  • ts type naming: use upper camel case naming (UpperCamelCase), and add a type prefix, such as interface naming IState,IUserInfo
  • Request interface naming: use req prefix + uppercase camel case naming (UpperCamelCase), such as reqGetUserInfo, reqGetUserList.

Summarize

The above is my summary and suggestions on how to make the code more elegant and easier to read during the front-end development process. Of course, these methods are not set in stone, nor are they the only correct ones. Different projects and teams may have different needs and styles. But I think that no matter what, we should pursue writing elegant and readable code, because this can improve our development efficiency and code quality, and also make our code easier to understand and accept by others. Hope this blog is helpful to you

Guess you like

Origin blog.csdn.net/wz9608/article/details/128967401