当前位置: 首页 > Web前端 > HTML5

Vue全栈开发之百度贴吧

时间:2023-04-05 02:13:49 HTML5

本百度贴吧项目是vue+koa+sequelize项目。由于没有百度贴吧API接口,我写了后端项目部分截图(GIF)项目和前期准备工作的依赖:vue+vuex+axios+better-scroll+iview+stylus(也有分散的依赖来完成一些Module,比如moment在项目中完成时间需求)前端依赖"dependencies":{"axios":"^0.19.0","better-scroll":"^1.15.2","iview":"^3.4.2","js-cookie":"^2.2.0","jsonwebtoken":"^8.5.1","moment":"^2.24.0","vue":"^2.5.2","vue-photo-preview":"^1.1.3","vue-router":"^3.0.1","vuex":"^3.1.1"},后端:koa+koa-router+mysql2+sequelize(这些是主要的,还有很多中间件)后端依赖"dependencies":{"bcrypt":"^3.0.6","env2":"^2.2.2","jsonwebtoken":"^8.5.1","koa":"^2.7.0","koa-body":"^4.1.0","koa-bodyparser":"^4.2.1",“koa-jwt”:“^3.5.1”,“koa-router”:“^7.4.0”,“koa-session”:“^5.12.0”,“koa-static”:“^5.0.0”","koa2-cors":"^2.0.6","mysql2":"^1.6.5","sequelize":"^5.8.12"},前端代码初始化用于vue-cli脚手架。图标来自阿里巴巴矢量图标库,找到的图标尽量与百度贴吧保持一致。前端UI框架选择iview(选择有点不对,因为百度贴吧的项目是移动端的,应该用vant这样优秀的移动端UI框架会比较合适)准备工作是添加一些路径项到build目录下的webpakc.base.conf.js文件中的alias选项,添加一些下工程常用的路径。有几点说说项目的权限控制只用了一个token,比较简单,但是不太安全。有兴趣的可以看看权限控制写的代码,由于前后端分离,所以登录认证时设置的cookie是前端取不到的(应该是域名)accessproblem,anditisundefined),所以token信息只能传递给前端,让前端自己设置cookies(公平的衡量标准,不推荐)。没有API,也没有写爬虫,所以数据是手写的,数据量小,所以有些效果无法实现。最近看的帖子和最近的访问,这两个模块的数据都存储在localStorage中,其他数据来自后台。因为后台写的不好,后台的内容就不说了。项目启动Tabbar。在vue-router中采用router-link的效果进行属性配置就是成品效果了。点这一项会多出两个类属性router-link-exact-active(精确匹配规则,路由路径完全一样时会有)router-link-active(都包含匹配规则,即父路由也会有的)在router配置中加入linkActiveClass:'active',将router-link-active替换为active,那么还可以自定义active页面的样式结构大致分为5部分,几个零散的页面。5个部分中的4个(除了info)对应4个tabbar选项来划分页面。info中共有三个页面,分别是userInfo、baInfo、tieInfo路由和权限控制路由。这五个部分分别定义。最后,由于本项目的登录认证在页面上变化较大,所以在路由的beforeEach钩子函数中进行登录状态。判断,对必须登录才能访问的页面进行强制登录判断,如果失败则跳转到登录页面。router.beforeEach((to,from,next)=>{//必须登录的url没有认证信息登录if(routerLoginRole.some(route=>to.path===route)&&!Cookies.get('username')){next('/login')return}}必须登录的页面如下exportconstrouterLoginRole=['/release','/message','/user','/focuslist','/fanslist','/focusbalist','/tielist','/setting','/userhome','/useredit','/browsehistory','/collection','/release','/like']同时,不同页面的tabbar显示和消失状态也不同,将tabbar的显示状态放到vuex中,在beforeEach钩子函数中统一管理if(TabbarRoutes.some(route=>(to.path.indexOf(route)===0))){store.dispatch('hiddenTabbar')}else{store.dispatch('showTabbar')}需要隐藏tabbar的页面如下exportconstTabbarRoutes=['/login','/register','/search','/focuslist','/fanslist','/focusbalist','/tielist','/setting','/userhome','/useredit','/userinfo/','/tieinfo/','/bainfo/','/browsehistory','/release','/collection','/like']提取基本配置并导入插件在iview组件中使用按需导入,在uti中在ls目录下创建一个iview.js,统一管理iview引入的代码importVuefrom'vue'import{Button,Input,Switch,Progress,Form,FormItem,Icon,Upload,Dropdown,DropdownMenu,DropdownItem,Message,Spin}from'iview'import'iview/dist/styles/iview.css'Vue.component('Button',Button)Vue.component('i-input',Input)Vue.component('i-switch',Switch)Vue.component('Progress',Progress)Vue.component('Form',Form)Vue.component('FormItem',FormItem)Vue.component('Icon',Icon)Vue.component('Upload',Upload)Vue.component('Dropdown',Dropdown)Vue.component('DropdownMenu',DropdownMenu)Vue.component('DropdownItem',DropdownItem)Vue.component('Spin',Spin)Vue.prototype.$Message=MessageexportdefaultVuefilter全局过滤器,使用moment实现时间的处理,数字处理,统一management为axios设置一个拦截器,它有3个作用:1.设置axios请求的默认路径,运行时携带cookie信息2.部分api接口需要登录验证,需要传递给服务端包括tokencookie凭证3.请求数据时加载动画axios.defaults.baseURL='http://192.168.1.4:3000/'axios.defaults.withCredentials=trueaxios.defaults.timeout=5000axios.interceptors.request.use(config=>{//为$http请求设置cookie请求头store.dispatch('showLoading')consttoken=Cookies.get('username')constisTokenRight=!!(token&&JsonWebToken.decode(token))if(isTokenRight){config.headers.common['Authorization']='Bearer'+token}returnconfig},error=>{Message.error('网络异常,请稍后再试')store.dispatch('hiddenLoading')returnPromise。reject(error)})axios.interceptors.response.use(response=>{store.dispatch('hiddenLoading')if(response.data.statusCode!==200){Message.error(response.data.message)返回Promise.reject(response)}returnresponse},error=>{Message.error('网络异常,请稍后重试')store.dispatch('hiddenLoading')returnPromise.reject(error)})一些函数具体实现首页刷新功能效果图分为两个阶段。首先是监听滚动事件。如果滚动值超过一定值(个人设置500),触发事件会将tabbar中的首页替换为刷新按钮。点击刷新按钮,改变vuex中的内容refreshData属性变为true。然后在首页监听这个属性,重新加载数据并触发better-scroll滚动事件滚动到顶部。还有一些小问题:tabbar使用了router-link,在它的事件冒泡阶段会阻止事件冒泡,执行自己的路由跳转事件,导致自定义事件无法触发。解决方法是在内部处理去除点击事件(即在点击事件冒泡到渲染元素之前先处理点击事件,防止点击事件冒泡)tabbar中首页选项的html结构页面

首页Refresh其触发的刷新方法refresh(){if(this.$store.getters.isRefresh){this.$store.commit('updateRefreshData',true)}},为了避免冗余加载数据,所以使用了keep-alive标签。当触发better-scroll的scrollTo方法时,该方法失效。具体原因不明,后来自己找到了better-sc卷装版是基本款。后面改成全容量滚动后就可以正常使用了(知道具体原因的朋友可以说说),实现高质量的左右滚动效果。html可以分为两部分,顶部三个tab,下面三个页面顶部的tab动画效果是csstransition:所有0.3sease页面都采用better-scroll,在scrollEndhook函数中进行相关操作topmarkerslideeventromve(index){letname='message-title-'+indexthis.index=indexthis.oldX=-index*this.$refs['message-content'].offsetWidththis.$refs.unline.style.left=this.$refs[name].offsetLeft+'px'this.contentScroll.scrollTo(-this.$refs['message-content'].offsetWidth*index,0,300)},左和右滚动初始化initScroll(){this.$nextTick(()=>{if(!this.contentScroll){this.contentScroll=newBScroll(this.$refs['message-content'],{startX:0,点击:true,tap:true,scrollX:true,scrollY:false,momentum:false//不要让它产生滚动动画})}else{this.contentScroll.refresh()}this.contentScroll.on('scrollEnd',({x})=>{letwidth=this.$refs['message-content'].offsetWidth//获取单页宽度if(x!==-width&&x!==-2*width&&x!==0){//避免自动滚动后继续滚动if(Math.abs(x-this.oldX)x){//向左滑动时自动滚动到右侧页面this.contentScroll.scrollTo(-(++this.index)*width,0,300)}else{//Right滑动时自动滚动到左侧页面.index)//使顶部标记滑动到相应位置}})this.romve(0)//初始化顶部标记到第一个})}页面布局html主要用到div、span、img、p等。标签css方面选择器使用的class选择器布局主要采用flex布局。z-index级别为1-9,文字级别低,动画遮罩级别略高。图标icon的定义形式为background-size:30px30pxbackground-repeat:no-repeatbackground-position:centercenterbackground-image:url('../../assets/icon/left.png')问题到注意:z-index层问题,子元素会继承父元素的层级。设置level后,还是会出现下层元素浮起来的问题。可能是上面的元素是透明的,加个背景色就行了。应该减少使用js的setInterval形成的帧动画,改用css形成的tween动画。结语每页写的小功能不多,但是很多模块不难,没必要写的很详细。有关详细信息,请参阅源代码。整个项目写下来,问题很多。主要原因是缺乏完整性,组件化不够彻底。在UI风格上,还是没办法和百度贴吧保持一致(有一定的偏差)。如果您喜欢本文或者对您有帮助,请给作者点个鼓励,点个赞,走起!同时也真心希望看到这篇文章的你能发表一下意见!前端源代码后端源代码