前言
好记性不如烂笔头,今天看了B站的一些视频,就来做个简单的记录了,今天主要讲解得是三个小问题,希望对大家有用,如果觉得有用,请点小赞吧
问题1:假设后端返回给前台返回十万条数据,前端如何渲染呢
方式一:使用分页+settimeout
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>
<script>
//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
if(curTotal <= 0){
return false;
}
//每页多少条
let pageCount = Math.min(curTotal , once);
setTimeout(()=>{
for(let i = 0; i < pageCount; i++){
let li = document.createElement('li');
li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
ul.appendChild(li)
}
loop(curTotal - pageCount,curIndex + pageCount)
},0)
}
loop(total,index);
</script>
方式二:使用requestAnimationFrame减少重排
代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>
<script>
//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
if(curTotal <= 0){
return false;
}
//每页多少条
let pageCount = Math.min(curTotal , once);
window.requestAnimationFrame(function(){
for(let i = 0; i < pageCount; i++){
let li = document.createElement('li');
li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
ul.appendChild(li)
}
loop(curTotal - pageCount,curIndex + pageCount)
})
}
loop(total,index);
</script>
方式三:使用文档碎片做一次性插入 代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<ul id="container"></ul>
</body>
</html>
<script>
//需要插入的容器
let ul = document.getElementById('container');
// 插入十万条数据
let total = 100000;
// 一次插入 20 条
let once = 20;
//总页数
let page = total/once
//每条记录的索引
let index = 0;
//循环加载数据
function loop(curTotal,curIndex){
if(curTotal <= 0){
return false;
}
//每页多少条
let pageCount = Math.min(curTotal , once);
window.requestAnimationFrame(function(){
let fragment = document.createDocumentFragment();
for(let i = 0; i < pageCount; i++){
let li = document.createElement('li');
li.innerText = curIndex + i + ' : ' + ~~(Math.random() * total)
fragment.appendChild(li)
}
ul.appendChild(fragment)
loop(curTotal - pageCount,curIndex + pageCount)
})
}
loop(total,index);
</script>
问题2:v2中得data为什么是一个函数,v3为什么要使用return呢
其实无论是v2还是v3其中的自定义数据,都是要需要做为函数进行返回,不直接写死的原因是在于当组件复用时避免数据的污染,其实就是避免数据重复。
举例1:当data是一个对象时
<script>
let Test = function () {
this.val = this.val
}
Test.prototype.val = {
a:'1',
b:'2'
}
var conponent1 = new Test()
var conponent2 = new Test()
conponent1.val.a = '6'
console.log(conponent1); // a=12
console.log(conponent2); // a=12
</script>
打印结果如下:
可以看到,如果我们在直接使用对象时,当我们在改变对象的某一属性时,其他实例的属性值也会同步的发生改变。
举例2:当data是一个函数时
<script>
function Test() {
this.val = this.val()
}
Components.prototype.val = function () {
return {
a:'1',
b:'2',
}
}
var conponentA = new Components()
var conponentB = new Components()
conponentA.val.a = '6'
console.log(conponentA); // a=6
console.log(conponentB); // a=1
</script>
打印结果如下:
问题3:对象的原型
其实看到这句话的时候大家都知道答案了,我呢只不过是在这里多絮叨一下。
首先我们都知道,原型是函数特有的属性,普通的对象或者某一变量它是不具备原型的
其次是,原型链的终极是nul,这一点大家都是毋庸置疑的,原型的依次查找形成了一层原型链。
还有一点就是,原型的特点之一就是继承,儿子可以继承老子的特点,但是儿子也可以保留自己的特点。
一行代码证明对象无原型:
<script>
let obj = {
a: 1,
b: 2
}
let test = function () {
console.log(11);
}
test.prototype.a = 22;
const res = new test();
console.log(res)
obj.prototype.c = 12;
console.log(obj)
</script>
打印结果如下:
所以可以看出普通的对象是没有原型的,只有函数才会有原型