我的前端笔记

目录

  • react
  • 小程序
  • vue
  • typescript
  • 经验(踩坑)

react

useMemo 和 useCallback 都是用来做性能优化的,把 useMemo 当成一个值,把 useCallback 当成一个函数即可。

详见 useMemo 与 useCallback 源码解析

useEffect

useEffect 是在布局(layout)和绘制(paint)之后触发的。

useEffect 不提供依赖数组和提供空数组有什么区别?

给它一个空数组就像 componentDidMount 一样,它只运行一次。

不给它第二个参数充当 componentDidMount 和 componentDidUpdate ,因为它首先在安装上运行,然后在每次重新渲染时运行。

useEffect 忽略依赖列表的 functions 时, 是否安全?

答案是,否。看个示例:

function Example({ someProp }) {
    function doSomething() {
        console.log(someProp);
    }
    useEffect(() = >{
        doSomething();
    }, []); //  This is not safe (it calls `doSomething` which uses `someProp`) }
}

可以改进一下,将 function 丢进 useEffect 的回调里:

function Example({ someProp }) {
    useEffect(() = >{
        function doSomething() {
            console.log(someProp);
        }
        doSomething();
    },
    [someProp]); // ✅ OK (our effect only uses `someProp`)
}

也可以使用 useCallback 包裹函数:

function Example({ someProp }) {
    const doSomething = useCallback(() = >{
        console.log(someProp);
    },
    [someProp]);
    useEffect(() = >{
        doSomething();
    },
    [doSomething]);
}

useCallback

使用空数组作为输入的 useCallback 和没有第二个参数的 useCallback 之间有什么区别?

如果第二个参数是一个空数组,则该值将被内存一次并始终返回。
如果省略第二个参数,该值将永远不会被内存。

useLayoutEffect

useEffect 和 useLayoutEffect 的区别:

useEffect 是异步执行的,而useLayoutEffect是同步执行的。

useEffect 的执行时机是浏览器完成渲染之后,而 useLayoutEffect 的执行时机是浏览器把内容真正渲染到界面之前,和 componentDidMount 等价。

一般会影响到渲染的操作尽量放到 useLayoutEffect 中去,避免出现闪烁问题。

参考:https://zhuanlan.zhihu.com/p/348701319

小程序

使用 Component 来实现接收跳转参数,无需通过 onLoad 的 options 参数获取哦:

只需在 Component 里面声明 properties 即可, 别的页面跳转过来待参,就可以通过 this.data 获取到相应的 property。

普通页面:

我是跳转按钮

组件页面:

Component({
    properies: {
        activeIndex: String,
    },
    methods: {
        onLoad() {
            console.log(this.data.activeIndex); // '1'
        }
    }
})

小程序页面返回带参方案:

通过 navigateTo 的 success 的 response 里的 eventChannel 来向目标页发布事件,而目标页可通过this.getOpenerEventChannel() 来监听事件,示例:

// 当前页
wx.navigateTo({
    url,
    success: ({ eventChannel }) = >{
        eventChannel.emit('init', {
            a: 1
        });
    }
});
// 目标页
ready() {
    this.getOpenerEventChannel().on('init', ({
        a
    }) = >{
        // doSomething
    });
}

ios 扫小程序码没有进入小程序,而是进入一个空白网页:

ios 需要有权限才可访问小程序,改 appid,需要已经添加过开发者的 appid

vue

自动引入路由实现方案:(底层是利用 require.context api 实现,即是说,require.context 可以引入多个文件)

路由的目录为:

router

  • modules
  • index.js
const modules = require.context('./modules', true, /\.js$/);
modules.keys().forEach(name => {
  const module = modules(name);
  if (module.default) {
    addRoute(module.default);
  } else {
    Object.values(module).forEach(addRoute);
  }
});

typescript

TypeScript 中当一个变量为 object 或 null 时,使用解构赋值可能报错的解决方法(在变量后面加个!即可):

type SomeData = {
    a: string;
    b: string;
    c: string;
};
const someData: SomeData | null = null;
const { a, b, c } = someData!;

类型推断

可以合理利用类型推断,节省返回参数声明。
示例:

// api.ts
export function getSomething() {
  return get>({
    url: xxx
  });
}

// index.ts
import { getSomething } from './api';
const _getSomething = async () => {
    /** 
        * 此处的 data 可以不做类型声明,因为在 api.ts 里面已经声明了
        * 然后 return 即会触发 typescript 的类型推断,因此推断出 data 的类型了
    */
  const { data } = await getSomething(6);
  // do something
};

经验(踩坑)

Taro-cropper 在某些情况下“完成”按钮没显示出来:

虽然不知道具体原因,但是翻看其源码可以看到它的 props 里有一行注释:

hideFinishText: boolean,    // 隐藏完成按钮(可以自己实现,然后调用本实例的cut方法进行剪裁)

因此,解决方案就是自己实现一份“完成”按钮,Over。

带分页数据的实时刷新方案:

可以以第一页的数据为模板,在轮询的时候进行比较,如果出现差异,则为(数据)有更新,然后更新数据为最新第一页数据即可。

export default 不能正确解构:

export default 经过了 webpack的构建后,会变成类似:

import a from './a'
a.default.b

因此无法通过解构 a 来拿到 b,如果想要能正确解构拿到变量,尽量这样操作:

export const b = 1

具体参考:https://www.cnblogs.com/pixcai/p/5597109.html

你可能感兴趣的:(我的前端笔记)