Awesome
技术栈
前端:vue3 + vuex + vite + stylus + nginx
后端:koa2
项目运行
源码地址: https://github.com/lybenson/bilibili-vue
如何运行
运行前请先安装nodejs
clone
项目到本地
git clone https://github.com/lybenson/bilibili-vue.git
前端运行
cd bilibili-vue && yarn && yarn dev
后端运行
cd bilibili-vue/bilibili-api && yarn install && yarn 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
。每次发起网络需要经历下面的步骤
-
请求中
rootState.requesting = true //请求状态更新为true,表示请求中 commit(TYPE.XX_REQUEST) // 发送同步操作,请求中的数据处理
-
请求成功
rootState.requesting = false //请求状态更新为false,表示请求结束 commit(TYPE.XX_SUCCESS, response) //发送同步操作,处理请求成功后数据
-
请求失败
rootState.requesting = false //请求状态更新为false,表示请求结束 rootState.error = error commit(TYPE.XX_FAILURE, error) //发送同步操作,处理请求失败
动画
B站首页充斥着大量的动画效果。目前动画使用的主要有三种方式:
-
以
hover
效果触发。 -
通过
js
触发的效果,如点击轮播图的原点时,主要通过设置css属性transition: .2s;
,再通过js
设置css属性this.$refs.banner.style.marginLeft = left
。 -
通过
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
性能优化
-
图片懒加载
-
压缩
js
、css
-
服务器开启
gzip
-
浏览器缓存
-
...
发布
完成项目后将发布到自己的服务器上,首先确保服务器已安装nodejs
,具体安装步骤不再赘述。
后端发布
后端采用pm2
做项目管理
安装pm2
npm install pm2 -g
启动项目
cd bilibili-api && npm install
pm2 start index.js
前端发布
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'
}
这样打包后还会出现stylus
中background-image
资源无法找到的问题,我采用的方式修改ExtractTextPlugin
配置,在webpack.prod.conf.js
中修改
new ExtractTextPlugin('[name].[contenthash].css')
将分离的css
打包路径分离到static
文件夹之外。
打包完成后上传到服务器/var/www/html/bilibili
目录下。
-
配置nginx服务器。
location /bilibili { root /var/www/html; index index.html; }
总结
相关截图:
首页:
轮播:
直播:
排行:
游戏:
拖拽排序与滚动效果: