重構商城App專案——知識總結

omnoob發表於2019-08-02

參考文件:mint UIswiper


  1. index.html 標籤解釋
  • <link rel="dns-prefetch" href="#"> DNS預解析,可以減少圖片的解析時間。
  1. Vue 相關知識
  • vue例項掛載點,不能是 body 或 html , 所以要加一層容器,包裹想要掛載的地方。
  • 單vue檔案,template 是必需的而且只能有一個根節點,style 可以有多個。
  • Vue元件庫:自行查詢
Mint UI 對比 Element UI
複製程式碼

首頁

  1. Mint UI :基於 Vue.js 的移動端元件庫
- 1. npm安裝
    $ npm i mint-ui -S
    
- 2. 引入 Mint UI
    - 1. 完整引入
    - 2. 按需引入
         1.需要安裝babel-plugin-component:
         $ npm install babel-plugin-component -D
         2.然後,將 .babelrc 修改為:
             {
              "presets": [
                ["es2015", { "modules": false }]
              ],
              "plugins": [
                  // 主要是這部分 , 實際使用時,大括號外的中括號需去掉(程式碼複製於官網)
                  ["component", [  
                    {
                      "libraryName": "mint-ui",
                      "style": true
                    }
                  ]]
                  // 到這部分
              ]
            }
            
- 3. 選擇想要引入的元件按指令操作即可。
複製程式碼
  • 觸底載入更多資料———Infinite scroll:無限滾動指令
- 1. 引入
    import { InfiniteScroll } from 'mint-ui';
    Vue.use(InfiniteScroll);
    
- 2. 例子
    為 HTML 元素新增 v-infinite-scroll 指令即可使用無限滾動。滾動該元素,
    當其底部與被滾動元素底部的距離小於給定的閾值(通過 infinite-scroll-distance 設定)時,
    繫結到 v-infinite-scroll 指令的方法就會被觸發。
    
    <ul
      v-infinite-scroll="getLists"        // 繫結到 v-infinite-scroll 指令的方法就會被觸發
      infinite-scroll-disabled="loading"  // 若為真,則無限滾動不會被觸發       
      infinite-scroll-distance="10">      // 觸發載入方法的滾動距離閾值(畫素)   
      <li v-for="item in list">{{ item }}</li>
    </ul>
    
- 3. bug: 觸發繫結的方法期間,若再次觸發,則仍會觸發該方法,這是不合理的。
    設定loading值:在觸發方法時先設定loading=true ,方法完成後設定loading=false
    
- 4. bug: 每次觸發方法只重新整理資料,原資料被覆蓋,這不符合商品列表的期望。
    得到當前的商品列表(curLists)時,判斷商品列表(lists)是否為空:
        空則直接賦值 this.lists = curLists
        非空則使用陣列拼接方法連線資料 this.lists = this.lists.concat(curLists) 
    
複製程式碼
  1. bottom-nav
- 1. 將 bottom-nav 單獨拿出來,放在新建的 Foot.vue 中, 並且抽出對應的css 放入style中。
- 2. 點選底部按鈕時,要完成兩個任務
    - 1. 點選按鈕,切換頁面,切換樣式
        - 1. 將四個按鈕使用v-for渲染,let navConfig = [],存放四個按鈕的 name,href,icon
        - 2. 使用 index === curIndex 法渲染 active 效果。
        發現:切換頁面後,渲染的效果失效
        方法: 切換頁面時傳遞index引數: location.href = `${list.href}?index=${index}`
              渲染介面時,解析href得到index: 
                let {index} = qs.parse(location.search.substr(1))
                curIndex: parseInt(index) || 0 
     
     需要引入 qs ,解析 location 。
複製程式碼
  1. swiper
將 swiper-container 拿出來,放在新建的 Swipe.vue 中

使用swiper元件:
- 1. 下載並安裝swiper
     $ npm install swiper
     
- 2. 分析:除首頁需要輪播,商品詳情頁需要輪播,所以把輪播元件單獨拿出來,
     使用的時候只需要傳遞不同的資料(引數)即可。
     
- 3. 在 index.html 中引入 Swipe
    - 1. 在 api.js 中加入 輪播圖的路徑:  banner: '/index/banner'
    - 2. 在 index.js 的 methods 中 寫 getBanner 方法,並且放入 created 中
    - 3. 在 index.js 中引入 Swipe.vue ,並放入 components 中
    - 4. 在 index.html 中對應位置寫<Swipe></Swipe>
    
- 4. 把資料傳遞給給元件,讓元件進行渲染 ———— props(Vue-元件-prop 檢視 props的陣列形式、物件形式)
    - 1. 在 Swipe.vue 中 寫props物件形式(物件形式能進行 prop驗證 )
        物件形式:
          props:{
              lists:{
                type: 指定輸出型別
                required: true時,必須符合 type 的型別  
              }
          }
    - 2. 當 prop 驗證失敗的時候,(開發環境構建版本的) Vue 將會產生一個控制檯的警告。
         注意那些 prop 會在一個元件例項建立之前進行驗證,所以例項的屬性 
         (如 data、computed 等) 在 default 或 validator 函式中是不可用的。
         
- 5. 使用 Swiper 元件時,要遵守人家給出的頁面格式:
        <!-- Slider main container 滑塊主容器 -->
        <div class="swiper-container">
            <!-- Additional required wrapper 附加所需包裝器 -->
            <div class="swiper-wrapper">
                <!-- Slides 幻燈片 -->
                <div class="swiper-slide">Slide 1</div>
                <div class="swiper-slide">Slide 2</div>
                <div class="swiper-slide">Slide 3</div>
                ...
            </div>
            <!-- If we need pagination 如果我們需要分頁 -->
            <div class="swiper-pagination"></div>
        
            <!-- If we need navigation buttons 如果我們需要導航按鈕 -->
            <div class="swiper-button-prev"></div>
            <div class="swiper-button-next"></div>
        
            <!-- If we need scrollbar 如果我們需要滾動條 -->
            <div class="swiper-scrollbar"></div>
        </div>
     所以按照此格式,在 index.html-Swpie 中補充 class ,加入分頁器
     
- 6. v-for 列表渲染 swiper-slide , 並且動態繫結url、img

- 7. swiper是對dom節點進行操作的,dom節點什麼時候生成?
     生命週期:mounted
     - 1. index.html 中
          <Swipe :lists="bannerLists" v-if="bannerLists"></Swipe>
          只有獲得了資料,才會渲染
     - 2. Swipe.vue 中 (此時不需要限制 lists 的型別)
          對資料進行監聽
          created() {
            // console.log('created: ',document.querySelectorAll(".swiper-slide"));
          },
          mounted() {
            // console.log('mounted: ',document.querySelectorAll(".swiper-slide"));
          },
          watch: {
            lists(value, oldValue) {
              console.log('value, oldValue: ',value, oldValue);
              console.log('before nextTick: ',document.querySelectorAll(".swiper-slide"));
              this.$nextTick(() => {
                console.log('after nextTick: ',document.querySelectorAll(".swiper-slide"));
              });
            }
          }
          結果:
            created:  NodeList []
            mounted:  NodeList []
            value, oldValue:  (3) [{…}, {…}, {…}, __ob__: Observer] null
            before nextTick:  NodeList []
            after nextTick:  
            NodeList(3) [div.swp-page.swiper-slide, div.swp-page.swiper-slide, div.swp-page.swiper-slide]
            
    注意:專案中選擇了 1 方法,以下程式碼都是按照 1 方法進行。
    
- 8. 引入 Swiper ,並引入 Swiper 的樣式:
        import Swiper from 'swiper'
        import 'swiper/dist/css/swiper.css'
        
- 9. 配置Swiper(參考官方文件)
     在mounted中:
            var mySwiper = new Swiper(".swiper-container", {
              direction: "horizontal", // 水平方向輪播
              loop: true,              // 設定為true以啟用連續迴圈模式
              pagination: {            // 分頁器
                el: ".swiper-pagination"
              },
              autoplay: {              // 自動輪播,延遲5s
                delay: 5000
              }
            });
複製程式碼

分類頁

  1. 基礎處理
- 1. 將 category.html category.css 放入新建的 pages/category 資料夾,
     並建立 category.js ,引入響應的css,引入Vue、axios、Foot、url 。
     並將 category.html 中Foot對應的部分刪除,切換為   <Foot></Foot>
     用div(id=app) 包裹整個頁面,用來掛載vue例項
     
- 2. 找到右邊商品列表的容器:class="main-content",在對應的css上寫   overflow-y: scroll;
     overflow:定義當一個元素的內容太大而無法適應 塊級格式化上下文 時候該做什麼
               是 overflow-x、overflow-y 的簡寫
            屬性:
             - 1. visible:預設值。內容不會被修剪,可以呈現在元素框之外。
             - 2. hidden:如果需要,內容將被剪裁以適合填充框。 不提供滾動條。
             - 3. scroll:如果需要,內容將被剪裁以適合填充框,瀏覽器一直顯示滾動條
             - 4. auto:取決於使用者代理。如果內容適合填充框內部,則它看起來與可見內容相同,
                        但仍會建立新的塊格式化上下文。 如果內容溢位,桌面瀏覽器會提供滾動條。
            注意:
             - 1. 除visible外的值均會建立一個新的快格式化上下文。
             - 2. 為使 overflow 有效果,塊級容器必須有一個指定的高度(height或者max-height)
                  或者將white-space設定為nowrap。
             - 3. 設定一個軸為visible(預設值),同時設定另一個軸為不同的值,會導致設定visible
                  的軸的行為會變成auto。
             - 4. 即使將 overflow 設定為 hidden ,也可以使用JavaScript Element.scrollTop
                  屬性來滾動HTML元素。
複製程式碼
  1. 頁面分析
- 1. 側邊的一級分類的資料也是獲得的,
    data-cid="xx" 是什麼意思?
複製程式碼
  1. 獲得 一級分類 的資料並渲染
- 1. 在 api.js 中 url寫入:topList: '/category/topList'
- 2. 在 category.js 中 建立vue例項,並繫結在 div(app) 上,
     data 中宣告    topLists: null
- 3. methods 中寫 getTopList(){axios.get(url.topList).then(res => {this.topLists = res.data.lists})}
     並在 created 中 呼叫該方法 created() { this.getTopList() }
- 4. 在 category.html 中
     找到一級分類,在 li 上使用v-for進行列表渲染 v-for="(list,index) in topLists"
     
     此處有兩個問題:
     1. 點選不同的li,渲染不同的標籤(實際上只有綜合排行為一種,剩下的分類為一種)
     - 1. category.html 中
          在 <li> 上繫結事件    @click="getSubList(index,list.id)"
          在綜合排行對應的div上寫 v-show="topIndex===0" (後更改為v-if)
          在其餘分類對應的div上寫 v-show="topIndex>0"  (後更改為v-if)
     - 2. category.js 中
          data:{ topIndex: 0 // 此處按照下標進行區分,綜合排行為0,其餘均大於0 }
          methods: {  getSubList(index,id) { this.topIndex = index}  }
     2. 點選不同的li,切換 class"active"(焦點狀態切換問題)
     - 1. 在<li>上新增  :class="{active:index===topIndex}"
          由 getSubList() 方法可知,點選哪個li就會使得topIndex等於被點選li的index
          當點選 li 時,就會使得條件成立,渲染clas"active"
          此時其餘的未被點選的 li 的index是不等於topIndex的
          所以就實現了切換 active 的需求。
複製程式碼
  1. 獲得 二級分類(綜合排行、普通分類) 的資料並渲染
- 1. 在 api.js 中 url寫入:  
        subList:'/category/subList',
        rank:'/category/rank',
- 2. 在 category.js 中 建立vue例項,並繫結在 div(app) 上,
     data 中宣告    topLists: null
- 3. methods 中寫 getTopList(){axios.get(url.topList).then(res => {this.topLists = res.data.lists})}
     並在 created 中 呼叫該方法 created() { this.getTopList() }
- 4. 在 category.html 中
     找到對應的 li 使用 v-for 進行渲染,並對資料進行替換
- 5. 問題:subData、rankData 初始值為null,再頁面剛開啟時就渲染會報錯。
     辦法:在對應的 ul 上寫 v-if="subData" 或者 v-if="rankData"
           當獲取資料後,才渲染。
- 6. 將價格變為帶兩位小數的浮點數:
     使用filter,結合toFixed()方法即可。
複製程式碼
  1. 問題補充:null 和 undefined

複製程式碼

列表頁

  1. sku
  2. 為什麼data要return資料:在單vue頁面下,多個元件可能會共享資料,為了保持資料的獨有性,就把資料return出去。
  3. qs: querything 是一個增加了一些安全性的查詢字串解析和序列化字串的庫。
qs.parse()
複製程式碼
  1. 點選熱門品牌、熱門分類下的 item ,會跳轉到 search.html ,且傳遞點選 tiem 的 id 和 name
location.href = `search.html?keyword=${list.name}&cate_id=${list.id}`
複製程式碼
  1. search 中
search.js 中
- 1. getSearchList(){} 發請求獲取searchLIst
- 2. let { keyword, id } = qs.parse(location.search.substr(1)) 接收 keyword,id

search.html 中
- 1. input中接收keyword:`:value="keyword"`
- 2. 對應 li 上v-for 渲染資料。
複製程式碼
  1. 發現:foot元件複用,formatePrice 方法複用,所以引入 mixin.js
- 1. src/modules/js/mixin.js 中
    import Foot from '@/components/Foot.vue'
    let mixin = {
      filters: {
        formatePrice(value) {
          return value.toFixed(2)
        }
      },
      components: {
        Foot
      }
    }
    export default mixin
    
    將引入 foot 、formatePrice 方法均放入 mixin.js 中
- 2. 在需要引入 mixin.js 的檔案中
     import mixin from 'js/mixin.js'
    new Vue({
        ···
        mixins:[mixin]
        ···
    })
複製程式碼
  1. 回到頂部
使用第三方庫:velocity
複製程式碼

過渡

  1. 過渡的概念
  2. 在哪些場景使用過渡
  3. 怎麼用
  4. 涉及到的知識點
  1. 元件的封裝
  2. slot--元件
  3. 元件的通訊
  1. 父子
  2. 兄弟
  3. vuex
  4. slot
  1. fullpage
  1. 靜態資料:mounted
  2. 非同步資料:this.$nextTick

詳情頁

  1. 入口、資料獲取和渲染
  2. 商品詳情和本店成交
  3. 選擇規格彈框:過渡效果、資料增減
  4. 加入購物車:購物車按鈕顯示、資訊提示

知識點:

  1. v-cloak
  2. v-html
  3. 過渡效果

相關文章