1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Vue技術(shù)團(tuán)隊(duì)都在推廣的代碼規(guī)范

        共 12096字,需瀏覽 25分鐘

         ·

        2021-07-18 11:16

        點(diǎn)擊上方程序IT圈”,選擇“置頂或者星標(biāo)”

        你的關(guān)注意義重大!


        作者 / 匿名

                 閱讀本文需要 3分鐘

        規(guī)范與每個(gè)團(tuán)隊(duì)和個(gè)人都是息息相關(guān)的,因?yàn)槠溆绊懙牟恢皇谴a的維護(hù)和理解成本,嚴(yán)重的時(shí)候是會(huì)影響成員開(kāi)發(fā)的心情

        一個(gè)團(tuán)隊(duì)的編碼規(guī)范、git規(guī)范等,并沒(méi)有絕對(duì)的最優(yōu)解,心里要清楚明白沒(méi)有銀彈,規(guī)范是為了讓團(tuán)隊(duì)統(tǒng)一,提高代碼閱讀性、降低代碼維護(hù)成本等,本文是記錄一些在項(xiàng)目code review中常見(jiàn)的規(guī)范,僅供參考

        JS部分

        和渲染無(wú)關(guān)的數(shù)據(jù)

        vuedata的數(shù)據(jù)默認(rèn)便會(huì)進(jìn)行雙向數(shù)據(jù)綁定,若是將大量的和渲染無(wú)關(guān)的數(shù)據(jù)直接放置在data中,將會(huì)浪費(fèi)雙向數(shù)據(jù)綁定時(shí)所消耗的性能,將這些和渲染無(wú)關(guān)的數(shù)據(jù)進(jìn)行抽離并配合Object.freeze進(jìn)行處理

        tablecolumns數(shù)據(jù)可以單獨(dú)提取一個(gè)外部js文件作為配置文件,也可以在當(dāng)前.vue文件中定義一個(gè)常量定義columns數(shù)據(jù),因?yàn)闊o(wú)論如何都是固定且不會(huì)修改的數(shù)據(jù),應(yīng)該使用Object.freeze進(jìn)行包裹,既可以提高性能還可以將固定的數(shù)據(jù)抽離,一些下拉框前端固定的數(shù)據(jù)也建議此操作

        const columnList = Object.freeze([
          { title'姓名'key'name'align'center' },
          { title'性別'key'gender'align'center' }
        ])

        需要注意的是 Object.freeze() 凍結(jié)的是值,這時(shí)仍然可以將變量的引用替換掉,還有確保數(shù)據(jù)不會(huì)變才可以使用這個(gè)語(yǔ)法,如果要對(duì)數(shù)據(jù)進(jìn)行修改和交互,就不適合使用凍結(jié)了。

        Modal框的控制

        一個(gè)頁(yè)面種通常會(huì)存在很多個(gè)不同功能的彈框,若是每一個(gè)彈框都設(shè)置一個(gè)對(duì)應(yīng)的變量來(lái)控制其顯示,則會(huì)導(dǎo)致變量數(shù)量比較冗余和命名困難,可以使用一個(gè)變量來(lái)控制同一頁(yè)面中的所有Modal彈框的展示

        比如某個(gè)頁(yè)面中存在三個(gè)Modal彈框

        // bad
        // 每一個(gè)數(shù)據(jù)控制對(duì)應(yīng)的Modal展示與隱藏
        new Vue({
            data() {
                return {
                    modal1false,
                    modal2false,
                    modal3false,
                }
            }
        })

        // good
        // 當(dāng)modalType為對(duì)應(yīng)的值時(shí) 展示其對(duì)應(yīng)的彈框
        new Vue({
            data() {
                return {
                    modalType'' // modalType值為 modal1,modal2,modal3
                }
            }
        })

        debounce使用

        例如遠(yuǎn)程搜索時(shí)需要通過(guò)接口動(dòng)態(tài)的獲取數(shù)據(jù),若是每次用戶(hù)輸入都接口請(qǐng)求,是浪費(fèi)帶寬和性能的

        當(dāng)一個(gè)按鈕多次點(diǎn)擊時(shí)會(huì)導(dǎo)致多次觸發(fā)事件,可以結(jié)合場(chǎng)景是否立即執(zhí)行immediate

        <Select :remote-method="remoteMethod">
            <Option v-for="item in temoteList" :value="item.value" :key="item.id">{{item.label}}</Option>
        </Select>
        import {debounce} from 'lodash'

        methods:{
            remoteMethod:debounce(function (query{
                // to do ...
               // this 的指向沒(méi)有問(wèn)題
            }, 200),
        }

        圖片

        功能的開(kāi)發(fā)過(guò)程中,圖片的處理往往是比較容易被忽略的環(huán)節(jié),也會(huì)在一定程度影響開(kāi)發(fā)的效率和頁(yè)面的性能

        • 圖片壓縮問(wèn)題,除非特別要求圖片必須高質(zhì)量的顯示,否則都應(yīng)該進(jìn)行對(duì)應(yīng)的壓縮處理

        • 不同業(yè)務(wù)場(chǎng)景進(jìn)行圖片格式的選型

          • JPG 適用于呈現(xiàn)色彩豐富的圖片,JPG 圖片經(jīng)常作為大的背景圖、輪播圖或 Banner 圖出現(xiàn)等
          • Logo、顏色簡(jiǎn)單且對(duì)比強(qiáng)烈的圖片或背景、需要透明度等
          • 將常用且變動(dòng)頻率很低的小圖片進(jìn)行合并成雪碧圖,對(duì)于變動(dòng)比較頻繁和小于6KB的圖片進(jìn)行base64處理
          • 根據(jù)項(xiàng)目圖片數(shù)量和項(xiàng)目的用戶(hù)機(jī)型分布等,考慮采取webp進(jìn)行圖片的處理

        路由組件傳參

        在組件中使用 $route 會(huì)使之與其對(duì)應(yīng)路由形成高度耦合,從而使組件只能在某些特定的 URL 上使用,限制了其靈活性。

        使用 props 將組件和路由解耦:

        取代與 $route 的耦合

        const User = {
          template'<div>User {{ $route.params.id }}</div>'
        }
        const router = new VueRouter({
          routes: [
            { path'/user/:id'component: User }
          ]
        })

        通過(guò) props 解耦

        這樣你便可以在任何地方使用該組件,使得該組件更易于重用和測(cè)試。

        const User = {
          props: ['id'],
          template'<div>User {{ id }}</div>'
        }
        const router = new VueRouter({
          routes: [
            { path'/user/:id'component: User, propstrue },

            // 對(duì)于包含命名視圖的路由,你必須分別為每個(gè)命名視圖添加 `props` 選項(xiàng):
            {
              path'/user/:id',
              components: { default: User, sidebar: Sidebar },
              props: { defaulttruesidebarfalse }
            }
          ]
        })

        參考:路由組件傳參

        Vue生命周期

        在父子組件中,掌握父子組件對(duì)應(yīng)的生命周期鉤子加載順序可以讓開(kāi)發(fā)者在更合適的時(shí)候做適合的事情父組件

        <template>
        <div>
        <h3>home</h3>
        <list @hook:mounted="listMounted" />
        </div>
        </template>

        <script>
        import List from './list'

        export default {
        name: "home",
        components: {
        List
        },
        methods: {
        listMounted(){
        console.log('------------ listMounted');
        }
        },
        beforeCreate() {
        console.log("home beforeCreate");
        },
        created() {
        console.log("home created");
        },
        beforeMount() {
        console.log("home beforeMount");
        },
        mounted() {
        console.log("home mounted");
        },
        beforeDestroy() {
        console.log("home beforeDestroy");
        },
        destroyed() {
        console.log("home destroyed");
        }
        }
        </script>

        子組件

        <template>
        <div>
        list
        </div>
        </template>

        <script>
        export default {
        naem: "list",
        beforeCreate() {
        console.log("list beforeCreate");
        },
        created() {
        console.log("list created");
        },
        beforeMount() {
        console.log("list beforeMount");
        },
        mounted() {
        console.log("list mounted");
        },
        beforeDestroy() {
        console.log("list beforeDestroy");
        },
        destroyed() {
        console.log("list destroyed");
        }
        }
        </script>

        加載時(shí)父子組件的加載順序

        home beforeCreate --> home created --> home beforeMount --> list created --> list beforeMount --> list mounted

        銷(xiāo)毀時(shí)父子組件的銷(xiāo)毀順序

        home beforeDestroy --> list beforeDestroy --> list destroyed --> home destroyed

        實(shí)際開(kāi)發(fā)過(guò)程中會(huì)遇到當(dāng)子組件某個(gè)生命周期完成之后通知父組件,然后在父組件做對(duì)應(yīng)的處理

        emit up

        // 子組件在對(duì)應(yīng)的鉤子中發(fā)布事件
        created(){
        this.$emit('done')
        }

        // 父組件訂閱其方發(fā)
        <list @done="childDone">

        hook

        通過(guò)@hook監(jiān)聽(tīng)子組件的生命周期

        <list @hook:mounted="listMounted" />

        Select優(yōu)化

        下拉框遍歷時(shí),需要注意options標(biāo)簽保持同一行,若是存在換行,會(huì)導(dǎo)致選中時(shí)的值存在多余的空白

        <!-- bad -->
        <Select :remote-method="remoteMethod">
            <Option v-for="item in temoteList" :value="item.value" :key="item.id">
                {{item.label}}
            </Option>
        </Select>

        需要將Options和下拉框的值保持在同一行

        <!-- good -->
        <Select :remote-method="remoteMethod">
            <Option v-for="item in temoteList" :value="item.value" :key="item.id">{{item.label}}</Option>
        </Select>

        data數(shù)據(jù)層級(jí)

        data數(shù)據(jù)具有數(shù)據(jù)層級(jí)結(jié)構(gòu),切勿過(guò)度扁平化或者嵌套層級(jí)過(guò)深,若是過(guò)度扁平化會(huì)導(dǎo)致數(shù)據(jù)命名空間沖突,參數(shù)傳遞和處理,若是層級(jí)嵌套過(guò)深也會(huì)導(dǎo)致vue數(shù)據(jù)劫持的時(shí)候遞歸層級(jí)過(guò)深,若是嵌套層級(jí)喪心病狂那種的,小心遞歸爆棧的問(wèn)題。而且層級(jí)過(guò)深會(huì)導(dǎo)致數(shù)據(jù)操作和處理不便,獲取數(shù)據(jù)做容錯(cuò)處理也比較繁瑣。一般層級(jí)保持2-3層最好。

        若是只有一層數(shù)據(jù),過(guò)于扁平

        {
            name: '',
            age: '',
            gender: ''
        }

        導(dǎo)致處理不方便

        // 作為接口參數(shù)傳遞
        ajax({
         this.name, this.age, this.gender
        })

        // 接口獲取數(shù)據(jù),批量處理
        ajax().then(res => {
         const {name, age, gender} = res.data
            this.name = name
            this.age = age
            this.gender = gender
        })

        適當(dāng)?shù)膶蛹?jí)結(jié)構(gòu)不僅增加代碼的維護(hù)和閱讀性,還可以增加操作和處理的便捷性

        {
            person: { // 個(gè)人信息
                name: '',
                age'',
                gender''
            }
        }

        可以針對(duì)person進(jìn)行操作

        // 作為接口參數(shù)傳遞
        ajax(this.person)

        // 接口獲取數(shù)據(jù),批量處理
        ajax().then(res => {
         const {name, age, gender} = res.data
            this.$set(this, 'person', {name, age, gender})
        })

        策略模式

        策略模式的使用,避免過(guò)多的if else判斷,也可以替代簡(jiǎn)單邏輯的switch

        const formatDemandItemType = (value) => {
            switch (value) {
                case 1:
                    return '基礎(chǔ)'
                case 2:
                    return '高級(jí)'
                case 3:
                    return 'VIP'
            }
        }

        // 策略模式
        const formatDemandItemType2 = (value) => {
            const obj = {
                1'基礎(chǔ)',
                2'高級(jí)',
                3'VIP',
            }
            
            return obj[value]
        }

        解構(gòu)

        解構(gòu)賦值以及默認(rèn)值,當(dāng)解構(gòu)的數(shù)量小于多少時(shí)適合直接解構(gòu)并賦值默認(rèn)值,數(shù)據(jù)是否進(jìn)行相關(guān)的聚合處理

        const {
          naem = '',
          age = 10,
          gender = 'man'
        } = res.data

        // bad
        this.name = name
        this.age = age
        this.gender = gender

        // good
        this.person = {
          naem,
          age,
          gender
        }

        職責(zé)單一

        任何時(shí)候盡量是的一個(gè)函數(shù)就做一件事情,而不是將各種邏輯全部耦合在一起,提高單個(gè)函數(shù)的復(fù)用性和可讀性

        每個(gè)頁(yè)面都會(huì)在加載完成時(shí)進(jìn)行數(shù)據(jù)的請(qǐng)求并展示到頁(yè)面

        created() {
          this.init();
        },
        methods: {
          // 將全部的請(qǐng)求行為聚合在init函數(shù)中
          // 將每個(gè)請(qǐng)求單獨(dú)拆分
          init() {
            this.getList1()
            this.getList2()
          },
          getList1() {
            // to do ...
          },
          getList2() {
            // to do ...
          }
        }

        v-bind

        HTML部分

        html書(shū)寫(xiě)

        編寫(xiě)template模板時(shí),屬性過(guò)多時(shí),是否換行

        <template>
        <!-- 不換行 -->
        <VueButton class="icon-button go-up" icon-left="keyboard_arrow_up" v-tooltip="$t('org.vue.components.folder-explorer.toolbar.tooltips.parent-folder')" @click="openParentFolder" />

        <!-- 換行 -->
        <VueButton
        class="icon-button go-up"
        icon-left="keyboard_arrow_up"
        v-tooltip="$t('org.vue.components.folder-explorer.toolbar.tooltips.parent-folder')"
        @click="openParentFolder"
        />
        </template>

        實(shí)體使用

        html中展示一些如<,>,&等字符時(shí),使用字符實(shí)體代替

        <!-- bad -->
        <div>
          > 1 & 12
        </div>

          
        <!-- bad -->
        <div>
          &gt; 1 &amp; &lt; 12
        </div>

        CSS部分

        樣式穿透

        在開(kāi)發(fā)中修改第三方組件樣式是很常見(jiàn),但由于 scoped 屬性的樣式隔離,可能需要去除 scoped 或是另起一個(gè) style 。這些做法都會(huì)帶來(lái)副作用(組件樣式污染、不夠優(yōu)雅),樣式穿透在css預(yù)處理器中使用才生效。

        • less使用  /deep/

        <style scoped lang="less">
        .content /deep/ .el-button {
        height: 60px;
        }
        </style>
        • scss使用 ::v-deep

        <style scoped lang="scss">
        .content ::v-deep .el-button {
        height: 60px;
        }
        </style>

        • stylus使用 >>>
        <style scoped ang="stylus">
        外層 >>> .custon-components{
        height: 60px;
        }
        </style>

        空格

        適當(dāng)?shù)目崭窨梢蕴嵘a的閱讀體驗(yàn),顯得更為優(yōu)雅和美觀

        選擇器后、屬性值

        .custom-style { // 選擇器和{ 之間空格
        margin: 0; // 屬性值前
        transform: scale(1.5, 2.2); // 逗號(hào)之后增加空格
        }

        換行

        html類(lèi)型,當(dāng)某行的屬性很多,適當(dāng)?shù)膿Q行可以提高閱讀和美觀

        .custom-style{
        // 可以在一次聲明中定義一個(gè)或多個(gè)屬性
        background: background-clip
        background-color
        background-image
        background-origin
        background-position
        background-repeat
        background-size;
        }

        當(dāng)一個(gè)規(guī)則包含多個(gè)選擇器時(shí),每個(gè)選擇器聲明必須獨(dú)占一行,過(guò)長(zhǎng)導(dǎo)致需要橫向滾動(dòng)閱讀剩余的內(nèi)容,應(yīng)該盡量使得閱讀順序縱向化

        .custom .header .title,
        .other .header .title {
        color: #f0f;
        }

        嵌套層級(jí)

        瀏覽器在解析css時(shí),是按照從右到左遞歸匹配的,過(guò)深的層級(jí)嵌套不僅影響性能,而且還會(huì)導(dǎo)致樣式閱讀性和代碼維護(hù)性降低,一般層架控制在5層之內(nèi)

        雙引號(hào)

        屬性選擇器中的值必須用雙引號(hào)包圍,不允許使用單引號(hào),也不允許不使用引號(hào),html的屬性值也是推薦使用雙引號(hào),js中使用單引號(hào)

        .custom-style{
        font-family: "PingFang SC", "STHeitiSC-Light";
        }

        屬性順序

        同一 規(guī)則下的屬性在書(shū)寫(xiě)時(shí),應(yīng)按功能進(jìn)行分組。并以 Formatting Model(布局方式、位置) > Box Model(尺寸) > Typographic(文本相關(guān)) > Visual(視覺(jué)效果) 的順序書(shū)寫(xiě),以提高代碼的可讀性。

        解釋

        • Formatting Model 相關(guān)屬性包括:position / top / right / bottom / left / float / display / overflow 等
        • Box Model 相關(guān)屬性包括:border / margin / padding / width / height 等
        • Typographic 相關(guān)屬性包括:font / line-height / text-align / word-wrap 等
        • Visual 相關(guān)屬性包括:background / color / transition / list-style 等

        另外,為增加可讀性,如果包含 content 屬性,應(yīng)放在屬性的最前面。

        參考

        • 三年 Vue 前端開(kāi)發(fā)的血與淚總結(jié)
        • 編碼規(guī)范作用
        —————END—————

        推薦閱讀:


        10 個(gè)CSS技巧前端開(kāi)發(fā)必須要知道
        做一些動(dòng)圖,學(xué)習(xí)一下 EventLoop
        萬(wàn)字總結(jié),體系化帶你全面認(rèn)識(shí) Nginx !
        Vue超好玩的新特性:在CSS中使用JS變量

        最近面試BAT,整理一份面試資料前端面試BAT通關(guān)手冊(cè),覆蓋了前端技術(shù)、CSS、JavaScript、框架、 數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。
        獲取方式:關(guān)注公眾號(hào)并回復(fù) 前端 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。
        明天見(jiàn)(??ω??)??
        瀏覽 29
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            我撕校花衣服揉她胸好爽 | 91成人在线免费电影 | 久久xx | 自拍青青在线视频 | 精品 国产 无码 怀孕 | 日韩精品在线播放 | 国产jy 视频 | 韩国三级片在线视频 | 精品国产网| 女18一成人免费A级毛片 |