首页 文章 精选 留言 我的

精选列表

搜索[webapp],共664篇文章
优秀的个人博客,低调大师

Vue开发的电影预告webApp介绍

即将迎来的端午小假期,小伙伴们都准备好怎么度过了么。我每次出去玩都避免不了去看场电影,这次借此机会向大家介绍下我开发的可以查看电影预告片的小项目,希望大家可以去测试,浏览一波即将上映的电影同时可以帮助我测试一下,指出不足,我都会虚心接受的呦!谢谢大家。 项目演示地址 效果图 项目介绍 前端是通过vue-cli进行构建项目,后端接口是使用Koa进行编写的。电影相关数据是使用puppeteer进行爬取并存在mongoDB数据库中,为减轻带宽压力将预告片上传到七牛云上。其主要功能包括: 电影列表的展示 电影详情信息及预告片播放功能 根据上映情况、分类、评分进行筛选电影 电影热度前十榜单 搜索电影功能 用户的注册与登录。 未来想完善的功能: 对电影的收藏与喜欢 根据所在地推荐购票地点 用户信息相关的操作 电影数据的自动爬取更新 项目web端、小程序端 技术问题 电影上映状态路由切换问题 电影上映状态分为正在热映与即将上映,其中list路由页是通过参数进行转换,1为正在上映,2为即将上映。路由配置如下: { path: '/movie', name: 'movie', component: Movie, children: [ { path: 'all/:type', name: 'list', component: List } ] }复制代码 同路由组件参数切换不会再次触发created、mounted生命周期函数,所以要实现参数切换重新请求数据需要在组件内导航守卫中beforeRouteUpdate进行操作。其核心代码如下: beforeRouteUpdate (to, from, next) { this.page = 1 this.max_page = 0 this.movies = [] this._getMovies(to.params.type) next() }复制代码 应对不同场合的Card组件 本项目页面中大量用自己写的Card组件,在list页面、搜索页面、筛选页面、榜单页面等均有使用到。其主要效果如下图: 但当在榜单页面时所有Card组件前都需要有排名,所以可以通过扩展组件的props实现,新增一个rank属性,当为true时则将排名展示出来,其代码如下: <p class="text" v-if="rank" :class="'rank-' + index">{{index}}</p>复制代码 props: { movie: Object, index: Number, rank: { type: Boolean, default: false } }复制代码 电影数据爬取 电影相关数据信息是使用doubanApi结合puppeteer进行爬取得到的,获取电影数据总共分为四步: 利用puppeteer模拟浏览器访问豆瓣网站获取电影的名字、海报、doubanId、评分存入数据库。爬取网址是:const nowUrl = 'https://movie.douban.com/cinema/nowplaying/beijing/' const comUrl = 'https://movie.douban.com/coming'复制代码 利用豆瓣提供的开放API,通过循环数据库中电影doubanId来获取到电影详细的信息,例如导演、演员、简介、类型、上映日期等。 利用puppeteer浏览豆瓣电影详情页,从而跳转到预告片页面爬取预告片的资源,存入数据库。爬取网址是:const url = 'https://movie.douban.com/subject/' 复制代码 使用七牛云提供的NodeSDK将视频资源上传到七牛云床上,并将返回的key值存在数据库中,通过服务器CNAME可以访问七牛云上的短片。其核心代码如下:// 上传函数 const uploadToQiniu = async (url, key) => { return new Promise((resolve, reject) => { bucketManager.fetch(url, bucket, key, function (err, respBody, respInfo) { if (err) { reject(err) } else { if (respInfo.statusCode == 200) { resolve({key}) } else { reject(respBody) } } }) }) } // 循环数据库中数据将上传后返回的keuy值存在数据库 ;(async () => { const movies = await Movie.find({ $or: [ {videoKey: {$exists: false}}, {videoKey: null}, {videoKey: ''} ] }) for (let i = 0; i < movies.length; i++) { let movie = movies[i] if (movie.video && !movie.videoKey) { try { let videoData = await uploadToQiniu(movie.video, nanoid() + '.mp4') let posterData = await uploadToQiniu(movie.poster, nanoid() + '.jpg') let coverData = await uploadToQiniu(movie.cover, nanoid() + '.jpg') const arr = [] for (let i = 0; i < movie.images.length; i++) { let { key } = await uploadToQiniu(movie.images[i], nanoid() + '.jpg') if (key) { arr.push(key) } } movie.images = arr for (let j = 0; j < movie.casts.length; j++) { if (!movie.casts[j].avatar) continue; let { key } = await uploadToQiniu(movie.casts[j].avatar, nanoid() + '.jpg') if (key) { movie.casts[j].avatar = key } } if (videoData.key) { movie.videoKey = videoData.key } if (posterData.key) { movie.posterKey = posterData.key } if (coverData.key) { movie.coverKey = coverData.key } await movie.save() } catch (error) { console.log(error) } } } })()复制代码 利用Decorator修饰器定义Route路由类 本项目是通过koa-router进行拦截请求,并进行数据库相关操作,由于接口数量较多,所以可以采用Decorator方式去定义路由,更利于开发与维护。例如: // 利用Decorator修饰类的行为 @controller('api/client/movie')export class movieController { @get('/get_all') // 获取符合条件的电影条数 @required({ query: ['page_size', 'page'] }) async getAll (ctx, next) { const { page_size, page, type } = ctx.query const data = await getAllMovies(page_size, page, type) ctx.body = { code: 0, errmsg: '', data } } ...... }复制代码 如果想让上述代码有效,需要在项目运行时将修饰器函数定义好,并且载入koa-router中间件,符合修饰器参数的路由则执行相关类实例的方法,其Route类实现代码如下: export class Route { constructor (app, apiPath) { this.app = app this.apiPath = apiPath this.router = new Router() } /** * 遍历routerMap,得到请求路径和方法,路径和controller装饰器的参数拼接 * 通过koa-router实例调用请求方法(请求路径, 对应的路由中间件) * 通过koa实例载入router中间件 */ init () { glob.sync(path.resolve(__dirname, this.apiPath, './**/*.js')).forEach(require) for (let [conf, controllers] of routerMap) { controllers = toArray(controllers) const prefixPath = conf.target[symbolPrefix] prefixPath && (prefixPath = normalizePath(prefixPath)) const routerPath = prefixPath + conf.path this.router[conf.method](routerPath, ...controllers) } this.app.use(this.router.routes()).use(this.router.allowedMethods()) } } // 将path统一成 '/xxx' const normalizePath = path => path.startsWith('/')? path : `/${path}` // 将路由类,请求路径以及方法,装饰器对应的方法存入routerMap中 export const router = conf => (target, key, desc) => { conf.path = normalizePath(conf.path) routerMap.set({ target, ...conf }, target[key]) } // 将path挂载到路由类的prototyp上,实例上可以访问 export const controller = path => target => (target.prototype[symbolPrefix] = path) export const get = path => router({ path, method: 'get'})复制代码 总结 项目总体来说较为简单,而且有很多不足的地方,之后我也会一直完善项目,希望小伙伴们可以提出不足,以及自己的建议。还有这是我第一次写文章,水平有限,写不出深层次的知识,只好拿自己项目作为处女作。希望各位小伙伴多多包涵。最后,如果感觉项目还不错的,不要吝啬你的star呦!谢谢! GitHub项目地址 原文发布时间:2018-06-15原文作者:lihaozecq本文来源 掘金如需转载请紧急联系作者

优秀的个人博客,低调大师

WebApp2.0时代启程:跨平台的JSPatch

紧接上回,Cocos2d-JS通过JSBinding从C++API到JSAPI,完成了H5的跨平台加速,这一回,我们一起来见证一下JSPatch的跨平台实现,为JS语言增加消息转发机制,无需修改js脚本,让下面这段代码可以正确地运行起来: var controller = UIViewController.alloc().init(); 而不是让app翻译成: UIViewController.__c('alloc')().__c('init')(); JSPatch依赖JavaScriptCore作为运行环境,在iOS7.0之后越来越受到终端开发者的欢迎,我们简单地分析JSPatch的技术框架和原理,来引出SpiderMonkey在Patch上的lazy加载机制: 1. JSPatch通过JS动态调用OC的代码 使用反射机制` C

优秀的个人博客,低调大师

WebApp2.0时代启程:倒立者赢,跨平台技术离我们很近

紧接上文,我们提到移动互联网时代,前端的成本重复而臃肿,后端开发基本稳定,作为商业公司:利润和成本使我们不断追求的目标。这里我们从跨平台的角度,来看待如何降低成本。 1. 首先我们看一段视频: 3个平台:浏览器、Android、iOS,一套JS代码,运行在不同设备上【注意,终端展示没有用WebView相关容器】 测试的demo地址:点击进入测试:Android也可以直接扫码安装: Safari/iOS/Android H5测试也可以扫码在手机端测试: 安卓客户端只适配了480x800的分辨率,分辨率不同的屏幕点击处理就会有问题,这点我们留给后面再讲。 包的大小11M,毕竟一套C++代码需要编译多个平台的so包,armeabi和armeabi-v7a各5.8M,加起来就11M了,这就是很多大型Android游戏,首次启动要动态下载链接库的原因,

优秀的个人博客,低调大师

WebApp2.0时代启程:Cocos2d-JS为什么选择SpiderMonkey(二)

紧接上文,cocos2d-JS为我们提供了图形引擎、物理引擎、JS引擎等基础库,在多终端时代提供了非常nice的游戏引擎,在浏览器普及在各个终端的今天,为什么还要单独搞一套JS引擎呢? 我们先看看使用SpiderMonkey的技术产品有哪些? 没有看错,SpiderMonkey就是FireFox浏览器的JS虚拟机(后续简称jsvm),FireFox的实力也是赢得了众多前端开发者的芳心;cocos2d-x更是不用说了,东亚97%的2D游戏开发者的选择,手游开发者的入门技能,k-3D也是在AEPIXI(我们内部实现的跨平台的js图形引擎)的3D技术的源泉,在众多新兴的图形引擎中,我们都找到SpiderMonkey的影子,为什么开发者不选择JavaScriptCore或者V8呢? 主流的JS引擎对比,SpiderMonkey vs v8 vs

优秀的个人博客,低调大师

WebApp2.0时代启程:倒立者赢,NativePixi,所见即所得的开发方式

紧接上文,在终端设备中,不管是游戏引擎还是UIKit,图形图像都是基于跨平台的OpenGL ES技术,区分不同的场景,图形图像分为两个分支,一个以高性能的图形显示为目标的cocos2d-x引擎,一个是以省电节能适合App的UIKit框架。 一)今天我们继续逆向思维 Game VS App,既然都是基于OpenGL ES,那我们找出共同点,是否可以让二者的界限,变得更模糊?既可以满足高性能的Game引擎,可以保持App开发? 请仔细观看上图,我们的框架多了一个WebKit?对的,我以为WebKit是统一Game与App的一个代表作,也就是H5框架,它提供的WebGL本质是就是一层薄薄的OpenGL的封装,可以提供高性能的图形渲染能力;上层提供的Dom框架,从一开始就定义为UI布局而生。灵活轻量的JavaScript语言,无需编译直接运行

优秀的个人博客,低调大师

WebApp2.0时代启程:倒立者赢,从CPU到GPU,一张图片的旅行

紧接上文,终端开发使用的WindVane、wax、ReactNative等已经是一种跨平台的技术,我们称之为上层跨平台,Cocos2d-x这种直接使用C/C++,我们成为底层跨平台。上层跨平台,提升开发效率;下层跨平台,提升程序性能。 1. 为什么Cocos2d-x性能比Native开发要好? 因为Cocos2d-X是游戏引擎呗,人家是专业做游戏特效的好不好,直接调用GPU的OpenGL绘图的好不好。打开Cocos2d-X代码,感触最深的不是CCNode这些游戏节点,cocos2d-x已经开始为App开发做准备了!大家看到了什么?UIImageView?UIScrollView?OMG!当我们还在纠结要不要学习一下游戏开发的时候,人家都已经开始做UI系统了,有木有!! 很长一段时间,我们以为Game和App之间有一种天然的鸿沟,长久以来

优秀的个人博客,低调大师

WebApp2.0时代启程:倒立者赢,从过去到现在的变化,看将来的发展(一)

1. 移动互联网的兴起,我认为2009年是个分水岭。 开始的时候,我也是做Java开发,习惯了Webx架构,可以熟练的使用Spring、iBatis、veloctiy、HSF、Notify、Tair、Session这些阿里具有代表性的Java框架,也会使用IC、UIC、SC、DC等等服务集群做电商核心业务。概括起来,基本也是三层服务端架构: 2. 技术架构也非常稳定 后台MySQL分库分表、服务端HSF业务处理,前端浏览器使用Html做展示,技术人员的重叠率较低,公司内部资源达到了最大化价值体现,市场出现了一种声音:将来的计算机世界应该只有一个应用就是浏览器,浏览器入口是通向互联网的大门,谁占领了浏览器,谁就拥有了无线的用户流量。这个需求在当时是正确的,各大巨头不断的把战线迁往更靠近用户的浏览器,国内浏览器以安全、急速、稳定为名,纷纷推

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册