日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
前端開發(fā)變量命名系列-JavaScript篇

JavaScript作為前端開發(fā)從業(yè)人員必須掌握的3大基礎(chǔ)知識中最重要的一環(huán),也是平是接觸時間最長、寫得最多的。在開發(fā)過程中必然會遇到命名的問題,你會詞窮、糾結(jié)、惆悵嗎?本文的出現(xiàn)相信能夠解決大部分煩惱,讓你輕松寫出符合規(guī)范、易讀、簡短的代碼。

創(chuàng)新互聯(lián)建站長期為成百上千客戶提供的網(wǎng)站建設(shè)服務(wù),團(tuán)隊(duì)從業(yè)經(jīng)驗(yàn)10年,關(guān)注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務(wù);打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為烏當(dāng)企業(yè)提供專業(yè)的網(wǎng)站制作、成都網(wǎng)站設(shè)計,烏當(dāng)網(wǎng)站改版等技術(shù)服務(wù)。擁有十載豐富建站經(jīng)驗(yàn)和眾多成功案例,為您定制開發(fā)。

本文將通過大量的實(shí)例來試圖自圓其說,形成一套系統(tǒng)化、實(shí)用的變量命名理化體系。通過按JavaScript的數(shù)據(jù)類型分類著手、細(xì)到一個函數(shù)的參數(shù)命名,并提供眾多可選方案,并盡量給出其適用范圍和利弊。

需要注意的是由于個人寫作水平、和知識有限,很多方面敘述上有些生硬,在分類上也沒有什么特別的依據(jù),文章也沒有人審稿,所以有什么紕漏還請留言告知。由于寫作倉促,內(nèi)容可能不全,后續(xù)會隨著工作和學(xué)習(xí)的深入而不斷地調(diào)整和更新。

布爾值(Boolean)命名

Boolean值是兩種邏輯狀態(tài)的變量,它包含兩個值:真和假。在JavaScript中對應(yīng) true 和 false,在實(shí)踐中通常使用數(shù)字1表示真值,0來表示假值。

雖然Boolean的狀態(tài)只有兩種但是在命名時可以進(jìn)一步分類,這里給出幾種場景:

  •  場景一:表示可見性、進(jìn)行中的狀態(tài)

解釋:可見性在通常指頁面中的元素、組件是否顯示(或者組件掛載到DOM上,但并不可見)。進(jìn)行中主要是說明某種狀態(tài)是處于持續(xù)進(jìn)行中。

推薦命名方式為 is + 動詞(現(xiàn)在進(jìn)行時)/形容詞,同時這種方式也可以直接不寫 is,但是為了更好的作區(qū)分,建議還是加上。

 
 
 
  1.   isShow: '是否顯示', 
  2.   isVisible: '是否可見', 
  3.   isLoading: '是否處于加載中', 
  4.   isConnecting: '是否處于連接中', 
  5.   isValidating: '正在驗(yàn)證中', 
  6.   isRunning: '正在運(yùn)行中', 
  7.   isListening: '正在監(jiān)聽中' 
  8. }

注意: 在Java中使用這種方式是有一定副作用的,為什么請移步:為什么阿里巴巴禁止開發(fā)人員使用 “isSuccess” 作為變量名?

  •  場景二:屬性狀態(tài)類

解釋:通常用來描述實(shí)體(例如:HTML標(biāo)簽、組件、對象)的功能屬性,而且定法比較固定。

 
 
 
  1.   disabled: '是否禁用', 
  2.   editable: '是否可編輯', 
  3.   clearable: '是否可清除', 
  4.   readonly: '只讀', 
  5.   expandable: '是否可展開', 
  6.   checked: '是否選中', 
  7.   enumberable: '是否可枚舉', 
  8.   iterable: '是否可迭代', 
  9.   clickable: '是否可點(diǎn)擊', 
  10.   draggable: '是否可拖拽' 
  11. }
  •  場景三:配置類、選項(xiàng)類

解釋:主要是指組件功能的開啟與關(guān)閉,功能屬性的配置。

這是一種比較常見的情景,目前命名方式也有很多種,但是歸納起來也不多。推薦使用 withXx 來表示組件在基本功能形態(tài)外的其它功能,比如組件的基礎(chǔ)功能到高級功能的開啟;使用 enableXx 來表示組件某些功能的開啟;使用 allowXx 來表示功能屬性的配置;使用 noXx 用于建議功能使用者這個不建議開啟。

 
 
 
  1.   withTab: '是否帶選項(xiàng)卡', 
  2.   withoutTab: '不帶選項(xiàng)卡', 
  3.   enableFilter: '開啟過濾', 
  4.   allownCustomScale: '允許自定義縮放', 
  5.   shouldClear: '是否清除', 
  6.   canSelectItem: '是否能選中元素', 
  7.   noColon: '不顯示label后面的冒號', 
  8.   checkJs: '檢查Js', 
  9.   emitBOM: 'Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files.' 
  10. }

注意:如果嫌分類太多,可以只使用其中一種方式,比如在Typescript中使用了 allownXx 和 noXx。

除了上面這些帶有特定的前置介詞、動詞方式外還有一些在語義上帶有疑問性質(zhì)的組合通常也是作為Boolean命名的一種參考。

 
 
 
  1.   virtualScroll: '是否啟用虛擬滾動模式', 
  2.   unlinkPanels: '在范圍選擇器里取消兩個日期面板之間的聯(lián)動', 
  3.   validateEvent: '輸入時是否觸發(fā)表單的校驗(yàn)' 
  4. }

函數(shù)命名

函數(shù)在不同的上下文中的叫法也不一樣,在對象中稱為方法,在類中有構(gòu)造函數(shù)、在異步處理時有回調(diào)函數(shù),還有立即執(zhí)行函數(shù)、箭頭函數(shù)、柯里函數(shù)等。

函數(shù)命名的方式常常是和業(yè)務(wù)邏輯耦合在一起的,但是在命名規(guī)則上也有一些常見的模式可以遵循。

  •  場景一:事件處理

事件處理函數(shù)是前端平時用到最多的,包括瀏覽器原生事件、異步事件和組件自定義事件。在寫法上最常見的兩種命名分別為 onXx、onXxClick和handleXx、handleXxChange。

這里如何在二者之間選擇,可以從二方面來歸類。一是,原生事件采用 onXx,而自定義事件使用 handleXx。二是,事件主動監(jiān)聽采用 onXx,被動處理使用 handleXx。

從實(shí)踐及三大主流框架的文檔關(guān)于事件部分的內(nèi)容來看,推薦使用 handleXx 這種方式,而在表單提交的時候通常采用 onSubmit 函數(shù)。

其實(shí),在實(shí)際項(xiàng)目中很少嚴(yán)格這樣來命名事件處理函數(shù),因?yàn)檫@種方式有一定的局限性,比如點(diǎn)擊按鈕打開一個對話框,使用 handleOpenDlg 和 onOpenDlg 都沒有直接寫 openDlg 方便,如果頁面有多個不同功能的對話框采用這種方式會顯得變量名過長,而handle和on就顯得沒有必要了,比如 hanldeOpenCommentDlg 就沒有 openCommentDlg 直白。

下面列出了一些約定成俗的適用例子:

 
 
 
  1.   onSubmit: '提交表單', 
  2.   handleSizeChange: '處理分頁頁數(shù)改變', 
  3.   handlePageChange: '處理分頁每頁大小改變', 
  4.   onKeydown: '按下鍵' 
  5. }
  •  場景二:異步處理

這里主要是指在寫數(shù)據(jù)層服務(wù)、狀態(tài)管理中的Action命名,以及Ajax回調(diào)的命名規(guī)則。

 
 
 
  1.   getUsers: '獲取用戶列表', 
  2.   fetchToken: '取得Token', 
  3.   deleteUser: '刪除用戶', 
  4.   removeTag: '移除標(biāo)簽', 
  5.   updateUsrInfo: '更新用戶信息', 
  6.   addUsr: '添加用戶', 
  7.   createAccount: '創(chuàng)建賬戶' 
  8. }

命名主要圍繞數(shù)據(jù)的增刪查找來劃分,獲取數(shù)據(jù)通常是 getXx 和 fetchXx,在作者看來兩者在使用上的區(qū)分在于 getXx 的數(shù)據(jù)來源不一定直接取自異步的原始數(shù)據(jù),可能是加工處理后的,而 fetchXx 是直接拿的原始數(shù)據(jù)。當(dāng)然在實(shí)際項(xiàng)目中并沒有區(qū)分,看個人喜好。

deleteXx 主要用于數(shù)據(jù)刪除,而 removeXx 在語義上是移除數(shù)據(jù),通常情況數(shù)據(jù)是還存在的,只是沒有顯示或數(shù)據(jù)假刪除。updateXx 是指數(shù)據(jù)更新操作,addXx 是在已有列表數(shù)據(jù)中添加新的子項(xiàng)、而createXx 主要是創(chuàng)建新的實(shí)例,比如新建一個賬戶。

  •  場景三: 跳轉(zhuǎn)路由

在實(shí)際開發(fā)過種中,比如在使用react-router/vue-router時,在模板或者JSX中可以直接在標(biāo)簽中寫上目標(biāo)地址,但有些時候跳轉(zhuǎn)的目標(biāo)地址是經(jīng)過判斷或者組合后的,并且通過事件觸發(fā)跳轉(zhuǎn)的,這個時候就需要一個函數(shù)來處理,那么在函數(shù)命名的時候可以考慮使用

 
 
 
  1.   toTplDetail: '跳轉(zhuǎn)到模板詳情頁面', 
  2.   navigateToHome: '導(dǎo)航到首頁', 
  3.   jumpHome: '跳轉(zhuǎn)首頁', 
  4.   goHome: '跳轉(zhuǎn)首頁' 
  5. }

推薦使用 toXx 和 goXx 這兩種方式,如果不是在當(dāng)前頁面打開/跳轉(zhuǎn)頁面,可以使用 toBlankTplDetail 或者 goBlankHome 這種方式來進(jìn)一步語義化。如果前端頁面是位于Webview中,也可以考慮采用 toNativeShare 這種方式來命名。

  •  場景四:框架相關(guān)特定方法

這里主要是針對前端3大主流流行框架,有一些命名是帶有特定標(biāo)識符的,還有就是一些生命周期的命名方式。

 
 
 
  1.   formatTimeFilter: '在AngularJs和Vue中,通常用于過濾器命名', 
  2.   storeCtrl: '用于AngularJs定義控制器方法', 
  3.   formatPipe: '用于Angular中,標(biāo)識管道方法', 
  4.   $emit: 'Vue中的實(shí)例方法', 
  5.   $$formatters: 'AngularJs中的內(nèi)置方法', 
  6.   beforeCreate: 'Vue的生命周期命名', 
  7.   componentWillMount: 'React生命周期命名', 
  8.   componentDidMount: 'React生命周期命名', 
  9.   afterContentInit: 'Anuglar生命周期命名', 
  10.   afterViewChecked: 'Angula生命周期命名', 
  11.   httpProvider: 'AngularJs服務(wù)', 
  12.   userFactory: '工廠函數(shù)', 
  13.   useCallback: 'React鉤子函數(shù)' 
  14. }
  •  場景五:數(shù)據(jù)的加工

這類場景在處理列表的時候經(jīng)常會碰到,比如排序、過濾、添加額外的字段、根據(jù)ID和索引獲取特定數(shù)據(jù)等。

情形一:根據(jù)特定屬性獲取屬性

這里可以參考DOM方法的命名,比如:getElememtById()、getElementsByTagName()、getElementsByClassName() 和 getElementsByName(),然后提煉出一個比較實(shí)用的模板:getXxByYy()。其中 Xx 可以是:element, item, option, data, selection, list, options 以及一些特定上下文的名字,比如:user(s), menu(s) 等。Yy 相對來說比較固定,經(jīng)常用到的就是 id, index, key, value, selected, actived 等。

除了使用 get,還可以使用 query 和 fetch,但是需要注意和上面提到的異步數(shù)據(jù)處理作一個區(qū)分。

 
 
 
  1.   getItemById: '根據(jù)ID獲取數(shù)據(jù)元素', 
  2.   getItemsBySelected: '根據(jù)傳入的已選列表ID來獲取列表全部數(shù)據(jù)', 
  3.   queryUserByUid: '根據(jù)UID查詢用戶' 
  4. }

注意:在 getItemsBySelected 這種情形下直接寫成 getItemsSelected 更好,但只適用于 Yy 為形容詞的場景

情形二:格式化數(shù)據(jù)

這里的格式化操作包括排序、調(diào)整數(shù)據(jù)結(jié)構(gòu)、過濾數(shù)據(jù)、添加屬性。命名通常使用 formatXx, convertXx, inverseXx, toggleXx, parseXx, flatXx, 也可以結(jié)合數(shù)組的一些操作方法來命名,比如 sliceXx, substrXx, spliceXx, sortXx, joinXx 等來命名。

 
 
 
  1.   formatDate: '格式化日期', 
  2.   convertCurrency: '轉(zhuǎn)換貨幣單位', 
  3.   inverseList: '反轉(zhuǎn)數(shù)據(jù)列表', 
  4.   toggleAllSelected: '切換所有已選擇數(shù)據(jù)狀態(tài)', 
  5.   parseXml: '解析XML數(shù)據(jù)', 
  6.   flatSelect: '展開選擇數(shù)據(jù)', 
  7.   sortByDesc: '按降序排序' 
  8. }

數(shù)組命名

數(shù)組的命名推薦使用復(fù)數(shù)形式來命名,還有就是名詞和具有列表意思的單詞組合。常見的詞匯有 options, list, maps, nodes, entities, collection 等。

 
 
 
  1.   users: '用戶列表', 
  2.   userList: '用戶列表', 
  3.   tabOptions: '選項(xiàng)卡選項(xiàng)', 
  4.   stateMaps: '狀態(tài)映射表', 
  5.   selectedNodes: '選中的節(jié)點(diǎn)', 
  6.   btnGroup: '按鈕組', 
  7.   userEntities: '用戶實(shí)體' 
  8. }

選項(xiàng)元素、下拉元素命名

主要針對的是在下拉選擇框、選項(xiàng)卡元素、Radio、Checkbox等數(shù)據(jù)源每個選項(xiàng)數(shù)據(jù)的命名。常見的詞匯有:title, name, key, label, field, value, id, children, index, nodes 等。

基中 title/name/key/label/field 作為選項(xiàng)顯示名, value/id 用于唯一標(biāo)識選項(xiàng),children/nodes 用于包含子節(jié)點(diǎn)內(nèi)容。如果選項(xiàng)元素的語義很明確的情況下也可以直接使用特定單詞來代替提到的這些泛指的詞匯,例如菜單列表就可以使用 menu 來作為顯示名。

 
 
 
  1. // 最常見組合 
  2.   title: '標(biāo)題', 
  3.   value: 'ID值' 
  4. // 組合二 
  5.   label: '標(biāo)簽名', 
  6.   value: 'ID值' 
  7. // 組合三 
  8.   name: '元素名', 
  9.   id: 'ID值' 
  10. // 組合四 
  11.   field: '字段', 
  12.   value: '標(biāo)識', 
  13.   index: '索引' 
  14. }

當(dāng)前選項(xiàng)、激活項(xiàng)命名

適用列表的選中項(xiàng)、菜單選中項(xiàng)、步驟操作的當(dāng)前進(jìn)行步驟、頁面路由當(dāng)前路由等的命名。

 
 
 
  1.   activeTab: '當(dāng)前選中選項(xiàng)卡', 
  2.   currentPage: '當(dāng)前頁', 
  3.   selectedData: '當(dāng)前選項(xiàng)中數(shù)據(jù)', 
  4. }

臨時數(shù)據(jù)、比對數(shù)據(jù)命名

針對在代碼中有時會使用一些臨時的變量來存儲數(shù)據(jù)、保存數(shù)據(jù)快照的場景下的命名。

 
 
 
  1.   swapData: '臨時交換數(shù)據(jù)', 
  2.   tempData: '臨時數(shù)據(jù)', 
  3.   dataSnapshot: '數(shù)據(jù)快照' 
  4. }

數(shù)據(jù)循環(huán)語句中變量命名

在使用 for 循環(huán)時,多層嵌套請依次使用 i/j/k,超過3層可以使用 x/y/z,m/n 來命名。使用 forEach, map, filter 等方法時,每一個元素命名可以根據(jù)不同語境下的特殊名字來命名,比如遍歷 menus,那么每個元素可以命名為 menu,不然則使用上下文無關(guān)的詞匯,比如:item, option, data, key, object 等。至于索引通常使用 index,如果多層可以使用 index + 數(shù)字 的形式,也可以直接使用 i/j/k 來作為索引,甚至還可以使用 subIndex/grandIndex 這種方式來命名。

對于在使用 for 循環(huán)時數(shù)組長度如果需要單獨(dú)命名的話,可以使用 xxlength/xxLens,或者 xxCount。

在循環(huán)的過程中通常還會統(tǒng)計某個條件下數(shù)據(jù)匹配的次數(shù)、重復(fù)元素數(shù)量、記錄中間結(jié)果等情況。這里推薦使用 count 表示次數(shù),skipped 表示跳過的數(shù)量,result 表示結(jié)果。

 
 
 
  1. // for 循環(huán) 
  2. for (let i = 0; i < 10; i++) { 
  3.   for (let j = 0; j < 10; j++) { 
  4.     for (let k = 0; k < 10; k++) { 
  5.       // do something 
  6.     } 
  7.   } 
  8. for (let i = 0, lens = this.options.length; i < lens; i++) { 
  9.   // do something 
  10. // forEach 
  11. users.forEach((item, index) => { 
  12.   // do something 
  13. }) 
  14. menus.forEach((menu, index) => { 
  15.   if (menu.children) { 
  16.     menu.children.forEach((subMenu, subIndex) => { 
  17.       if (subMenu.children) { 
  18.         subMenu.children.forEach((grandMenu, grandIndex) => { 
  19.           // 一個不常用的示例 
  20.         }) 
  21.       } 
  22.     }) 
  23.   } 
  24. })

方法參數(shù)命名

方法的參數(shù)名稱和數(shù)量在不同的方法中各不相同,但是還是有一些固定的模式可以參考,比如在Vue中監(jiān)聽屬性變化的新值和舊值;reduce 方法的上一個值,當(dāng)前值;回調(diào)函數(shù)的命名、剩余參數(shù)的命名等。

情形一:新值、舊值

常見于Vue中watch 對像中的屬性監(jiān)聽回調(diào)函數(shù),推薦使用

 
 
 
  1.   oldVal: '舊值', 
  2.   newVal: '新值' 
  3. }

情形二:上一個值、下一個值和當(dāng)前值

這種情形見于路由的鉤子方法,Object.assign 數(shù)據(jù)拷貝的參數(shù)。

 
 
 
  1. // 組合一 
  2.   from: '從...', 
  3.   to: '到...' 
  4. // 組合二 
  5.   prev: '上一個...', 
  6.   next: '下一個...', 
  7.   cur: '當(dāng)前' 
  8. // 組合三 
  9.   source: '源', 
  10.   target: '目標(biāo)' 
  11. // 組合四 
  12.   start: '開始', 
  13.   end: '結(jié)束' 
  14. }

情形三:異步數(shù)據(jù)返回

用于Promise的then方法參數(shù),await 的返回的Promise等。可選擇的詞匯有:res, data, json, entity,推薦使用 res。

 
 
 
  1. demoPromise.then(res => { 
  2.   // do something 
  3. })

情形四:其它情況

一些使用不多,但是在編程時約定成俗的命名方式。例如 ch 表示單個字符,str 表示字符串, n 代表次數(shù), reg 表示正則, expr 表示表達(dá)式, lens 表示數(shù)組長度, count 表示數(shù)量, p 表示數(shù)據(jù)的精度, q 表示查詢(query), src 表示數(shù)據(jù)源(source), no 表示數(shù)字(number), rate 表示比率, status 表示狀態(tài), bool 表示布爾值, arr 表示數(shù)組值, obj 表示對象值, x 和 y 表示坐標(biāo)兩軸, func 表示函數(shù), ua表示User Agent, size 表示大小, unit 表示單位, hoz 表示水平方向, vert 表示垂直方向, radix 表示基數(shù),根

 
 
 
  1. // 傳入單個字符 
  2. function upper(ch) {} 
  3. // 數(shù)量重復(fù) 
  4. function repeat(str, n) 
  5. // 正則 
  6. 'abab'.replace(reg, 'bb')

事件命名

這里根據(jù)DOM、nodejs和一些框架和UI組件的事件進(jìn)行歸納

  •  DOM事件

這里列舉DOM中常見的事件命名

 
 
 
  1.   load: '已完成加載', 
  2.   unload: '資源正在被卸載', 
  3.   beforeunload: '資源即將被卸載', 
  4.   error: '失敗時', 
  5.   abort: '中止時', 
  6.   focus: '元素獲得焦點(diǎn)', 
  7.   blur: '元素失去焦點(diǎn)', 
  8.   cut: '已經(jīng)剪貼選中的文本內(nèi)容并且復(fù)制到了剪貼板', 
  9.   copy: '已經(jīng)把選中的文本內(nèi)容復(fù)制到了剪貼板', 
  10.   paste: '從剪貼板復(fù)制的文本內(nèi)容被粘貼', 
  11.   resize: '元素重置大小', 
  12.   scroll: '滾動事件', 
  13.   reset: '重置', 
  14.   submit: '表單提交', 
  15.   online: '在線', 
  16.   offline: '離線', 
  17.   open: '打開', 
  18.   close: '關(guān)閉', 
  19.   connect: '連接', 
  20.   start: '開始', 
  21.   end: '結(jié)束', 
  22.   print: '打印', 
  23.   afterprint: '打印機(jī)關(guān)閉時觸發(fā)', 
  24.   click: '點(diǎn)擊', 
  25.   dblclick: '雙擊', 
  26.   change: '變動', 
  27.   select: '文本被選中被選中', 
  28.   keydown/keypress/keyup: '按鍵事件', 
  29.   mousemove/mousedown/mouseup/mouseleave/mouseout: '鼠標(biāo)事件', 
  30.   touch: '輕按', 
  31.   contextmenu: '右鍵點(diǎn)擊 (右鍵菜單顯示前)', 
  32.   wheel: '滾輪向任意方向滾動', 
  33.   pointer: '指針事件', 
  34.   drag/dragstart/dragend/dragenter/dragover/dragleave: '拖放事件', 
  35.   drop: '元素在有效釋放目標(biāo)區(qū)上釋放', 
  36.   play: '播放', 
  37.   pause: '暫停', 
  38.   suspend: '掛起', 
  39.   complete: '完成', 
  40.   seek: '搜索', 
  41.   install: '安裝', 
  42.   progress: '進(jìn)行', 
  43.   broadcast: '廣播', 
  44.   input: '輸入', 
  45.   message: '消息', 
  46.   valid: '有效', 
  47.   zoom: '放大', 
  48.   rotate: '旋轉(zhuǎn)', 
  49.   scale: '縮放', 
  50.   upgrade: '更新', 
  51.   ready: '準(zhǔn)備好', 
  52.   active: '激活' 
  53. }
  •  自定義事件

在封裝組件時提供的事件名除了參考DOM事件外,在命名上也可以參考Github Api 采用 動詞過去時 + Event 的方式

 
 
 
  1.   assignedEvent: '分配事件', 
  2.   closedEvent: '關(guān)閉事件', 
  3.   labeledEvent: '標(biāo)簽事件', 
  4.   lockedEvent: '鎖事件', 
  5.   deployedEvent: '部署事件' 
  6. }

此外,很多命名方式可以根據(jù)場景使用 元素 + click 、元素 + change 、select + 范圍等方式靈活運(yùn)用

 
 
 
  1.   selectAll: '選擇所有', 
  2.   cellClick: '當(dāng)某個單元格被點(diǎn)擊時會觸發(fā)該事件', 
  3.   sortChange: '當(dāng)表格的排序條件發(fā)生變化的時候會觸發(fā)該事件' 

分享題目:前端開發(fā)變量命名系列-JavaScript篇
轉(zhuǎn)載來源:http://www.5511xx.com/article/dpedddo.html