以下内容仅为个人见解,如有错误欢迎指正~
vue
双向绑定
原理:
vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,
通过Object.defineProperty()来劫持各个属性的setter,getter,
在数据变动时发布消息给订阅者,触发相应的监听回调。
延伸:
* Object.defineProperty() 是ES5 中一个无法 shim 的特性, 这也就是 Vue 不支持 IE8 以及更低版本浏览器的原因。
* Object.defineProperty(对象,属性,属性描述符) 用于在一个对象上定义一个新的属性, 或者修改一个对象现有的属性,并返回这个对象
实现:
通过Obeject.defineProperty()来监听数据属性变动,将数据对象进行递归遍历,包括子属性对象的属性,都加上 setter和getter。
详解:
*实现一个监听器Observer:
给对象的某个值赋值 ==> 触发setter(监听到数据变化)==> 通知订阅者(notify(在调用订阅者的update方法))
*实现一个订阅者Watcher:
可以收到属性的变化通知并执行相应的函数,从而更新视图。(getter(const dep = new Dep();然后清空,减少性能浪费))
*实现一个解析器Compile:
可以扫描和解析每个节点的相关指令,并根据初始化模板数据以及初始化相应的订阅器。
watch | computer
共同点:
希望在数据发生改变的时候,数据根据预先定义好的函数,发生“自动”的变化。
区别:
watch擅长处理的场景:一个数据影响多个数据
computed擅长处理的场景:一个数据受多个数据影响
组件传值
父改子:
ref $ref
父传子:
props
子传父:
$emit
兄弟组件:
$on
通用:
利用缓存(store locationstrage 后端....)
延伸:vue监听子组件生命周期
// Parent.vue
<Child @mounted="doSomething"/>
// Child.vue
mounted() {
this.$emit("mounted");
}
或者
<Child @hook:mounted="doSomething"/>
keep-alive
原理:
Vue 的缓存机制并不是直接存储 DOM 结构,而是将 DOM 节点抽象成了一个个 VNode节点。
因此,Vue 的 keep-alive 缓存也是基于 VNode节点 而不是直接存储 DOM 节点。
用法:
<keep-alive>是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
include: 字符串或正则表达式。只有匹配的组件会被缓存。
exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
max:最多几个(vue2之前不生效)
v-if v-for 使用
v-for 优先级高,因此不建议同时使用,可在上层dom 使用 v-if
路由(hash | history + 路由守卫)
hash:
就是指 url 尾巴后的 # 号以及后面的字符,window.location.hash获取hash值
history:
window.history(可直接写成history)指向History对象,它表示当前窗口的浏览历史
路由守卫
全局
router.beforeEach((to, from, next) => { // ...})
router.afterEach((to, from) => { // ... })
路由独享的守卫
const router = new VueRouter({
routes: [ {
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => { // ... }
} ]
})
组件内的守卫
beforeRouteEnter
beforeRouteUpdate (2.2 新增)
beforeRouteLeave
虚拟dom优缺点
什么是虚拟dom:
用js模拟一颗dom树,放在浏览器内存中.当你要变更时,虚拟dom使用diff算法进行新旧虚拟dom的比较,将变更放到变更队列中,
反应到实际的dom树,减少了dom操作.虚拟DOM将DOM树转换成一个JS对象树,
diff算法逐层比较,删除,添加操作,但是,如果有多个相同的元素,可能会浪费性能,所以,
react和vue-for引入key值进行区分.
优点:
*虚拟DOM具有批处理和高效的Diff算法,最终表现在DOM上的修改只是变更的部分,可以保证非常高效的渲染,优化性能.
缺点:
*性能差(虽然虚拟 DOM + 合理的优化,足以应对绝大部分应用的性能需求,但在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化。)
*首次渲染大量DOM时,由于多了一层虚拟DOM的计算,会比innerHTML插入慢。
es6
promise
先执行getData1,在执行getData2
let getData1=new Promise(function(resolve,reject){
$.ajax({
type:"get",
url:".../getData1",
success:function(data){
if(data.state=="200"){
resolve(data.data) // 在异步操作成功时调用
}else{
reject(data.msg); //在异步操作失败时调用
}
}
});
})
let getData2=new Promise(function(resolve,reject){
$.ajax({
type:"get",
url:".../getData2",
success:function(data){
if(data.state=="200"){
resolve(data.data) // 在异步操作成功时调用
}else{
reject(data.msg); //在异步操作失败时调用
}
}
});
})
getData1.then(function(res){
return getData2(res)
}).then(function(res){
console.log(res)
}).catch(function(err){
console.log(err)
})
先执行getData1和getData2,在执行getData3
let getData3=new Promise(function(resolve,reject){
$.ajax({
type:"get",
url:".../getData3",
success:function(data){
if(data.state=="200"){
resolve(data.data) // 在异步操作成功时调用
}else{
reject(data.msg); //在异步操作失败时调用
}
}
});
})
Promise的all方法,等数组中的所有promise对象都完成执行
Promise.all([getData1,getData2]).then(function([ResultJson1,ResultJson2]){
//这里写等这两个ajax都成功返回数据才执行的业务逻辑
getData3()
})
for in | for of
for in 循环的是 index
for of 循环的是 item
proxy
js
数组方法
1.splice(index,howmany,[item1,...]):从数组中添加/删除元素,返回被删除项,注意:这个操作会改变原始数组。
2.slice(start,[end]):从已有数组中返回选定元素,此操作不会修改原始数组。
3.shift():删除数组第一个元素,返回删除项,改变原始数组,不产生新数组。
4.unshift(newelement1,[...]):在数组开头添加一或多个元素,并返回新的长度。改变原数组,不产生新数组。
5.pop():删除数组最后一个元素,并返回删除的值,若是操作空数组,返回undefined。改变原数组。
6.push(element1,[......]):向数组末尾添加一个或多个元素,返回数组长度。直接修改原数组。
7.concat(arrayX,......):连接两个或多个数组,返回被连接数组的副本,不会改变原始数组。
8.reverse():颠倒数组元素顺序,改变原始数组,不会创建新数组。
9.sort():对现有数组进行排序,改变原始数组。此方法会在排序之前首先对数组的每一项调用toString()方法,再进行排序
10.join([separator]):对数组元素以指定的分隔符进行分隔,参数为空,默认以“,”进行分隔。返回值是分隔后形成的字符串
数据类型
基本数据类型包括undefined、null、number、boolean、string;
对象类型Object,比如:Object、array、function、data等;
从输入URL到页面展示的详细过程
1、输入网址
2、DNS解析
3、建立tcp连接
4、客户端发送HTPP请求
5、服务器处理请求
6、服务器响应请求
7、浏览器展示HTML
8、浏览器发送请求获取其他在HTML中的资源。
闭包
闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
通俗的来说就是:JavaScript中所有的function都是一个闭包。不过一般来说,嵌套的function所产生的闭包更为强大,也是大部分时候我们所谓的“闭包”
当函数a的内部函数b被函数a外的一个变量引用的时候,就创建了一个闭包。