Error in nextTick: “TypeError: Converting circular structure to JSON
[Vue warn]: Error in nextTick: "TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Vue'
| property '$options' -> object with constructor 'Object'
| property 'router' -> object with constructor 'VueRouter'
--- property 'app' closes the circle"
内容翻译
一般报错
TypeError: Converting circular structure to JSON
是因为存在循环引用,并且使用JSON.stringify
方法去转化成字符串
案例
// 问题代码
const x = { a: 8 };
const b = { x };
b.y = b; // 循环引用
JSON.stringify(b); // 触发报错
// 解决问题代码
const x = { a: 8 };
const b = { x };
b.y = JSON.parse(JSON.stringify(b)); // 隐式深拷贝,主要实现深拷贝,解除循环引用
JSON.stringify(b);
// 也可以不使用深拷贝,直接去掉循环引用的代码,问题的关键点是解除循环引用
报错位置不能显式看到循环引用,因为循环引用的代码是Vue框架代码自己实现的,因此发现问题的产生地方更难一点。
产生问题的原因
- vuex中的状态管理state中存储了router实例(组件中获取的this.$route),存在循环引用
- vuex使用了插件vuex-persistedstate
- state中有了循环引用,插件vuex-persistedstate要执行JSON.stringify把state数据转化成字符串然后存储到浏览器本地存储。
- 接下来就是解决,那就是解除循环引用,解除办法就是对组件中获取的this.$route进行深拷贝,然后再存储到state
参考
/**
* 获取数据类型
* @param {All} [o] 需要检测的数据
* @returns {String}
*/
export function getType(o){
return Object.prototype.toString.call(o).slice(8,-1);
}
/**
* 判断是否是指定数据类型
* @param {All} [o] 需要检测的数据
* @param {String} [type] 数据类型
* @returns {Boolean}
*/
export function isKeyType(o, type) {
return getType(o).toLowerCase() === type.toLowerCase();
}
/**
* 深拷贝,支持常见类型 object Date Array等引用类型
* @param {Any} sth
* @return {Any}
*/
export function deepClone(sth) {
let copy;
if (null == sth || "object" != typeof sth) return sth;
if (isKeyType(sth, 'date')) {
copy = new Date();
copy.setTime(sth.getTime());
return copy;
}
if (isKeyType(sth, 'array')) {
copy = [];
for (let i = 0, len = sth.length; i < len; i++) {
copy[i] = deepClone(sth[i]);
}
return copy;
}
if (isKeyType(sth, 'object')) {
copy = {};
for (let attr in sth) {
if (sth.hasOwnProperty(attr)) copy[attr] = deepClone(sth[attr]);
}
return copy;
}
return null;
}
本文来自博客园,作者:JackieDYH,转载请注明原文链接:https://www.cnblogs.com/JackieDYH/p/17634198.html