zoukankan      html  css  js  c++  java
  • [bug]——vue 组件状态外置引发的一个 bug

    背景

    在编写 .vue 组件时,可以将状态外置来获取一些额外的好处,譬如有这么一个组件(global-components.vue):

    <template>
      <div>
        <c-popup
          :title="uiState.popup.title"
          :content="uiState.popup.content"
          :visible="uiState.popup.visible"
        ></c-popup>
        <c-notify
          :type="uiState.notify.type"
          :message="uiState.notify.message"
          :visible="uiState.notify.visible"
        ></c-notify>
      </div>
    </template>
    
    <script>
      import store from './store';
      export default {
        data() {
          return {
            uiState: store.state
          }
        },
      }  
    </script>
    

    将组件的状态外置,即 store.js 如下:

    export default {
      state: {
        popup: {},
        notify: {}
      },
    
      setState (key, value) {
        this.state[key] = value;
      },
    
      clearState () {
        this.state = {};
      }
    };
    

    组件状态外置有两个好处:

    • 单独的 js 文件,可以享受编辑器的代码提示功能
    • 可以在任意地方,引入 store.js 就可以修改组件的内部状态

    然而这都不是今天讨论的重点,重点是,上面的代码隐藏着一个 bug。

    bug 回放

    在 store.js 中,我们通过方法 setState 设置组件的状态,通过 clearState 重置所有组件状态。

    对于全局组件,我们希望在路由切换的时候关闭这些组件,自然,可以使用 clearState 来达到这一目的。

    一切都很美好。

    某天,组里一个同学发现,前进一个页面后再返回,调用 setState,组件状态没有发生变化。

    bug 修复

    显然,调用 setState 肯定会更改 state,但 vue 为什么没有观察到这个变化呢?我们再看下 data:

    data() {
      return {
        uiState: store.state
      }
    }
    

    嗯,这肯定没有问题。

    在 bug 回放中,我们看到,因为路由切换才导致了这个问题,于是猜测是 clearState 的锅——我们粗暴的使用“=”重置 state 为一个新的空对象,而 vue 还保留着原来的那个 state 对象。

    更改 clearState 的实现:

    clearState () {
      Object.keys(this.state).forEach(key => {
        this.state[key] = {};
      })
    }
    

    所以,我们能学到点什么教训/经验?

    水一篇博文?手动狗头

  • 相关阅读:
    《Docker Deep Dive》Note
    使用 Angular RouteReuseStrategy 缓存(路由)组件
    我的 VSCode 配置
    TCP/IP协议
    Fiddler代理手机抓包
    基于 Docker 和 GitLab 的前端自动化部署实践笔记
    Vue.js 2.x render 渲染函数 & JSX
    服务器免密登陆脚本
    gitlab+jenkins+pm2+rsync实现node的自动化部署
    nginx常用
  • 原文地址:https://www.cnblogs.com/fayin/p/11081553.html
Copyright © 2011-2022 走看看