コードが標準化されていないため、同僚は涙を流しています。フロントエンドとして、コードをよりエレガントにするにはどうすればよいでしょうか?


序文

フロントエンド開発は、HTML、CSS、JavaScript、Vue などの複数のテクノロジーと言語が関係する分野です。フロントエンド コードをよりエレガントで読みやすくするには、いくつかのコーディング標準とベスト プラクティスに従って、コードをより明確で意味があり、理解して伝達しやすくする必要があります。この記事では、一般的なフロントエンドのコーディング標準と提案をいくつか紹介します。お役に立てば幸いです。

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

1. コードを最適化するにはどうすればよいですか?

1. if と return の組み合わせと if のネスト

原則: return ステートメントは現在の関数を終了し、現在の関数の値を返します。if+return を使用すると、コードの可読性が大幅に向上し、else と elseif を使用して if をネストすることを避けることができます。else または else- を書きすぎると、その場合、コードはインデントされます

最適化前

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',
		})
	}
},

最適化された

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 非同期と待機

原則: Promise は非同期です。async と await を使用すると、コードが同期しているように見え、.then ステップが不要になり、コールバック地獄の問題が効果的に解決されます。コールバック地獄とは何ですか? あれは

 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
         });
       });
     });
   });
 });

最適化前

 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",
     });
   });
 },

最適化された

 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" });
 },

ここで最初のステップを見てみましょう。コードは 18 行から 6 行に最適化され、コードがより読みやすく、より簡潔になりました。

3.ES6 lastIndexOf 関数

原則: Array の lastIndexOf メソッドは、条件を満たすサブ項目の添字を返します。この関数を使用すると、次の関数コードを簡素化できます。

最適化前

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);  
    })
}

最適化された

  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. ネストされたループを避ける

原則: コードを作成するときに、この種の頭痛の種のループに遭遇することを最も恐れていると考えられます。es6 を有効に活用し、ネストされたループを避けてください~~

最適化前

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
},

最適化された

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

5.uniappルーティングのカプセル化

最適化前

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

最適化された

/**
 * 封装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.複数条件の判定を解決する機能が含まれています

原則: Array.includes() は値を受け取り、配列内のいずれかの値が受信値と同じ場合は true を返し、それ以外の場合は false を返します。

最適化前

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

最適化された

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

7. 簡単なコードを一行ずつ記述可能

最適化前

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

最適化された

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

9.チェーンコール

例:

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. if の判断にはブール変換ルールを合理的に使用する

原則: js では、ブール値に変換されると、未定義、null、+0、-0、'' (空の文字列)、および NaN はすべて false になります。

バックエンドが条件を与え、戻り値が 0 または 1 であるが、null は除外しないと仮定します。

最適化前

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

最適化された

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

11. セレクターのオプションを統一してjsonコメントを書く

日常生活でコードを書くとき、フォームやフィルターに触れるときは、基本的にセレクターを使用します。他のモジュールでもこれらのオプションが使用される可能性があります。カプセル化しないと、ctrl+c、ctrl+v、そしてあなたがおかしくなります「便利」を書いているときはそう感じるかもしれませんが、後からオプションを追加する必要がある場合、注意しないと追加することを見逃してしまう可能性があります。

ほとんどの人は // の方法でコメントを書くことに慣れているかもしれません。コードにはスマートなプロンプトはありませんが、json コメント /** */ を使用するとプロンプトが表示されます。

// 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 },
]

ここに画像の説明を挿入します

12. フックを適切に使用してコード量を節約する

以前書いた記事はこちら

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

13. ページにジャンプし、ジャンプパラメータをカプセル化します。

日常生活では、非常によく似たいくつかの異なる機能を使用することがありますが、フォームの追加、フォームの変更、

もう少しページをコピーしたい人もいるかもしれませんが、機能が複雑な場合、修正には複数のページを変更する必要があり、非常に不親切ですが、同じページに記述する場合、パラメータが混在するのが怖いです。ジャンプパラメータを変更します よりセマンティックにするためにカプセル化の層を作成し、コメントを書き込みます

最適化前

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

最適化された

// 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.1000個のifを書くには? ブランチによる最適化

最適化前

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()
            }
        }

最適化された

 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. 自分で付けた名前をやめよう

最適化前

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

最適化された

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

2. ネーミング仕様

命名は頭の痛い問題です。多くの人が、あらゆる種類の奇妙な名前を思いつきます。命名は、プログラミングにおいて最も基本的かつ重要な作業です。適切な命名により、コードがより明確になり、より意味があり、理解しやすく、伝達しやすくなります。命名規則の重要なポイントをいくつか示します。

  • プロジェクト名: すべて小文字で、ダッシュで区切られます ( など) my-project
  • ディレクトリの命名: すべて小文字で、ダッシュで区切られます。複数の構造がある場合は、複数の命名方法を使用する必要があり、省略形は複数である必要はありません ( 、 などcomponents) assets
  • index.htmlファイル名: すべて小文字で、ダッシュで区切られます ( 、main.jsなど) style.css
  • 変数の名前付け: 小文字のキャメルケースの名前付け方法 ( lowerCamelCase ) を使用します。つまり、最初の単語の最初の文字は小文字で、後続の単語の最初の文字は大文字になります ( 、 などuserName) isLogin
  • 定数の名前付け: すべて大文字、アンダースコアで区切られた単語 ( MAX_LENGTH、など) API_URL
  • getData関数の名前付け: 小文字のキャメルケースの名前付け ( lowerCamelCase ) を使用し、 、など、関数または関数の役割を反映する必要がありますhandleClick
  • クラスの命名: Upper CamelCase 命名方法 (UpperCamelCase) を使用します。つまり、 、 のように、各単語の最初の文字が大文字になりUserますProduct
  • コンポーネントの命名: Upper CamelCase 命名方法 (UpperCamelCase) を使用し、 、 などの略語ではなく完全な単語を使用しHeaderますFooter
  • ts 型の名前付け: 大文字のキャメルケースの名前付け (UpperCamelCase) を使用し、インターフェイスの名前付けなどの型の接頭辞を追加しますIStateIUserInfo
  • reqGetUserInfoリクエストインターフェイスの命名: 、 など、req プレフィックス + 大文字のキャメルケース命名 (UpperCamelCase) を使用しますreqGetUserList

要約する

上記は、フロントエンド開発プロセス中にコードをよりエレガントで読みやすくする方法に関する私の要約と提案です。もちろん、これらの方法が絶対に正しいというわけではありませんし、唯一正しいというわけでもありません。プロジェクトやチームが異なれば、ニーズやスタイルも異なる場合があります。しかし、何はともあれ、エレガントで読みやすいコードを書くことを追求すべきだと思います。そうすることで、開発効率とコードの品質が向上し、コードが他の人に理解しやすく受け入れられやすくなるからです。このブログがお役に立てば幸いです

おすすめ

転載: blog.csdn.net/wz9608/article/details/128967401