背景

在编写 .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] = {};
})
}

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

水一篇博文?手动狗头

[bug]——vue 组件状态外置引发的一个 bug的更多相关文章

  1. webpack单独构建scss文件与.vue组件里构建scss的一个坑

    在入口main.js里构建scss是通过引入模块的方式 import './assets/_reset.scss'; import './assets/_flex.scss'; import './a ...

  2. vue组件自定义属性命名

    今天自己写vue组件demo的时候发现一个有趣的问题:vue组件自定义属性命名不支持用驼峰命名! 上面图示为正常情况下的自定义属性,没有任何问题. 但是一旦出现自定义属性中包含了大写字母,则如下图所示 ...

  3. React: React的组件状态机制

    一.简介 在React中,有两个核心的默认属性,分别是state和props.state会记录组件的状态,React根据状态的变化,会对界面做相应的调整或渲染.props则是数据流向属性,React通 ...

  4. c#版阿里云oss上传——基于layui、pupload的oss 后端web端直传的vue组件

    废话前言 去年,做项目用到oss上传,度娘上逛了一圈写了个前后端代码结合的c#版oss上传. 今年又要用到oss上传时发现很难复用,复用改动的范围太大,显然这个轮子不合格.于是想了下,花了一天的时间( ...

  5. vue组件data函数

    vue组件data通常定义为一个函数并return一个对象,对象中定义的就是组件数据,当然定义数据还有props.computed等方式. data如果直接定义为对象data: {message: ' ...

  6. 聊聊vue组件开发的“边界把握”和“状态驱动”

    vue有着完整的组件化开发机制,但是官网只给了开发的方式,对于开发规范以及组件化开发的最佳实践,还需要我们来摸索.本文就平时开发中的经验来谈谈“把握边界”和“状态驱动”这两个话题. 边界把握 边界把握 ...

  7. vuex-- Vue.的中心化状态管理方案(vue 组件之间的通信简化机制)

    vuex-- Vue.的中心化状态管理方案(vue 组件之间的通信简化机制) 如果你在使用 vue.js , 那么我想你可能会对 vue 组件之间的通信感到崩溃 .vuex就是为了解决组件通信问题的. ...

  8. vue组件化开发-vuex状态管理库

    Vuex 是一个专为 Vue.js 应用程序开发的状态管理模式.它采用集中式存储管理应用的所有组件的状态,并以相应的规则保证状态以一种可预测的方式发生变化.Vuex 也集成到 Vue 的官方调试工具 ...

  9. 如何写好一个vue组件,老夫的一年经验全在这了【转】 v-bind="$attrs" 和 v-on="$listeners"

    如何写好一个vue组件,老夫的一年经验全在这了 一个适用性良好的组件,一种是可配置项很多,另一种就是容易覆写,从而扩展功能 Vue 组件的 API 来自三部分——prop.事件和插槽: prop 允许 ...

随机推荐

  1. Servlet 容器

    Servlet容器主要是JavaWeb应用提供运行时环境,所以也可以称之为JavaWeb应用容器,或者Servlet/JSP容器.Servlet容器主要负责管理Servlet.JSP的生命周期以及它们 ...

  2. WHAT IS THE DIFFERENCE BETWEEN REACT.JS AND REACT NATIVE?

    Amit Ashwini - 09 SEPTEMBER 2017 React.js was developed by Facebook to address its need for a dynami ...

  3. [Java] Spring boot 的maven设置阿里云仓库

    Spring boot 的maven设置阿里云仓库 打开根目录下的 pom.xml 文件,在对应为止出加入如下 红色 代码: <build> <plugins> <plu ...

  4. LOJ3097 SNOI2019 通信 题解

    题目链接 费用流,当建边需要依靠位置和权值两个偏序关系时,可以用cdq分治优化建边. 代码: #include<bits/stdc++.h> using namespace std; #d ...

  5. python 整数转16进制数

    def toHex(num): """ :type num: int :rtype: str """ chaDic = {: : : : : ...

  6. 文件系统EXT3,EXT4和XFS的区别

    1. EXT3 (1)最多只能支持32TB的文件系统和2TB的文件,实际只能容纳2TB的文件系统和16GB的文件 (2)Ext3目前只支持32000个子目录 (3)Ext3文件系统使用32位空间记录块 ...

  7. 表格样式、表格css、

    .mytab{ border-collapse: collapse;}.mytab tr,.mytab td,.mytab th{ text-align: center; border: 1px so ...

  8. 解决'maven lifecycle mapping not converted'的问题

    基于maven的项目,使用各种maven plugin来完成开发中的各种工作,例如编译代码,打包,部署等等… 每个plugin包含许多的goal,用来做特定的事情.典型的基于java的maven项目就 ...

  9. Tensorflow 损失函数(loss function)及自定义损失函数(三)

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/limiyudianzi/article ...

  10. jeecg数据库切换至mysql8.0方式

    1.修改pom.xml   mysql版本 <mysql.version>8.0.11</mysql.version> 2.修改dbconfig.properties文件 hi ...