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¬ice=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}`
})