7 月
- top bottom等 是相对于上一个有定位(relative absolute等)的父元素来说
- yarn的时候报错error An unexpected error occurred: "registry.npm.taobao.org/webpack-ali…: Request failed "404 Not Found"". 原因是在npm中没有指定的aliyun-oss版本,改用0.3.12版本
- 封装组件需要给出足够的灵活性,就如日期选择器来说,一开始我只写了value,onChange,placeholder这三个属性,这样的话使用组件的时候就只能传入这三个属性,所以封装的组件灵活性就会受限。因此,使用Partial<DateProps & DatePickerProps>的交叉类型来获取组件的属性,再用...rest来获取剩余的属性。并且在组件用使用。这样使用者可以传入NutUI组件所拥有的任意属性,极大拓宽了组件的灵活性。
`const reLocation = () =>
{` ```setIsLoading(true) //开始加载效果``
const options = { ` `showButton: false, //是否显示定位按钮`
`buttonPosition: 'LB', //定位按钮的位置` `/* LT LB RT RB */`
`buttonOffset: new AMap.Pixel(10, 20), //定位按钮距离对应角落的距离`
`showMarker: true, //是否显示定位点`
`markerOptions,` `showCircle: false, //是否显示定位精度圈` `}` `AMap.plugin(['AMap.Geolocation'],
function ()
{` `const geolocation = new AMap.Geolocation(options)` `map.current.addControl(geolocation)`
`geolocation.getCurrentPosition(function (`
`status,` `result: {`
`formattedAddress: string`
`position: mapLocation` `message: string` `}`
`) {` `if (status == 'complete')
{` `setAddress(result?.formattedAddress)`
`setIsMap(true)`
`locationChange?.({`
`locationLongitude: result.position.lng,`
`locationLatitude: result.position.lat,`
`location: result?.formattedAddress,`
`})`
`} else {`
`showToast({`
`title: 定位失败-${result?.message ?? '请检查是否获取定位权限'},`
`icon: 'error',` `})`
`}`
`})`
```setIsLoading(false) //加载结束 修改后`
`})``setIsLoading(false) //加载结束 修改前`
`}`
在方法中setIsLoading不生效,原因是 setIsLoading 的调用位置不正确。AMap.plugin 方法是异步执行的,而 geolocation.getCurrentPosition 方法也是异步的。这意味着setIsLoading(false) 会在内部回调函数之前被调用,因此加载状态将立即被设置为 false,无法正确显示加载效果。解决方案是将 setIsLoading(false) 移动到geolocation.getCurrentPosition 的回调函数中,确保在获取位置信息完成后再将加载状态设置为 false。
-
平原小程序线上问题,原因是在运行"dev:weapp": "npm run build:weapp -- --watch"的情况下走的是开发环境的代理,这样在线上是获取不到数据的。
-
在js中 ?? 和 || 和 && 的区别为:2.在js中 ?? 和 || 和 && 的区别为: A ?? B :如果A为null或者undefined则返回B,否则返回A A || B :如果A为false则返回B,否则返回A A && B :如果A为
false、0、''、null、undefined或者 NaN。直接返回 A,否则继续判断B** -
之前一直不知道hooks的钩子含义到底是什么意思,现在了解到:如果说函数组件是一台轻巧的快艇,那么 React-Hooks 就是一个内容丰富的零部件箱。“重装战舰”所预置的那些设备,这个箱子里基本全都有,同时它还不强制你全都要,而是允许你自由地选择和使用你需要的那些能力,然后将这些能力以 Hook(钩子)的形式“钩”进你的组件里,从而定制出一个最适合你的“专属战舰”。(引用自《深入浅出搞定 React》)
8月
useEffect和useLayoutEffect是React提供的两个钩子函数,它们都可以在组件渲染完成后执行副作用操作。它们的主要区别在于执行时机。
useEffect:useEffect是异步执行的,它会在浏览器绘制完成后才执行,不会阻塞渲染线程,不会影响视觉效果。适合大多数情况下的副作用操作,如数据获取、订阅事件、操作DOM等。useLayoutEffect:useLayoutEffect是同步执行的,它会在所有的DOM变更计算完成后、浏览器绘制之前执行。这意味着它会阻塞渲染线程,可能会导致视觉上的阻塞。建议在需要立即处理或依赖DOM准确布局信息的副作用操作时使用,比如测量DOM节点的尺寸、手动处理样式等。
一般来说,优先选择使用useEffect,因为它的异步特性使得它的性能表现更好,并且不会引起视觉阻塞。只有在某些特定场景下,如果需要在浏览器绘制之前执行副作用操作,才考虑使用useLayoutEffect。
需要注意的是,由于useLayoutEffect会阻塞渲染线程,过度使用或使用不当可能会导致性能问题和页面卡顿。因此,只有在确实需要同步操作DOM布局或获取准确信息时才应该使用useLayoutEffect,并在使用时要谨慎评估其对性能的影响。
- React setState
increment = () => {
// 进来先锁上
isBatchingUpdates = true
console.log('increment setState前的count', this.state.count)
this.setState({
count: this.state.count + 1
});
console.log('increment setState后的count', this.state.count)
// 执行完函数再放开
isBatchingUpdates = false
}
reduce = () => {
// 进来先锁上
isBatchingUpdates = true
setTimeout(() => {
console.log('reduce setState前的count', this.state.count)
this.setState({
count: this.state.count - 1
});
console.log('reduce setState后的count', this.state.count)
},0);
// 执行完函数再放开
isBatchingUpdates = false
}
react中setState是异步的,但是放在setTimeout中会逃脱异步约束,成为一个同步事件的原因是:
isBatchingUpdates锁 的true和false会在事件循环中先执行,所以无法对setState造成约束。即——在特定的情境下,它会从 React 的异步管控中“逃脱”掉。
-
const uploadRes = await Taro.uploadFile({ url: OSS_URL, filePath: path, name: 'file', formData: { bucket: OSS_BUCKET, name: `biz/n400/rtc/${Date.now().toString(32)}${index}.${path.split('.').pop()}.html`, }, fail(errMsg) { Taro.showToast({ title: '图片上传失败', }); realtimeLogger.error('图片上传失败', { errMsg, }); console.log('uploadFile fail', errMsg); }, complete() { Taro.hideLoading(); }, });
用户可以主动在name中修改文件后缀,可以绕过检查,通过传递script标签,达到xss攻击。
- 3.Function.proto===Function.prototype的原因
因为Function本身也是一个Function对象,也就是var Function = new Function(),这看起来有点鸡和蛋的意思,不过如果先给你一个蛋,那必然就是先有蛋后有鸡了。所以如果先给你一个Function对象的原形[[Prototype]],那么就可以通过一个函数构建出Function的实例了,这个函数就是Function本身。
引自:segmentfault.com/q/101000001…
5.闭包实现的原因是在执行上下文中维护的作用域链,让已经被销毁的函数中的值依然能被引用到。
6.作用域
var value = 1;
function foo() {console.log(value);}
function bar() {var value = 2;foo();}
bar();// 结果是 1
因为 js 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。所以当 value 向上查找的时候,查找的到的是 value=1 而不是 2。
//用数组序号[0]是不安全的方法,后端数组返回顺序有问题的话会出错
let options:fraudOpt[]=[]
variableField[0]?.fieldOptions?.forEach(element => {
options.push({value:element.optionValue,label:element.optionName})
});
setFraudOptions(options)
//此处优化为根据fieldName值来找到对应的对象
const {fieldOptions} = variableField.find((item)=>
item.fieldName === '诈骗类型') || {}
const map= fieldOptions?.map((item)=>{
return {value:item.optionValue,label:item.optionName}
})
//返回值只有一行,利用箭头函数语法糖
const {fieldOptions} = variableField.find((item)=>
item.fieldName === '诈骗类型') || {}
setFraudOptions(fieldOptions?.map(({ optionValue, optionName })
=>
({value: optionValue,label: optionName,})
))
可以通过使用解构赋值来筛选不需要的字段
const {templateVersion,...rest} =values
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = (function (i) {
return function(){
console.log(i);
}
})(i); // 立即执行函数,可以立即压入上下文栈,保存 i 在作用域链中
}
data[0]();
data[1]();
data[2]();
var data = [];
for (var i = 0; i < 3; i++) {
data[i] = function () {
console.log(i); //函数需要执行才能压入上下文栈
};
}
data[0]();
data[1]();
data[2]();
- 1===1===1(a===b===1) 结果为 false
因为 1===1 结果是 true,然后 true === 1 结果为false, 可以修改为(a===1&&b===1)
- 1== 1== 1 结果为 true
- 当有一个 for 循环的时候
循环过程中for(let i=0;i<arr.length;i++){ }不要修改 arr 数组,会同步影响到 for 循环中 arr.length的长度,影响循环次数