• 什么是单页应用?
  • 发布于 2个月前
  • 213 热度
    4 评论
  • Rock
  • 1 粉丝 29 篇博客
  •   
最近在学习Vue.js,经常会听到一个名词:单页应用。对于这个词我一直无法理解,哪位大侠能给解释一下什么是单页应用?最好能举个比较好理解的单页应用的例子。
用户评论
  • 董闵行
  • 什么是单页应用

    单页Web应用,就是只有一张Web页面的应用。浏览器一开始会加载必需的HTML、CSS和JavaScript,之后所有的操作都在这张页面完成,这一切都由JavaScript来控制。因此,单页Web应用会包含大量的JS代码,模块化开发和架构设计的重要性不言而喻。


    单页应用得优势
    1.操作体验流畅,媲美本地应用的感觉,切换过程中不会频繁有被“打断”的感觉。因为界面框架都在本地,与服务端的通讯基本只有数据,所以便于迁移,可以用比较小的代价,迁移成桌面产品,或者各种移动端Hybrid产品。
    2.完全的前端组件化,前端开发不再以页面为单位,更多地采用组件化的思想,代码结构和组织方式更加规范化,便于修改和调整;
    3.API 共享,如果你的服务是多端的(浏览器端、Android、iOS、微信等),单页应用的模式便于你在多个端共用 API,可以显著减少服务端的工作量。容易变化的 UI 部分都已经前置到了多端,只受到业务数据模型影响的 API,更容易稳定下来,便于提供更棒的服务;

    4.组件共享,在某些对性能体验要求不高的场景,或者产品处于快速试错阶段,借助于一些技术(Hybrid、React Native),可以在多端共享组件,便于产品的快速迭代,节约资源。


    单页应用得缺点
    1.首次加载大量资源,要在一个页面上为用户提供产品的所有功能,在这个页面加载的时候,首先要加载大量的静态资源,这个加载时间相对比较长;
    2.对搜索引擎不友好,因为界面的绝大部分都是动态生成的,所以搜索引擎很不容易索引它。

    3.开发难度相对较高,开发者的JavaScript技能必须过关,同时需要对组件化、设计模式有所认识,他所面对的不再是一个简单的页面,而是一个运行在浏览器环境中的桌面软件。


    开发框架
    为解决大规模单页应用代码逻辑问题,出现了不少MV*(MVC、MVP、MVVM)框架,他们的基本思路都是在JS层创建模块分层和通信机制,为单页面应用开发提供了必需的模版、路径解析和处理、后台服务api访问、DOM操作等功能。这类框架包括Vue(Vue-router),Backbone,Knockout,AngularJS,Avalon等,而且,它们几乎都在这些模式上产生了变异,以适应前端开发的特点。mvc、mvp、mvvm使用关系总结

    框架能极大的提高我们开发的便利,但是框架一般都限制过多,所以我们也可以抛弃框架,直接写原生代码。


    代码隔离
    单页应用比页面型网站更加依赖于JavaScript,由于页面的单页化,各种子功能的JavaScript代码聚集到了同一个作用域,所以代码的隔离、模块化变得很重要。
    代码合并与加载策略

    把更多的公共功能放到首次加载,以减少每次加载的载入量。

    在单页应用中,无需像网站型产品一样,为了防止文件加载阻塞渲染,把js放到html后面加载,因为它的界面基本都是动态生成的。


    路由与状态的管理
    单页应用中,因为界面上的各种功能区块是动态生成的,所以需要把产品功能划分为若干状态,每个状态映射到相应的路由,然后通过根据不同的url路径动态解析路由,匹配功能界面。
    缓存与本地存储

    在单页应用的运作机制中,缓存是一个很重要的环节。
    由于这类系统的前端部分几乎全是静态文件,所以它能够有机会利用浏览器的缓存机制,而比如动态加载的界面模板,也完全可以做一些自定义的缓存机制,在非首次的请求中直接取缓存的版本,以加快加载速度。

    在单页产品中,业务代码也常常会需要跟本地存储打交道,存储一些临时数据,可以使用localStorage或者localStorageDB来简化自己的业务代码。


    服务端通信
    传统的Web产品通常使用JSONP或者AJAX这样的方式与服务端通信,但在单页Web应用中,有很大一部分采用WebSocket这样的实时通讯方式。

    WebSocket与传统基于HTTP的通信机制相比,有很大的优势。它可以让服务端很便利地使用反向推送,前端只响应确实产生业务数据的事件,减少一遍又一遍无意义的AJAX轮询。

    由于WebSocket只在比较先进的浏览器上被支持,有一些库提供了在不同浏览器中的兼容方案,比如socket.io,它在不支持WebSocket的浏览器上会降级成使用AJAX或JSONP等方式,对业务代码完全透明、兼容。

    内存管理

    传统的Web页面一般是不需要考虑内存的管理的,因为用户的停留时间相对少,即使出现内存泄漏,可能很快就被刷新页面之类的操作冲掉了,但单页应用是不同的,它的用户很可能会把它开一整天,因此,我们需要对其中的DOM操作、网络连接等部分格外小心。


    样式的规划
    在单页应用中,因为页面的集成度高,所有页面聚集到同一作用域,样式的规划也变得重要了。
    样式规划主要是几个方面:

    1. 基准样式的分离

    这里面主要包括浏览器样式的重设、全局字体的设置、布局的基本约定和响应式支持。


    2. 组件样式的划分

    这里面是两个层面的规划,首先是各种界面组件及其子元素的样式,其次是一些修饰样式。组件样式应当尽量减少互相依赖,各组件的样式允许冗余。


    3. 堆叠次序的管理
    传统Web页面的特点是元素多,但是层次少,单页应用会有些不同。

    在单页应用中,需要提前为各种UI组件规划堆叠次序,也就是z-index,比如说,我们可能会有各种弹出对话框,浮动层,它们可能组合成各种堆叠状态。新的对话框的z-index需要比旧的高,才能确保盖在它上面。

    vue + vue-router单页实例

    html

    <script src="https://unpkg.com/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
    <div id="app">
        <h1>Hello App!</h1>
        <p>
            <!-- 使用 router-link 组件来导航. -->
            <!-- 通过传入 `to` 属性指定链接. -->
            <!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
            <router-link to="/foo">Go to Foo</router-link>
            <router-link to="/bar">Go to Bar</router-link>
        </p>
        <!-- 路由出口 -->
        <!-- 路由匹配到的组件将渲染在这里 -->
        <router-view></router-view>
    </div>
    

    js

    // 0. 如果使用模块化机制编程,导入Vue和VueRouter,要调用 Vue.use(VueRouter)
    // 1. 定义(路由)组件。
    // 也可以从其他文件 import 进来
    const Foo = { template: '<div>foo</div>' }
    const Bar = { template: '<div>bar</div>' }
    // 2. 定义路由
    // 每个路由应该映射一个组件。 其中"component" 可以是
    // 通过 Vue.extend() 创建的组件构造器,
    // 或者,只是一个组件配置对象。
    const routes = [
        { path: '/foo', component: Foo },
        { path: '/bar', component: Bar }
    ]
    
    // 3. 创建 router 实例,然后传 `routes` 配置
    // 你还可以传别的配置参数, 不过先这么简单着吧。
    const router = new VueRouter({
        routes // (缩写)相当于 routes: routes
    })
    // 4. 创建和挂载根实例。
    // 记得要通过 router 配置参数注入路由,
    // 从而让整个应用都有路由功能
    const app = new Vue({
        router
    }).$mount('#app')
    // 现在,应用已经启动了!
    

  • 2018/5/14 12:52:00 [ 0 ] [ 0 ] 回复
  • 老铁没毛病
  • 提到单页面,不得不提到ajax与seo这两者的关系。前端原本是一个纯page的工作,但随着产品对用户体验的要求越发苛刻,ajax的使用也就越发的频繁,从起初的信息验证到后来的前端mvc,ajax虽然只是前后端通讯的工具,但在其中起到越来越重要的作用。

    然而相较与后端mvc,ajax渲染的方式存在一个很严重的问题。就是面对SEO几乎不举,而且刷新或发送url无法保留浏览进度。这时其实已经暴露出一个问题,就是如何界定前后端MVC的界限,以及如何处理前后端视图的统一。单页面就是为了解决这类问题而生的。前端自豪的拿到了监管url的权利,通过监听页面地址变化来调用前端MVC模块,渲染不同页面。当然,前端这时也拥有了修改URL的能力。管理好前端视图与URL,整个单页面就已经架构完成。(关键点:hmtl5使用historyAPI的支持,低级浏览器采用hash段的管理或无视)。

    然而这只解决了浏览进度与URL的维持,并没有解决SEO的问题。在确定了需要保持的页面后,前后端围绕页面各自负责视图的渲染,当然这一步需要有一个相互坑的过程。考虑会遇到这类问题的项目一般是这么两类(自己YY的),一是应用类的项目,权限、交互比较频繁,对于SEO可以无视,甚至还要尽力避免(再次YY,这类应用是未来的趋势)。再一类是对于页面过场效果比较有要求的“高大上”的应用,比较在意SEO!针对这两类项目,解决前后端MVC协同问题的也大致就出来了!对于第一类项目,后端仅渲染基础页面和基础数据的填充。后端配合提供ajax数据支持,前端渲染视图,完成交互及业务逻辑。第二类自行尝试,前后端切记要保持良好的基友关系,不可打架。

    上面吧啦吧啦的一堆话,仅仅是自己在项目和博客里尝试得到的一些经验,下面是一些与单页面相关的关键字,请自行google!模块定义模块加载模板引擎pushStaus

  • 2018/5/14 12:45:00 [ 0 ] [ 0 ] 回复
  • XSPACE
  • 所谓的单页应用通俗点来讲,就是应用在整个使用流程里浏览器由始至终没有刷新,所有的数据交互由ajax完成。但是用户体验起来和app一样,有明确的页面区分,即所谓的web app。例子的话,PC最早期就是 gmail了,github移动端可以看看  百度图片  百度视频  。

  • 2018/5/14 12:42:00 [ 0 ] [ 0 ] 回复
  • 王建栗
  • 说白就是无刷新,整个webapp就一个html文件,里面的各个功能页面是javascript通过hash,或者history api来进行路由,并通过ajax拉取数据来实现响应功能。因为整个webapp就一个html,所以叫单页面!
  • 2018/5/14 12:41:00 [ 0 ] [ 0 ] 回复