摘要:用開發仿旅游站項目總結上該說的話,該表明的上篇已經表明了。之后的路由切換不再請求數據是因為組件內容是從內存取了不會再重新創建了,對應的鉤子函數不會再執行了。此時,通過新增的生命周期鉤子函數以及這個緩存值就實現了我們要的功能了。
用Vue開發仿旅游站webapp項目總結 (上)有些話還是要說的該說的話,該表明的上篇已經表明了。謝謝上篇評論區一些同學~ 很鼓勵我,不過下下篇估計沒了,這篇總結完,下下篇可能就是之后學習路的總結記錄啦。
接觸vue不久的朋友應該會有收獲。此項目也才是萌新做的第二個Vue項目,使用了腳手架工具(vue-cli2.x非3),前輩老手們有時間看的話,有寫得不好的地方還請多多指導!~
項目中Vuex的不那么低級的用法因為這只是總結操作/思路,沒一步步講代碼,還是先給個官網的圖,這樣方便看點:
前提假設,在腳手架中,我們跟路由引入全局的方法一致去在全局中引入Vuex。創建一個文件夾store,在文件夾下創建個index.js腳本。在store/index.js里面寫Vuex的一些用法邏輯,然后在入口函數main.js里引入就行了。如下:
先忽略馬賽克...
在入口函數main.js中引入:
此時index.js里面的邏輯
拆分以此項目中為例,隨著項目的開發,index.js里的邏輯會越來越復雜,所以選擇拆分。
所以,我們建立兩個腳本(state.js、mutations.js)來分別存儲這兩段代碼。
然后在index.js中引入:
這樣拆分完成,簡潔不少。
mapState輔助函數在項目中,如下圖用法去取得state里面city的數據,是不是顯稍長了點?
Vuex為我們提供了一個方便的API -> mapState
這樣用:
mapState是指,我把State區域里面的公有屬性值映射到這個計算屬性里。
在這里是:把state里city這個公有屬性的值映射到這里的計算屬性city里。
這樣子的話,就可以把
變成可以直接調用這個計算屬性:
...mapState({}/[])這里面可以是數組也可以是對象。是數組的話,那我們就等于直接給計算屬性取名city了,和公有屬性的名稱一樣。
是對象的話,我們就可以給計算屬性自定義取名。
舉個...mapState(對象)的例子:
在當前城市這里也可以改:
這里就是傳對象給mapState,等于把公有屬性city的值映射到計算屬性currentCity里。
此時就可以這樣用:
這樣子就不用寫的那么復雜了。
mapMutations輔助函數利用Vuex提供的這個API可以簡化下列代碼:
這樣用:
mutations里面是有changeC2()這個函數的(這個命名就....僅當測試,輕噴)。我們想在組件中調用mutations里的這個函數去改變公有數據區域state里的值,運用mapMutations可以這樣簡潔地在組件中調用。
這什么意思呢?
mutations里有個叫做changeC2這個方法,這里在該組件的methods中是把這個mutations里的changeC2方法映射到了該組件中methods的changeC2方法里。
...mapMutations()參數也是可接收[]/{}的。
還是用...mapMutations(對象寫法)好理解一點,如下,做個測試:
(亂入的小姐姐~)
這樣子寫也是可以的。也更容易理解這里的映射。
Getter、ModuleGetter和Module該項目中都沒有用到。
Getter假如我們想根據state的值,通過一些計算得到新的值的話,就可以用getter來提供新的數據,避免數據冗余。它的定義也和computed一樣。
getter可以認為是store的計算屬性。就像計算屬性一樣,getter 的返回值會根據它的依賴被緩存起來,且只有當它的依賴值發生了改變才會被重新計算。
Getter 接受 state 作為其第一個參數,也可以接收其他 getter 作為第二個參數。可以屬性訪問(store.getters),可以通過方法訪問,也有 mapGetters輔助函數(該輔助函數主要也是映射關系,將store中的getter映射到局部組件的計算屬性中)。官方文檔給的例子也比較好理解,可以自行看文檔。
ModuleModule的話,看得勉強理解,Vuex允許我們將store分割成模塊(module)。每個模塊擁有自己的state、mutation、action、getter、甚至是嵌套子模塊。
當應用變得非常復雜時,可以使用Module避免store對象變得相當臃腫。
我覺得Module具體的應用要在復雜項目中親自練手過才能熟練,目前不敢輕易下手記錄,暫且記一筆。
使用keep-alive優化性能我們可以在 開發者工具 network 的xhr 中看到
每次我們路由切換的時候(從Home組件頁面跳轉到City組件頁面或反之的時候)都要發送ajax請求數據。
這樣子就重復請求ajax數據了,因為每次路由切換到一個組件的時候,都要重新執行該組件鉤子函數,如果該組件有在mounted鉤子里請求ajax的話,就每次路由切換都要執行了。這樣性能不好。
此時就可以用vue內置的 keep-alive標簽來優化。
在全局根組件App.vue中
我的路由的內容被加載過一次之后,我的路由中的內容就都放到內存之中,下一次再進這個路由的內容的時候,就只需要從內存里把以前的內容拿出來就可以了。
此時,不管切換多少次路由,都只有兩次ajax數據請求了。
因為使用了keep-alive標簽,導致有了新的生命周期函數activated(keep-alive組件激活時調用)、deactivated(keep-alive 組件停用時調用)。
之后的路由切換不再請求ajax數據是因為組件內容是從內存取了不會再重新創建了,對應的mounted鉤子函數不會再執行了。
但每次切換、頁面重新顯示的時候,activated鉤子會執行。
此時可以利用這個鉤子實現一個需求:
當在列表頁選擇點擊了哪個城市后,路由切換回到首頁時,首頁顯示的數據是對應著該城市的數據(意味著ajax只請求該城市對應的Home組件頁面的數據),然后如果在列表頁,選擇了與原本在Home頁相同的城市的話,就不發送ajax請求新數據。
之前,發ajax請求的時候,是直接這樣子發:
實際上,在發送ajax請求的時候,應該帶一個參數的。帶的這個參數應該是 Vuex 中公有的這個數據。也就是當點擊哪個城市的時候,這個參數就是對應哪個城市的名稱。
怎么在請求中帶參數呢?
在請求的連接后面 加上 ?=參數數據
如:
在網頁上試一試,發送的參數就在下面
實現需求的思路是:
在每一次頁面重新顯示的時候(activated鉤子函數觸發)我們判斷此時頁面上的城市是否和上一次顯示的城市相同 如果不相同 就發送ajax請求
然后我們設置個空字符串 lastCity (當做一個中間緩存值用于判斷)
緊接著,當頁面掛載完畢的時候,我們給它賦予當前頁面的城市數據。
然后在頁面更新的時候,判斷上一次的 this.lastCity 的值 是否等于 更新后的 this.city 的值。如果不等于的話,就發送新的ajax請求,請求相應city的數據,如果等于的話就不發送。
此時,通過keep-alive新增的生命周期鉤子函數以及lastCity這個緩存值就實現了我們要的功能了。
詳情頁想記錄下來的東西 實現畫廊組件功能的主要思路先看個gif說明此功能啥樣:
就這個玩意兒。這個就是畫廊。上面有輪播,下面有頁碼。
因為這不僅僅只有一個頁面會用到,可能以后很多頁面都會用到,所以 寫個全局公用的組件Gallary.vue。
需要在詳情頁的一個組件 Banner.vue 里面去使用這個公共組件
gallary用fixed占滿全屏。
利用flex布局,讓這個如下wrapper區域垂直居中
然后使用 Vue-awosome-swiper第三方插件,先放入兩張圖
然后給那個.wrapper定義個寬高100%。按照如下這種寫法的話width先有個100%的寬度了然后height也100%的意思是針對于這個width的寬度來說的,所以這里定義了這個100%的height的意思是這個height與width的寬度相等 意思是一個正方形。
此時頁面:
我們讓圖片按比例自適應這個正方形,再把wrapper下的背景顏色去掉,此時兩張圖片可以正常顯示輪播了:
然后加頁碼,其實這個頁碼就是該插件的按鈕區和配置參數一起控制的。先加上按鈕區代碼:
vue-awesome-swiper這個插件是基于swiper實現的,這里面的配置參數比如 pagination 可以去 swiper 官網找的。
我們去官網找找看能不能找到配置我們頁碼需求的參數(當然是能找到的,不然我還寫個啥...):
由此可見,這個頁面的翻頁樣式就是對應這個paginnation中的paginationType 中的 fraction。
現在來配置參數,首先在swiper上加上 :options="swiperOption"。
然后在data里配置。先把按鈕區配置出來:
再把paginationType ‘fraction’ 分式 給配置出來
現在就有了,但在小小的地方,審查元素才可以看見
原本框架的樣式,通過審查元素找出這里是絕對定位。
那么我們這樣改bottom -1rem就行了?
那肯定是不行的...
這里有個坑,當感覺代碼沒寫錯,頁面卻沒達到預期的時候,就是再次審查元素的時候了...審查元素發現這個插件組件有個swiper-container里還定義了個overflow: hidden。
所以我們在畫廊組件里穿透作用域來改掉這個樣式就行
畫廊邏輯部分很簡單就跳過不記錄了,不過有個坑還是值得提一下。
在畫廊自身的組件gallary.vue里測試功能的時候都好好的,但是gallary這個公有組件是要在詳情頁的Banner.vue組件中引入的。
那么問題就來了,當我們在Banner組件對應的頁面一下子點進去gallary組件對應的頁面的時候,輪播插件會出現一個計算寬度高度的問題。如下gif圖這樣:
要解決這個問題,需要在gallary的輪播插件配置參數中加上這兩個配置參數
加上這兩個參數的意思是:
我這個swiper插件,只要監聽到我這個元素,或者父級元素變化的時候(這個監聽的就是swiper和swiper的父級元素),這個插件會自動地自動刷新一次,重新計算寬高。
通過這次自我刷新,就可以解決輪播插件的這個計算寬度高度的問題。(這些配置參數在swiper官網都可以查到怎樣用的)
實現header區塊漸隱漸現的效果看個gif。
僅提這段,當手指往下滑的時候,逐漸顯示清晰之后一直清晰的div景點詳情框邏輯。
這個逐漸顯示清晰的這塊是用個div框來fixed定位寫的。
邏輯一開始v-show不顯示這個div框并且讓該div框的opacity為0,在activated鉤子函數中檢測全局scroll(window.onscroll)事件(即檢測滾動條的狀態,滾動條一旦動了就觸發scroll事件),當觸發scroll事件時,執行一個方法,此方法里面寫邏輯。寫的邏輯是:當滾動條往下滑動60px外時讓這個div框的v-show參數為true并且通過公式
let opacity = document.documentElement.scrollTop / 140
來讓該div框隨著越往下滑動清晰度越高,然后在這條語句下面限制opacity透明度值為1:opacity = opacity > 1 ? 1 : opacity。
顯而易見:document.documentElement.scrollTop的意思是獲取當前頁面的滾動條縱坐標位置。
這樣功能實現了,但還有個很重要的坑。對全局事件的解綁。
對全局事件的解綁在header區塊邏輯中,我們在activated鉤子中定義了個全局scroll事件。
因為這個是全局事件,所以我們在其他組件中也可以監測到。這樣很容易引發一系列嚴重的隱藏的bug。
所以我們應該在detail下header.vue組件中對該組件解綁:
對應keep-alive引用而可以使用的鉤子還有一個deactivated鉤子。該鉤子在頁面即將被替換成新的頁面的時候觸發。
所以這里我們利用deactivated鉤子和removeEventListener函數來解綁全局事件。
組件中name屬性的三個作用 1、做遞歸組件的時候會用到舉個例子,list組件的name: "DetailList"。在list組件模板中想要使用遞歸組件調用自身時,就要根據name的值來用作標簽(detail-list)調用。如下:
2、對某個頁面取消keep-alive的緩存的時候會用到假設有個Detail.vue組件,其name: " Detail"。當想要keep-alive全局組件時,Detail.vue組件對應的頁面,路由重新切換到這個頁面不用去內存中取緩存值,可以利用Detail組件的name的值如下使用:
這樣等于是除了Detail.vue組件,其他組件都可以擁有設置keep-alive后的功能。
3、vue-devtools調試工具如上圖紅框里的組件名稱,這里的名稱就取決于設置的組件的name屬性的值。
動態路由中ajax動態獲取各個路由目錄對應的值舉項目中例子說明,注意下圖紅框中的值
此時我們應該獲取的是,動態路由中 id為0002的參數的數據。
這樣設置后,其實動態路由中,會把對應的參數存在 這個變量id里。
每次請求,希望把這個id帶給后端,就可以這樣寫:
寫法一現在可以在network的XHR里看見我們發送給后端的請求中附帶了 id
寫法二前面只寫接口名 后面這樣子寫(我們把參數放到params去了):
其實還有問題,這地方我想一步一步來總結設置的動態路由,只是動態加了個id參數并不能自動讓頁面也跟著動態顯示數據,動態顯示數據還得靠ajax請求數據。
而目前這個組件是在mounted鉤子中執行ajax請求的,并且該組件有keep-alive的作用影響著。這樣當路由跳轉到id為0003/0004...頁面的時候,組件也只會從內存中取出第一次進入該組件某個id的頁面。并不能根據id對應顯示頁面。
怎樣通過ajax請求而動態顯示數據呢?有兩種方法,兩種方法上面都提到過。
第一種
在列表頁選擇某個城市,路由自動跳轉回首頁后,首頁需要顯示的是該城市對應的數據這里記錄過。(提示一下:利用activated鉤子,判斷參數id是否等于之前的id,如果不等則重新執行ajax請求。)
第二種
組件中name屬性的三個作用中的第二個作用已經說出了解決方案。
這兩種方式留給讀者自行思考,想不通的可以參考下我github該倉庫里的代碼。src/pages/detail/Detail.vue
路由滾動行為來看個gif
這就是路由跳轉頁面會帶來的影響。會把當前頁面(Home.vue)的屏幕的顯示的寬高 帶到 我們跳轉到的頁面(Detail.vue)上去。造成如上gif所示現象。
這樣來解決。
這個在官方文檔中稱為 路由的滾動行為。
我們現在是想讓每次路由切換進入到下一個頁面的時候滾動在頂部顯示。 繼續看文檔。
把這段代碼復制到路由配置項中:
這樣就實現我們預期的需求。
配置打包 前后端聯調一般等后端數據寫好后,我們就不再使用自己前端模擬的數據,而是去使用后端給過來的數據來調試。
如果要訪問服務器上的數據的話,要在配置文件config/index.js下的proxyTable里把target改為服務器的地址(可以寫內網的IP地址 或 外網的域名都行)。然后改pathRewrite的話,就見實際情況數據存放在服務器的哪個文件夾下了。
真機測試這里的前端的項目是通過 webpack-dev-server 啟動的,默認不允許通過ip來訪問內部服務器。所以我們需要把默認的配置項做修改。
想讓這個 webpack-dev-sever 能夠被ip訪問的話,需要這樣配置下:
(貌似漏點了... 其實也沒關系....)
然后這里真機測試的時候,有時候就會遇到一些在PC上開發時發現不了的bug以及要考慮兼容性。這個就要各人根據實際情況來改了。
打包上線vue-cli 2.x中,就可以在項目目錄下執行指令 npm run build,此時Vue的腳手架工具會幫我們自動地對src目錄下源代碼進行打包編譯生成一個能被瀏覽器運行的代碼,同時這個代碼也是壓縮過后的代碼。
打包完成后會生成一個dist文件夾,給到后端開發人員,或者直接把static文件夾里的內容扔到后端服務器根目錄上就OK了。這只是基本的操作,想要改變訪問路徑或怎樣的操作,就各位小伙伴自己去找了,有心自會找到~
結語這篇文章僅是在這個項目中對于我個人而言覺得可以總結記錄下來的,更具體更詳細的知識和流程,感興趣不妨去imooc支持一下DellLee老師的這門課程~
有部分地方代碼量太多不方便貼出來,想參考代碼學習的可以進我Github。
希望也能幫到你們~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/114205.html
摘要:寫著寫著發現會寫不少內容全部寫在一篇文章里感覺太多了不方便看,所以分為上下篇吧下篇寫完啦,感興趣的朋友可以繼續關注開發仿旅游站項目總結下溫馨提示此文章,僅是做完項目后的個人覺得可以總結下來的操作思路,接觸不久的朋友應該會有收獲。 寫著寫著發現會寫不少內容... 全部寫在一篇文章里感覺太多了不方便看,所以分為上下篇吧...下篇寫完啦,感興趣的朋友可以繼續關注 => Vue開發仿旅游站we...
摘要:寫著寫著發現會寫不少內容全部寫在一篇文章里感覺太多了不方便看,所以分為上下篇吧下篇寫完啦,感興趣的朋友可以繼續關注開發仿旅游站項目總結下溫馨提示此文章,僅是做完項目后的個人覺得可以總結下來的操作思路,接觸不久的朋友應該會有收獲。 寫著寫著發現會寫不少內容... 全部寫在一篇文章里感覺太多了不方便看,所以分為上下篇吧...下篇寫完啦,感興趣的朋友可以繼續關注 => Vue開發仿旅游站we...
摘要:用開發仿旅游站項目總結上該說的話,該表明的上篇已經表明了。之后的路由切換不再請求數據是因為組件內容是從內存取了不會再重新創建了,對應的鉤子函數不會再執行了。此時,通過新增的生命周期鉤子函數以及這個緩存值就實現了我們要的功能了。 用Vue開發仿旅游站webapp項目總結 (上)該說的話,該表明的上篇已經表明了。謝謝上篇評論區一些同學~ 很鼓勵我,不過下下篇估計沒了,這篇總結完,下下篇可...
閱讀 2800·2021-11-22 14:44
閱讀 541·2021-11-22 12:00
閱讀 3683·2019-08-30 15:54
閱讀 1570·2019-08-29 17:15
閱讀 1898·2019-08-29 13:50
閱讀 1106·2019-08-29 13:17
閱讀 3512·2019-08-29 13:05
閱讀 1181·2019-08-29 11:31