采用数据劫持+发布订阅模式
通过递归遍历整个data,用Object.defineProperty()来劫持各个属性的setter和getter方法,给每个属性创建一个订阅中心,在get方法中添加订阅者到订阅中心,在set方法中通知订阅中心,继而通知每个订阅者。
1、实现一个数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者。
2、实现一个指令解析器Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数。
3、实现一个Watcher,作为连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图。
4、mvvm入口函数,整合以上三者。
①Axios是一个基于promise的HTTP库,同时支持浏览器和node环境,支持对请求和响应的拦截。
②常用的get,post,put,delete等方法。post请求方法,参数key为data,其他的请求参数key为params。
③浏览器核心函数,浏览器(XMLHttpRequest),node环境(http[s].request)
④源码解读:
核心词汇: a.拦截器 请求拦截器(interceptors.request):用于对发起的请求进行拦截,可修改一些配置文件。
响应拦截器(interceptors.response):用于对响应结果的处理,可有效阻止crsf攻击。 b.数据转换器 请求转换器(transformRequest):在请求前对数据进行转换。 响应转换器(transformResponse):对响应后的响应体进行转换。 c.config配置 用于对默认配置项和自定义配置项的合并处理,比如说: 跨域请求携带cookie:使用withCredentials = true。 设置请求超时时间:timeout = 3000 d.http请求适配器 主要用于处理是浏览器环境还是node环境。
Fetch API 提供了一个获取资源的接口(包括跨域请求),提供了更强大和灵活的功能集。
①接口合理化,AJAX 是将所有不同性质的接口都放在 XHR 对象上,而Fetch是将它们分散在几个不同的对象上(Headers,Body,Request,Response),设计更合理;
②Fetch操作返回 Promise 对象,避免了嵌套的回调函数。
③即使响应是HTTP 404或500,从 fetch() 返回的Promise也不会拒绝HTTP错误状态。相反,它将正常解析(ok状态设置为false),并且它只会在网络故障时拒绝,或者如果任何东西阻止了请求的完成。
④默认情况下, 如果网站使用cookie来维护用户身份时(发送cookie,必须设置credentials init选项),否则fetch不会发送或接收来自服务器的任何cookie,从而导致未经身份验证的请求。
function ajaxRequest(method, url, data, callback, flag) {
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
//IE
xhr = new ActiveXObject('Microsoft.XMLHttp');
}
}
if (method == 'GET') {
xhr.open(method, url + '?' + data, flag);
xhr.send();
} else if (method == 'POST') {
xhr.open(method, url, flag);
xhr.setRequestHeader('content-type', 'application/x-www-form-urlencoded');
xhr.sed(data);
}
xhr.onreadystatechange = function () {
/* 0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
*/
if (xhr.readyState == 4) {
if (xhr.status == 200) {
callback(xhr.responseText);
}
}
}
①代码版本管理,Git or SVN?
②技术选型:
基础框架选择(vue,react,团队成员能力?)
HTTP请求库(axios,fetch)
CSS预处理器(less,scss)
UI库选择(iview,element ui,ant design,vant等等)
静态资源(图标字体,图片格式?)
安全处理(csrf,xss,https?)
数据mock(eolinker,还是自己搭建yapi?)
③自动编译发布jenkins
④灰度发布(金丝雀发布)
⑤监控埋点:百度统计,友盟
⑥报警与错误处理:sentry,BetterJS,Logan等。
⑦开发工具配置
eslint配置,vscode快捷插件等。
⑧开发文档撰写
①业务如何分层?模块如何划分?
②路由如何设计?父子嵌套?
③数据如何管理?
④组件如何划分?划分原则是什么?
⑤浏览器兼容性如何处理?
⑥代码规范?如何命名?
⑦性能优化如何做?
生命周期函数 | 作用 |
---|---|
beforeCreate | 实例初始化之后,数据观测和事件配置之前被调用 |
created | 实例创建完成之后被调用 |
beforeMount | 挂载之前被调用,相关的render函数首次被调用 |
mounted | el被新创建的vm.$el替换,并挂载到实例上去之后调用该钩子 |
beforeUpdate | 数据更新时调用,发生在虚拟DOM重新渲染和打补丁之前 |
updated | 虚拟DOM重新渲染后调用 |
activated | keep-alive组件激活时调用 |
deactivated | keep-alive组件停用时调用 |
beforeDestory | 实例销毁之前调用 |
destory | 实例销毁后调用 |
父beforeCreate->父created->父beforeMount-> 子beforeCreate->子created->子beforeMount->子mounted-> 父mounted
父beforeUpdate->子beforeUpdate->子updated->父updated
父beforeUpdate->父updated
父beforeDestory->子beforeDestory->子destoryed->父destoryed
URL(Universal Resource Locator)即统一资源定位符,又称网页地址,用于定位浏览器中所需显示的网页资源。在H5之前切换URL都会导致浏览器强制刷新,耗费时间和资源。而HTML5History允许在不刷新浏览器的情况下更新页面局部布局。
HTML5History接口允许操作浏览器的曾经在标签页或者框架里的历史记录,通俗说就是,可以通过window可以对history对象进行属性的获取和方法的操作。
属性或者方法 | 操作说明 |
---|---|
history.length | 返回一个整数,表示会话历史中元素的数目,包括当前页的加载 |
history.state | 返回一个表示历史堆栈顶部的状态值,在没有调用pushState()或者replaceState()之前,state的值为null |
history.back() | 返回上一页,等价于history.go(-1) |
history.forward() | 下一页,等价于history.go(1) |
history.pushState(state,title,url) | 用于向当前浏览器堆栈添加一个新的state |
history.replaceState(state,title,url) | 用于更新当前历史记录(更新state或者URL) |
Copyright© 2013-2020
All Rights Reserved 京ICP备2023019179号-8