bilibili: 仿哔哩哔哩 线上地址:bilibili.codeape.site 主要技术:Vue和element

您所在的位置:网站首页 b站搜索栏用不了 bilibili: 仿哔哩哔哩 线上地址:bilibili.codeape.site 主要技术:Vue和element

bilibili: 仿哔哩哔哩 线上地址:bilibili.codeape.site 主要技术:Vue和element

2024-07-10 03:32| 来源: 网络整理| 查看: 265

仿哔哩哔哩的网页版 (仅有首页和搜索页面) 线上地址:codeape.site:8181 b站效果展示视频:https://www.bilibili.com/video/bv1564y1U71T csdn介绍:https://blog.csdn.net/weixin_52014110/article/details/116353612 两个页面的效果展示:

点击图片中的内容,会跳转到官方b站的相应视频页面,由于网上没有视频的接口(人家赚钱的东西当然不能有啦😂),所以就没有进行接下来的制作了。

首页制作

用 element-ui 和 html 加 css 相结合的方式尽可能的还原哔哩哔哩页面,首页主要布局分4部分

1 navbar 绘制

​ 自定义封装好 nav-bar 用于首页和搜索页面使用。搜索框会根据页面的宽度大小来显示与隐藏,主要功能代码如下

​ 搜索框下方的提示使用 el-autocomplete 组件将获取到的数据进行效果展示

image-20210501092214610

​ 数据获取

​ html结构

2 tab栏区域的绘制 3 轮播图和轮播图右边区域的绘制

​ 这里要提到一个访问外网接口跨域的问题

解决方案如下:

​ 在项目根路径中新建一个 vue.config.js 文件

​ 在里面添加图中红框框出来的关键代码 (修改完 vue.config.js 文件记得要重新跑一次项目)

image-20210501093522978

​ 在 main.js 文件中导入并注册全局 axios

​ 在 Home.js 文件中使用,根据前面定义的名字,在这里直接使用就可以替换原路径

​ 紧接着这里还会出现请求过来的图片的跨域问题。

解决方案如下:

​ html 中新增 meta 标签关键代码:content="no-referrer"

.... ....

​ 这里我觉得加在这个文件中就可以(但我没有尝试过,如果不行可尝试下面方法)

​ 一开始我不知道加在哪,因为这里是 vue 项目全是 .vue 文件,于是用了一种绕一点的方法

​ 首先在 router 的配置文件中添加

​ 再在 main.js 文件中添加如下代码 就相当于新增了一个 meta 标签

// 路由操作 解决跨域问题 router.beforeEach((to, from, next) => { /* 路由发生变化修改页面meta */ if (to.meta.content) { let head = document.getElementsByTagName('head'); let meta = document.createElement('meta'); meta.name = to.meta.name; meta.content = to.meta.content; head[0].appendChild(meta) } /* 路由发生变化修改页面title */ if (to.meta.title) { document.title = to.meta.title; } next() }); 4 页面主要内容的绘制

​ 由于需要多次复用,将视频内容展示和排行榜都各自封装成组件

​ 由于接口数据有限,排行榜的展示顺序是根据左边视频内容的播放量,来进行排序展示的。

​ 视频内容区域的接口提供了图片、标题等各种数据,但是没有链接数据。所以本网站点击了该区域会以标题 为搜索内容,跳转到搜索页面。当点击了搜索页面中的对象时,会跳转到b站原官网。

搜索页面制作 1 顶部继续复用封装好的 navbar

​ 但这里是搜索页面,不显示搜索框

2 页面中的搜索和 tab 栏区域 3 可折叠的选择标签区域

​ 这里的布局和功能的实现是最为复杂的,折叠区域用 el-collapse 进行功能绘制,在 el-collapse-item 中放入 el-radio-group 单选按钮来进行 标签 选择,展开的内容为:时长的标签和分区的标签。

第一行标签 (综合排序等)

​ 就是根据数据内容中的类型,来对原数据进行一次排序,下面是综合排序的方法,其他类似

// 综合排序的方法(得分最高) comprehensiveSort() { // sort 不传参就是按照字符编码的顺序进行排序 // 提供比较函数,该函数要比较两个值 // obj1 小于 obj2,在排序后的数组中 obj1 应该出现在 obj2 之前 返回一个小于 0 的值 this.mainDataList.sort((obj1, obj2) => { return obj2.rank_score - obj1.rank_score; }); }, 第二行标签 (全部时长等)

​ 这里是先获取点击到的标签,改变 currentTime 的值

​ 接下来就可以监听 currentTime 的值,只要变化了就根据变化的数值来决定返回的时间

​ 下面是点击tab栏时间的方法,就由于接口中获取过来的时间是一个字符串,所以下面要进行两次的时间格式的转换。

// 点击tab栏时间的方法 allTimeMethods() { // this.mainDataListCopy 是获取到数值后,另外保存的一份副本 // this.$lodash.cloneDeep 这是深拷贝 let arr = this.$lodash.cloneDeep(this.mainDataListCopy); // 将时间转化为秒 let arr2 = this.changeSeconds(arr); // 返回值是true还是false决定保留还是丢弃该元素。 arr2 = arr2.filter((item) => { switch (this.currentTime) { case 0: return item.duration; case 600: return item.duration < 600; case 1800: return 600 { let t = array[index].duration.split(":"); array[index].duration = t[0] * 60 + parseInt(t[1]); }); return arr; }, // 将秒钟格式化 formatSeconds(arr2) { let timeFormat = ""; for (let i in arr2) { timeFormat = ""; allTime(arr2[i].duration); arr2[i].duration = timeFormat; } function allTime(time) { if (time < 60) { let s = time > 0 ? time : ""; s = s { el.disabled = false }, binding.value || 1000) } }) } }) } }

​ 紧接着在 main.js 中导入这个文件

​ 由于b站官网这里的弹出框点击其他地方是不消失的,后面我把 el-popover 的触发方式改为了 trigger="manual" 手动的,所以上面的方法可能就不需要了。但这里可以记录一下防止以后再次踩坑!!

3 选择分区后,弹出框的按钮

​ 这里也存在点击两次的问题,但不会影响功能的实现,但可以作为优化然后记录一下

// 分区里面的对话框被点击了 partitionItemClick(e, item) { // 防止点击两次 // 因为原生click事件会执行两次,第一次在label标签上, // 第二次在input标签上,故此处理 if (e.target.tagName === "INPUT") return; let arr = this.$lodash.cloneDeep(this.mainDataListCopy); let arr2 = []; arr.forEach((value) => { if (value.typename === item) { arr2.push(value); } }); this.mainDataList = this.$lodash.cloneDeep(arr2); }, 4 视频内容区域

​ 由于要根据获取到的数据进行渲染,这里也是封装成一个独立的组件 videoitem.vue,便于复用。

​ 下面格式化标签中播放量和日期的计算属性

项目心得体会

​ 这是刚学习完一遍 vue ,用来练手和顺便复习 html + css + js 的项目,其中出现了很多的问题。虽然最后都一一解决了,但还是说明技术不过关。

​ 这也是我写的第一篇博客,用于记录一些我所实现的功能的方法供大家参考,还有所遇到的问题以及解决方法希望能帮助到大家,写得不好的地方,希望大家轻喷!!🤣🤣



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3