资讯专栏INFORMATION COLUMN

一个人的团队(一)

wh469012917 / 3405人阅读

摘要:作者原文章知乎上有人问比一个人吃火锅更寂寞的是什么我想回答一个人写前后端,却要装成一个团队。预告下一篇我会介绍一个人的团队二神兵利器之和

作者 @zwhu
原文章 @github

知乎上有人问「比一个人吃火锅更寂寞的是什么?」我想回答「一个人写前后端,却要装成一个团队。」

我们在前期开发的过程中,更多是一个人单打独斗,因为是自己一个人,可以把代码写的很随意,也不用注意什么工程化的东西;但作为一个有追求的程序员,不能为未来的自己挖坑,坚决走前端工程化的路线。

虽然我是一个人,但我是一个团队。

所以这是我自己在开发过程中总结的一些知识,慢慢会写成一个系列吧。「单页应用」作为系列的第一篇。

单页应用 定义

对于单页应用我的定义是:在浏览器地址栏输入地址之后,服务器获取到HTML文档,之后所有页面的呈现都在这份HTML文档之上进行。

为什么是单页应用

因为这是流行啊。即使我司对性能啥的完全没有任何要求,我还是强行用了单页应用,自己不努力,没人帮我学。具体有什么好处还是坏处,如果自己没写过单页应用,即使别人说一大堆好处坏处你也还是不懂。(这是吐槽,不用理会)

从头开始实现 SPA

在浏览器地址栏输入地址之后,会从服务器端下载HTML文档并开始渲染。(这个谁能看懂,谁看吧,反正我看不懂)在渲染的过程中,解析 script 标签,外部引入的话,就发起请求获取 JavaScript 文件。
页面渲染完成,之后所有网站的内容都会在这个页面上呈现,所有的操作也只会在这个页面进行。

假设我们在浏览器输入 http://xxxx.com 的时候,服务端会返回 index.html 文档如下:

  
    
      
        
        demo
      
      
        

这里插一句为什么把 script 标签放到最后?浏览器在渲染的时候会被 script 标签阻塞,影响页面的首次渲染。可能会因为 JavaScript 文件过大,等待加载时间过长(如果是外部引入),页面一直是空白。

我们在构建单页面应用时,大部分的内容通过 JavaScript 生成。在 app.js 中,我们会生成一个导航:

var $nav = $("#nav")

var sLi = ["home","about","article","history"].reduce(function(pre, n) {
    return pre + "
  • " + n + "
  • "; }, ""); var sUl = "
      " + sLi + "
    "; $nav.html(sUl);

    生成如下图的导航条

    之后我们想根据导航生成不同的页面内容:

    var $container = $("#container")
    
    $("#nav ul li").on("click", function() {
      $container.html("这是" + $(this).find("a").text() + "区域哦")
      return false;
    })

    然而现实中,我们的页面多数是根据后端返回的数据来渲染,例如我们的后端提供了一个接口 /api/home, 通过这个接口可以获得数据 ["今", "天", "天", "气", "不", "错", "啊"],当我们进入 home 页面的时候页面上会结合通过 api 接口获取来的数据展示新的页面:

    $("#nav ul li").on("click", function() {
      var route = $(this).find("a").text()
      if("home" === route) {
        $.get("/api/home", function(data) {
          $container.html(data.join("") + "!")
        })
      } else {
        $container.html("这是" + route + "区域哦")
      }
      return false;
    })

    单页应用的重点 ---- 路由

    这是我刚接触单页应用时候比较头疼的地方。

    没有路由,我就不知道你在哪儿。 --- by 我要某上头条君

    通过 Ajax 可以获取服务器的数据然后再渲染到页面上,这个方法虽然交互很友好,不需要重新刷新页面就可以看到新的内容;但是有一点不好,那就是当点击导航后,浏览器地址栏的链接不会有变化,用户完全不知道现在在哪个页面。

    不过这里有个知识点是需要大家理解的,当我们在浏览器地址栏输入地址或者通过其他页面的外链跳转到这个页面时,整个页面都会刷新一遍,从服务器获取 HTML 文档渲染。在 JavaScript 中,可以通过 location.href 修改地址,但是这个方法和浏览器输入地址的效果是相同的,那有没有办法只修改浏览器的地址栏,而不刷新整个页面呢?

    还好我们有 HTML5 的 History Api 来解决这个问题,当然低版本的IE浏览器也可以通过 location.hash 的方法实现,hash 来解决的方法不在这里深究了。毕竟低版本浏览器已经没必要支持了。

    $("#nav ul li").on("click", function() {
      var route = $(this).find("a").text()
      history.pushState({ title: route }, route, route)
      show()
      return false;
    })
    
    function show() {
      var route = window.location.pathname
      if("/home" === route) {
        $.get("/api/home", function(data) {
          $container.html(data.join("") + "!")
        })
      } else {
        $container.html("这是" + route + "区域哦")
      }
    }

    在点击导航之后,会将当前的路由体现在浏览器的地址中。不过,浏览器地址变化之后,点击前进后退,页面并不会有什么变化。我们可以通过对 window 对象绑定 popstate 方法来解决

        window.addEventListener("popstate", show);

    传统的网站,用户通常输入具体 url 来进入相关页面,例如:我们进入 GitHub 自己的主页是输入的是 github.com/user;但是单页面应用,我们的页面都是在一个空的 html文档中通过 JavaScript 生成的页面,所以服务器不能通过url来返回具体的页面(其实是可以的,同构,不在这里展开),那么应该怎么做呢?

    对于服务器来说,不用管那么多,当用户输入 url 之后,只要 url 符合一定的规则(例如:请求头的 accept 是 "text/html" 或者所有非 /api/ 开头的 url 等),都返回默认的 index.html。JavaScript 可以通过当前的路由来渲染:

     function show() {
      var route = window.location.pathname
      if("/home" === route) {
        $.get("/api/home", function(data) {
          $container.html(data.join("") + "!")
        })
      } else if("/" !== route) {
        $container.html("这是" + route + "区域哦")
      }
    }
    
    // 初始化的时候就调用
    show()
    结尾

    到此为止,单页面的应用就算介绍完了。理解了单页面应用的原理,对于最近流行的 AngularReactVue 之类库或框架的才算刚刚开始。

    如果觉得本文对你有帮助的话,就点个推荐呗。

    预告

    下一篇我会介绍 一个人的团队(二)--- 神兵利器之 webpack 和 webpack-dev-server

    文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

    转载请注明本文地址:https://www.ucloud.cn/yun/91526.html

    相关文章

    • 如何招聘名优秀前端

      摘要:如何考察一个人是不是经验丰富我们需要在问答式的面试中,对其项目经验进行挖掘。如何设置笔试题现在网上有大量的面经的存在,对于我们面试是一个巨大的挑战。尊重应聘者我们要尊重每一个来应聘的人,不要轻视别人,或者故意刁难别人。 时光荏苒,2个月前,我才刚总结了如何应对面试官,现在的我开始总结如何面试别人了。笑哭.png 1.我们需要什么样的人 招聘肯定要有标准,这样我们才能更快的找到我们需要的...

      aervon 评论0 收藏0
    • 如何招聘名优秀前端

      摘要:如何考察一个人是不是经验丰富我们需要在问答式的面试中,对其项目经验进行挖掘。如何设置笔试题现在网上有大量的面经的存在,对于我们面试是一个巨大的挑战。尊重应聘者我们要尊重每一个来应聘的人,不要轻视别人,或者故意刁难别人。 时光荏苒,2个月前,我才刚总结了如何应对面试官,现在的我开始总结如何面试别人了。笑哭.png 1.我们需要什么样的人 招聘肯定要有标准,这样我们才能更快的找到我们需要的...

      Mr_houzi 评论0 收藏0
    • 从程序猿到SAP产品经理,我是如何转型

      摘要:前言回顾是最好的成长成都研究院的程序猿向我约稿,要我谈一谈是如何从一名程序猿转型为产品经理的。所以,故事就从我进入成为程序猿开始吧。程序猿把一件事情做好和结缘,那是十年前了。相对程序猿,有更多的机会和产品经理直属领导以及其他团队打交道。 文章作者:Jason Xia(夏建军) Jerry: 今天的文章来自Jason Xia, 我的老同事,和我一样从2007年进入SAP成都研究院工作至今...

      Brenner 评论0 收藏0
    • 从程序猿到SAP产品经理,我是如何转型

      摘要:前言回顾是最好的成长成都研究院的程序猿向我约稿,要我谈一谈是如何从一名程序猿转型为产品经理的。所以,故事就从我进入成为程序猿开始吧。程序猿把一件事情做好和结缘,那是十年前了。相对程序猿,有更多的机会和产品经理直属领导以及其他团队打交道。 文章作者:Jason Xia(夏建军) Jerry: 今天的文章来自Jason Xia, 我的老同事,和我一样从2007年进入SAP成都研究院工作至今...

      go4it 评论0 收藏0
    • 团队协作分工,人力1+1等于几

      摘要:小于当两个人做一个无法绝对拆分的模块时一个人从头做到尾,不依赖任何人两个人功能拆分,协商对接各自开发可以会有依赖的功能,有前后依赖关系功能整合这样假如一个人开发需要个小时,两个人开发肯定是大于个小时的等于当两个人做两个完全独立的功能两个人没 小于2 当两个人做一个无法绝对拆分的模块时 一个人:从头做到尾,不依赖任何人 两个人: 1.功能拆分,协商对接 2.各自开发(可以...

      alexnevsky 评论0 收藏0

    发表评论

    0条评论

    wh469012917

    |高级讲师

    TA的文章

    阅读更多
    最新活动
    阅读需要支付1元查看
    <