1. 程式人生 > >vue專案---仿寫音樂app----遇到的問題及解決總結

vue專案---仿寫音樂app----遇到的問題及解決總結

0.https://y.qq.com/m/index.html 1. 基於router-link的導航跳轉 :     html:         <router-link tag="div" :to="item.path"              class="tab-item tCenter" v-for="(item,index) in tabLists"             exact                ><span class="tab-link">{{item.title}}</span></router-link>     css:                 .tab-link                 padding-bottom:5px             &.router-link-active                     .tab-link                     color:#ffcd32                     border-bottom:2px solid #ffcd32     js:         tabLists:[{"path":"/","title":"推薦"},{"path":"/singer","title":"歌手"},{"path":"/rank","title":"排行"},{"path":"/search","title":"搜尋"}],                     index.js:         {           path: '/',           component: Home,           children:[{               path: '/',               component: Recommend,           }, {               path: '/singer',               component: Singer,           },{               path: '/rank',               component: Rank,           },{               path: '/search',               component: Search,           }]         }     注意:以上程式碼中 exact關鍵字 能幫助只允許一個router-link被啟用,&.router-link-active定義了標籤被啟用的樣式。         2. 在vue中引用模組函式,

如果是export default function fun(){},則import fun from "./"即可,如果是export function fun(){},則需要import {fun} from "./"

3. jsonp是可以實現跨越請求獲取資料的,不是通過ajax,是通過新建一個標籤,其src指向從而實現跨越請求。     //引入jsonp     import originJsonp from "jsonp"          //封裝一個名叫jsonp的函式,url表示純地址,data表示地址後面的引數,option為第三方外掛jsonp的引數,返回一個promise,在這個promise中呼叫原始的第三方外掛jsonp     //根據執行的結果的是否儲存執行promise     export default function jsonp (url,data,option){         url+=(url.indexOf("?")<0?"?":"&")+param(data);  //拼接url,如有原引數url有?號表示已經存在至少一個引數了,直接在後面拼接&,然後拼接param(data),如果沒有?則先拼接?在拼接param(data)         //最後拼接的樣式如:https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg?g_tk=5381&uin=0&format=json&inCharset=utf-8&outCharset=utf-8&notice=0&platform=h5&needNewCode=1&_=1533171846949             return new Promise((resolve,reject)=>{             originJsonp(url,option,(err,data)={  //呼叫第三方外掛jsonp                 if(!err){                     resolve(data)                 }else{                     reject(err)                 }             })         })     }          //定義一個param函式,將引數data拼接在一起 data 格式{uname:"Ace",upwd:"123456"}     function param(data){         let url="";         for(var k in data){             let val=data[k] !== undefined ? data[k]:"";             url+=`&${k}=${encodeURLCompoent(val)}`   ;   //ncodeURLCompoent是url地址的格式轉換,讓瀏覽器能識別         }  //拼接結果的url = &uname=Ace&upwd=123456                           return url? url.substring(1):"";  //如果url存在就去掉第一個&返回uname=Ace&upwd=123456,否則返回“”     }

4. 封裝一個介面函式,呼叫該函式,直接向介面發生jsonp獲取介面的資料     import jsonp from "../common/js/jsonp.js"   //引用jsonp獲取recommend推薦相關的資料     import {commonParams,options} from "./config.js"   //獲取通用引數          //https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg介面需要配置如下引數     //g_tk: 5381     //uin: 0                     //qq號,沒登入預設為0     //format: json     //inCharset: utf-8     //outCharset: utf-8     //notice: 0     //platform: h5               //平臺來源h5     //needNewCode: 1     //_: 1533171846949          export function getRecommend(){         const url="https://c.y.qq.com/musichall/fcgi-bin/fcg_yqqhomepagerecommend.fcg";                  const data=Object.assign({},commonParams,{     //Object.assign()是es6的新語法,表示將多個物件合併成一個物件             platform: 'h5',             needNewCode:1,             uin: 0          })                  return jsonp(url,data,options)     }          //在適當的時候呼叫介面函式getRecommend     getRecommend().then((res)=>{         if(res.code===ERR_OK){             console.log(res)         }     })     5. 新思路,將通用的對dom操作的封裝成一個通用的js檔案如dom.js,如給標籤新增刪除class樣式,可以封裝成dom函式。可重複使用

6. 新思路:建立一個滑動載入better-scroll的元件,在任何時候,需要頁面滑動的時候,包裹該元件即可     <div class="bscroll" ref='wrap'>         <slot></slot>    //這裡是需要包裹的頁面滑動的內容     </div>     import BScroll from "better-scroll"     export default{         props:{             data:{                 type:Array,                 default:null             },             isClick:{                 type:Boolean,                 default:true             },             probeType:{    //該屬性時當 probeType 為 1 的時候,會非實時(螢幕滑動超過一定時間後)派發scroll 事件;當 probeType 為 2 的時候,會在螢幕滑動的過程中實時的派發 scroll 事件                         type:Number,    //當 probeType 為 3 的時候,不僅在螢幕滑動的過程中,而且在 momentum 滾動動畫執行過程中實時派發 scroll 事件。如果沒有設定該值,其預設值為 0,即不派發 scroll 事件                 default:1             },             listenScroll:{   //是否監聽滾動事件的滾動位置,預設情況是不監聽                 type:Boolean,                 default:false             }         },         mounted(){             this.$nextTick(()=>{                 this._initScroll();             })         },         methods:{             _initScroll(){                 if(!this.$refs.wrap){return}    //即初始化時剛開始傳遞過來的引數可能是undefined                 this.scroll=new BScroll(this.$refs.wrap,{                     click:this.isClick,                     probeType:this.probeType                 })                 if(this.listenScroll){    //如果呼叫該better-scroll元件傳入的引數要求監聽滾動距離,即this.listenScroll=true,就給better-scroll滾動時通過自定義事件傳遞滾動位置資料                     var me=this;                     this.scroll.on("scroll",(pos)=>{                         me.$emit("scroll",pos)                     })                 }             },             enable(){    //同步better-scroll的enable方法                 this.scroll && this.scroll.enable()             },             disable(){    //同步better-scroll的disable方法                 this.scroll && this.scroll.disable()             },             refresh(){    //同步better-scroll的refresh方法,重新計算滾動高度                 this.scroll && this.scroll.refresh()             },             scrollTo(){     //同步better-scroll的scrollTo方法,滾動到頁面指定位置高度,因為需要帶有引數,所有用apply()呼叫原來函式 的可傳入引數                 this.scroll && this.scroll.scrollTo.apply(this.scroll,arguments)             },             scrollToElement(){     //同步better-scroll的scrollToElement方法,滾動到頁面指定位置元素標籤處,因為需要帶有引數,所有用apply()呼叫原來函式 的可傳入引數                 this.scroll && this.scroll.scrollToElement.apply(this.scroll,arguments)             }         },         watch:{             data(){  //傳入的資料發生改變,重新計算滾動高度                 this.$nextTick(()=>{                     this.refresh();                 })             }         }              } //    引用better-scroll頁面元件     import ReBscroll from "../base/bscroll.vue"     <div class="abs recommend">      //注意recommend必須有相對/覺得定位、recommend-scroll繼承父元素的高寬,或者recommend-scroll必須相對絕對定位,且寬高         <re-bscroll class="recommend-scroll">             <div >                 <!--1.輪播圖-->                 <re-swiper :imgLists="imgLists" ></re-swiper>                 <!--2.熱門歌曲列表-->                 <recommend-list :lists="lists"></recommend-list>             </div>         </re-bscroll>     </div>     .recommend         width: 100%         top: 88px         bottom: 0         overflow:hidden         .recommend-scroll             height: 100%                  scrollEle(a){         this.$refs.listView.scrollToElement(this.$refs.listGroup[a],0);   //接受子元素傳遞過來的字母下標索引,並滾動到該位置     }

7. <img @load="imgLoad"/>  //表示圖片的onload載入完成之後執行的函式,如用於,在使用了better-scroll外掛計算滾動高度時,需要在圖片載入完成撐起圖片高度之後,在重新計算滾動高度     即this.refresh(); 如在imgLoad方法中 if(!this.checkload){this.refresh();this.checkload=true } ,表示第一張圖片載入完成之前this.checkload不存在,帶圖片載入完成之後     就執行一次計算滾動頁面高度,然後定義this.checkload=true,之後圖片在載入完成時,應該已經撐起滾動頁面高度,且this.checkload已經存在,避免了很多圖片,每張圖片載入一次     就要重複計算頁面高度的繁瑣執行。     8. vue-lazyload:圖片懶載入的第三外掛,即    頁面滾動到底部時才執行載入更多的圖片,避免的一次性載入太多圖片。     npm install vue-lazyload --save     在main.js中     import VueLazyLoad from "vue-lazyload"     Vue.use(VueLazyLoad,{         loading:require("./common/image/default.png");   //載入中暫時存放的圖片,相對main.js的替代圖片的位置     })     使用:     <img  v-lazy="url"/>  //將src/:src被v-lazy代替即可,也可用於背景圖,詳情見官網     9. swiper無法實現loop:true可能選原因是遠端獲取圖片,遠端的圖片動態不定時改變。

10. 根據物件的key值排序Object.keys(map).sort((a,b)=>{ })

11. vue支援@touchstart事件:<div class="abf tCenter singer-abc" @touchstart="touchWhich"/>

12. 解決[Intervention] Unable to preventDefault inside passive event listener due to target being treated as報錯:     兩個方案:     12.1、註冊處理函式時,用如下方式,明確宣告為不是被動的     window.addEventListener('touchmove', func, { passive: false })          12.2、應用 CSS 屬性 touch-action: none; 這樣任何觸控事件都不會產生預設行為,但是 touch 事件照樣觸發。     touch-action 還有很多選項,     13. 配置跳轉子路由:  子路由並非真正的頁面,只是覆蓋在父路由上的一層蒙層,所有層級z-index要高     children:[{           path: ':id',           component: SingerDetail,           }]     this.$router.push({         path:`/singer/${a.id}`     })