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>

        總結(jié)Vue 團隊開發(fā)的一些基本配置封裝分享

        共 12870字,需瀏覽 26分鐘

         ·

        2021-01-20 11:16

        • 本文已獲得原作者的獨家授權(quán),有想轉(zhuǎn)載的朋友們可以在后臺聯(lián)系我申請開白哦!
        • PS:歡迎掘友們向我投稿哦,被采用的文章還可以送你掘金精美周邊!

        本文已授權(quán)掘金開發(fā)者社區(qū)公眾號獨家使用,包括但不限于編輯、標注原創(chuàng)等權(quán)益

        簡介

        本篇文章主要帶來的是 vue 基礎(chǔ)架構(gòu)?篇,大家都知道, Vue3.0?后 Vue2.0?會有一個終結(jié)版出來,也就說明 Vue?迎來了新時代,但是并不是所有項目都能夠一起邁向新時代的輪船。本文主要是承接上篇優(yōu)化的技巧文章做一個續(xù)篇吧,這個續(xù)篇主要是針對團隊開發(fā)相關(guān)的東西,相關(guān)插件和庫只是微微帶過,如果本文能夠推動你們的生產(chǎn)線,就點個贊吧。

        配置相關(guān)類的可以去搜索對應的分享貼,或者看我之前的文章,本文內(nèi)容較為貼合團隊開發(fā),非工具鏈分享文,大部分都能引發(fā)一些技術(shù)層面的思考。

        前言

        在很多時候,對于 vue?項目來說,很多剛?cè)腴T,或者是受業(yè)務妥協(xié)的朋友大都是從百度 CV?一套看得過去的架子,如常見的 D2Admin?, vue-element-admin?,進行一個二次迭代的開發(fā),其項目本身非常的優(yōu)質(zhì),而在其 template?中去進行一個更改能夠使得項目在一開始有一個很好的基礎(chǔ)環(huán)境,但是如果沒有花時間去琢磨透其中三分明細。在后續(xù)排雷來說,無疑是非常的困難的,因此大部分前端團隊都會重構(gòu)出自己的一套基礎(chǔ)腳手架封裝,有通過 webpack進行處理的,也有基于 VueCli?打造的,最終都是自身團隊的財產(chǎn),從技術(shù)分享都細分實踐都能給團隊的小伙伴或多或少帶來一些開發(fā)上面的便利。對后續(xù)團隊人員的變動也能快速的投入生產(chǎn)當中。

        做了什么?

        • 基本 HTTP 請求封裝
        • 約定式 HTTP 請求管理
        • Mmixin 數(shù)據(jù)管理
        • jsdoc 項目文檔
        • log 異常處理
        • 組件和頁面管理
        • 常用的指令
        • 使用 sass 還是 scss?
        • @mixin 和 %placeholder
        • eslint

        基本 HTTP 請求做了什么?

        錯誤處理

        在這里選用的是現(xiàn)如今兼容性比較好的 axios?,可以說是比較好的一個請求庫,相比于 fetch?來說,兩者各有優(yōu)勢,(我已經(jīng)開始使用 fetch?)。這一部分其實無非就是封裝一些公共調(diào)用時需要處理的行為,如:token?, 請求攔截?, 響應攔截?, 錯誤碼約定?, 異常上報?, 中間件?等一系列基礎(chǔ)的行為模式。

        如下實例,當 HTTP?請求出現(xiàn)錯誤的時候,首先通過 getEnv?獲取當前的開發(fā)環(huán)境,如果是 dev(開發(fā)環(huán)境下)?只做一個簡單的 console.log,非開發(fā)環(huán)境下,則是上報進行異常監(jiān)聽,對于前后端來說都

        function?handleError?(?error,?msg)?{
        ??if?(getEnv()?===?'dev')?{
        ????tools.log.danger('>>>>>>?HTTP?Error?>>>>>>')
        ????console.log(error,?msg)
        ??}?else?{
        ????Store.dispatch('logs/push',?{
        ??????message:?msg,
        ??????type:?'danger'
        ????})
        ??}
        }

        RESTFul

        相對于一些攔截器來說,都非常的簡單,需要注意的無非就是根據(jù)團隊的一些規(guī)范制定一些規(guī)則,如常見的 code?碼等方法,大部分情況下,如無意外,99% 的接口都是請求成功的,但因為特殊性,內(nèi)部會有一個 code?的狀態(tài)來定義正反向。同樣的,在操作接口時,一些狀態(tài)也是需要和接口的請求方式同步,參考如下:

        • GET: 200 OK
        • POST: 201 Created
        • PUT: 200 OK
        • DELETE: 204 No Content

        現(xiàn)如今大部分的接口的規(guī)范都使用 RESTful?,如果不知道 RESTful?是什么,可以看看 @阮一峰?的文章來初步了解。RESTful API 最佳實踐 @阮一峰的網(wǎng)絡日志

        狀態(tài)碼機制

        同樣的 code?中我們也自定義日常開發(fā)中的一些狀態(tài)碼,當我們需要用到 第三方API?的時候,前后端都需要快速的定位是自身服務的問題,還是其他服務(例如中臺)的問題,因此對接服務我們都自定義了一些 code?來陳述這一類錯誤的處理??梢詤⒖既缦?,這些其實都是創(chuàng)建在一個對象當中的: 自定義 code

        code狀態(tài)描述
        30000invalid credential不合法的憑證
        30001invalid connect_type不合法的 connect_type
        30001invalid group_conf_id不合法的 group_conf_id
        ..................

        當我們細化一些異常時,這時候是可以劃分的非常細致的,這里給出微信的一些參考:

        40039invalid url size不合法的 url 長度
        40048invalid url domain不合法的 url 域名
        40054invalid sub button url domain不合法的子菜單按鈕 url 域名
        40055invalid button url domain不合法的菜單按鈕 url 域名
        40066invalid url不合法的 url
        41001access_token missing缺失 access_token 參數(shù)
        41002appid missing缺失 appid 參數(shù)
        41003refresh_token missing缺失 refresh_token 參數(shù)
        41004appsecret missing缺失 secret 參數(shù)
        41005media data missing缺失二進制媒體文件
        41006media_id missing缺失 media_id 參數(shù)
        41007sub_menu data missing缺失子菜單數(shù)據(jù)
        41008missing code缺失 code 參數(shù)
        41009missing openid缺失 openid 參數(shù)
        41010missing url缺失 url 參數(shù)
        42001access_token expiredaccess_token 超時
        42002refresh_token expiredrefresh_token 超時
        function?createHttpService?(settings)?{
        ??const?service?=?Axios.create(settings)
        ??service.interceptors.request.use(
        ????config?=>?{
        ??????
        ??????const?token?=?localStorage.getItem('access_token')
        ??????config.headers.token?=?token
        ??????return?config
        ????},
        ????error?=>?{
        ??????return?Promise.reject(error)
        ????}
        ??)
        ??
        ??service.interceptors.response.use(
        ????response?=>?{
        ??????console.log(response)
        ??????const?{?code,?message,?data?}?=?response.data
        ??????
        ??????if?(code?>=?30000)?{
        ????????console.log('>>>?自定義錯誤信息,全局提示處理',?message)
        ????????return?data
        ??????}
        ??????
        ??????if?(code?>=?200?&&?code?????????return?data
        ??????}

        ??????
        ??????if?(code?>=?300?&&?code?????????return?Promise.reject(response.data)
        ??????}
        ????},
        ????error?=>?{
        ??????const?{?status?=?404?}?=?error?.response
        ??????if?(Object.prototype.hasOwnProperty.call(codeMessage,?status))?{
        ????????handleError(error,?codeMessage[status])
        ??????}
        ??????throw?error
        ????}
        ??)
        ??return?service
        }

        const?http?=?createHttpService({
        ??withCredentials,
        ??timeout,
        ??baseURL
        })

        約定式 http 請求

        看過我上幾篇文章的文章大家都大致清楚,約定式請求可以很好的簡化請求封裝的復雜度,同樣的當你公司存在小白或者是實習生的話,對于請求的拆封是沒有考慮的,當你交付一個任務,完成并不是等于較為好的完成。

        約定式除了減少新手開發(fā)者在團隊中不穩(wěn)定的代碼因素的同時,也減少了開發(fā)時一個個的寫 AxiosPromise?函數(shù)的重復行為。下面是一個基本的接口約定,在 login-api.js?下寫的文件,都將被映射成為 請求函數(shù)

        export?default?{
        ??getPerson:?'GET?/person',
        ??setPerson:?'POST?/person',
        ??updatePerson:?'PUT?/person/:id',
        ??deletePerson:?'DELETE?/person/:id'
        }

        log.js?打印的結(jié)果,團隊開發(fā)人員不需要關(guān)注函數(shù)本身,只需要關(guān)注調(diào)用。同時, 開發(fā)環(huán)境下?所有的接口信息都會通過 console.table?輸出到控制臺,在沒有很好的類型推導的情況下,依舊可以快速的調(diào)用對應接口來獲取后端數(shù)據(jù)。

        本身 api 函數(shù)拆分出來,其實都是一個重復的工作,對開發(fā)者成長是毫無意義的。

        不同的調(diào)用方式

        為了統(tǒng)一的調(diào)用,也適當?shù)慕o出了兩種使用方式,大多數(shù)場景下使用都是通用的,第一種方式較為的保守,其本質(zhì)上是交由成員來處理任務,實例:


        上述實例非常的簡單,相信有一點基礎(chǔ)的同學都可以看得出來,第一種方法非常的普遍,適用于大多數(shù)人群,但是弊端也很明顯,如果每一個接口都需要做一次 then & catch & finally?的話無疑是一個災難,因此第二種方法誕生了,對于新手來說,更加的友好。如下實例:


        在原先 api 的基礎(chǔ)上, useServices?為 Promise?的行為包裹了一層中間件,當你決定使用非常態(tài)請求時,這個 promise中間件 行為會被觸發(fā)。且將 Promise 后的結(jié)果形態(tài)抽象成為了一個數(shù)組返回出來,那么在邏輯塊中,我們只需要簡單的通過 async & await?對結(jié)果中的數(shù)據(jù)進行處理,而不必關(guān)注無意義的 try catch?和 then catch?。

        兼容兩種方式的原因是不同開發(fā)者不同習慣問題,有些時候開發(fā)者認為,錯誤的處理還是交由處理人去解決,從而達到錯誤解決目的。

        Mixin 數(shù)據(jù)管理 (model)

        有了約定式的請求,很統(tǒng)一的解決我們請求的問題,但隨之而來的就是異步數(shù)據(jù)的管理問題,很長一段時間中,Vue 開發(fā)者都習慣性的將接口請求,數(shù)據(jù)邏輯處理放在 vue 文件中,比如最常見的 分頁表格數(shù)據(jù)?, 基礎(chǔ)表單顯示,每一個頁面中都聲明了非常多的 total?, pageSize?, currentPage?,tableData?等字段,并且樂此不疲的反復 CV,結(jié)束忙碌的一天后美滋滋覺得今天又完成了 10 多個頁面。其實細心的同學也發(fā)現(xiàn)了,不管你 CV 多少次代碼,對自身的提升是有限度的,無非就是孰能生巧,復制粘貼的速度更加快了,就好比你寫了 4000 次 hello?不代表你有了 4000 個詞匯一般。

        因此就產(chǎn)生了封裝自己的表格組件,只需要傳遞很小一部分參數(shù)進去(如 HTTP 請求方法),就可以達到渲染表格的實現(xiàn)。同樣的,也有小伙伴們封裝了 Global Mixin?來解決這部分的任務。同樣的,為了很好的管理數(shù)據(jù)層,我也在嘗試不同的數(shù)據(jù)管理,隨著業(yè)務邏輯增大,大部分的頁面的異步數(shù)據(jù)都難以管理,或多或少會和頁面的邏輯數(shù)據(jù)混淆,過一段時間后,需要將 $data?中的數(shù)據(jù)解構(gòu)重新梳理,才能泡通邏輯。

        因此,在嘗試不同的解決方案后, mixin?成了首當其沖的方案,它并不像 vuex?一般會在全局生效,而只對混入的頁面生效,所以在簡單的嘗試后,對 mixin 進行了包裝,抽象成為了一個 model?層,這個 model?層的作用主要是處理菜單級頁面的異步數(shù)據(jù)的流向打造的,視圖頁面數(shù)據(jù)在 .vue?中聲明, 后端數(shù)據(jù)?在 model.js?中。

        一個基本的 model.js 它看起來是這樣的

        export?default?{
        ??namespace:?'Home',
        ??state:?{
        ????move:?{},
        ????a:?1,
        ????b:?2
        ??},
        ??actions:?{
        ????
        ????async?setUser?(state,?{?payload,?set?})?{
        ??????const?data?=?await?test()
        ??????await?set(state,?'move',?data)
        ??????return?state.move
        ????}
        ??}
        }

        const?test?=?()?=>?{
        ??return?new?Promise(resolve?=>?{
        ????setTimeout(()?=>?{
        ??????resolve({
        ????????user:?'wangly',
        ????????age:?21
        ??????})
        ????},?2000)
        ??})
        }

        那么在頁面中,聲明的組件都會被傳入到 useModels?中進行混入,混入后的 Mixin?命名格式已經(jīng)比較復雜了,這個時候來使用的就不是當前的 this.xxx?,而是統(tǒng)一執(zhí)行 this.useDispatch?進行處理,并沒有直接去觸發(fā) model methods?,同樣的對所有的 model?狀態(tài)都在發(fā)生改變,內(nèi)部會有不同的 loading。

        一個簡單的實例

        通過一個簡單的實例來模擬一次服務端數(shù)據(jù)加載,從無到有的過程,純 model.js?控制數(shù)據(jù)和狀態(tài) 通過下面 test 模擬一個數(shù)據(jù)接口,在 getDesserts?進行獲取,為了保證閱讀質(zhì)量,模擬的數(shù)據(jù)就截斷了,可以參考 vuetifyUI Table Demo 數(shù)據(jù)。

        export?default?{
        ??namespace:?'Admin',
        ??state:?{
        ????mockTabData:?[],
        ????headers:?[
        ??????{?text:?'Dessert?(100g?serving)',?value:?'name'?},
        ??????{?text:?'Calories',?value:?'calories'?},
        ??????{?text:?'Fat?(g)',?value:?'fat'?},
        ??????{?text:?'Carbs?(g)',?value:?'carbs'?},
        ??????{?text:?'Protein?(g)',?value:?'protein'?},
        ??????{?text:?'Iron?(%)',?value:?'iron'?}
        ????]
        ??},
        ??actions:?{
        ????
        ????async?getDesserts?(state,?{?payload,?set?})?{
        ??????const?data?=?await?test()
        ??????console.log(data)
        ??????if?(data)?{
        ????????state.mockTabData?=?data
        ??????}
        ????}
        ??}
        }

        const?test?=?()?=>?{
        ??return?new?Promise(resolve?=>?{
        ????setTimeout(()?=>?{
        ??????resolve([
        ????????{
        ??????????name:?'Frozen?Yogurt',
        ??????????calories:?159,
        ??????????fat:?6.0,
        ??????????carbs:?24,
        ??????????protein:?4.0,
        ??????????iron:?'1%'
        ????????},
        ????????
        ??????])
        ????},?2000)
        ??})
        }

        在頁面中,在 created?鉤子中,通過調(diào)用 this.useDispatch('Admin/getDesserts')?進行數(shù)據(jù)獲取,然后將 Admin.headers?, Admin.mockTabData?賦值到對應的組件參數(shù)上去,同時通過 當前model?方法的副作用進行骨架屏的控制。

        所有的 model?方法都會在 data?中生成一個副作用狀態(tài),為避免沖突,data 中避免定義 model?,以免被 model.js?覆蓋。




        看看效果把,非常的簡單的控制數(shù)據(jù)響應變化:

        該特性實驗中,只作為參考。性能壓測還在進行中 QAQ。

        jsDoc 項目文檔

        項目文檔是一個非常重要的事情,不要過度相信自己的代碼,如果業(yè)務大的話,3 個月左右的時間,你經(jīng)手的項目可能就會丟失一部分直觀的記憶,這個時候不論是你繼續(xù)維護還是新人繼續(xù)維護都是一件非常頭疼的事情,同時需要考慮的是當項目進行到一般,后面有新人加入的時候,龐大的 components?, utils?, api?都會讓新人感到無從下手的感覺,因此一份文檔就顯得格外珍貴了。那么有同學問了,我業(yè)務都忙不過,還要花時間整理文檔,其他人的事情關(guān)我什么事?

        一個好的項目必然會有一個好的文檔,基于這類問題,所以才引入了一個文檔工具來生成文檔,在這個期間,也同時的對文檔進行了改進,更加的貼合 vue?本身,首先就是對文檔語法 @module?進行了改造,同時通過 @page?來聲明頁面,通過 @component?聲明公共組件,如下示例:




        那么最終通過 yarn doc?命令生成文檔:

        yarn doc

        效果看上去是下面這樣的 可以看到,現(xiàn)在的一些注釋就已經(jīng)很規(guī)范了,但依舊不完美,主要因素是來自于 jsdoc?文檔的主題問題,如果團隊需要的話,可以自己重構(gòu)一套出來,也相對來說簡單。

        文中實例僅限參考,注釋文檔請移步:jsdoc

        自定義開發(fā)日志 log

        對于 console?的使用,當時在看 D2Admin?的時候?qū)⑵淇寺×艘环葸^來,對于拋錯的日志來說,我們并不需要將自身的一些 consle?也進行收集,但是 console?之間也存在等級,如果通過 console.error 進行的話,可能會被捕捉從而傳入給后臺,因此,重寫了一份 log.js 用于開發(fā)版和測試版的調(diào)試使用。

        const?log?=?{}


        function?typeColor?(type?=?'default')?{
        ??let?color?=?''
        ??switch?(type)?{
        ????case?'default':
        ??????color?=?'#303133'
        ??????break
        ????case?'primary':
        ??????color?=?'#409EFF'
        ??????break
        ????case?'success':
        ??????color?=?'#67C23A'
        ??????break
        ????case?'warning':
        ??????color?=?'#E6A23C'
        ??????break
        ????case?'danger':
        ??????color?=?'#F56C6C'
        ??????break
        ????default:
        ??????break
        ??}
        ??return?color
        }


        log.capsule?=?function?(title,?info,?type?=?'primary')?{
        ??console.log(
        ????`%c?${title}?%c?${info}?%c`,
        ????'background:#35495E;?padding:?1px;?border-radius:?3px?0?0?3px;?color:?#fff;',
        ????`background:${typeColor(
        ??????type
        ????)};?padding:?1px;?border-radius:?0?3px?3px?0;??color:?#fff;`,
        ????'background:transparent'
        ??)
        }


        log.colorful?=?function?(textArr)?{
        ??console.log(
        ????`%c${textArr.map(t?=>?t.text?||?'').join('%c')}`,
        ????...textArr.map(t?=>?`color:?${typeColor(t.type)};`)
        ??)
        }

        log.default?=?function?(text)?{
        ??log.colorful([{?text?}])
        }

        log.primary?=?function?(text)?{
        ??log.colorful([{?text,?type:?'primary'?}])
        }

        log.success?=?function?(text)?{
        ??log.colorful([{?text,?type:?'success'?}])
        }

        log.warning?=?function?(text)?{
        ??log.colorful([{?text,?type:?'warning'?}])
        }

        log.danger?=?function?(text)?{
        ??log.colorful([{?text,?type:?'danger'?}])
        }

        export?default?log

        如下圖效果:

        log.default('>>>?我是一些默認提示')
        log.primary('>>>?我是一些標記提示')
        log.success('>>>?我是一些成功提示')
        log.warning('>>>?我是一些警告提示')
        log.danger('>>>?我是一些錯誤提示')

        組件和頁面管理

        在開發(fā)過程中,同樣養(yǎng)成一些好習慣對于項目體驗會有很好的幫助,寫代碼就和針線活一樣,細心謹慎,邏輯分明才能學到更多,減少 P0 BUG?的出現(xiàn),如果你項目不趕,還一直出現(xiàn)同一個問題,感官是非常差的。因此,牢記以下小技巧,希望對你有幫助

        頁面文件

        在這里推薦所有的頁面級別都放在一個樹下,目錄菜單使用文件夾且默認視圖為 index.vue?,名稱都為小寫駝峰,最好是一句小寫涵蓋如:home?, user?。等等,組件統(tǒng)一放在起始頁面的 components?下,且名稱為大駝峰帶模塊名,如 Admin?下的 Header?組件為 AdminHeader.vue?,使用時則為:?,引入時,統(tǒng)一使用 @/views/admin/components/xxx?引入。菜單在深都是在一級菜單下的東西,帶上頁面名稱是為了更好的區(qū)分,防止組件混淆。

        方法導出

        很多時候,不同的團隊成員在編寫 utils?時,有使用箭頭函數(shù),也有使用 function?來聲明的,因此,在這里推薦統(tǒng)一使用 export function?的形式進行 js?的聲明,如下方法:

        import?asyncAxiosInstance?from?'@/plugin/createService'
        import?currentModels?from?'@/plugin/createModel'

        export?function?getEnv?()?{
        ??return?process.env.VUE_APP_MODE?||?'dev'
        }


        export?function?useModels?(component,?models,?isDispatch?=?true)?{
        ??const?current?=?[]
        ??currentModels.forEach(item?=>?{
        ????if?(models.includes(item.name))?{
        ??????current.push(item.mixin)
        ????}
        ??})
        ??if?(isDispatch?&&?current.length?>?0)?{
        ????current.push(currentModels[0].mixin)
        ??}
        ??console.log(current)
        ??if?(component?.mixins)?{
        ????const?preMixin?=?component.mixins
        ????component.mixins?=?current.concat(preMixin)
        ????return?component
        ??}
        ??component.mixins?=?[...current]
        ??console.log(component)
        ??return?component
        }

        常用的指令

        日常開發(fā)中,一些指令能夠達到事半功倍的效果,但是指令需要貼合業(yè)務進行,同時設(shè)計者在設(shè)計時,同樣需要標注文檔,方便團隊成員查看。下面的一些指令推薦在進行注冊掉:

        • v-click-outside 外部點擊指令:當點擊非綁定元素會進行元素隱藏
        • v-intersect 元素監(jiān)視器:檢測元素在用戶視圖中是否可見
        • v-resize 縮放監(jiān)聽器:窗口進行縮放時的監(jiān)聽指令
        • v-scroll 滾動監(jiān)視器:可以靈活觀察綁定的元素滾動變化
        • v-touch 觸控監(jiān)視器:可以靈活監(jiān)視移動端當中的觸摸行為,并產(chǎn)生回調(diào)
        • v-auth 權(quán)限監(jiān)視器:重寫自 v-permission?主要做按鈕級別權(quán)限校驗和頁面權(quán)限校驗

        指令資源

        使用 SASS 還是 SCSS?

        現(xiàn)如今最好的 CSS擴展語言?依舊是 SASS?和 LESS?,兩者大差不差,可以根據(jù)團隊需要進行更換,使用起來沒有啥差別。在開發(fā)項目中,對于 SASS?我是首先推薦的(非 SCSS),如果沒有熟悉使用 SASS?的同學會覺得非常反人類,但如果你的規(guī)范好的話,我想你可以看下下面的這段 SASS?代碼:

        @mixin?flex?($mod:?flex,?$justifyContent:?center,?$alignItems:?center,?$direction:?initial)
        ??display:?$mod
        ??justify-content:?$justifyContent
        ??align-items:?$alignItems
        ??flex-direction:?$direction
        //?end?flex?mixin?...

        在寫 CSS 時,都建議在末尾加上一段 end?注釋來作為邏輯符號的完成,用于區(qū)分樣式塊的代碼,防止邏輯混亂,當大量的樣式維護較差時,我想 SCSS?給的安全感是比較高的,同理,當維護的好的時候, SASS?無疑是更加簡潔。當然也容易出錯。

        兩者殊途同歸,可以根據(jù)團隊成員習慣選擇。

        @mixin 和 %placeholder

        首先, @mixin 適合用來寫一些具有邏輯性的 css ,如最基本的 flex ,可以通過傳遞的 params 進行不同的設(shè)置,這是 %placeholder 欠缺的,但是 %placeholder 在靜態(tài)樣式的繼承上,可以減少重復 css 的調(diào)用,減少重復代碼,運用的多數(shù)場景為:基本卡片樣式 , 統(tǒng)一的組件樣式 等設(shè)計稿無偏差的時候使用,因此不需要無腦使用 @mixin ,有時候 %placeholder 更香。

        使用一個實例進行比對:

        %demo
        ??color:?red
        ??font-size:?20px
        ??border:?1px?solid?red
        ?//?end?...

        .test1
        ??@extend?%demo
        //?end?...

        .test2
        ??@extend?%demo
        //?end?...

        .test3
        ??@extend?%demo
        復制代碼

        如上代碼,使用 %placeholder 最終會生成的樣式是下面這樣的:

        .test1,?.test2,?.test3?{
        ??color:?red
        ??font-size:?20px
        ??border:?1px?solid?red
        }

        而如果換成 @mixin ,他們的結(jié)果是這樣的:

        @mixin?demo()
        ??color:?red
        ??font-size:?20px
        ??border:?1px?solid?red
        //?end?...

        .test1
        ??@include?demo()
        //?end?...

        .test2
        ??@@include?demo()
        //?end?...

        .test3
        ??@@include?demo()
        //?end?...

        編譯后:

        .test1?{
        ??color:?red
        ??font-size:?20px
        ??border:?1px?solid?red
        }
        .test2?{
        ??color:?red
        ??font-size:?20px
        ??border:?1px?solid?red
        }
        .test3?{
        ??color:?red
        ??font-size:?20px
        ??border:?1px?solid?red
        }

        不用我說,你應該知道怎么用了吧。

        ESLint

        理想的情況下,大部分前端團隊都會存在有 Eslint?,作為一個代碼質(zhì)量的標準,但也僅僅只是一個標準,配合 Git Commit?前置動作可以執(zhí)行代碼檢閱是否合格來防止低于標準的代碼提交到存儲庫中,這一個動作需要開發(fā)者自身養(yǎng)成良好的編碼習慣和代碼質(zhì)量意識。

        如果使用的是 VS CODE?那么就需要在編譯器中進行配置來開啟規(guī)則檢查,當違背了語法警告的同時,會提示如下警告:

        不推薦直接 commit 時直接編譯化代碼,Eslint 是幫助開發(fā)者代碼成長的,而不是一個表面功夫的工具。

        源碼和資源

        • jsDoc: 立即前往
        • 源碼地址:立即前往
        • vuetifyjs:立即前往
        • model 管理數(shù)據(jù)思考:點擊前往
        • api 約定式: 點擊前往

        總結(jié)

        不知不覺兩個月沒寫文章了,除了換工作后確實更忙了之外,有時間都在陪一個人和看文學書,看到很多朋友轉(zhuǎn)載我的文章感到非常的驚喜,同時也對文章質(zhì)量要求更高了,隨著工作經(jīng)驗和技術(shù)學習的累加,希望文章的內(nèi)容對你們是有技術(shù)上的提升的。

        這一篇文章應該是承接上一篇 Vue開發(fā)中的一些常見套路和技巧(上) 的下卷,相對于上來說,這篇文章東西更加的多,也更加實用,除了推動個人開發(fā)者外,更多的是團隊開發(fā)上思考。前端工程化慢慢的變得完善,團隊建設(shè)變得至關(guān)重要,幾年前,還沒有前端架構(gòu)的存在,到如今前端架構(gòu)在開發(fā)中變得至關(guān)重要。都是時代的弄潮,只有不斷學習,思考才能在風起云涌的浪花上,冒出一點零星的水花。

        深夜寫文,作為一個 Vue + React 的小前端分享的一篇 Vue 文章,如果對你,或者對你團隊有幫助,點個贊給作者換件衣服過冬穿吧。冬天的杭州確實很冷呀。

        最后




        如果你覺得這篇內(nèi)容對你挺有啟發(fā),我想邀請你幫我三個小忙:

        1. 點個「在看」,讓更多的人也能看到這篇內(nèi)容(喜歡不點在看,都是耍流氓 -_-)

        2. 歡迎加我微信「huab119」拉你進技術(shù)群,長期交流學習...

        3. 關(guān)注公眾號「前端勸退師」,持續(xù)為你推送精選好文,也可以加我為好友,隨時聊騷。


        點個在看支持我吧,轉(zhuǎn)發(fā)就更好了



        瀏覽 71
        點贊
        評論
        收藏
        分享

        手機掃一掃分享

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

        手機掃一掃分享

        分享
        舉報
        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>
            四虎国产永久在线精品 | 手机天堂手机板 | 中文字幕在线看 | 国产AAA毛片 | 黄A色毛aaaaaaa精品 | 人妻口爆 | 琪琪色导航 | 操逼电影五月天 | 午夜91| 女生裸体网站在线观看 |