vue中的插件封装
解决路由缓存
在路由更新时更新数据
可选链解决异步渲染
在异步请求过程中获取数据并渲染到页面上
这个时候我们并不确定在页面渲染前result是否可以获取到
这时候可以用可选链操作来解决
将对象转换为formdata键值对
const fd = new FormData()
for (const key in formModel.value) {
const item = formModel.value[key]
fd.append(key, item)
}
fd.append(key,value) 向formdata中添加数据
vueuse工具
监听是否进入视口区域:useIntersectionObserver
监听滚动距离:useScroll(Window)
监听是否进入视口区域需要stop
Tab类切换
使用definePropty重写get,set
const obj = {
a: 0,
b: 1,
};
Object.defineProperty(obj, "c", {
get() {
this.b++;
return this.a;
},
set(a) {
this.c = a;
},
});
// 给obj的a赋值就会触发a的set方法,这时候a的值就变为33
obj.a = 33
// 这时候访问了obj的c,会调用c的get方法,让b自增,并返回a的值,这时候c的值就是33
console.log(obj.c)
// 但需要注意的是,这时候并没有给c赋值,所以并没有触发c的set方法
// obj.c = 22
// 那么就会触发c的set方法,这时候给c赋值了,所以会访问c的set方法
通过该方法来创建对象属性
const o = {}; // 创建一个新对象
Object.defineProperty(o, "a", {
value: 37,
writable: false, //属性不可修改false
});
根据数组中对象value,进行对象分组
let newArr = [] // 对数组对象value进行去重分组
let obj = {} // 新建对象
1.第一种方式
// 添加数组元素
peoples.forEach(item => {
if(!newArr.includes(item.age)){
newArr.push(item.age)
}
});
2.第二种方式使用set
(1)new Set()
(2)遍历对象,将key添加到set中
// 对数组中元素分组
newArr.forEach(item => {
obj[item] = peoples.filter(item1=>item1.age == item)
});
3.第三种reduce
const people = [
{ name: "Alice", age: 21 },
{ name: "Max", age: 20 },
{ name: "Jane", age: 20 },
];
function groupBy(objectArray, property) {
return objectArray.reduce((acc, obj) => {
const key = obj[property];
const curGroup = acc[key] || [];
return { ...acc, [key]: [...curGroup, obj] };
}, {});
}
const groupedPeople = groupBy(people, "age");
console.log(groupedPeople);
// {
// 20: [
// { name: 'Max', age: 20 },
// { name: 'Jane', age: 20 }
// ],
// 21: [{ name: 'Alice', age: 21 }]
// }
统计多个值的出现次数
const names = ["Alice", "Bob", "Tiff", "Bruce", "Alice"];
const countedNames = names.reduce((allNames, name) => {
const currCount = allNames[name] || 0;
return {
...allNames,
[name]: currCount + 1,
};
}, {});
// countedNames 的值是:
// { 'Alice': 2, 'Bob': 1, 'Tiff': 1, 'Bruce': 1 }
判断一个值是否存在于对象key中
const codonTable = {
'IIX': '人类',
'VII': '哈喽',
'III': '你好',
'IXI': '赞',
'XVI': '嗨',
'CUV': '打击',
'XII': '夜晚',
'IVI': '我',
'XIC': '想',
'XIV': '交个朋友',
'VIX': '月亮',
'XCI': '代码',
'XIX': '祈福',
'XVI': '和',
'XXI': 'stop',
};
//定义一个字符串为
let str = '';
//若要判断str是否存在于key中
//1.可以用object.keys()取出keys用include判断
//2.可以用if(codoTable[str])判断key是否存在
fetch运用
fetch("http://example.com/movies.json")
.then((response) => response.json())
.then((data) => console.log(data));
动态组件
<!-- currentTab 改变时组件也改变 -->
<component :is="tabs[currentTab]"></component>
在上面的例子中,被传给 :is的值可以是以下几种:
被注册的组件名
导入的组件对象
Map和Set
let map = new Map([
["key", "value"],
[{d:1}, "value"],
["key", "value"],
]);
// 通过二维数组进行初始化
// set方法来添加键值对,get方法取值,del方法删除键值对,has方法来检验键值对是否存在
// Map保存键值对,可以记住原始键值对插入的顺序,任何值都能作为键或值,可以更改值不能更改键
let set = new Set([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]);
// 通过一维数组来进行初始化
// set的值可以是任意类型
// set是一个值不重复的集合,只能通过迭代器来更改值
如何隐藏元素
display:none (元素不可见,不占据空间,无法响应点击事件,会回流和重绘)
visibility:hidden(元素不可见,占据空间,无法响应点击事件,不会回流,会重绘)
透明度0(元素不可见,占据空间,响应点击事件,不会回流和重绘)
宽高为0,设置overflow:hiden,(元素不可见,不占据空间,不响应点击事件,会导致回流和重绘)
绝对定位+移除可视区
裁剪(API适配不好)
三种会话的区别
session:关闭浏览器后清空
local:可以持久化存储,数据不可以和其它网页共享
cookies:可以持久化存储,可以设置过期时间,可以与其它网页共享数据
清除浮动
为父元素设置
overflow:hidden/auto/scroll
或者设置宽高为要清除浮动的元素设置
clear:both
为父元素的伪元素设置
content:'';display:block;clear:both
margin塌陷或重叠
一、margin塌陷:父级和子级同时设置了margin-top,两个元素会采用值较大的margin
BFC:是一个块级格式化上下文,形成一个独立的空间,不影响独立空间之外的布局,决定了元素对其的定位以及其他元素之间的作用关系
如何创建BFC:
子元素或者父元素的float不为none
子元素或者父元素的position不为relative或static
父元素的overflow为auto或scroll或hidden
父元素的display的值为table-cell或inline-block
解决方法:触发BFC、为父级添加padding或者bored
子元素或者父元素的float不为none
子元素或者父元素的position不为relative或static
父元素的overflow为auto或scroll或hidden
父元素的display的值为table-cell或inline-block
二、margin重叠:两个元素margin互相重叠,只有其中一个有效
只设置其中的一个margin即可
base标签
可以规定页面的主要href和target
const、let、var区别
块级作用域
是es6新增的定义
一般是由{}定义,定义的变量超出{}则失效
if或for定义的变量不会污染外层,即使是在最外层使用const或let声明变量,也不会挂载到全局(Windows,global)
外部脚本引入时,defer和async的区别
defer
async:
event.target,event.currentTarget
event.target : 是触发事件的元素
event.currentTarget : 是绑定事件的元素
DNS域名解析
作用:通过访问域名解析到指定的IP地址,让计算机正确发送请求获取内容