工作笔记-知识碎片-2019-9
1.Echarts的cursor指向无效
原因:echarts使用canvas画图,使用行内样式设定canvas的cursor:pointer;
解决:使用样式覆盖这个行内样式比如:.echarts canvas{cursor:pointer !important;}
2.轮播图片宽高自适应问题
效果图:
宽度为自适应屏幕宽度,有最小宽度,高度不管是设为固定px或百分比都会导致图片变形或被裁剪,所以应动态设定图片高度。
html:
<div class="ty-carousel">
<el-carousel ref='ctest' :height="imgHeight+'px'" :interval='5000'>
<el-carousel-item v-for="(item,index) in carouselData" :key="index">
<img ref="image" :src="item.src" alt="">
</el-carousel-item>
</el-carousel>
</div>
style:
.ty-carousel{ margin-bottom: 16px; }
.ty-carousel .el-carousel__item img {
width: 100%;
height: auto;
}
.ty-carousel .el-carousel__indicators{left: auto; right:0; }
js:(基于vue框架)
import axios from "axios";
export default{
data(){
return{
imgHeight: "",
carouselData:[
{
src:'/static/static_web/images/ty/Carousel-1.png',
},{
src:'/static/static_web/images/ty/Carousel-2.png',
},{
src:'/static/static_web/images/ty/Carousel-3.png',
},{
src:'/static/static_web/images/ty/Carousel-4.png',
},
]
}
},
methods: {
imgLoad() {
this.$nextTick(function() {
// 定义页面初始的轮播图高度
this.imgHeight = this.$refs.image[0].height
});
},
getImgUrl() {
axios
.get("/module_web/MI-SecurityMonitorStrategy2.html")//页面路径
.then(res => {
// 调用this.imgLoad()方法定义图片初始高度
this.imgLoad();
})
.catch(error => {
console.log(error);
});
}
},
mounted() {
this.getImgUrl();
// 监听窗口变化,使得轮播图高度自适应图片高度
window.addEventListener("resize", () => {
this.imgHeight = this.$refs.image[0].height;
});
}
}
3.深拷贝与浅拷贝
浅拷贝:只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化,这就是浅拷贝
深拷贝:是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变,这就是深拷贝
let obj1= {
a:1;
b:123
}
let obj2 = obj1;
obj2.a=2;
console.log(obj2.a);//2
console.log(obj1.a);//2
解构赋值也是浅拷贝
一开始我只是用简单的数组进行测试:
let arr1= [11,22];
let arr2=[...arr1];
arr2[0]=33;
console.log(arr2);//[33,22];
console.log(arr1);//[11,22]
改变拷贝后的数组后,原数组并没有改变我便以为其为深拷贝(深复制);但其实它只是拷贝了浅浅一层,是fake!,是骗子!它是浅拷贝,而不是层层递进的深拷贝:
let arr1= [{a:11},{b:22},44];
let arr2=[...arr1];
arr2[0].a=33;
arr2[2] = 55;
console.log(arr2);// [{a:33},{b:22},55]
console.log(arr1);// [{a:33},{b:22},44]
大概是这样的内存结构:
明确一下深拷贝与浅拷贝:
浅拷贝:
创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址 ,所以如果其中一个对象改变了这个地址,就会影响到另一个对象。
深拷贝:
将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象,且修改新对象不会影响原对象
实现深拷贝
参考https://juejin.im/post/5d6aa4f96fb9a06b112ad5b1
- 乞丐版
可以使用parse和stringify进行深拷贝
let arr1 = [{a:11},{b:22},44];
let arr2 = JSON.parse(JSON.stringify(arr1))
arr2[0].a=33;
console.log(arr2);// [{a:33},{b:22},44]
console.log(arr1);// [{a:11},{b:22},44]
- 基础版
用递归实现层层递进深拷贝
缺陷:拷贝其他引用类型、拷贝函数、循环引用等
function clone(target) {
if (typeof target === 'object') {
let cloneTarget = {};
for (const key in target) {
cloneTarget[key] = clone(target[key]);
}
return cloneTarget;
} else {
return target;
}
};
如果是原始类型,无需继续拷贝,直接返回
如果是引用类型,创建一个新的对象,遍历需要克隆的对象,将需要克隆对象的属性执行深拷贝后依次添加到新对象上。
缺陷:没有考虑数组
- 兼容数组
module.exports = function clone(target) {
if (typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {};
for (const key in target) {
cloneTarget[key] = clone(target[key]);
}
return cloneTarget;
} else {
return target;
}
};
- 考虑循环引用
解决循环引用问题,我们可以额外开辟一个存储空间,来存储当前对象和拷贝对象的对应关系,当需要拷贝当前对象时,先去存储空间中找,有没有拷贝过这个对象,如果有的话直接返回,如果没有的话继续拷贝,这样就巧妙化解的循环引用的问题。
这个存储空间,需要可以存储key-value形式的数据,且key可以是一个引用类型,我们可以选择Map这种数据结构:
function clone(target, map = new Map()) {
if (typeof target === 'object') {
let cloneTarget = Array.isArray(target) ? [] : {};
if (map.get(target)) {
return map.get(target);
}
map.set(target, cloneTarget);
for (const key in target) {
cloneTarget[key] = clone(target[key], map);
}
return cloneTarget;
} else {
return target;
}
};
检查map中有无克隆过的对象
有 - 直接返回
没有 - 将当前对象作为key,克隆对象作为value进行存储
继续克隆
使用WeakMap提代Map来使代码达到画龙点睛的作用:
function clone(target, map = new WeakMap()) {
// ...
};
- 性能优化和其他类型考虑可查看参考的文章
4.shift方法
shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值
5.函数节流与防抖
对持续触发的事件进行时间频率控制
具体方法参考https://www.jianshu.com/p/c8b86b09daf0
防抖:就是指触发事件后在 n 秒内函数只能执行一次,如果在 n 秒内又触发了事件,则会重新计算函数执行时间。
function debounce(func, wait) {
let timeout;
return function () {
let context = this;
let args = arguments;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(() => {
func.apply(context, args)
}, wait);
}
}
节流:就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
function throttle(func, wait) {
let previous = 0;
return function() {
let now = Date.now();
let context = this;
let args = arguments;
if (now - previous > wait) {
func.apply(context, args);
previous = now;
}
}
}
6.粘性布局
position:sticky
7.强制不换行
white-space:no-wrap
8.截取字符串中指定字符的前后字符串
.split(str)[0].split(str)[1]
9.computed计算属性
set get
10.loadsh
cloneDeep
11.水球图配置
https://github.com/ecomfe/echarts-liquidfill#api
来源:CSDN
作者:hen1183392934
链接:https://blog.csdn.net/hen1183392934/article/details/100698619