halo,大家好,我是 132 唔,經過四天時間,c站的 3.0 重構終於告一段落啦
重構真的是,最不合算的重複勞動了 可是每次重構,都或多或少的,學到新東西
之前的 2.0 重構的文章,在這裡:github.com/frontend9/f…
重構背景
v2 版本一來,經過接近一年的時間,隨著c站業務的發展,已經出現一些問題 比如我們的番劇系統,需要更加強大的索引 比如我們的 ugc 版權,需要更加合理的上傳稽核機制 等等 加上多人協作,程式碼質量每況愈下
本來是打算等到 vue3 發版再重構的來著,但是還是沒能忍得住,就提前重構了
目標
- 對程式碼進行重新梳理,提高程式碼質量,減小維護成本
- 對各個端進行重構,更完美的服務業務,更有利於下次重構
開始
後端 API 重構
重構的開端還是從 API 開始 本次後端重構,最主要的是重構了番劇索引介面
場景主要就是,這種索引的場景,其中,分類、狀態等,單選,標籤多選,條件間取交集,標籤取並集其實這個場景在視訊網站中非常多見,對於後端來說,是個一對多,多對多的問題 上個版本 c站 使用了 redis 來做這個邏輯
略複雜,這個版本,使用了更簡單的方式,拼接字串
var query string
if status != "" && status != "nowait" {
query = fmt.Sprintf(`AND posts.status ='%s'`, status)
}
if sort != "" {
query += fmt.Sprintf(`AND posts.sort ='%s'`, sort)
}
if uid != 0 {
query += fmt.Sprintf(`AND posts.uid ='%d'`, uid)
}
if status == "nowait" {
query += `AND NOT posts.status='wait'`
}
···
這樣就會根據引數,拼成一個字串
為了防止所有引數都沒有的情況,可以預設攜帶一個 1=1
```sql
sqlRaw := fmt.Sprintf(`SELECT posts.id,posts.title,posts.content,posts.status,posts.sort,posts.tag,posts.time,users.id,users.name,users.qq FROM posts LEFT JOIN users ON posts.uid = users.id
WHERE 1=1 %s ORDER BY time DESC`, query)
複製程式碼
這樣就可以做成一個完美的查詢介面啦,一個介面搞定一切查詢的 case
介面預覽:api.clicli.us/posts?statu…
然後對於使用者介面等,同時也做了類似的調整 然後後端就沒啥啦
前端
前端的重構,其實就是重新寫了 API,大概提幾個要點吧
###. 跨域
跨域是個很尷尬的問題,之前面試還一直被問,我當時是咋說的來著?
不解釋,就是反代 這次最坑的是,我真的是,三天重構時間,因為我沒有去反代,浪費了一天時間
最主要的是非簡單請求的 options攜帶 cookie 的問題 據說,需要同時滿足兩個條件:
withcredentials必須設定為true, origin不能用萬用字元*
可惜,搗鼓了好久,還是不能很好的解決 最終我很後悔這次嘗試,我從一開始就應該堅定立場
面試官你再敢問,我就不解釋,反代送給你
新番時間表
場景如圖,需要一個從 週一到週日 的新番表之前我們是後臺手動設定,很不夠傻瓜化
這次決定做成自動的 方法就是對資料的重新遍歷
let ret = {
1: [],
2: [],
3: [],
4: [],
5: [],
6: [],
0: [],
}
res.data.posts.forEach(item => {
let day = new Date(item.time).getDay()
ret[day].push(item)
})
this.items = ret
複製程式碼
ret 一個以數字為 key 的 物件,分別代表了週一到週日,0 為週日 然後渲染就很容易啦
<li v-for="item in items[activeIndex]">
<router-link :to="'/play/gv'+item.id">
<img :src="getSuo(item.content)" :alt="item.title">
<div class="text">
<div class="title">{{item.title}}</div>
</div>
</router-link>
</li>
複製程式碼
activeIndex 就是今天的 getDay()
其實這種通過當前日期來自動歸類資料的小技巧,還是經常用用 能縮減很多維護量的
標籤
場景如圖,就是標籤的選擇和去選擇 通常,很多人喜歡用多選框來做,然後通過 label 去繫結樣式等等但是其實不用,因為無論怎麼選擇,最終對應的都是字串而已 在此之前,先搞定,多個引數怎麼在 url 裡傳遞
GET /posts?tag=標籤1+標籤2
後端拿到的,其實是兩個標籤中間,有一個空格
標籤1 標籤2
也就是說,我們選擇多少個標籤,只需要用空格去追加字串即可
selectTag(item) {
if (this.state.tag.includes(item)) {
this.setState({
tag: this.state.tag.replace(` ${item}`, '')
})
} else {
this.setState({
tag: this.state.tag + ` ${item}`
})
}
}
複製程式碼
通過 includes ,包含這個字串就高亮,再點選就是移除字串,取消高亮 一個非常簡單的標籤功能就搞定了
然後,好像就沒有然後了::>_<::
APP
app 是由 @jwchan1996 小哥哥負責更新的,我只是打輔助,不知道他會不會發文章呢::>_<::
然後我遇到了一個問題,就是版本釋出的坑,我們每次釋出,都沒有好的版本控制
導致很多人下載不到最新的版本,也沒辦法上架應用商店
所以想了個辦法,釋出到 npm 上,每次就可以 @latest 啦,哈哈哈
總結
細細想來,這次重構確實,沒什麼新的東西
都怪我尿性使然,等不及 vue 3
不過等 vue3 發版,我們還會繼續重構,到時候再來一波分享吧
連結
c站首頁:clicli.us c站原創頁:clicli.us/explore
APP 永久最新下載地址:unpkg.com/@clicli/app
github 開源地址:github.com/acgzone