HTML5单页框架View.js介绍
什么是单页应用
单页应用,是指将用户视觉上的多个页面在技术上使用一个载体来实现的应用。
换句话来讲,用户视觉效果,与技术实现的载体,并不是一定要一一对应的。采取哪种技术方案,取决于产品设计、技术组成以及方案之间的优劣平衡。
放到 Web 前端环境中,这个承载了多个视觉效果的载体,就是 html 文件(或 asp,jsp 等)。
为便于描述,本文将使用多个术语。其名称及对应的含义如下所示:
页面:技术上的一个html文件;
视图:视觉上的一页内容;
初步实现单页应用
直观效果的单页应用,其实现过程其实并不复杂。
我们可以使用 div 或 section 等标签承载视图的展现,并通过脚本实现特定视图的呈现与隐藏。例如:
1 2 3 4 5 6 7 8 | <!DOCTYPE HTML> <html> <head>...</head> <body> <div id = "view1" class = "view" >page1</div> <div id = "view2" class = "view" >page2</div> </body> </html> |
1 2 3 4 5 6 | .view{ display: none; } .view.active{ display: block; } |
1 2 3 4 5 6 | var find = function(selector){ return document.querySelector(selector); }; find( ".view.active" ).classList.remove( "active" ); find( "#view2.view" ).classList.add( "active" ); |
这可能是最简单的单页应用了。
和其它框架相比,View.js为单页应用开发提供了的以下几个关键特性彰显了它的比较优势:
无需配置和开发,视图导航开箱可用
允许在视图切换时传递任意类型的参数
允许自定义视图切换动画
允许自定义视图配置
以事件驱动地形式完成视图功能的开发
View.js是为了简化移动端单页应用的功能开发而创建的,web前端开发者可以继续沿用既有技术栈,不会因为使用view.js而面临较大的冲击。
需要注意的是,和vue不同,对于使用View.js完成的单页应用,其HTML文档仍然由HTML、CSS和JS组成。开发者一如既往地需要手动建立html、css和js文件,并手动完成资源的引用。因为View.js的舞台,是浏览器装载文档之后的运行时环境。
视图导航
视图导航,在视图切换时由View.js自动完成。下面是一个例子
1 2 3 4 5 6 | /* 切换至商品详情视图 */ View.navTo( "goods-detail" , { options: { goodsId: "G01" } }); |
视图切换后,页面URL将自动变更为:http://domain:port/context/index.html#goods-detail!goodsId=G01。
View.js当前仅支持hash形式的地址表示。
视图传参
View.js允许以视图为单位拆分任务,执行多人协作。视图之间使用参数完成协作。参数在进行视图切换时传递,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | View.navTo( "goods-detail" , { options: { /* 使用options传递的参数将反馈到地址栏中,因此只能传递字符串类型的参数 */ goodsId: "G01" } }); /* ---------------------------------- */ View.navTo( "delivery-address-list" , { params : { /* 使用params传递的参数不会反馈到地址栏中,因此可以是任意被浏览器所支持的类型 */ selectCallback: function(selectedAddress){ //... } } }); /* ---------------------------------- */ View.navTo( "goods-detail" , { params : { goodsId: "G01" , }, options: { goodsId: "G02" } }); var view = View.ofId( "goods-detail" ); view. on ( "enter" , function(){ var goodsId = view.getParameter( "goodsId" ); // --> G01 goodsId = View.getActiveViewOption( "goodsId" ); // --> G02 goodsId = view.seekParameter( "goodsId" ); // --> G01 }); |
视图配置
多数情况下,一个视图的表现和行为是固定的一种。但对于软件提供商,其同一产品在被多个客户购买时,会遇到“不同客户有不同需求,拒绝需求没收入,答应需求成本高”的窘境。而不同需求的差异点通常也并不高,可能也就只有10-30%左右的差别。但因为10%的差别,就要把源码硬拷贝2份,对于软件提供商而言,成本无疑高了许多。
View.js考虑到了这一点。
通过引入视图配置,开发者可以将视图开发为多种形态的综合体,最终以视图配置的方式指定视图的具体工作模式或表现形式。如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | var view = View.ofId( "register" ); /* 默认配置:密码最少位数 */ view.config. get ( "password-min-length" ).setValue(6); /* 默认配置:密码最多位数 */ view.config. get ( "password-max-length" ).setValue(20); /* -------------------------------------------- */ view.find( ".submit" ).addEventListener( "click" , function(){ var pwd = pwdObj.value.trim(); var minLen = view.config. get ( "password-min-length" ).getValue(), maxLen = view.config. get ( "password-max-length" ).getValue(); if (pwd.length < min){ alert( "密码长度不能少于" + minLen + "位" ); return ; } if (pwd.length > max){ alert( "密码长度不能多于" + maxLen + "位" ); return ; } }); /* -------------------------------------------- */ /* 客户A的视图配置 */ /* 重载既有配置:密码最少位数 */ view.config. get ( "password-min-length" ).setValue(10, true ); /* 第二个参数用于复写可能已经存在的值,如果不传且已经有值,则赋值无效,相当于什么也没做 */ /* 重载默认配置:密码最多位数 */ view.config. get ( "password-max-length" ).setValue(20, true ); /* -------------------------------------------- */ /* 客户B的视图配置 */ /* 重载既有配置:密码最少位数 */ view.config. get ( "password-min-length" ).setValue(4, true ); /* 重载默认配置:密码最多位数 */ view.config. get ( "password-max-length" ).setValue(10, true ); |
事件驱动
开发者通过监听视图的相关事件来决定执行特定操作的时机。View.js为每个视图实例预制了如下几个事件:
ready - 视图就绪,在视图第一次进入时触发;
beforeenter - 视图即将进入
enter - 视图进入
afterenter - 视图进入后
leave - 视图离开
除此之外,开发者还可以根据自己的业务需要,自行发起并消费事件,如下所示:
1 2 3 4 5 6 | var view = View.ofId( "myView" ); view. on ( "myevent" , function(e){ view.logger.debug( "Event name: {}, event data: {}" , e.name, e.data); }); //… view.fire( "myevent" , {a: 1}); //-> 0918 10:20:54 [View#myView]: Event name: null, event data: {"a":1} |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
2018-06-28 C# 可选参数 命名参数