Vuejs刷新页面子组件数据丢失问题的一点笔记
来源:互联网 发布:面包板与单片机的连接 编辑:程序博客网 时间:2024/06/06 11:46
最近在学Vuejs, 发现在路由中给子组件传递数据后,刷新页面出现数据丢失问题。
// 子组件代码props: { // 用于接收父组件的数据goodsData goodsData: { type: Array, required: true } },computed: { ... item () { // 计算属性item根据地址栏查询关键字在goodsData中筛选并返回符合条件的数据 // http://localhost:8080/#/goods/food_detail?i_S=0&i_F=1 const indexS = this.$route.query.i_S const indexF = this.$route.query.i_F return this.goodsData[indexS].foods[indexF] } },
从父路由点进去非常正常,但是重新刷新页面子组件会直接消失,返回父页面。页面地址显示正常,子组件渲染出错,按出dev-tool 组件内部的数据存储也是没有问题的,该有的都有。但是控制台还是报错typeError,无法获取undefinded的foods属性。
在子组件created钩子函数,添加了一条在控制台打印 this.goodsData
的命令, 运行后输出了一个空数组,dev-tool中依旧显示this.goodsData
非常正常,甚至item也是正常的,应该是加载数据的时候出错了,也就是 计算属性item
第一次运行时由于this.goodsData
还没有传过来,所以渲染出错了。说到底应该是生命周期的问题?(不太熟悉)
解决方法是给计算属性添加一个判断条件
item () { const indexS = this.$route.query.i_S const indexF = this.$route.query.i_F if (this.goodsData.length > 0) return this.goodsData[indexS].foods[indexF] return false }
依靠该数据进行初始化的数据也不能再放到created,因为它需要在item加载后调取里面的数据进行初始化。
我这里就需要提交item里面的ratings属性到vuex,本来是created的时候就可以执行的,但是现在created阶段item数据并没有准备好,所以需要准备一个函数,在item返回值不为false的时候替我初始化ratings数据并提交到vuex中。
我选择用watch去观察item,computed应该也可以。但是自己感觉用watch好像更适合点,就用watch了。
watch: { item: function (newVal, oldVal) { if (newVal) { this._initComments() this.refreshScroll() // bscroll 对象更新dom } } },
问题解决。
主要解决方案就是给computed加个条件判断,计算属性获取失败时返回false,在this.goodsData
变化(获取成功)时, 计算属性自动执行并更新,watch属性通过监视该计算属性的值,进行其他初始化操作。
2017 / 09 / 07 更新
其实没有解决。
今天搞评价页面(path: /ratings)的时候又发现了新问题,这个页面也是有一堆评论,从评价页面和商品详情页面(path: /goods/food_detail, query: { i_s = :indexS, i_f = indexF })来回切换,comment组件的数据没有更新,但是如果在页面上刷新一次就可以正常显示……
负责初始化vuex中的comment数据的是watch观察属性,按理说,只要$route.query.i_S, $route.query.i_F发生变化,计算属性item就会更新,同时更新dom,并且观察属性也会被触发,初始化新的comment数据,然而vue-devtool里面看到的item的计算属性是已经更新了的状态。
watch对象item函数添加两个命令: console.log(newVal); console.log(oldVal)。 来回切换路由依然是没有反应,控制台没有打印任何数据,只有刷新当前页面时才会有输出。说到底就是,计算属性item更新了,但是观察属性item没反应。
折腾了一下,发现问题在于观察属性观察的对象是个计算属性,改成data属性就什么破事都没有了。
但是还是要计算属性返回需要的数据给data里面的属性,而且如果计算属性自己没有在dom里面被读取,或者它依赖的响应属性没有被更新,它就不会自动执行。
要么把初始化comments数据放到计算属性item里面,要么在data中造个属性来存放计算属性每次更新改变的值(当然你要让计算属性自动执行,也就是说你要改变它依赖的响应属性,或者在dom中引用它里边的数据,让它在更新的过程中,顺带更新下data里面的那个用于被观察属性观察的值)。
当dom的数据准备加载了,被引用的computed属性就会自动执行
这时候,当计算属性获得有效的goodsData后,就会根据$route.query的两个属性获取这个页面需要的那条数据,然后赋值(不一定要赋值该数据,只要能被观察属性观测到都可以……)给data里面的那个用于观察的值,同时自己返回这条数据,dom中数据更新。
因为data里面的那个属性发生了变化(暂时喊它 dataItem
), watch也就被正常触发了,这是所有的初始化操作都能正常执行了,问题解决,可喜可贺。结论是:不要用watch属性去观察一个computed属性。
当然不搞watch属性初始化,直接在计算属性item里面初始化也是可以的。但是如果使用了created里用 $nextTick
初始化一个对象,并在这个item里面使用该对象的方法的话, 可能会导致出错。
我的情况是这样:
created函数中的$nextTick
初始化一个BScroll对象,
然后在计算属性item成功获取数据,更新comment数据后在$nextTick
回调函数里调用BScroll对象的refresh()方法,重新获取dom高度。
听起来好像也没什么不对。然而如果我从/foods这个路由进去 /foods/food_detail?…的话,就会报错: bscroll对象未定义。刷新页面后又完全正常。
在created的$nextTick
回调里面控制台输出,在计算属性里面的 $nextTick
也搞个控制台输出。路由切换时,nextTick是computed属性中的执行得快,created的慢。 刷新页面的时候倒是反过来。
为了避免它搞事,老老实实在计算属性里面初始化BScroll算了
- Vuejs刷新页面子组件数据丢失问题的一点笔记
- 结合localStorage解决vuex页面刷新数据丢失的问题
- vue 后台数据获取与组件渲染、页面刷新数据消失的问题小结
- ASP.NET中页面刷新用户选择丢失的问题
- .Net中刷新页面时session丢失的问题
- vue页面刷新或者后退参数丢失的问题
- VUEJS 2.0 子组件访问/调用父组件的 方法
- 刷新页面数据丢失(高手勿进)
- JS页面刷新保持数据不丢失
- vuejs组件使用问题
- Vuejs关闭打开的窗口后刷新父页面
- 刷新页面数据自动增加的问题
- vuejs几种不同组件(页面)间传值的方式
- vuejs几种不同组件(页面)间传值的方式
- Vuejs 页面的区域化与组件封装
- vuejs几种不同组件(页面)间传值的方式
- js 弹出子页面与关闭子页面刷新父页面的问题
- js 弹出子页面与关闭子页面刷新父页面的问题
- jquery.dataTables 按条件查询后重新生成表格 点击排序还是原来的数据问题
- LeetCode5—Longest Palindromic Substring
- pat 乙级 1034. 有理数四则运算(20)
- 代码重构(六):代码重构完整案例
- luogu1073 【noip2009提高】最优贸易(spfa)
- Vuejs刷新页面子组件数据丢失问题的一点笔记
- jquery的appendTo怎么用?
- git pull问题
- 边框的样式
- SpringBoot(一):快速搭建一个springboot项目
- Segue几种类型(Show、Show Detail、Present modally、Present as Popover)的区别
- 【MPI学习1】简单MPI程序示例
- 为什么内核设计人员要给进程创造一种僵尸状态?
- 编程珠玑之二分搜索