該專案用到的技術主要有:vue-cli + vuex + mockjs。 github地址
互動功能
- 點選選單欄新增按鈕,進入頻道管理頁面,可進行頻道新增刪除
- 點選header左側郵箱圖片,彈出框顯示
- 點選header右側搜尋按鈕,進入搜尋頁面,搜尋非同步查詢到結果進行高亮
- 頻道選單欄切換非同步查詢,對應頻道新聞展示
- 新聞展示懶載入,每次展示10條資料,滑到底部再載入10條。
展示功能
這裡主要講述我在實現時,覺得以後開發中可能會經常遇到的經驗問題
1.選單欄水平方向可以滑動展示多餘內容
如圖所示:
這裡佈局如下:
這裡我用的方法是:
我們給這個ul外面套著一個div(.ul-box),該div的樣式如下:
.nav-container .ul-box {
width: 100vw;
height: 0.8rem;
overflow-x: scroll;
}
複製程式碼
其內部的ul的樣式如下:使用彈性佈局
.nav-container .ul-box .nav-ul {
line-height: 0.8rem;
display: -webkit-box;
display: flex;
height: 0.8rem;
margin-right: 0.2rem;
}
複製程式碼
第二種方法,使用white-space: norwrap
這裡不需要更改上面最外層div的樣式,只需要更改ul的樣式,使用white-space: norwrap
.nav-container .ul-box .nav-ul {
line-height: 0.8rem;
white-space: norwrap//劃重點就是這句話
height: 0.8rem;
margin-right: 0.2rem;
}
複製程式碼
2.新聞卡片,不同型別的卡片不同的佈局
這裡的新聞有四種不同佈局
- 沒有圖片的新聞
- 有一個圖片非廣告類新聞
- 有三張圖片的非廣告類新聞
- 廣告
針對這四種不同型別的卡片,我的區分是首先我覺得後端可能給我的資料只會分新聞和廣告,所以我用一個欄位判斷是新聞還是廣告,然後對新聞就是通過判斷該條新聞的圖片個數,來進一步確定不同佈局。
專案遇到的奇奇怪怪的bug和注意事項
1. 對router-link新增點選事件不起作用
<router-link @click.native="changeTab(item.id)" :to= "{path: `/home/` + item.id}" tag="a" :data-id="item.id" :class="{selected: curIndex === item.id}">{{item.name}}</router-link>
複製程式碼
這裡需要給這個點選事件後面加上.native,加上這個之後,就將這個vue元件轉為普通的html元素。給vue元件繫結原生事件就需要.native修飾v-on,否則無法註冊成功
2.header佈局,左側元素float:left,讓中間元素居中,我發現浮動的元素會影響中間元素
其佈局圖就是這樣:
由於我一般情況下是能不用定位就不用,這裡我第一想法是父元素設定text-align:center,左邊元素浮動即可,浮動元素脫離文件流啊。。。嗯。。想法很好,然而我發現左浮的元素竟然佔空間,中間的元素明顯往右移動了很多。。。忍無可忍,我使用了定位,果然定位真是厲害。這裡我就很有點疑惑了,不都是脫離文件流嗎,咋會有不一樣的效果。
通過查閱資料發現,css中的脫離文件流是將元素從普通的佈局排版中拿走,這樣其他元素在頁面佈局時,會忽略脫離文件流的元素。但是注意同樣是脫離文件流,浮動的元素和定位的元素還是有區別的:
浮動元素:使用浮動的元素,雖然該元素已經脫離文件流了,但是頁面中其他盒子內的文字依然會為這個元素讓出位置
定位元素:頁面中的其他元素會徹底無視
示例:
分別對div1使用浮動和絕對定位,其效果差如下
<div class="header">
<div class="left">div1</div>
<div class="center">div2</div>
</div>
複製程式碼
.header .left {
/* float: left; */
position: absolute;
left: 0;
background: #f00;
}
.header .center {
background: #0ff;
}
複製程式碼
float:left;
position:absolute;
3.關鍵詞搜尋高亮
一開始的寫法是:
let exchangeKey = `<highlight>` + key + `</highlight>`
arr[index].title = arr[index].title.replace(key, exchangeKey)//key是使用者輸入的內容
複製程式碼
比較懂正則的應該發現,我忘記全域性匹配了,這個點真的需要注意考慮全面,一開始我寫的假資料中一句話中也不會有重複的詞,所以也沒發現,一直到後期看正規表示式才發現這個點。
進一步修改為:
let reg = new RegExp("(" + key + ")", "ig");
arr[index].title = arr[index].title.replace(reg, `<highlight>$1</highlight>`)
複製程式碼
這下就沒有啥問題了
4.去掉url上的#
在目錄router/index.js里加上mode: `history`
vue-router有兩種模式(這兩種模式的區別,以及應用場景還需要進一步學習和總結)
- hash
- history
5.vuex的使用
這裡不贅述,之前總結了
6.mock的使用
見其他總結
7.返回上一頁
常見的返回上一頁的方法有:
- window.history.go(-1);
- window.history.back(-1);
進入下一頁的方法有:
- window.history.forward()
以上的方法都會重新整理頁面,我們的專案中使用了vuex,所以重新整理是不能夠的,請使用路由的跳轉
8.將mock.js放入mock資料夾內,再在store資料夾裡import路徑會出錯
這個問題暫時沒有解決,就還是將mock.js放在mock資料夾外了,但是看著真是不舒服
9.使用mapState只能讀state裡的值,不可以進行修改
修改請在actions.js或者mutations.js裡修改,或者使用store.state取值修改
10.npm run build後dist資料夾裡index.html找不到對應靜態資源
改config檔案裡的index.js
11.新聞訊息懶載入
懶載入主要是監聽window.onscroll事件來處理,這裡注意滑動到底部之後,會發現一直會觸發,這樣會出現抖屏的現象,所以這裡我是使用一個canGetMoreList標誌位進行判斷,只有當非同步請求成功之後canGetMoreList為true。判斷滑到底部且canGetMoreList為true時才傳送非同步請求。
window.onscroll = function () {
var scrollT = document.documentElement.scrollTop || document.body.scrollTop;
var scrollH = document.documentElement.scrollHeight || document.body.scrollHeight;
var clientH = document.documentElement.clientHeight || document.body.clientHeight;
if (scrollT >= scrollH - clientH && store.state.canGetMoreList) {
this.pageNum++
store.state.showMoreFlag = true
e.state.canGetMoreList = false
setTimeout (function () {
this.getList(this.curIndex)
}.bind(this), 200)
}
}.bind(this)
複製程式碼
專案總結
每一次做一個完整的專案就好像是一個掃盲的過程,只有在遇到問題的時候才知道自己有多麼的無知,給自己列一個下一步的學習計劃:
- 網路方面的知識
- 正規表示式的學習
- webpack的配置學習