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>

        一個優(yōu)秀的Vue團隊代碼規(guī)范是什么樣子的?

        共 6586字,需瀏覽 14分鐘

         ·

        2020-09-15 19:15

        作者:前端宇宙 公號

        規(guī)范與每個團隊和個人都是息息相關(guān)的,因為其影響的不只是只是代碼的維護和理解成本,嚴重的時候是會影響成員開發(fā)的心情


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

        JS部分

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

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

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

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

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

        Modal框的控制

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

        比如某個頁面中存在三個Modal彈框

        //?bad
        //?每一個數(shù)據(jù)控制對應的Modal展示與隱藏
        new?Vue({
        ????data()?{
        ????????return?{
        ????????????modal1:?false,
        ????????????modal2:?false,
        ????????????modal3:?false,
        ????????}
        ????}
        })

        //?good
        //?當modalType為對應的值時?展示其對應的彈框
        new?Vue({
        ????data()?{
        ????????return?{
        ????????????modalType:?''?//?modalType值為?modal1,modal2,modal3
        ????????}
        ????}
        })

        debounce使用

        例如遠程搜索時需要通過接口動態(tài)的獲取數(shù)據(jù),若是每次用戶輸入都接口請求,是浪費帶寬和性能的

        當一個按鈕多次點擊時會導致多次觸發(fā)事件,可以結(jié)合場景是否立即執(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?的指向沒有問題
        ????},?200),
        }

        圖片

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

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

        • 不同業(yè)務場景進行圖片格式的選型

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

        路由組件傳參

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

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

        取代與?$route?的耦合

        const?User?=?{
        ??template:?'
        User?{{?$route.params.id?}}
        '

        }
        const?router?=?new?VueRouter({
        ??routes:?[
        ????{?path:?'/user/:id',?component:?User?}
        ??]
        })

        通過?props?解耦

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

        const?User?=?{
        ??props:?['id'],
        ??template:?'
        User?{{?id?}}
        '

        }
        const?router?=?new?VueRouter({
        ??routes:?[
        ????{?path:?'/user/:id',?component:?User,?props:?true?},

        ????//?對于包含命名視圖的路由,你必須分別為每個命名視圖添加?`props`?選項:
        ????{
        ??????path:?'/user/:id',
        ??????components:?{?default:?User,?sidebar:?Sidebar?},
        ??????props:?{?default:?true,?sidebar:?false?}
        ????}
        ??]
        })

        參考:路由組件傳參

        Vue生命周期

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

        <template>  <div>    <h3>homeh3>    <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 { name: "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>

        加載時父子組件的加載順序

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

        銷毀時父子組件的銷毀順序

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

        實際開發(fā)過程中會遇到當子組件某個生命周期完成之后通知父組件,然后在父組件做對應的處理

        emit up

        // 子組件在對應的鉤子中發(fā)布事件created(){  this.$emit('done')}
        // 父組件訂閱其方發(fā)@done="childDone">
        hook

        通過@hook監(jiān)聽子組件的生命周期

        :mounted="listMounted" />

        Select優(yōu)化

        下拉框遍歷時,需要注意options標簽保持同一行,若是存在換行,會導致選中時的值存在多余的空白


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

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


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

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

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

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

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

        導致處理不方便

        //?作為接口參數(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
        })

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

        {
        ????person:?{?//?個人信息
        ????????name:?'',
        ????????age:?'',
        ????????gender:?''
        ????}
        }

        可以針對person進行操作

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

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

        策略模式

        策略模式的使用,避免過多的if else判斷,也可以替代簡單邏輯的switch

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

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

        解構(gòu)

        解構(gòu)賦值以及默認值,當解構(gòu)的數(shù)量小于多少時適合直接解構(gòu)并賦值默認值,數(shù)據(jù)是否進行相關(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
        }

        職責單一

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

        每個頁面都會在加載完成時進行數(shù)據(jù)的請求并展示到頁面

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

        v-bind

        HTML部分

        html書寫

        編寫template模板時,屬性過多時,是否換行

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

        實體使用

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


        <div>
        ??>?1?&?12
        div>
        ??

        <div>
        ??>?1?&?div>

        CSS部分

        樣式穿透

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

        • 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>

        空格

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

        選擇器后、屬性值

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

        換行

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

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

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

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

        嵌套層級

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

        雙引號

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

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

        屬性順序

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

        解釋

        • 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 屬性,應放在屬性的最前面。


        專注分享當下最實用的前端技術(shù)。關(guān)注前端達人,與達人一起學習進步!

        長按關(guān)注"前端達人"

        瀏覽 26
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

        分享
        舉報
        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>
            欧美淫色图| www天天操 | 凸凹日日摸日日碰夜夜爽 | 曰韩成人无码一区二区三区四区 | 公交车被弄到高潮嗯啊视频 | 欧美三级免费看 | 韩漫歪歪 | 免费一级婬片AA片观看 | 2018天天日夜夜操 | 欧美性爱天天看 |