vue大型電商項目尚品匯(前臺篇)day03

来源:https://www.cnblogs.com/heymar/archive/2022/05/20/16294088.html
-Advertisement-
Play Games

堆積了兩天一起發的,先祝大家節日快樂 後面任務很繁重,還有登錄註冊組件還有後臺管理頁面,真的繁重,我現在感覺每天全天時間都在學都不一定學得完,主要想在六月一號之前把整個項目過一遍。看看能不能創造奇跡 一.防抖和節流 拋出一個問題,就是我們的三級聯動,正常情況你慢慢的去滑動是沒有bug的,但是當你快速 ...


堆積了兩天一起發的,先祝大家節日快樂
後面任務很繁重,還有登錄註冊組件還有後臺管理頁面,真的繁重,我現在感覺每天全天時間都在學都不一定學得完,主要想在六月一號之前把整個項目過一遍。看看能不能創造奇跡

一.防抖和節流

拋出一個問題,就是我們的三級聯動,正常情況你慢慢的去滑動是沒有bug的,但是當你快速的從上往下滑一圈,你會發現只會觸發幾個標題,如果這個時候我們的回調也就是滑動的事件函數裡面有大量的業務邏輯,他會執行完一個再去執行另一個,但是你已經滑完很久了,所以這個時候頁面就會有卡頓現象

1.防抖

什麼是防抖?防抖就是一個事件觸發多次,最終只會有觸發一次的結果。

我們這裡防抖和節流採用一個 Lodash的插件來完成,但是自己也要懂防抖和節流的一個原理,首先防抖大概封裝是這樣的,定義一個函數,接受的參數為我們事件的回調和定時器的等待時間,裡面先清除一個定時器,然後定義一個定時器,定時器裡面調用我們的事件回調,當我們事件觸發就去執行這個防抖函數,意思就是比如我們有一個鍵盤輸入事件,當我們一輸入就會清除定時器,在執行定時器,定時器裡面的回調才會列印輸出我們輸入的內容,要等個500ms,那麼在這500ms之內你再次輸入,又不會列印輸出了因為定時器被清除了,又會重新計時500ms,這就是防抖的一個思想。

image-20220519104839618

註意這個clear只能寫在函數的外面

2.節流

防止觸發頻率過快,在一個時間段內只執行一次。

一定要把防抖和節流做一個區別:防抖是可以觸發n次,但是只會以你不觸發後的最後一次為準,而節流是可以觸發n次,但是限制了你的觸發頻率,所以n次內其實只觸發了不到n次

自己封裝就像這樣,需要一個節流閥flag,當我點擊一次去判斷節流閥,判斷成功進來先把節流閥關閉,在執行定時器,單位時間內執行完節流閥才會打開,所以這段時間,你怎麼點擊都執行不了回調,這裡不需要清除定時器,因為定時器會自動到時間就結束

image-20220519111724587

3.三級聯動節流

首先要註意一點,vue腳手架預設是給你安裝好了lodash

image-20220519141334043

怎麼來用具體可以參照他的中文文檔,它有兩種引入方式,以節流為例,在文檔裡面找到_.throttle,最主要的是引入如果是全部引入,因為他還有很多的方法,數組求和等等,直接以_命名他

image-20220519141942293

然後用的時候就像官網文檔一樣用

image-20220519142003430

但是我們這裡如果就想用一下節流就沒必要全部導入了,直接導入我們想要的節流,註意怎麼導入的,在lodash找到throttle

image-20220519142139353

然後用的時候也是直接用,還要註意一下這裡要回歸原始的es5的鍵值對的形式才可以使用這個節流

image-20220519142235795

二.三級聯動組件路由跳轉

當我們呢點擊三級聯動的一二三級標題的時候,可以實現跳轉到search頁面,並且會把自己的id和標題當成參數傳過去,所以這裡就涉及到,路由的跳轉,我們的這些標題又剛好是a標簽用一個router-link就可以跳轉過去,但是這樣做會有一點不完善,因為我們一級標題還好後面二級三級那麼多,每一個都轉換為router-link,這個組件標簽又是vue內部提供的,去點擊一次還要進入vue內部處理一次,就會造成頁面卡頓

那麼就只有採用編程式跳轉了,其實這裡編程式跳轉也不太好,為什麼?我們每一個a標簽都要來一個點擊事件,是不是跟上面這種情況差不多了

這裡最好的解決辦法是,用編程式路由導航➕事件委托來做,我們給他們共同的父元素來一個點擊事件,他們的父元素只有一個不就可以解決了嗎

image-20220519144438643

現在就要去解決一些問題了

  • 第一個問題:我們下麵這麼多元素,怎麼就能確保點擊的是a標簽?

    我們可以把每一級標題添加一個自定義屬性data-categoryName,當我們點擊的時候再通過e.target.dataset.categoryName來判斷點擊的元素是否是a標簽

    image-20220519151556136

  • 第二個問題:怎麼來區分點擊的是一級、二級還是三級標題,因為我們傳過去的參數有id1、id2、id3,這裡做一下改造,將我們前面獲取到的自定義屬性採用解構賦值,註意一下,我們雖然自定義屬性是駝峰命名,但是最終到頁面會給你轉化為小數 ,為一個變數

    image-20220519152926258

    我們給每個標題同樣通過自定義屬性給他們的id給到,同時以解構賦值接受給變數

    image-20220519153158831

    得到參數之後,因為我們是編程式導航嘛,所以最終肯定是要通過push方法傳出去值的,判斷為a標簽後定義一個對象裡面放的是要跳轉的地址也就是search,然後依次判斷是否是id1,是就來個query的對象裡面正常寫一般寫在push裡面query裡面的參數形式,最後都判斷完了,把query對象放到跳轉地址這個對象裡面,直接push即可

    image-20220519154134089

    image-20220519154147119

三.search模塊商品分類

將三級聯動全局組件直接拿過來,然後給三級聯動來一個條件渲染,預設為true

image-20220519160930007

這裡要考慮一點,當我們進入home那麼在search裡面的組件就會被銷毀,當我們進入search,在home裡面的組件就會被銷毀,所以當我們切換到search的時候,typenav的mounted又會被執行一次,那麼我們就可以把邏輯寫在這裡,就是當$route.path!=home這個時候就把條件改為false

image-20220519161356937

image-20220519161407935

然後滑鼠移入分類,又改為true

image-20220519161718491

移出可以接著上次在共同父級設置的移出這裡做,同樣還是要判斷一下是不是home頁面,因為home不能隱藏

image-20220519162006615

1.過渡動畫

回顧一下過渡動畫,要寫vue的過渡動畫必須有一個前提 那就是必須要有v-for或者v-show,由transition標簽包裹,然後可以寫自己的name,css部分name-enter,name-enter-to,離開是leave,最後時間以及要變化哪些都寫在active裡面

image-20220519164022245

image-20220519164221157

四.三級聯動列表優化

現在還有什麼優化的地方,有一個地方,我們剛纔說過,切換一次路由,裡面的所有組件都會被銷毀,包括三級聯動組件,所以頻繁切換,三級聯動也在頻繁銷毀頻繁執行mounted,而我們的mounted裡面寫了一個東西,dispatch派發到vuex裡面的actions,並且這裡還有邏輯處理,就是發送了ajax請求,所以問題就出現在這裡,我們切換一次路由組件,就會發送一次ajax請求,但針對於這裡來說,這裡三級聯動的請求,只需要一次就夠了,也沒有改,所以就需要換位置,他的統計都不只是只執行一次,繼續往父級走,那就是App組件,就寫在這裡,因為app組件只會執行一次,在這裡派發到actons,typenav需要的時候就state來取就是

image-20220519165722507

五.合併參數

就是將我們的query和我們的params參數合併起來。

這裡主要是考慮兩種場景,一個是點擊搜索會有params的參數,這個時候我點擊分類標題會將他的query參數合併上去。因為我們是後點的三級聯動列表,所以邏輯應該在後點這裡合併上去

image-20220519173441444

image-20220519173913604

然後還有一種場景,我已進入主頁就由三級聯動標題進入搜索頁,然後我再根據搜索頁去搜索更加詳細的查找內容,這個時候後點的是header裡面的搜索按鈕,所以邏輯在header組件去做

image-20220519174303785

六.mockjs模擬數據

因為我們現在首頁組件當中除了三級聯動後面的業務沒有介面,包括輪播圖等,這個時候就需要一個模擬數據,mockjs是一個插件,專門用來生成數據,攔截ajax請求

1.創建數據

使用方法:

  • 首先src創建一個mock文件夾

  • 第二步開始創建假數據,我們的數據都是json格式,所以直接在mock裡面創建json文件,放入數據,註意格式化一下,不能留有空格,不然跑不起來

    image-20220519203248533

    這是輪播圖的模擬數據,註意點mock數據需要的圖片要放到public文件夾下,因為只有public下麵的文件打包的時候才會原封不動輸送出去

  • 第三步創建mockServer.js通過mockjs來模擬出數據

    image-20220519203710987

    註意引入Mock名字必須是大寫首字母,它是一個對象,後面引入兩個json文件,為什麼沒有export,這裡可以直接導入?因為webpack是預設對圖片、json文件導出的,這些文件是預設導出的,不用export

  • 然後就可以調用Mock裡面的mock方法,兩個參數,第一個是請求路徑,第二個是請求數據

    image-20220519204007784

  • 然後我們的mockServer.js文件需要在入口文件引入,表示至少需要執行一次,我們的模擬數據才會出現,這裡不需要暴露,直接在入口文件引入這個js文件,表示直接執行

    image-20220519204159152

2.應用數據

這樣一來我們的模擬數據就創建好了,接下來就是怎麼來用他的問題了。

他雖然不會發起真正的ajax請求,會被瀏覽器攔截,但是可以把他當做真正的請求看,所以第一步我們先去介面統一管理裡面,給他來一個請求和響應的攔截器,並且用axios創建一個他的實例,而且baseurl要為/mock

image-20220519205518793

然後去介面統一管理處,創建一個獲取banner的介面函數

image-20220519205936553

這個時候回到我們需要輪播圖的組件,給他的mounted派發actions,把我們的數據用vuex管理起來,同時在actions獲取ajax請求

image-20220519210138301

去actions發起ajax請求

image-20220519210448598

可以在列印台看到,我們確實得到了數據,最重要的一點沒有網路請求,這就是ajax的攔截

image-20220519210551214

這個時候mutations將我們的數據給上,同時state定義一個數組裝這個數據

image-20220519211602139

在我們輪播圖組件拿到這個數據,通過計算屬性

image-20220519211756813

3.輪播圖(方案一)

我們用swiper實現輪播圖功能

  • 第一步下載導入,swiper需要導入兩個,一個是css樣式,由於我們下麵的組件也會用到這個樣式,所以直接導入在入口文件,還有一個是js哪裡要用就導入在哪

    image-20220520093725129

  • 實現swiper輪播圖第二步就是要定義好結構,結構這裡最重要的是用我們的mock模擬出來的數據,列表渲染出來

    image-20220520094226560

  • 這個時候可以去用她的js邏輯了,但是要想一下這個定義在哪裡,有一個很重要的前提,new Swiper首先必須頁面上有這些結構,如果我們把new Swiper寫在mounted,這個時候頁面上確實有結構了,但是我們的列表迴圈裡面的bannerList是通過ajax得來的,要知道ajax是典型的的非同步函數,所以當我們開始new的時候,圖片這些數據還沒有開始遍歷的,這個時候結構就不完整,輪播圖的實現就有問題

    這裡有一個比較笨的解決方法,就是開一個定時器,將new swiper放在裡面

    image-20220520103855570

4.輪播圖(方案二)

這也是最佳的完美解決方案,我們首先可以通過watch來做,去觀察bannerList的值,當他發生變化就已經代表了ajax請求回來了,所以這個時候再去new swiper

image-20220520112621313

當然只是這樣還是不夠,為什麼?這個時候我們的bannerList確實有值了,非同步操作也已經完成了,但是這個時候要把這些數據拿去v-for列表迴圈又需要一定的等待時間,這個時候你直接去new了,其實頁面上的結構還是沒有的,這裡真正完美的做法是watch+nextTick來做

nextTick:官網的解釋在下次 DOM 更新迴圈結束之後執行延遲回調。在修改數據之後立即使用這個方法,獲取更新後的 DOM。

其意思就是當DOM完全呈現之後包括迴圈結束之後才會去執行nextTick的回調函數

image-20220520113401392

七.floor組件模擬數據

又要給一個組件動態渲染數據了,由於前面已經通過mock模擬出來了數據,這個時候需要先將數據的介面寫進介面統一管理

image-20220520115442914

然後vuex三部曲走起,因為我們的介面請求都是在actions裡面來做的

image-20220520115814755

這個時候我們應該去去派發actions了,但是我們先觀察一下這個數據的結構,它是一個數組裡面有兩個對象,而我們的floor這個組件當時也復用了兩次,說明是不同的兩個對象,如果我在floor組件裡面去派發actions到時候來的數據就是一個數組有兩個對象,你用這個也不行用那個也不行,都體現不了復用性,這裡應該在他們父級也就是放他們組件標簽處來接收數據,並且通過v-for遍歷組件標簽

image-20220520120044567

image-20220520120814646

接下來遍歷我們的floor組件標簽,同時父傳子,通過props把屬於他們自己的那個對象傳過去

image-20220520120935575

image-20220520121019340

1.floor數據渲染

註意點:

  • swiper5及以前的版本最大的容器叫做swiper-container不是現在官網上的swiper

image-20220520141823868

  • 還有一個點我這裡直接在floor組件的mounted函數裡面new swiper是可以實現的,為什麼?

    image-20220520144317153

    要知道當時不能實現是因為在mounted裡面還發了ajax這個非同步操作請求,所以那個時候接著來一個new swiper是沒有完整結構的,但是在這裡我們的ajax是在父級home這個組件完成的,並且都已經把數據通過props發過來了,你在floor裡面也沒有影響結構的非同步了,所以直接在這裡的mounted new swiper就沒問題

    image-20220520144614907

八.共用組件carousel

當我們開發項目時,如果看到某一個組件在很多地方都使用,而且結構包括邏輯這些都一樣的話,就可以拆分為全局組件,大家直接復用,就比如這裡的上下兩個輪播圖。

當然大的輪播圖是用watch來做的,我們也可以把小輪播圖用watch來做,你會發現監視不了這個數據

image-20220520151728083

因為我們這個數據是父組件派發然後傳過來的,可以說過來的時候就已經是那個樣子了,從沒有變過,沒有變動還怎麼去監視,這裡可以添加immediate讓監視屬性一開始就監視一次。

image-20220520151912712

既然是一開始就執行,那時候肯定floor也為空,不然怎麼會監視到數據變化,所以還是要配合nextTick讓數據都有了到DOM上了再來new

image-20220520152341267

這樣我們就開始拆分組件了,全局組件放在components下麵,關鍵步驟在於我們需要接受一個從外部傳進來的輪播圖數據,並且全局組件監聽的就是他

image-20220520152904531

然後在我們模板上遍歷的也是他

image-20220520152931032

註冊全局組件

image-20220520153445819

將我們的組件標簽運用上,同時將數據傳過來

image-20220520154938162

九.Search模塊

1.靜態組件

完成一個組件開發,還是那個套路顯示靜態頁面完成,然後拆分組件,發請求,vuex三部曲,組件獲取數據並渲染出來

2.Search模塊vuex操作

我們已經完成了靜態組件以及拆分,下一步就是ajax的api請求,因為是api開頭的所以可以直接用封裝好的axios來獲取請求,但是還是要去介面統一管理封裝一下函數,因為這裡我們search搜索商品的參數很多,所以是用一個對象傳進來,而且正常的寫法data後面本身就是一個對象,所以這裡params傳進來的參數至少都是一個空對象

image-20220520163925204

然後就可以去vuex三部曲,通過介面文檔可以看到,我們返回的結果是一個對象,所以這裡直接數據定義為對象形式,但是這裡還測試不了,用到了我們之前還沒怎麼用過的dispatch的第二個參數就是我們要傳進來的值

image-20220520164611319

3.數據動態展示

我們可以看到獲取過來的數據有很多是數組形式的,這個時候就要用到 getters了,項目中的getters主要作用就是簡化倉庫中的數據,就是當我們state定義的數據裡面還嵌套多層數據,這個時候就可以用gettes來簡化,然後我們到時候用的話,就會簡便的多

image-20220520173340596

所以把上面這個數組通過gettes來獲取,註意的是gettes可以接受一個參數,就是當前倉庫中的state

image-20220520173600739

同樣也是寫在計算屬性裡面來獲取

image-20220520173735788

然後我們就可以開始先把下麵商品詳情頁的數據動態展示了,先獲取getters

image-20220520174957860

在我們getters裡面有一點要註意,雖然一般不會出現這種情況,就是怕別人沒有網了,這個時候我們沒有goodsList等這些數組,那麼用一個亦或語法讓其成為空數組以防網頁崩潰

image-20220520175139917

4.根據不同參數獲取數據展示

要根據不同參數獲取數據展示,那我們就需要將mounted裡面發起ajax請求的派發封裝為一個函數

image-20220520203953003

但是這裡發起一個空對象去搜索有點扯,我們需要把發給伺服器的參數整起來,看介面文檔可知,要發給伺服器的參數為一個對象,所以我們可以把這個參數定義在data裡面,然後再mounted之前傳進去參數,自然而然mounted掛載之後就會是我們從主頁通過點三級聯動及搜索頁面的詳情頁或者是從主頁通過搜索得來的詳情頁

image-20220520204845268

當然我們不能就以這個數據發過去,所以在mounted,也就是dispatch之前將真正的參數傳進來,註意這裡用到一個es6新增對象的方法Object.assign,他可以合併多個對象,如果有相同的就以後面的值為準,沒有的就添加上最後形成一個新對象

image-20220520210004186

5.search模塊子組件動態開發

既然我們都做了serach的搜索了,search裡面還有一個子組件,來展示品牌和一些標簽選擇的,這些數據也是順帶返回回來的所以順便就做了,因為這兩個數據是數組返回,所以直接getters,然後組件接受getters

image-20220520212629613

6.再次請求獲取數據

為什麼要再次請求,因為我們剛纔做的版本只是在進入search這個組件由於重新掛載了,所以只能請求mounted那一次,如果我要繼續搜索呢?

這個時候,有一個關鍵的技術點,當我們每一次搜索或者點擊三級聯動列表的時候,我們的url是不是在變

image-20220520214601112

而且以前我們都知道我們的響應數據一般是data裡面或者計算屬性裡面,通過vue管理者工具可以看到,我們的$route其實也是響應式數據

image-20220520214658847

所以關鍵點就在於這裡,我們可以監聽$route,然後把參數來一次assign方法合併,再次dispatch即可做到重覆搜索的功能

image-20220520221209548


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、概述 Hue是一個開源的Apache Hadoop UI系統,最早是由Cloudera Desktop演化而來,由Cloudera貢獻給開源社區,它是基於Python Web框架Django實現的。通過使用Hue我們可以在瀏覽器端的Web控制臺上與Hadoop集群進行交互來分析處理數據,例如操作 ...
  • 一、安裝mysql8.0 ##下載mysql安裝包 http://mirrors.sohu.com/mysql/MySQL-8.0/ wget http://mirrors.sohu.com/mysql/MySQL-8.0/mysql-community-client-8.0.18-1.el7.x8 ...
  • 分享嘉賓:王懷遠 阿裡雲 表格存儲架構師 編輯整理:李瑤 DataFun 出品平臺:DataFunTalk 導讀: 大家好,我是王懷遠,我2015年加入阿裡雲,一直從事表格存儲的研發和架構相關工作,目前擔任表格存儲的架構師。我在存儲和資料庫領域有一些研發和架構方面的經驗。 本次分享的主題是一站式物聯 ...
  • 一、概述 Impala 直接針對存儲在 HDFS、HBase或 Amazon Simple Storage Service (S3)中的 Apache Hadoop 數據提供快速的互動式 SQL 查詢。Impala是一個基於Hive、分散式、大規模並行處理(MPP:Massively Paralle ...
  • 今天我們來認識一位接觸 OpenHarmony 不到一年,便帶領團隊成功開發出一款“啟航 KP“智能開發套件的開發者——軟通動力資深項目經理許北林。 ...
  • 這次更新的設計規範不僅新增了更多應用場景案例,幫助大家高效設計不同類型的業務應用,還通過清晰直觀的案例對比圖,幫助大家有效避坑。 ...
  • 在音視頻應用中我們經常涉及到耳機麥克風和設備麥克風的切換。不同聲道的配置。在遇到這種情況的時候,我們如何配置呢? 耳返即耳機採集監聽,在設備上插入耳機(普通耳機或藍牙耳機)後,能從本機耳機側聽到本設備麥克風采集的聲音。 雙聲道即兩個聲音通道,聽到聲音時可以根據左耳和右耳對聲音相位差來判斷聲源的具體... ...
  • 對於運營者來說,消息推送一直是提升用戶活躍與轉化的重要工具,如何在提升轉化的情況下,同時不降低用戶的接受程度,這一直是運營不斷追求的目標。 好的推送不只在於優質的推送內容,還需要把握合適的時機。在合適時機把用戶喜歡的內容推送給他們,才能有效促進推送轉化。作為一名用戶,大家每天都會在各個時間點收到不同 ...
一周排行
    -Advertisement-
    Play Games
  • 什麼是工廠模式 工廠模式是最常用的設計模式之一,屬於創建型模式。 有點: 解耦,可以把對象的創建和過程分開 減少代碼量,易於維護 什麼時候用? 當一個抽象類有多個實現的時候,需要多次實例化的時候,就要考慮使用工廠模式。 比如:登錄的抽象類ILoginBusiness,它有2個實現,一個用用戶名密碼登 ...
  • 這次iNeuOS升級主要升級圖形渲染引擎和增加豐富的圖元信息,可以很快的方案應用。總共增加41個通用和行業領域的圖元應用,增加2154個圖元信息,現在iNeuOS視圖建模功能模塊總共包括5894個行業圖元信息。現在完全支持製作高保真的工藝流程和大屏展示效果。 ...
  • 效果圖先附上: 首先 這是我是參考 教程:使用 SignalR 2 和 MVC 5 實時聊天 | Microsoft Docs 先附上教程: 在“添加新項 - SignalRChat”中,選擇 InstalledVisual> C#>WebSignalR>,然後選擇 SignalR Hub 類 (v ...
  • 一、前言 項目中之前涉及到胎兒心率圖曲線的繪製,最近項目中還需要添加心電曲線和血樣曲線的繪製功能。今天就來分享一下心電曲線的繪製方式; 二、正文 1、胎兒心率曲線的繪製是通過DrawingVisual來實現的,這裡的心電曲線我也是採用差不多相同的方式來實現的,只是兩者曲線的數據有所區別。心電圖的數據 ...
  • 安裝 Redis # 首先安裝依賴gcc, 後面需要使用make編譯redis yum install gcc -y # 進入 /usr/local/src 目錄, 把源碼下載到這裡 cd /usr/local/src # 下載 redis 7.0.2 的源碼,github被牆,可以使用國內的地址 ...
  • Redis 的定義? 百度百科: Redis(Remote Dictionary Server ),即遠程字典服務,是一個開源的使用ANSI C語言編寫、支持網路、可基於記憶體亦可持久化的日誌型、Key-Value資料庫,並提供多種語言的API。 中文官網: Redis是一個開源(BSD許可),記憶體存 ...
  • 事情的起因是收到了一位網友的請求,他的java課設需要設計實現迷宮相關的程式——如標題概括。 我這邊不方便透露相關信息,就只把任務要求寫出來。 演示視頻指路👉: 基於JavaFX圖形界面的迷宮程式演示_嗶哩嗶哩_bilibili 完整代碼鏈接🔎: 網盤:https://pan.baidu.com ...
  • Python中的字典 Python中的字典是另一種可變容器模型,且可存儲任意類型對象。鍵值使用冒號分割,你可以看成是一串json。 常用方法 獲取字典中的值 dict[key] 如果key不存在會報錯,建議使用dict.get(key),不存在返回None 修改和新建字典值 dict[key]=va ...
  • 迎面走來了你的面試官,身穿格子衫,挺著啤酒肚,髮際線嚴重後移的中年男子。 手拿泡著枸杞的保溫杯,胳膊夾著MacBook,MacBook上還貼著公司標語:“加班使我快樂”。 面試官: 看你簡歷上用過MySQL,問你幾個簡單的問題吧。什麼是聚簇索引和非聚簇索引? 這個問題難不住我啊。來之前我看一下一燈M ...
  • tunm二進位協議在python上的實現 tunm是一種對標JSON的二進位協議, 支持JSON的所有類型的動態組合 支持的數據類型 基本支持的類型 "u8", "i8", "u16", "i16", "u32", "i32", "u64", "i64", "varint", "float", "s ...