前端 vue+后端 koa,全栈式开发 bilibili 首页

2017-04-25 15:29:25 +08:00
 lybenson

预览地址: http://www.lybenson.com/bilibili/

前言

为什么是写哔哩哔哩(俗称 B 站)呢?其一是因为本人是 B 站的重度使用者,每周基本上都会在 B 站上看看火影忍者、暴走大事件等。另外一个原因呢,就是 B 站首页很美观大方,而且处处充满了细节。所以对于实践确实是一个不错的项目。目前的技术栈主要的采用的是前端 Vue2+后端 Koa2 的前后端分离的方式,语法全部使用 ES6/7 。关于数据也来自真实的数据接口。

技术栈

前端: vue2 + vuex + webpack + ES6/7 + stylus + nginx

后端: koa2

项目运行

源码地址: https://github.com/lybenson/bilibili-vue

如何运行

运行前请先安装nodejs

clone项目到本地

git clone https://github.com/lybenson/bilibili-vue.git

前端运行

cd bilibili-vue
npm install
npm run dev

后端运行

cd bilibili-vue/bilibili-api
npm install
npm run dev

为了确保运行正确,请先运行后端服务。再运行前端,之后访问 http://localhost:8080

组件

根据首页的各模块的功能不同,划分出了共 20 多个可复用的组件。具体请看下方

├── banner  //轮播组件
│   ├── Banner.vue
│   └── BannerItem.vue
├── common  // 公共组件
│   ├── BHeader.vue
│   ├── BMenu.vue
│   ├── BMenuItem.vue
│   ├── PostMaterial.vue
│   ├── Search.vue
│   └── TopContainer.vue
├── content  // 主内容组件
│   └── BContent.vue
├── contentRow  // 单个分类的组件
│   ├── BContentRow.vue
│   ├── BRowBody.vue
│   ├── BRowHead.vue
│   ├── BRowItem.vue
│   ├── BRowRank.vue
│   └── BRowRankBody.vue
├── contentTop  // 页面顶部组件
│   ├── BContentTop.vue
│   └── BContentTopItem.vue
├── live  //直播所在的组件
│   ├── BLive.vue
│   ├── BLiveItem.vue
│   ├── BLiveRank.vue
│   └── BLiveRankItem.vue
├── nav  //右侧导航条组件
│   ├── BNavSide.vue
│   └── smooth-scroll.js
└── promote  // 推广组件
    ├── BPromote.vue
    └── BPromoteItem.vue

组件的原则就是尽量将复杂的 UI 布局划分成单个小的 UI 组件,逻辑处理也被划分成更多的单个小的逻辑。数据流动采用的单向数据流动。子组件的数据更多的是来自于父组件,父组件的数据主要是其本身发起的ajax请求。本项目中ajax请求库使用的是axios

状态管理

目前的状态管理采用vuex。由于vuex可以分多个子module。所以在不同模块下单独维护一份状态,同时对于一些公共的状态,比如发起网络请求的requesting,错误时的状态error则保存在根状态中,之后可以通过子模块中的rootState.requesting获取来赋值。

在子模块中发送网络请求获取数据是一个异步的过程,所以将网络请求放在actions。每次发起网络需要经历下面的步骤

  1. 请求中

    rootState.requesting = true  //请求状态更新为 true,表示请求中
    commit(TYPE.XX_REQUEST)  // 发送同步操作,请求中的数据处理
    
  2. 请求成功

    rootState.requesting = false  //请求状态更新为 false,表示请求结束
    commit(TYPE.XX_SUCCESS, response) //发送同步操作,处理请求成功后数据
    
  3. 请求失败

    rootState.requesting = false  //请求状态更新为 false,表示请求结束
    commit(TYPE.XX_SUCCESS, response) //发送同步操作,处理请求失败
    

动画

B 站首页充斥着大量的动画效果。目前动画使用的主要有三种方式:

  1. hover效果触发。

  2. 通过js触发的效果,如点击轮播图的原点时,主要通过设置 css 属性transition: .2s;,再通过js 设置 css 属性this.$refs.banner.style.marginLeft = left

  3. 通过vue提供的动画方式。

    <transition name="fade">
     <div v-if="isSort">
         <div class="tip"></div>
         <div class="custom-bg"></div>
     </div>
    </transition>
    

样式

样式文件使用的是stylus,暂未使用任何vue现成的 UI 组件。需要安装stylus-loader, stylus,由于vue-cli中的webpack已经配置好了stylus了,所以只需要安装就可以了。

npm install stylus-loader --save-dev
npm install stylus --save-dev

性能优化

发布

完成项目后将发布到自己的服务器上,首先确保服务器已安装nodejs,具体安装步骤不再赘述。

后端发布

后端采用pm2做项目管理

安装pm2

npm install pm2 -g

启动项目

cd bilibili-api && npm install 
pm2 start index.js

前端发布

  1. webpack打包
npm run build

需要注意的是,直接运行此命令可能会导致资源无法找到的问题。所以需要对webpack配置做一定的修改。

webpack.base.conf.js文件中修改publicPath如下

output: {
    path: config.build.assetsRoot,
    publicPath: './',  //资源的公共路径
    // publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath,
    filename: '[name].js'
}

这样打包后还会出现stylusbackground-image资源无法找到的问题,我采用的方式修改ExtractTextPlugin配置,在webpack.prod.conf.js中修改

new ExtractTextPlugin('[name].[contenthash].css')

将分离的css打包路径分离到static文件夹之外。

打包完成后上传到服务器/var/www/html/bilibili目录下。

  1. 配置 nginx 服务器。

    location /bilibili {
      root /var/www/html;
      index index.html;
    }
    

总结

目前主要功能都已经完成的差不多。主要还差一个预览视频与弹幕的功能尚未完成,希望能把 B 站首页写完,并且会持续更新中,后面可能会加上直播等功能。

相关截图:

首页:

轮播:

直播:

排行:

游戏:

拖拽排序与滚动效果:

15579 次点击
所在节点    程序员
53 条回复
gouchaoer
2017-04-25 15:41:02 +08:00
有点意思,你这个 css 和 html 模版是从 B 站复制的么,里面的 js 是复制的 B 站的还是自己重新写了一遍?
zakokun
2017-04-25 15:42:20 +08:00
你考虑过 B 站服务器的感受麽?
Rubicker666
2017-04-25 15:42:57 +08:00
666
LeeSeoung
2017-04-25 15:44:14 +08:00
star
jiar
2017-04-25 15:49:41 +08:00
mark
lybenson
2017-04-25 16:46:08 +08:00
@zakokun 你太小看 B 站服务器了
Tunar
2017-04-25 16:56:52 +08:00
掘金那里已喜欢😘
zoobop
2017-04-25 16:57:07 +08:00
厉害了~~~支持。 star
xbdsky
2017-04-25 16:59:53 +08:00
厉害了~~~支持+1 star
smithtel
2017-04-25 17:07:29 +08:00
小水管炸了
kely
2017-04-25 17:12:47 +08:00
厉害了!!我的哥!想问一下,写了多久?
learnshare
2017-04-25 17:23:02 +08:00
B 站首页很美观大方 不太认同,不够美
xrlin
2017-04-25 17:31:25 +08:00
@learnshare b 站首页感觉太杂了
yuluofanchen
2017-04-25 17:43:55 +08:00
网站打开速度太慢了。。。。。。








































































ps :不认为 B 站的首页很好看咧。不过萝卜白菜,各有所爱。
airycanon
2017-04-25 17:44:46 +08:00
请问楼主,项目目录结构是用什么画出来的?
charexcalibur
2017-04-25 17:44:58 +08:00
厉害啦 233333 我愿意给你一枚硬币
Jialin
2017-04-25 18:01:11 +08:00
那么 SEO 呢?
BlackCat02
2017-04-25 18:05:24 +08:00
收下我的硬币
beyoung
2017-04-25 18:08:29 +08:00
@yuluofanchen http://bt0.com/ 这个站的首页怎么样 评价一下
ecmadao
2017-04-25 18:10:03 +08:00
😂可以考虑什么时候去 B 站直播一下写 B 站

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/357255

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX