Vue3 JSX
Dialog.confirm({
title: "课程名称",
message: () => {
return h(
h(CellGroup),
h(Field, {
modelValue: groupInfo.value.title,
"onUpdate:modelValue": (value) => (groupInfo.value.title = value),
label: "群名称",
placeholder: "请输入新的群名称",
})
);
},
})
.then(async () => {
await handleEditGroupTitle();
})
.catch(() => {
// on cancel
});
Typescript
值为空或者类型不同
类型守卫
// in关键字,检测是否改属性
if ("startDate" in emp) {
console.log("Start Date: " + emp.startDate);
}
// typeof关键字,判断是否是该类型
if (typeof padding === "number") {
return Array(padding + 1).join(" ") + value;
}
if (typeof padding === "string") {
return padding + value;
}
// instanceof 关键字
interface Padder {
getPaddingString(): string;
}
class SpaceRepeatingPadder implements Padder {
constructor(private numSpaces: number) {}
getPaddingString() {
return Array(this.numSpaces + 1).join(" ");
}
}
class StringPadder implements Padder {
constructor(private value: string) {}
getPaddingString() {
return this.value;
}
}
let padder: Padder = new SpaceRepeatingPadder(6);
if (padder instanceof SpaceRepeatingPadder) {
// padder的类型收窄为 'SpaceRepeatingPadder'
}
// 自定义类型保护的类型谓词
function isNumber(x: any): x is number {
return typeof x === "number";
}
值为空
// 值为空 情形一
if (timeValue.value) {
editCalendarData.value.time_begin = moment(timeValue.value[0]).valueOf();
editCalendarData.value.time_end = moment(timeValue.value[1]).valueOf();
}
// 值为空 情形二
queueStatusPhraseMap[status] ?? status
前端数据对象类型注解
可以使用type
或者interface
两种方式
// 类型定义形式
export type SingalObj = {
signalName: string;
name: string;
}
// 接口形式
export interface {
signalName: string;
name: string;
}
ES5/ES3 中的异步函数或方法需要 “Promise” 构造函数。请确保具有一个 “Promise” 构造函数的声明,或在 “—lib” 选项中包含了 “ES2015”
在tsconfig.json中配置lib
{
"compilerOptions": {
"lib": [
"ES2015"
] /* Specify a set of bundled library declaration files that describe the target runtime environment. */,
},
}
异步行为
onchange
事件后只处理最后一次请求的数据
// 全局请求数据锁
let currentRequestId = 0;
/**
* 获得搜索后数据
*/
const getSearchData = async () => {
const id = ++currentRequestId;
getConceptSearchDataApi({
keyword: search.value,
}).then((r) => {
// 只处理最后一次数据请求
id === currentRequestId && timeFormat(r);
});
};
DOM
滚动事件监听
父元素为以下几种情况下不能直接监听事件:
- overflow : hidden
- 未超出父元素长度
使用以下方式解决
window.addEventListener(
'scroll',
() => {
console.log('scroll');
},
true,
);
CSS
a :visited
浏览器记录中访问过的URL都会被标记为 :visited
,如果有其他的需求需要与后端配合与接口配合或者由前端使用sessionStorage
实现。
大列表渲染卡顿
滚动获取数据节流
import { debounce } from 'lodash-es';
const box = document.querySelector('.intimenews-box');
// 网页被卷去的高
let winScrollTop = 0;
//网页正文全文高
let winHeight = 0;
// div被卷去的高度
let boxScrollY = 0;
const getnewintimenews = debounce(async () => {
await getInTimeNews(16, 'down');
// .then(() => {
oldWinHeight.value = document.body.scrollHeight;
// });
}, 80);
// 轮询获取数据
timer = setInterval(async () => {
// 判断滚动后的
await getInTimeNews(16, 'up');
winScrollTop = document.body.scrollTop;
winHeight = document.body.scrollHeight;
if (winScrollTop > 0) {
document.body.scrollTop = winHeight - oldWinHeight.value + winScrollTop;
oldWinHeight.value = winHeight;
}
boxScrollY = box.getBoundingClientRect().y;
}, 2000);
//滚动后获取新数据
document.body.addEventListener(
'scroll',
() => {
winScrollTop = document.body.scrollTop;
winHeight = document.body.scrollHeight;
boxScrollY = box.getBoundingClientRect().y;
if (boxScrollY < 0) {
getnewintimenews(16, 'down');
}
},
true,
);
禁止vue监听
const data = Object.freeze((await getDataApi()).data);
Object.freeze()
方法可以冻结一个对象。一个被冻结的对象再也不能被修改;也不能添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举型、可配置性、可写性,以及不能修改已有属性的值。
如果你有一个巨大的数组或者对象,并且确信数据不会修改,使用 Object.freeze()
可以让性能大幅提升。这种提升大约有5~10倍,倍数随着数据量递增。对于纯展示的大数据,都可以使用 Object.freeze
提升性能。Object.freeze()
冻结的是值,你仍然可以将变量的引用替换掉。
纯函数
- 此函数在相同的输入值时,需产生相同的输出。函数的输出和输入值以外的其他隐藏信息或状态无关
- 此函数不能有语义上可观察的函数副作用
let a = 2
function add(b) {
const total = a + b
return total
}
console.log(add(1, 3))
副作用
副作用指的是函数在执行过程中,除了返回可能的函数值之外,还对主调用函数产生附加的影响。
例如:修改了全局变量、修改了传入的参数、甚至是 console.log(), ajax 操作,直接修改 DOM,计时器函数,其他异步操作,其他会对外部产生影响的操作都是算作副作用。
我们运行上面的add函数,外部的变量a的值发生了改变,这就产生了副作用let a = 2
function add() {
a = 3
}
console.log(add())
Tips:console.log 也被称为副作用是因为它们会向控制台打印日志,控制台存在于函数外部
字段验证
- 所有字段必须使用对应的类型,一般为
date
、string
、number
- 在number类型时,值绑定使用
:value.number
修饰符,有些时候(eg:select元素)即使使用number修饰符也未必得到number类型这时需要强制类型转换。参考
【1】关于useEffect清除副作用