Skip to content

Untitled

仲灏2022-07-05约 1 分钟

数据请求缓存实现方案

  • 临时存储方案:定义全局变量(建议Map类型),用特定的方法函数去查看 更改 删除该变量,类似Vuex,Redux。后续可以添加一些边缘操作,如过期时间,加密等处理。缺点:当页面被刷新后所有的数据就会清空。
  • 持久存储方案:不同上述中运存方案,页面刷新会被垃圾回收机制收回。把数据存于浏览器的Storage中(session Storage,local Storage,cookie)等位置用于持久存储。缺点:性能相对不好,读存说白了就是I/O操作,当数据量过大尤为明显。
  • 中和方案:在运存和硬盘中哥存一份,当然你可以在页面执行销毁动作前再存入硬盘中,最好利用js运行机制使用异步方案存入。在读取的时候优先去运存中读取,保证速度,没有的时候再去硬盘中读取,保证质量。

请简述虚拟列表的实现原理

不太明白你所谓的虚拟列表具体指什么 vdom还是长列表中性能优化的虚拟列表

vdom: 在Vue 使用 Vue2中使用了三方库snabbdom.js实现模板解析为 render 函数,触发响应式,监听 data 属性 getter setter,执行 render 函数,生成 vnode , patch(elem, vnode),React中原理类似。

长列表虚拟:准确的说都不叫虚拟,叫模拟。在页面列表数据量过大,渲染dom过多时会引起页面卡顿等一些性能问题,特别是还有数据绑定的时间更为致命。对此可以对当前浏览器视口中显示的固定dom做计算渲染,看不见的部分可以结合数据量计算得出高度,固定高度使用块级元素填充整体高度。

请输出下述代码得打印结果:

jsx
class StateDemo extends React.Component {
  state = { number: 0 };
  handleClick = () => {
    this.setState({ number: this.state.number + 1 }, () => {
      console.log("callback1", this.state.number);
    });
    console.log(this.state.number);

    this.setState({ number: this.state.number + 1 }, () => {
      console.log("callback2", this.state.number);
    });
    console.log(this.state.number);

    this.setState({ number: this.state.number + 1 }, () => {
      console.log("callback3", this.state.number);
    });
    console.log(this.state.number);
  };

  render() {
    return (
      <div>
        {this.state.number}
        <button onClick={this.handleClick}>number++</button>
      </div>
    );
  }
}


0
0
0
callback1 1
callback2 1
callback3 1

一个组件在本地开发过程中没问题,上线后显示错误,请分析下原因:

原因

  • 代码在开发环境与生产环境有不一致的地方
  • 打包依赖问题
  • 线上环境问题,网络 依赖包下载 依赖包版本等等

解决方案

  • 确定组件代码中是否引用使用环境变量
  • 本地打包并运行排查
  • 确定线上环境(网络,依赖包完整度等问题)

实现一个消息分发系统

js 实现

javascript
class EventEmitter {
    constructor() {
        this._events = {};
    }
    on(event,callback) {
        //监听 event 事件,触发时调用 callback 函数
        let callbacks = this._events[event] || [];
        callbacks.push(callback);
        this._events[event] = callbacks;
        return this;
    }
    off(event,callback) {
        //停止监听 event 事件
        let callbacks = this._events[event];
        this._events[event] = callbacks && callbacks.filter(fn => fn !== callback);
        return this;
    }
    emit(event, ...args) {
        //触发事件,并把参数传给事件的处理函数
        const callbacks = this._events[event];
        callbacks.forEach(fn => fn.apply(null,args));
        return this;
    }
}

Vue2 实现, 用作mixins 使用

vue
function broadcast(componentName, eventName, params) {
  this.$children.forEach(child => {
    const name = child.$options.name;
    if (name === componentName) {
      child.$emit.apply(child, [eventName].concat(params));
    } else {
      broadcast
      .apply(child, [componentName, eventName]
      .concat([params]));
    }
  });
}
export default {
  methods: {
    dispatch(componentName, eventName, params) {
      let parent = this.$parent || this.$root;
      let name = parent.$options.name;
      while (parent && (!name || name !== componentName)) {
        parent = parent.$parent;
        if (parent) {
          name = parent.$options.name;
        }
      }
      if (parent) {
        parent.$emit.apply(parent, [eventName].concat(params));
      }
    },
    broadcast(componentName, eventName, params) {
      broadcast.call(this, componentName, eventName, params);
    }
  }
};

如何设计一个通用的弹框类系统

大概思路:

  1. 定义弹窗类

    1. 样式,显隐动画
    2. 挂载元素(默认body元素上)
    3. 位置(默认元素正中):上下左右...
    4. 事件:
      1. 打开
      2. 关闭
      3. 拖动等其他
  2. 使用

    1. 可单独引用,使用实例化类
    2. 可挂在window对象,app实例原型上,用于全局使用