回答 2 已采纳 js错误还是css导致的布局错误?你用了jquery,js兼容性应该不会有什么问题,除非你自己写了其他js代码 css布局错误就得慢慢调了。。这个得靠经验了
回答 3 已采纳 感觉可以划分为两个问题吧:
回答 2 已采纳 这个问题目前是 部分设备1px不显示,所以在设置边框时最好大于1px
@Web前端开发指导性概述 网站/网页 功能概述1 网站工程前端开发,就是创建整套的相关联的网页群组,反应业务运行逻辑,展示给特定用户群体使用;是用户与业务之间沟通的媒介,能够大幅度提升解决问题的效率,提升人...
一:web前端页面优化: 1.web页面的具体是什么?前身? web前端页面作为呈现给用户看的页面,也就是浏览器可以解析出资源的通过一定程序而出现的页面,对于可以开发人员,很好懂:就是HTML(Hyper Text Markup
回答 5 已采纳 ie不支持a对象的download属性的,也不再支持data协议打开图片,你的canvas toDataURL得到的就是data协议的数据,直接打开不了,会报错,你去掉open的第三发个参数看就知道了
回答 3 已采纳 不用回复,本人已自行解决
前端页面性能是一个非常核心的用户体验指标。本文介绍阿里UC 岳鹰全景监控平台 如何设计一个通用、低侵入性、自动上报的页面性能监控方案。主要采用的是Navigation Timing API以及sendBeacon等方法。 为什么要监控...
众所周知,APP兼容性覆盖测试一直以来被认为是一个高成本、耗时低效、耗人力的测试工作,且兼容性测试是一项必须要进行的测试项目,因为有不同的机型、系统平台、分辨率、网络、厂商、数据兼容以及不同兼容问题场景...
作为一个开发了多个 H5 项目的前端工程师,在开发过程中难免会遇到一些兼容性等爬过坑的问题。现在我将这些问题一一汇总一下,并在后面给出坑产生的原理,和现阶段常规的填坑方案。由此来做一个阶段性的总结。 问题...
世界上没有任何一个浏览器是一样的,同样的代码在不一样的浏览器上运行就存在兼容性问题。不同浏览器其内核亦不尽相同,相同内核的版本不同,相同版本的内核浏览器品牌不一样,各种运行平台还存在差异、屏幕分辨率不...
extend 是构造一个组件的语法器。 然后这个组件你可以作用到ponent 你可以创建 ,也可以取组件。png24位的图片在iE6浏览器上出现背景 解决方案是做成')
二、如何优化webpack构建的性能
一、减少代码体积 1.使用CommonsChunksPlugin 提取多个chunk之间的通用模块,减少总体代码体积
2.把部分依赖转移到CDN上,避免每次编译过程都由Webpack处理
3.对一些组件库采用按需加载,避免无用的代码
三、减少检索路经:resolve.alias可以配置webpack模块解析的别名,对于比较深的解析路经,可以对其配置alias
1、首屏加载和按需加载,懒加载
3、图片压缩处理,使用base64内嵌图片
4、合理缓存dom对象
7、不滥用web字体,不滥用float(布局计算消耗性能),减少font-size声明
8、使用viewport固定屏幕渲染,加速页面渲染内容
9、尽量使用事件代理,避免直接事件绑定
四、Vue的SPA 如何优化加载速度
五、移动端300ms延迟
在不改变外部行为的前提下,简化结构、添加可读性
2XX(成功处理了请求状态)
200 服务器已经成功处理请求,并提供了请求的网页
201 用户新建或修改数据成功
202 一个请求已经进入后台
3XX(每次请求使用的重定向不要超过5次)
304 网页上次请求没有更新,节省带宽和开销
4XX(表示请求可能出错,妨碍了服务器的处理)
400 服务器不理解请求的语法
401 用户没有权限(用户名,密码输入错误)
403 用户得到授权(401相反),但是访问被禁止
404 服务器找不到请求的网页,
5XX(表示服务器在处理请求的时候发生内部错误)
500 服务器遇到错误,无法完成请求
503 服务器目前无法使用(超载或停机维护)
二、304的缓存原理(添加Etag标签.last-modified) 304 网页上次请求没有更新,节省带宽和开销
1.服务器首先产生Etag,服务器可在稍后使用它来判断页面是否被修改。本质上,客户端通过该记号传回服务器要求服务器验证(客户端)缓存)
2.304是 HTTP的状态码,服务器用来标识这个文件没有被修改,不返回内容,浏览器接受到这个状态码会去去找浏览器缓存的文件
3.流程:客户端请求一个页面A。服务器返回页面A,并在A上加一个Tage客服端渲染该页面,并把Tage也存储在缓存中。客户端再次请求页面A
并将上次请求的资源和ETage一起传递给服务器。服务器检查Tage.并且判断出该页面自上次客户端请求之后未被修改。直接返回304
last-modified: 客服端请求资源,同时有一个last-modified的属性标记此文件在服务器最后修改的时间
客服端第二次请求此url时,根据http协议。浏览器会向服务器发送一个If-Modified-Since报头,
询问该事件之后文件是否被修改,没修改返回304
1、因为如果在一秒钟之内对一个文件进行两次更改,Last-Modified就会不正确(Last—Modified不能识别秒单位的修改)
2、某些服务器不能精确的得到文件的最后修改时间
3、一些文件也行会周期新的更改,但是他的内容并不改变(仅仅改变修改的事件),这个时候我们并不希望客户端认为文件被修改,而重新Get
1、两者互补,ETag的判断的缺陷,比如一些图片等静态文件的修改
2、如果每次扫描内容都生成ETag比较,显然要比直接比较修改时间慢的多。
ETag是被请求变量的实体值(文件的索引节,大小和最后修改的时间的Hash值)
1、ETag的值服务器端对文件的索引节,大小和最后的修改的事件进行Hash后得到的。
1.get数据是存放在url之后,以?分割url和传输数据,参数之间以&相连; post方法是把提交的数据放在http包的Body中
2.get提交的数据大小有限制,(因为浏览器对url的长度有限制),post的方法提交的数据没有限制
4.get的方法提交数据,会带来安全问题,比如登录一个页面,通过get的方式提交数据,用户名和密码就会出现在url上
四、http协议的理解
1.超文本的传输协议,是用于从万维网服务器超文本传输到本地资源的传输协议
2.基于TCP/IP通信协议来传递数据(HTML,图片资源)
3.基于运用层的面向对象的协议,由于其简洁、快速的方法、适用于分布式超媒体信息系统
请求行(request line)、请求头部(header),空行和请求数据四部分构成
请求行,用来说明请求类型,要访问的资源以及所使用的HTTP版本.
请求头部,用来说明服务器要使用的附加信息
空行,请求头部后面的空行是必须的
请求数据也叫主体,可以添加任意的其他数据。
状态行、消息报头、空行和响应正文
状态行,由HTTP协议版本号, 状态码, 状态消息 三部分组成
消息报头,用来说明客户端要使用的一些附加信息
空行,消息报头后面的空行是必须的
响应正文,服务器返回给客户端的文本信息。
https:是以安全为目标的HTTP通道,简单讲是HTTP的安全版本,通过SSL加密
http:超文本传输协议。是一个客服端和服务器端请求和应答的标准(tcp),使浏览器更加高效,使网络传输减少
长连接:HTTP1.0需要使用keep-alive参数来告知服务器建立一个长连接,而HTP1.1默认支持长连接
节约宽带:HTTP1.1支持只发送一个header信息(不带任何body信息)
host域(设置虚拟站点,也就是说,web server上的多个虚拟站点可以共享同一个ip端口):HTTP1.0没有host域
1.http2采用的二进制文本传输数据,而非http1文本格式,二进制在协议的解析和扩展更好
2.数据压缩:对信息头采用了HPACK进行压缩传输,节省了信息头带来的网络流量
3.多路复用:一个连接可以并发处理多个请求
4.服务器推送:我们对支持HTTP2.0的web server请求数据的时候,服务器会顺便把一些客户端需要的资源一起推送到客户端,免得客户端再次创建连接发送请求到服务器端获取。这种方式非常合适加载静态资源
1.web缓存就是存在于客户端与服务器之间的一个副本、当你第一个发出请求后,缓存根据请求保存输出内容的副本
(1)减少不必要的请求
(2)降低服务器的压力,减少服务器的消耗
(3)降低网络延迟,加快页面打开速度(直接读取浏览器的数据)
八、常见的web安全及防护原理
1.sql注入原理:是将sql代码伪装到输入参数中,传递到服务器解析并执行的一种攻击手法。也就是说,
在一些对server端发起的请求参数中植入一些sql代码,server端在执行sql操作时,会拼接对应参数,
同时也将一些sql注入攻击的“sql”拼接起来,导致会执行一些预期之外的操作。
防范:1.对用户输入进行校验
2.不适用动态拼接sql
2.XSS(跨站脚本攻击):往web页面插入恶意的html标签或者js代码。
举例子:在论坛放置一个看是安全的链接,窃取cookie中的用户信息
防范:1.尽量采用post而不使用get提交表单
2.避免cookie中泄漏用户的隐式
3.CSRF(跨站请求伪装):通过伪装来自受信任用户的请求
举例子:黄轶老师的webapp音乐请求数据就是利用CSRF跨站请求伪装来获取QQ音乐的数据
防范:在客服端页面增加伪随机数,通过验证码
1.XSS是获取信息,不需要提前知道其他用户页面的代码和数据包
2.CSRF代替用户完成指定的动作,需要知道其他页面的代码和数据包
九、CDN(内容分发网络)
1.尽可能的避开互联网有可能影响数据传输速度和稳定性的瓶颈和环节。使内容传输的更快更稳定。
2.关键技术:内容存储和分发技术中
3.基本原理:广泛采用各种缓存服务器,将这些缓存服务器分布到用户访问相对的地区或者网络中。当用户访问网络时利用全局负载技术
将用户的访问指向距离最近的缓存服务器,由缓存服务器直接相应用户的请求(全局负载技术)
十、TCP三次握手 (客服端和服务器端都需要确认各自可收发)
客服端发c起请求连接服务器端s确认,服务器端也发起连接确认客服端确认。
第一次握手:客服端发送一个请求连接,服务器端只能确认自己可以接受客服端发送的报文段
第二次握手: 服务端向客服端发送一个链接,确认客服端收到自己发送的报文段
第三次握手: 服务器端确认客服端收到了自己发送的报文段
十一、从输入url到获取页面的完整过程
1.查询NDS(域名解析),获取域名对应的IP地址 查询浏览器缓存
2.浏览器与服务器建立tcp链接(三次握手)
3.浏览器向服务器发送http请求(请求和传输数据)
4.服务器接受到这个请求后,根据路经参数,经过后端的一些处理生成html代码返回给浏览器
5.浏览器拿到完整的html页面代码开始解析和渲染,如果遇到外部的css或者js,图片一样的步骤
6.浏览器根据拿到的资源对页面进行渲染,把一个完整的页面呈现出来
十三、为什么css放在顶部而js写在后面
1.浏览器预先加载css后,可以不必等待HTML加载完毕就可以渲染页面了
2.其实HTML渲染并不会等到完全加载完在渲染页面,而是一边解析DOM一边渲染。
3.js写在尾部,主要是因为js主要扮演事件处理的功能,一方面很多操作是在页面渲染后才执行的。另一方面可以节省加载时间,使页面能够更加的加载,提高用户的良好体验
但是随着JS技术的发展,JS也开始承担页面渲染的工作。比如我们的UI其实可以分被对待,把渲染页面的js放在前面,时间处理的js放在后面
十四、存储方式与传输方式
1.indexBD: 是h5的本地存储库,把一些数据存储到浏览器中,没网络,浏览器可以从这里读取数据,离线运用。5m
2.Cookie: 通过浏览器记录信息确认用户身份,最大4kb,这也就限制了传输的数据,请求的性能会受到影响
1、cookie,sessionStorage,localStorage是存放在客户端,session对象数据是存放在服务器上 实际上浏览器和服务器之间仅需传递session id即可,服务器根据session-id找到对应的用户session对象 session存储数据更安全一些,一般存放用户信息,浏览器只适合存储一般的数据
4、数据有效期不同,cookie在设置的(服务器设置)有效期内有效,不管窗口和浏览器关闭 sessionStorage仅在当前浏览器窗口关闭前有效,关闭即销毁(临时存储) localStorage始终有效
SessionStorage和localStorage区别: 1.sessionStorage用于本地存储一个会话(session)中的数据,这些数据只有在用一个会话的页面中才能被访问(也就是说在第一次通信过程中) 并且在会话结束后数据也随之销毁,不是一个持久的本地存储,会话级别的储存 2.localStorage用于持久化的本地存储,除非主动删除数据,否则不会过期
1、token就是令牌,比如你授权(登录)一个程序时,他就是个依据,判断你是否已经授权该软件(最好的身份认证,安全性好,且是唯一的)
2、cookie是写在客户端一个txt文件,里面包括登录信息之类的,这样你下次在登录某个网站,就会自动调用cookie自动登录用户名
服务器生成,发送到浏览器、浏览器保存,下次请求再次发送给服务器(存放着登录信息)
3、session是一类用来客户端和服务器之间保存状态的解决方案,会话完成被销毁(代表的就是服务器和客户端的一次会话过程)
基于Token的身份验证:(最简单的token: uid用户唯一的身份识别 + time当前事件戳 + sign签名)
1、用户通过用户名和密码发送请求
3、服务器端返回一个带签名的token,给客户端
4、客户端储存token,并且每次用于发送请求
5、服务器验证token并且返回数据
每一次请求都需要token
1、cookie数据存放在客户的浏览器上,session数据放在服务器上。
2、cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。
3、session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE。
4、单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
1、session认证只是把简单的User的信息存储Session里面,sessionID不可预测,一种认证手段。只存在服务端,不能共享到其他的网站和第三方App
2、token是oAuth Token,提供的是认证和授权,认证针对用户,授权是针对App,目的就是让某APP有权访问某用户的的信息。Token是唯一的,
token不能转移到其他的App,也不能转到其他用户上。(适用于App)
3、session的状态是存在服务器端的,客户端只存在session id, Token状态是存储在客户端的
Cookie的弊端有哪些???(优势:保存客户端数据,分担了服务器存储的负担)
1、数量和长度的限制。每个特定的域名下最多生成20个cookie(chorme和safari没有限制)
在软件开发设计中是一个对象(subject),维护一系列依赖他的对象(observer),当任何状态发生改变自动通知他们。强依赖关系 简单理解:数据发生改变时,对应的处理函数就会自动执行。一个Subjet,用来维护Observers,为某些event来通知(notify)观察者
二、发布-订阅者 有一个信息中介,过滤 耦合性低 它定义了一种一对多的关系,可以使多个观察者对象对一个主题对象进行监听,当这个主题对象发生改变时,依赖的所有对象都会被通知到。
-两者的区别: 1.观察者模式中,观察者知道Subject ,两者是相关联的,而发发布订阅者只有通过信息代理进行通信 2.在发布订阅模式中,组件式松散耦合的。正好和观察者模式相反。 3.观察者大部分是同步的,比如事件的触发。Subject就会调用观察者的方法。而发布订阅者大多数是异步的()
4.观察者模式需要在单个应用程序地址空间中实现,而发布订阅者更像交叉应用模式。
一、两个栈实现一个队列,两个队列实现一个栈
二、红黑树(解决二叉树依次插入多个节点时的线型排列)
三、最小栈的实现(查找最小元素,用两个栈配合栈内元素的下标)
1.冒泡排序:重复走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把它们交换过来。
实现过程:1.比较相邻的元素。如果第一个比第二个大,就交换他们两个
2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对,这样在最后的元素应该会是最大的数
3.针对所有的元素重复以上的步骤,除了最后一个
4.重复步骤1-3,直到排序完成。
2.选择排序:首先在未排序序列中找到最小值,放在排序序列的起始位置,然后,在从剩下未排序元素中继续寻找最小值,然后放在与排序序列的末尾
3.插入排序:构建有序序列,对于未排序数据,在已排序序列中冲后向前扫描,找到相应位置并插入
实现过程:1.从第一个元素开始,该元素可以认为已经被排序
2.取出下一个元素,在已排序的元素序列中冲后向前扫描
3.如果该元素(以排序)大于新元素,将元素向后移一位
4.在取出一个元素,比较之前的,直到找到自己合适的位置
4.桶排序:将数据分布到有限数量的桶里,每个桶在分别排序
1.快速排序:快速排序使用分治法把一个串(list)分为两个子串(sub-lists).具体算法实现
实现过程:1.从数组中挑出一个元素,成为一个基准
2.重新排列数组,所有元素比基准小的摆在基准前面,所有元素比基准大的摆在基准后面(相同的可以摆在一边)
这个分区退出之后,该基准就处于数列的中间位置。成为分区操作。
3.递归的把小于基准值的子数列和大于基准值元素的子数列排序
2.堆排序:利用对这种数据结构所涉及的一种排序算法,堆积是一个近乎完全二叉树的结构,并同时满足堆积的性质:即子节点的键值或索引总是小于(或大于)它的父节点。
3.数组排序去重 最快你Olong
判断回文字符串:(递归的思想)
2.字符串头部和尾部,逐次向中间检测
七、二分查找(有序数组的查找)
二分查找可以解决已排序数组的查找问题,即只要数组中包含T(要查找的值),那么通过不断的缩小包含T的数据范围,就可以最终要找到的数
(1) 一开始,数据范围覆盖整个数组。
(2) 将数组的中间项与T进行比较,如果T比数组的中间项小,则到数组的前半部分继续查找,反之,则到数组的后半部分继续查找。
(3) 就这样,每次查找都可以排除一半元素,相当于范围缩小一半。这样反复比较,反复缩小范围,最终会在数组中找到T
一、动手实现一个bind(原理通过apply,call)
一句话概括:1.bind()返回一个新函数,并不会立即执行。
2.bind的第一个参数将作为他运行时的this,之后的一系列参数将会在传递的实参前传入作为他的参数
3.bind返回函数作为构造函数,就是可以new的,bind时指定的this值就会消失,但传入的参数依然生效
ajax的原理:相当于在用户和服务器之间加一个中间层(ajax引擎),使用户操作与服务器响应异步化。
优点:在不刷新整个页面的前提下与服务器通信维护数据。不会导致页面的重载
可以把前端服务器的任务转嫁到客服端来处理,减轻服务器负担,节省宽带
劣势:不支持back。对搜索引擎的支持比较弱;不容易调试
怎么解决呢?通过location.hash值来解决Ajax过程中导致的浏览器前进后退按键失效,
解决以前被人常遇到的重复加载的问题。主要比较前后的hash值,看其是否相等,在判断是否触发ajax
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。}
这几年里,单页面应用的框架令人应接不暇,各种新的概念也层出不穷。从过去的 jQuery Mobie、Backbone 到今天的 Angular 2、React、Vue 2,除了版本号不同,他们还有很多的相同之处。
刚开始写商业代码的时候,我使用的是 jQuery。使用 jQuery 来实现功能很容易,找到一个相应的 jQuery 插件,再编写相应的功能即可。对于单页面应用亦是如此,寻找一个相辅助的插件就可以了,如 jQuery Mobile。
尽管在今天看来,jQuery Mobile 已经不适合于今天的多数场景了。这个主要原因是,当时的用户对于移动 Web 应用的理解和今天是不同的。他们觉得移动 Web 应用就是针对移动设备而订制的,移动设备的 UI、更快的加载速度等等。而在今天,多数的移动 Web 应用,几乎都是单页面应用了。
过去,即使我们想创建一个单页面应用,可能也没有一个合适的方案。而在今天,可选择的方案就多了(PS:参见《第四章:学习前端只需要三个月【框架篇】》)。每个人在不同类型的项目上,也会有不同的方案,没有一个框架能解决所有的问题
当我们会用的框架越多的时候, 所花费的时间抉择也就越多。而单页面应用的都有一些相同的元素,对于这些基本元素的理解,可以让我们更快的适合其他框架。
我接触到单页面应用的时候,它看起来就像是将所有的内容放在一个页面上么。只需要在一个 HTML 写好所需要的各个模板,并在不同的页面上 data-role 表明这是个页面(基于 jQuery Mobile)——每个定义的页面都和今天的移动应用的模式相似,有
这样我们就在一个 HTML 里返回了所有的页面了。随后,只需要在在入口处的 href 里,写好相应的 ID 即可。
当我们点击相应的链接时,就会切换到 HTML 中相应的 ID。这种简单的单页面应用基本上就是一个离线应用了,只适合于简单的场景,可是它带有单页面应用的基本特性。而复杂的应用,则需要从服务器获取数据。然而早期受限于移动浏览器性能的影响,只能从服务器获取相应的 HTML,并替换当前的页面。
在这样的应用中,我们可以看到单页面应用的基本元素: 页面路由,通过某种方式,如 URL hash 来说明表明当前所在的页面,并拥有从一个页面跳转到另外一个页面的入口。
当移动设备的性能越来越好时,开发者们开始在浏览器里渲染页面。
当移动设备的性能越来越好时,开发者们开始在浏览器里渲染页面:
通过结合这一系列的工具,我们终于可以实现一个复杂的单页面应用。而这些,也就是今天我们看到的单页面应用的基本元素。我们可以在 Angular 应用、React 应用、Vue.js 应用 看到这些基本要素的影子,如:Vue Router、React Router、Angular 2 RouterModule 都是负责路由(页面跳转及模块关系)的。在 Vue 和 React 里,它们都是由辅助模块来实现的。因为 React 只是层 UI 层,而 Vue.js 也是用于构建用户界面的框架。
要说起路由,那可是有很长的故事。当我们在浏览器上输入网址的时候,我们就已经开始了各种路由的旅途了。
当我们做后台应用的时候,我们只需要关心上述过程中的最后一步。即,将对应的路由交给对应的函数来处理。这一点,在不同的后台框架的表现形式都是相似的。
而在 Laravel 里,则是通过参数的形式来呈现
虽然表现形式有一些差别,但是总体来说也是差不多的。而对于前端应用来说,也是如此,将对应的 URL 的逻辑交由对应的函数来处理。
React Router 使用了类似形式来处理路由,代码如下所示:
当页面跳转到 blog 的时候,会将控制权将给 BlogList 组件来处理。
从上面来看,尽管表现形式上有所差异,但是其行为是一致的:使用规则引擎来处理路由与函数的关系。稍有不同的是,后台的路由完全交由服务器端来控制,而前端的请求则都是在本地改变其状态。
并且同时在不同的前端框架上,他们在行为上还有一些区别。这取决于我们是否需要后台渲染,即刷新当前页面时的表现形式。
幸运的是,大部分的最新 Router 组件都会判断是否支持 history API,再来决定先用哪一个方案。
实现路由的时候,只是将对应的控制权交给控制器(或称组件)来处理。而作为一个单页面应用的控制器,当执行到相应的控制器的时候,就可以根据对应的 blog/12 来获取到用户想要的 ID 是 12。这个时候,控制器将需要在页面上设置一个 loading 的状态,然后发送一个请求到后台服务器。
对于数据获取来说,我们可以通过封装过 XMLHttpRequest 的 Ajax 来获取数据,也可以通过新的、支持 Promise 的 Fetch API 来获取数据,等等。Fetch API 与经过 Promise 封装的 Ajax 并没有太大的区别,我们仍然是写类似于的形式:
对于复杂一点的数据交互来说,我们可以通过 RxJS 来解决类似的问题。整个过程中,比较复杂的地方是对数据的鉴权与模型(Model)的处理。
模型麻烦的地方在于:转变成想要的形式。后台返回的值是可变的,它有可能不返回,有可能是 null,又或者是与我们要显示的值不一样——想要展示的是 54%,而后台返回的是 0.54。与此同时,我们可能还需要对数值进行简单的计算,显示一个范围、区间,又或者是不同的两种展示。
同时在必要的时候,我们还需要将这些值存储在本地,或者内存里。当我们重新进入这个页面的时候,我们再去读取这些值。
一旦谈论到数据的时候,不可避免的我们就需要关心安全因素。对于普通的 Web 应用来说,我们可以做两件事来保证数据的安全:
目前,流行的前端鉴权方式是 Token 的形式,可以是普通的定制 Token,也可以是 JSON Web Token。获取 Token 的形式,则是通过 Basic 认证——将用户输入的用户名和密码,经过 BASE64 加密发送给服务器。服务器解密后验证是否是正常的用户名和密码,再返回一个带有时期期限的 Token 给前端。
随后,当用户去获取需要权限的数据时,需要在 Header 里鉴定这个 Token 是否有限,再返回相应的数据。如果 Token 已经过期了,则返回 401 或者类似的标志,客户端就在这个时候清除 Token,并让用户重新登录。
现在,我们已经获取到这些数据了,下一步所需要做的就是显示这些数据。与其他内容相比,显示数据就是一件简单的事,无非就是:
不同的框架会存在一些差异。并且现代的前端框架都可以支持单向或者双向的数据绑定。当相应的数据发生变化时,它就可以自动地显示在 UI 上。
最后,在相应需要处理的 UI 上,绑上相应的事件来处理。
只是在数据显示的时候,又会涉及到另外一个问题,即组件化。对于一些需要重用的元素,我们会将其抽取为一个通用的组件,以便于我们可以复用它们。
并且在这些组件里,也会涉及到相应的参数变化即状态改变。
完成一步步的渲染之后,我们还需要做的事情是:交互。交互分为两部分:用户交互、组件间的交互——共享状态。
用户从 A 页面跳转到 B 页面的时候,为了解耦组件间的关系,我们不会使用组件的参数来传入值。而是将这些值存储在内存里,在适当的时候调出这些值。当我们处理用户是否登录的时候,我们需要一个 isLogined 的方法来获取用户的状态;在用户登录的时候,我们还需要一个 setLogin 的方法;用户登出的时候,我们还需要更新一下用户的登录状态。
在没有 Redux 之前,我都会写一个 service 来管理应用的状态。在这个模块里写上些 setter、getter 方法来存储状态的值,并根据业务功能写上一些来操作这个值。然而,使用 service 时,我们很难跟踪到状态的变化情况,还需要做一些额外的代码来特别处理。
有时候也会犯懒一下,直接写一个全局变量。这个时候维护起代码来就是一场噩梦,需要全局搜索相应的变量。如果是调用某个特定的 Service 就比较容易找到调用的地方。
事实上,对于用户交互来说也只是改变状态的值,即对状态进行操作。
举一个例子,当用户点击登录的时候,发送数据到后台,由后台返回这个值。由控制器一一的去修改这些状态,最后确认这个用户登录,并发一个用户已经登录的广播,又或者修改全局的用户值。