2020.03.24 vue - key的作用
问 : Vue项目时为什么要在列表组件中写 key,其作用是什么?
答 : Vue采用diff算法来对比新旧虚拟节点,key的作用是为了在diff算法执行时更快的找到对应的节点,提高diff速度。
析 : 如果只是简单的列表渲染,没有key的情况下,不用去对比,就地复用,不需要销毁和创建所以基于这种情况下不带key的性能更好,但是实际开发中列表大部分都会带有很多状态所以还是推荐写key,比如一个带有选框的列表选中了第一条数据[麻辣香锅],如果没有key的情况下,在列表中使用unshift插入一条记录,则选中的就变成刚刚插入数据,如果有key无论如何插入数据选中的始终都是[麻辣香锅]。
- 不带key效果
<!--完整组件demo-->
<template>
<div id="lists">
<p @click="add">添加</p>
<ul>
<li v-for="(data,index) in listData" :key="data.id">
<input type="checkbox"> {{data.title}}
</li>
</ul>
</div>
</template>
<script>
export default {
name: 'lists',
data() {
return {
listData: [
{id: 1,title: "麻辣香锅"},
{id: 2,title: "油焖大虾"},
{id: 3,title: "焦糖玛奇朵"},
{id: 4,title: "黑糖玛奇朵"}
],
addId:4
};
},
methods: {
add() {
this.listData.unshift({id: ++this.addId,title: "黑糖玛奇朵黑糖玛奇朵"})
}
}
}
</script>
<style scoped style="scss">
ul {
list-style-type: none;
padding: 0;
}
li {
margin: 10px;
}
</style>
2020.03.25 防抖和节流
问 : 防抖和节流?有什么区别?如何实现?
- 防抖
当持续触发事件时,一定时间段内没有触发事件,事件处理函数才会执行一次,如果设定的时间到来之前,又一次触发事件,就重新开始延时。常用的场景:input输入框
- 思路
每次触发事件时都取消之前的延时调用方法
- 节流
当持续触发事件时,保证一定时间段内只调用一次事件处理函数。常用的场景:页面滚动。
- 思路
每次触发事件时都判断当前是否有等待执行的延时函数。有两种实现方式:时间戳 、 定时器。时间戳版本的第一次会立即执行,但是最后一次不会被执行。定时器版本的第一次不会执行,但是最后一次触发后会执行。
- 节流
// 防抖
function debounce(fn, awaits=500) {
let timeout = null;
return function() {
clearTimeout(timeout)
timeout = setTimeout(()=>{
fn.call(this,arguments)
},awaits)
}
}
// 节流--定时器
function throttle(fn, awaits=500) {
let canrun = true;
return function() {
if(!canrun){
return;
}
canrun = false;
setTimeout(() => {
fn.call(this,arguments)
canrun = true;
}, awaits);
}
}
// 节流--时间戳
function throttle1(fn, awaits=500) {
let newdate = Date.now();
return ()=>{
let curdate = Date.now();
if(curdate - newdate >= awaits){
fn.call(this,arguments)
newdate = Date.now();
}
}
}
// 节流--时间戳+定时器
function throttle2(fn, awaits=500) {
let newdate = Date.now();
let timeout = null;
return ()=>{
clearTimeout(timeout)
let curdate = Date.now();
if(curdate - newdate >= awaits){
fn.call(this,arguments)
newdate = Date.now();
}else{
timeout = setTimeout(() => {
fn.call(this,arguments)
}, awaits);
}
}
}
<!--完整组件demo-->
<template>
<div class="box">
<input type="text" v-model="inputText" @input="inputFunction">
<ul>
<li></li>
<li></li>
</ul>
</div>
</template>
<script>
// 防抖
function debounce(fn, awaits=500) {
let timeout = null;
return function() {
clearTimeout(timeout)
timeout = setTimeout(()=>{
fn.call(this,arguments)
},awaits)
}
}
// 节流--定时器
function throttle(fn, awaits=500) {
let canrun = true;
return function() {
if(!canrun){
return;
}
canrun = false;
setTimeout(() => {
fn.call(this,arguments)
canrun = true;
}, awaits);
}
}
// 节流--时间戳
function throttle1(fn, awaits=500) {
let newdate = Date.now();
return ()=>{
let curdate = Date.now();
if(curdate - newdate >= awaits){
fn.call(this,arguments)
newdate = Date.now();
}
}
}
// 节流--时间戳+定时器
function throttle2(fn, awaits=500) {
let newdate = Date.now();
let timeout = null;
return ()=>{
clearTimeout(timeout)
let curdate = Date.now();
if(curdate - newdate >= awaits){
fn.call(this,arguments)
newdate = Date.now();
}else{
timeout = setTimeout(() => {
fn.call(this,arguments)
}, awaits);
}
}
}
export default {
name: 'debouncethrottle',
data() {
return {
inputText:''
};
},
methods: {
test:function () {
console.log(Math.random());
},
inputFunction:debounce(function(e){
console.log(this.inputText)
})
},
mounted() {
let _this = this;
window.addEventListener('scroll', throttle2(_this.test));
}
}
</script>
<style>
ul li{
display: block;
width: 100px;
height: 620px;
margin-bottom: 20px;
background: orange;;
}
</style>
2020.03.26 JS事件循环
基础概念 :
-
js是单线程的,同一个时间只能做一件事,虽然是单线程但是js有同步异步的概念解决了阻塞问题
-
任务队列:同步任务在主线程依次执行,前一个结束才能执行后一个,异步任务则进入任务队列
-
同步任务:一个函数返回的时候就可以拿到预期的结果,比如console.log()
-
异步任务:函数返回的时候调用者不能拿到预期的结果,需要在将来的某一时刻才能拿到,比如ajax请求,异步任务分为宏任务、微任务
-
宏任务(macro-task):script setTimeout, setInterval, setImmediate, I/O, UI rendering
-
微任务(micro-task):process.nextTick, Promises, Object.observe, MutationObserver
-
promise的then和catch等 才是微任务,构造函数内的代码不是
-
浏览器环境 node环境执行顺序不同
-
任务队列遵循 ‘先入先出’
console.log('global')
for (var i = 1;i <= 5;i ++) {
setTimeout(function() {
console.log(i)
},i*1000)
console.log(i)
}
new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('then1')
})
setTimeout(function () {
console.log('timeout2')
new Promise(function (resolve) {
console.log('timeout2_promise')
resolve()
}).then(function () {
console.log('timeout2_then')
})
}, 1000)
2020.03.30 js基础--原型链
function Person(){
}
Person.prototype.name = 'Blues';
let person = new Person();
console.log('person.name');
console.log(person.name);
console.log('person.__proto__');
console.log(person.__proto__);
console.log('Person.prototype');
console.log(Person.prototype);
console.log('person.__proto__ === Person.prototype');
console.log(person.__proto__ === Person.prototype);
console.log('Person.prototype.__proto__');
console.log(Person.prototype.__proto__);
console.log('Object.prototype');
console.log(Object.prototype);
console.log('Person.prototype.__proto__ === Object.prototype')
console.log(Person.prototype.__proto__ === Object.prototype)
今天发现的一篇挺不错的关于Vue的文章 -- Mark一下
2020.04.01 浏览器渲染过程
问 : 输入url到展示页面过程中做了什么事情?
- DNS查询
- TCP连接
- HTTP请求响应
- 服务器响应
- 客户端(浏览器)渲染
1.DNS查询
(Domain Name System,域名系统)最初,由于ip长且难记,通过ip访问网站不方便。所以后来通过发明了DNS服务器,这个时候我们访问网站输入网站域名,DNS服务器就解析我们的域名为ip。这样我们实际访问的就是对应的ip地址啦。
抽象点DNS就是 一个记录ip地址的超级分布式数据库。
在浏览器中访问的时候,会优先访问浏览器缓存,如果访问指定域名,没有命中返回,则访问OS缓存。最后再次访问dns服务器。
(备注:就像每个人都有身份证号,但是人们相互联系通过身份证号标识-ip地址会很难记,通常我们都是记住一个人的名字-域名。)
2.TCP连接
TCP连接三次握手,四次挥手。为什么中间不能节省一次握手或者挥手,因为TCP连接是可靠的,要保证建立连接的基础上还要保证数据传输的完整性。
5.浏览器渲染分为几个步骤
- 处理HTML并创建DOM树
- 处理CSS并创建CSSOM树
- 将DOM与CSSOM合并成一个渲染树
- 根绝渲染树来布局,以计算每个节点的几何信息
- 将各个节点绘制在屏幕上
思考题1:36匹马 6个赛道 如何快速决出前三名
思考题2:100枚硬币 两个人 一次拿1-5枚 第一个人第一次拿多少 一定能拿到最后1枚硬币
2020.04.07 CORS CSRF XSS
- CORS : Cross Origin Resourse-Sharing 跨站资源共享
- CSRF : Cross-Site Request Forgery 跨站请求伪造
- XSS : Cross Site Scrit 跨站脚本攻击(为与 CSS 区别,所以在安全领域叫 XSS)
2020.04.09 js --- 打印机 总结(点击按钮实现打印以及打印分页)
问 : 如何实现分页
答 : 在想要分页的地方放上此代码就可以实现打印机的强制分页,但是实现过程中发现并不生效,查阅资料发现是由于 float 属性影响,移除 float 就可以了,或者按照项目实际情况使用 display:inline-block;来解决。
//打印
window.print();
//分页
<div style="page-break-after:always"></div>
2020.04.21 表单提交的常用几种方式
问 : 表单提交的常用几种方式?
答 :
// 方法1:type=submit方式提交
<form name="form" method="post" action="#">
<input type="submit" name="submit" value="提交">
</form>
// 方法2:js提交
js : document.getElementById("form").submit();
jquery: $("#form").submit();
// 方法3:ajax提交
$.ajax({
type: "POST",
url: "/url.do",
data: params,
dataType : "json",
success: function(respMsg){
}
});
2020.04.22 post和get的区别
问 : post和get的区别
答 :
- Get是不安全的,因为在传输过程,数据被放在请求的URL中;Post的所有操作对用户来说都是不可见的。
- Get传送的数据量较小,这主要是因为受URL长度限制;Post传送的数据量较大,一般被默认为不受限制。
- Get限制Form表单的数据集的值必须为ASCII字符;而Post支持整个ISO10646字符集。
- Get执行效率却比Post方法好。Get是form提交的默认方法。
2020.04.23 响应式布局
问 : 响应式布局
- rem
- Grid 布局
- 媒体查询
(function(doc,win){
var docEI = doc.documentElement,
resizeEvt = 'orientationchange' in window?'orientataionchange':'resize',
recalc = function(){
var clientWidth = docEI.clientWidth;
if(!clientWidth) return;
docEI.style.fontSize = 100*(clientWidth/750)+'px';
}
if(!doc.addEventListener) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false);
})(document,window);
2020.04.29 前后端常见的几种鉴权方式(前端鉴权)
- HTTP Basic Authentication
- session cookie
- Token
- OAuth
待更
2020.09.09 标题
问 : 问题
答 :
析 :
js基础: ES6 、闭包 、 作用域问题 、 extends
网络相关: 从URL到页面显示的过程 、 http相关
安全相关: CSRF
其他:SSR