https://developer.mozilla.org/zh-CN/ 一个很好用的前端官方文档
HTTP
HTTP头常用字段
Cache-Control
通常,浏览器会缓存服务器发来的文件,比如图片,视频之类的,这样在下次再用的时候,就不用服务器发送回文件了,节省了时间。关于缓存机制,通过http头部的Cache-Control字段来表示。
在缓存中,我们需要一个机制来验证缓存是否有效。比如服务器的资源更新了,客户端需要及时刷新缓存;又或者客户端的资源过了有效期,但服务器上的资源还是旧的,此时并不需要重新发送。缓存校验就是用来解决这些问题的,在http 1.1 中,我们主要关注下Last-Modified 和 etag 这两个字段。
Last-Modifed
服务端在返回资源时,会将该资源的最后更改时间通过Last-Modified字段返回给客户端。客户端下次请求时通过If-Modified-Since或者If-Unmodified-Since带上Last-Modified,服务端检查该时间是否与服务器的最后修改时间一致:如果一致,则返回304状态码,不返回资源;如果不一致则返回200和修改后的资源,并带上新的时间。
etag
单纯的以修改时间来判断还是有缺陷,比如文件的最后修改时间变了,但内容没变。对于这样的情况,我们可以使用etag来处理。etag的方式是这样:服务器通过某个算法对资源进行计算,取得一串值(类似于文件的md5值),之后将该值通过etag返回给客户端,客户端下次请求时通过If-None-Match或If-Match带上该值,服务器对该值进行对比校验:如果一致则不要返回资源。
Content-Type
表示文件类型。可以是 text/plain, text/javascript, image/jpg等。
Cookie
https://blog.csdn.net/playboyanta123/article/details/79464684 这里面还讲了一些xhr和跨域资源请求的链接。
状态码
200
OK
301
永久重定向
302
临时重定向
304
请求的资源未修改
cookie
什么是cookie,当你登录淘宝网后,选择一个物品加入购物车, 淘宝的后端怎么知道是谁选择了这个商品,为什么没有让你输入账号密码,因为cookie中已经有了。
/1.jpg)
上图是从chrome浏览器查看一个网站的cookie的示意图,左边栏Cookies下方会列举当前网页中设置过cookie的域都有哪些。
一般情况下,当客户端发送请求时,都会在http头部的Cookie字段设置该网页设置过的cookie。
cookie的属性
1 | var cookie = "key=name; expires=Thu, 25 Feb 2020 04:18:00 GMT; domain=baidu.com; path=/; secure; HttpOnly" |
上面的每个等号左右就是键和值。若被;分割的块里没有等号,则表示相应属性置位,比如secure, HttpOnly。
1 | response.setHeader('Set-Cookie',cookie) //设置Cookie字段 |
增删改查
要想修改一个cookie,只需要重新赋值就行,旧的值会被新的值覆盖。但要注意一点,在设置新cookie时,path/domain这几个选项一定要旧cookie 保持一样。否则不会修改旧值,而是添加了一个新的 cookie。
删除一个cookie 也挺简单,也是重新赋值,只要将这个新cookie的expires 选项设置为一个过去的时间点就行了。但同样要注意,path/domain/这几个选项一定要旧cookie 保持一样。
js清除所有网页下cookie
1 | function deleteCookie() { |
原生js实现http请求
1 | function httpRequest(paramObj, fun, errFun) |
1 | /*请求参数*/ |
注意:如果在按钮的事件中进行http请求,而且请求的回应是html类型的文档,则浏览器不会自动跳转到这个html,所以如果想要跳转,必须把按钮替换为<a>标签。
express后端框架
原生的http在某些方面表现不足以应对我们的开发需求,所以我们就需要使用框架,让代码高度统一。Express是Node中的一个框架
路由
1 | /* |
express-art-template
1 | npm install art-template --save |
art-template官网:github.com/aui/art-template
express获取post表单数据
在express中没有内置获取表单 post 请求体的api。我们需要使用第三方插件:
1 | npm install body-parser --save |
在express官网的middle ware选项中可以查看详细用法
在express中express().get()方法无法处理带有查询语句的GET语句,比如/pinglun?name之类的。
一般情况下,请求html页面用get方法,提交表单数据用post方法。
封装ajax方法
1 | /* |
express的cookie操作
若浏览器没有保存cookie,则app.get(‘/‘,function(req,res)))中的req.cookies是undefined值。
宠物商店设计
我们登录到localhost:3000,默认是狗的页面,说明localhost:3000和localhost:3000/dog 的页面相同,都是返回index.html或者index_login.html,根据cookie中的用户信息来决定是index.html还是index_login.html。为了让点击导航是关于狗的商品,在导航的href中设置url时带上狗的标识,比如/dog/main_food表示选择狗的主食,然后返回一个页面。
退出登录时,要发送请求到服务器,清除对应的sessionId的,然后再在本地浏览器清除cookie。
在一个物品的主页,要设置一个隐藏表单,然后把加入购物车当做一个button,当点击这个button时,就发出ajax请求,顺带上隐藏表单的内容,然后后端在userInfos中的购物车中加入这个物品的信息,然后服务端发回一个数字,好让主页的购物车图标可以显示数字。
在选择主食后的页面,是一个很大的表单,下面是很多该类别下的链接,当点击表单的不同选项,就可以发送ajax请求,然后服务端发送一个json文件,然后我们就可以根据这个json来布置表单下的链接。
vue前端框架
组件
例子1
1 | <!-- |
1 | //index.js |
1 | <!-- |
例子2
1 |
|
1 |
|
例子3
1 |
|
1 |
|
这个例子体现了数据绑定的优势。
例子4
1 |
|
1 |
|
以上的代码可以实现我要的结果,也体现了组件化的优势。我在一个div里面要放多个com组件,同时com组件要传进去一些参数。com组件的数量由items决定,参数可以通过v-bind绑定组件属性与item的值。
vue的优点
双向数据绑定
也就是所谓的响应式数据绑定。这里的响应式不是@media 媒体查询中的响应式布局,而是指vue.js会自动对页面中某些数据的变化做出同步的响应。
也就是说,vue.js会自动响应数据的变化情况,并且根据用户在代码中预先写好的绑定关系,对所有绑定在一起的数据和视图内容都进行修改。而这种绑定关系,就是以input 标签的v-model属性来声明的,因此你在别的地方可能也会看到有人粗略的称vue.js为声明式渲染的模版引擎。
这也就是vue.js最大的优点,通过MVVM思想实现数据的双向绑定,让开发者不用再操作dom对象,有更多的时间去思考业务逻辑。
组件化
在前端应用,我们是否也可以像编程一样把模块封装呢?这就引入了组件化开发的思想。
Vue.js通过组件,把一个单页应用中的各种模块拆分到一个一个单独的组件(component)中,我们只要先在父级应用中写好各种组件标签(占坑),并且在组件标签中写好要传入组件的参数(就像给函数传入参数一样,这个参数叫做组件的属性),然后再分别写好各种组件的实现(填坑),然后整个应用就算做完了。
视图,数据,结构分离
使数据的更改更为简单,不需要进行逻辑代码的修改,只需要操作数据就能完成相关操作
虚拟DOM
现在的网速越来越快了,很多人家里都是几十甚至上百M的光纤,手机也是4G起步了,按道理一个网页才几百K,而且浏览器本身还会缓存很多资源文件,那么几十M的光纤为什么打开一个之前已经打开过,已经有缓存的页面还是感觉很慢呢?这就是因为浏览器本身处理DOM也是有性能瓶颈的,尤其是在传统开发中,用JQuery或者原生的JavaScript DOM操作函数对DOM进行频繁操作的时候,浏览器要不停的渲染新的DOM树,导致页面看起来非常卡顿。
而Virtual DOM则是虚拟DOM的英文,简单来说,他就是一种可以预先通过JavaScript进行各种计算,把最终的DOM操作计算出来并优化,由于这个DOM操作属于预处理操作,并没有真实的操作DOM,所以叫做虚拟DOM。最后在计算完毕才真正将DOM操作提交,将DOM操作变化反映到DOM树上。
运行速度更快
像比较与react而言,同样都是操作虚拟dom,就性能而言,vue存在很大的优势
axios中间件
axios是vue中的中间件,可以进行ajax请求
http://www.axios-js.com/zh-cn/docs/
event对象
vue通过$event的方式传入event对象
1 | <button v-for="peifang in dogZhuliangProp['peifangs']" v-on:click="selectProp($event, 'peifang')"> |
1 | selectProp: function (event, prop) { |
虚拟DOM
参考 https://www.jianshu.com/p/af0b398602bc
.vue组件
例子1
假设有一个组件<app>,它里面有两个子组件Header,Footer,如果不用.vue文件保存组件信息,直接把它们表述在.js文件中,是下面这个样子。
1 | var Header = Vue.extend({ |
3个组件同时写到了.js文件中,很不方便,而且,没法重用到其他的单页应用中。
下面用.vue的写法
1 | //App.vue |
Header组件和Footer组件分别保存在Header.vue和Footer.vue中。
什么是.vue组件
*.vue 文件,是一个自定义的文件类型,用类似HTML的语法描述一个Vue组件。每个.vue文件包含三种类型的顶级语言块 <template>, <script> 和 <style>。这三个部分分别代表了 html,js,css。
没用好组件化的实例(宠物商店)
宠物主粮有很多属性:大小,原料。用户要在界面上选择多个属性值,然后选择的属性值对应的元素样式是彩色的,未选择的是白色的。所以这个选择宠物主粮属性的块完全可以当做一个组件<dog_zhuliang_sel>
一开始,我没有这样做。我在vue实例中定义了所有宠物主粮属性值对应的style,保存在vm.$data的一个属性中,视图上所有宠物主粮属性值对应的button的style通过v-bind绑定到这个数据上。然后,监听宠物主粮属性值的click事件,根据这个事件,修改vm.$data中对应的属性。
但是,这样就使得子组件和父组件耦合太紧密了。我应该把上述的操作完全放在子组件中,对于父组件,我们就只提供它需要的信息。
vue修改元素样式
例子1
/1.png)
v-bind
1 | <template> |
1 | <script> |
color-picker组件会监听颜色的变化,然后改变titleColor,接着由于titleColor和style之间有单向数据绑定,所以style的值也变化了,这样就改变了样式。
时间监听和js原生获取元素
1 | <template> |
1 | <script> |
在这里,定义了color-picker的change事件的回调函数changeColor,然后在changeColor函数里面通过Js原生获取一个元素的style属性,然后改变它。
vue的$refs属性获取元素
vue $refs的文档:https://cn.vuejs.org/v2/api/#vm-refs
vue ref的文档:https://cn.vuejs.org/v2/api/#ref
和方法2类似。
1 | <template> |
1 | <script> |
vue自定义事件
例子1(向父组件传播)
1 |
|
在父组件的<my_btn>标签内添加属性@total="allcounter",然后在父组件的methods中写一个allCounter方法。
v-model
v-model的流程是:监听标签内的事件,将对应的属性和组件内的数据双向绑定在一起。所以核心是事件和属性。例如:
- text和textarea元素使用value属性和input事件
- checkbox和radio使用checked属性和change事件
- select使用value属性和change事件
对于自定义组件,使用哪个属性和事件呢?
v-model会默认利用value属性和input事件,v-model相当于
1 | <input v-bind:value="message" v-on:input="message=$event.target.value"> |
例子:
1 | <!--父组件--> |
1 | <!-- 子组件--> |
SPA单页面应用
例1
下面是Hash模式实现的SPA demo
1 |
|
例子2
参考 https://segmentfault.com/a/1190000019936510
用到了Hash模式跳转,但是用了route
1 | class Router{ |
1 | <div id="app"> |
优缺点
优点
1) 有良好的交互体验
能提升页面切换体验,用户在访问应用页面是不会频繁的去切换浏览页面,从而避免了页面的重新加载;
2) 前后端分离开发
单页Web应用可以和 RESTful 规约一起使用,通过 REST API 提供接口数据,并使用 Ajax 异步获取,这样有助于分离客户端和服务器端工作。更进一步,可以在客户端也可以分解为静态页面和页面交互两个部分;
3) 减轻服务器压力
服务器只用出数据就可以,不用管展示逻辑和页面合成,吞吐能力会提高几倍;
4) 共用一套后端程序代码
不用修改后端程序代码就可以同时用于 Web 界面、手机、平板等多种客户端;
缺点
1) SEO难度较高
由于所有的内容都在一个页面中动态替换显示,所以在SEO上其有着天然的弱势,所以如果你的站点对SEO很看重,且要用单页应用,那么就做些静态页面给搜索引擎用吧;
2) 开发难度高
较高的前端开发门槛,对技术能力要求较高,需要对设计模式有一定理解,因为面对不是一个简单的页面,而是一个运行在浏览器环境里面的桌面软件。
SPA优化
tips
可以在cdnjs.com/ 上查询很多前端框架的包并在js中引用, 不用自己下载。比如
1
https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.12/vue.min.js