vue学习|Vue基础实现bilibili移动端页面

【vue学习|Vue基础实现bilibili移动端页面】
Vue基础实现bilibili移动端页面

  • 一、Vue基础实现bilibili移动端页面

一、Vue基础实现bilibili移动端页面 简述:对于已经学到vue的同学,bilibili的页面布置难度不大,仔细阅读仔细体悟;难点在于怎么做到使用vue‘不操作’dom,从而实现较为复杂的逻辑方法。由于是按头部-导航-轮播-视频-底部的顺序,所以并没有多少注释,但是也并不难阅读。
axios.js可搜索自行下载
//html Document - 锐客网 src="https://www.it610.com/article/axios.js"> src="https://www.it610.com/article/request.js"> src="https://www.it610.com/article/vue.js">
width="12" height="18" viewBox="0 0 1024 1024"> >北冥有鱼,化而为鹏梵蒂冈连快递费过来付款定金
width="24" height="24" viewBox="0 0 80 80">
下载App
  • vue学习|Vue基础实现bilibili移动端页面
    文章图片
    viewBox="0 0 1024 1024"> {{ video.play }}
    viewBox="0 0 1024 1024"> {{ video.rank }}
    {{ video.title }}
> const vm = new Vue({ el: '#app', data: { navList: [], navHide: true, navActiveIndex: 0, bannerList: [], bannerWidth: 350, bannerStyle: { left: 0, transition: 'left .3s', }, bannerActiveIndex: 0, videoOldList: [], videoOldList: [], videoGettingData: false, videoCount: 0, }, computed: { videoList () { return this.videoOldList.map(video => { video.play = video.play > 10000 ? video.play / 10000 + '万' : video.play; video.rank = video.rank > 10000 ? video.rank / 10000 + '万' : video.rank; return video; }) } }, methods: { handleClick () { this.navHide = !this.navHide; }, handleNavClick (index) { this.navActiveIndex = index; }, autoMove () { setTimeout(() => { if(this.bannerActiveIndex === 0 ) {//判断轮播索引确定循环 this.bannerStyle.transition = 'left .3s'; }this.bannerActiveIndex ++; this.bannerStyle.left = -this.bannerActiveIndex * this.bannerWidth + 'px'; }, 1500) }, handleTransitionEnd () { if(this.bannerActiveIndex === 3) { this.bannerActiveIndex = 0; this.bannerStyle.left = 0; this.bannerStyle.transition = 'none'; } this.autoMove(); }, handleScroll (e) { const { scrollHeight, offsetHeight, scrollTop } = e.target; const toBottomHeight = scrollHeight - offsetHeight - scrollTop; //是否滑动到接近底部 const videoLength = this.videoList.length; if(videoLength === this.videoCount) { return; } if(toBottomHeight < 200 && !this.videoGettingData) {//接近底部则再次请求数据 this.videoGettingData = https://www.it610.com/article/true; axios.get('video', { params: { start: this.videoList.length, offset: 12 } }).then(res => { this.videoOldList.push(...res.data); //将多次视频数据拼接 this.videoGettingData = https://www.it610.com/article/false; })} }, getData () { axios.all([ axios.get('nav'),//对导航的处理 axios.get('banner'),//对轮播的处理 axios.get('video', {//对视频信息的处理 params: { start: 0, offset: 12 } }) ]).then(axios.spread((navRes, bannerRes, videoRes) => { this.initNavList(navRes); this.initBannerList(bannerRes); this.initVideo(videoRes); })); }, initNavList (navRes) { this.navList = navRes; }, initBannerList (bannerRes) { const bannerLaseEle = {...bannerRes[0]}; bannerLaseEle.id = Math.floor(Math.random() * 10000000); this.bannerList = [...bannerRes, bannerLaseEle]; }, initVideo (videoRes) { this.videoCount = videoRes.count; this.videoOldList = videoRes.data; } }, created () { this.getData(); }, mounted () { this.autoMove(); } })

//index.css html{ height: 100%; } body{ height: 100%; } #app{ height: 100%; overflow-y: scroll; } .header { position: fixed; top: 0; left: 0; right: 0; display: flex; align-items: center; justify-content: space-between; padding-top: 10px; padding-bottom: 15px; z-index: 3; background-color: #fff; }.header .logo { margin-left: 18px; }.header .search-input { width: 132px; height: 24px; margin-left: 5px; display: flex; align-items: center; font-size: 10px; color: #999; background-color: #f4f4f4; border-radius: 12px; }.header .search-input svg { margin-left: 10px; }.header .search-input span { width: 92px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }.header .avatar svg { border-radius: 50%; }.header .download-app { -webkit-user-drag: 78px; height: 23px; padding-left: 10px; padding-right: 10px; margin-right: 12px; line-height: 23px; text-align: center; color: #fff; background-color: #fb7299; font-size: 12px; border-radius: 4px; }.nav-box { position: fixed; top: 54px; left: 0; right: 0; z-index: 1; background-color: #fff; }.nav-box .nav-list { width: 85%; white-space: nowrap; overflow-x: scroll; padding-left: 24px; /* display: none; */ }.nav-box .nav-list::-webkit-scrollbar { display: none; }.nav-box .nav { display: inline-block; height: 30px; line-height: 30px; margin-right: 40px; color: #757575; font-size: 14px; border-bottom: 2px solid transparent; }.nav-box .nav.active { border-color: #fb7299; color: #fb7299; }.nav-box .down { position: absolute; top: -3px; right: 13px; }.hide-nav-box { position: fixed; top: 54px; left: 0; right: 0; padding-bottom: 20px; z-index: 2; transition: top .3s; background-color: #fff; }.hide-nav-box.hide { top: -117px; }.hide-nav-box .nav { display: inline-block; width: 32px; text-align: center; margin-left: 14px; margin-right: 14px; margin-bottom: 10px; padding-top: 6px; padding-bottom: 6px; font-size: 14px; color: #757575; border-bottom: 2px solid transparent; }.hide-nav-box .nav.big { width: 46px; margin-left: 7px; margin-right: 7px; }.hide-nav-box .nav.active { border-color: #fb7299; color: #fb7299; }.hide-nav-box .up { position: absolute; bottom: 0; left: 50%; transform: translateX(-50%); z-index: 1; }.banner-box { position: relative; top: 90px; left: 50%; transform: translateX(-50%); width: 350px; height: 110px; border-radius: 6px; overflow: hidden; }.banner-box .banner-list { position: absolute; left: 0; width: calc(350px * 4); transition: left .3s; }.banner-box .banner { float: left; width: 350px; height: 110px; }.banner-box .poster { width: 100%; height: 100%; }.banner-box .index-list { position: absolute; bottom: 3px; left: 50%; transform: translateX(-50%); display: flex; align-items: center; height: 10px; padding-left: 3px; padding-right: 3px; background-color: rgba(0, 0, 0, .5); border-radius: 5px; }.banner-box .index { width: 5px; height: 5px; border-radius: 50%; margin-left: 3px; margin-right: 3px; background-color: #fff; }.banner-box .index.active { background-color: #fb7299; } /* 视频区 */ .video-box{ margin-top: 100px; padding-left: 6px; padding-right: 6px; } .video-box .video-list::after{ display: block; content: ''; clear: both; } .video-box .video{ width: 50%; float: left; } .video-box .poster{ position: relative; height: 106px; margin-right: 6px; margin-left: 6px; border-radius: 6px; overflow: hidden; } .video-box .poster img{ width: 100%; height: 100%; } .video-box .poster .info{ position: absolute; bottom: 0; color: #fff; padding-top: 8px; padding-bottom: 2px; height: 18px; font-size: 12px; background-image: linear-gradient(rgba(33,33,33,0),rgba(33,33,33,0.8)); } .video-box .info div{ display: inline-flex; align-items: center; margin-left: 16px; } .video-box .info svg{ margin-right: 4px; margin-top: 2px; width: 14px; height: 14px; fill: #fff; } .video-box .title{ margin: 6px 6px 10px 6px; height: 38px; line-height: 20px; font-size: 13px; /* 单行文本溢出打点: 设置文本不换行 white-space: nowrap; 设置文字溢出用省略号代替 text-overflow: ellipsis; */ /* 多行文本溢出打点: */ overflow: hidden; /* 设置盒子为伸缩盒 */ display: -webkit-box; /* 设置伸缩盒内子元素的排列方式为vertical */ -webkit-box-orient: vertical; /* 限制一个块元素内显示的文本行数 */ -webkit-line-clamp: 2; }.footer { margin-top: 40px; }.footer p { margin-bottom: 20px; text-align: center; font-size: 13px; color: #999; }

//request.js axios.defaults.baseURL = 'https://developer.duyiedu.com/vue/bz/'; //默认配置请求地址公共部分 axios.interceptors.response.use((response) => { const { status } = response; const { baseURL, url } = response.config; if(status === 200) { if(url === baseURL + 'video') { return { count: response.data.count, data: response.data.data } } return response.data.data; } return response; });

vue学习|Vue基础实现bilibili移动端页面
文章图片

    推荐阅读