Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

同一路由切换时,上一次的页面数据会保留 #140

Open
ghost opened this issue Mar 20, 2018 · 116 comments
Open

同一路由切换时,上一次的页面数据会保留 #140

ghost opened this issue Mar 20, 2018 · 116 comments
Labels
important Valuable discussion

Comments

@ghost
Copy link

ghost commented Mar 20, 2018

同一级路由进入退出再进入另一个路由时,数据会先显示上一次的,闪一下才会显示新数据。
生命周期用onShow和mounted都会出现这个问题。直接用小程序不会出现。
issue

非mpvue小程序写的
normal

虽然可以在unload事件之后清空数据,但是感觉不是最好的解决方法。

@F-loat
Copy link
Contributor

F-loat commented Mar 20, 2018

原生小程序里也是会的吧,可以在 onUnload 时重置一下数据

@ghost
Copy link
Author

ghost commented Mar 20, 2018

@F-loat 并不会,而且并不是最好的解决办法。

@anchengjian
Copy link
Member

这个是可能的,因为页面数据是存在于 js 中,切换页面的时候是会把数据 setData 到 render 进程中,可能有个老数据显示的闪现,目前的解决方式可以在 onHide 的时候重置数据或者加载 loading 动画,在 onShow 的时候加载数和或者取消 loading 动画。
后期考虑可以从底层优化掉闪现的问题。

@ghost
Copy link
Author

ghost commented Mar 20, 2018

@anchengjian 恩 是暂时用占位符和清空数据来解决,但是每个页面都要处理,有些繁琐。thx

@ghost
Copy link
Author

ghost commented Mar 23, 2018

@anchengjian 现在遇到一个新的问题,如果是在一个组件内,切换页面,然后回到这个页面,这个组件不会触发created事件,响应的computed等也没有运行。因为数据是从上一层继承的props所以没法做清空数据。

@anchengjian
Copy link
Member

@kennywho 你用 develop/packages/mpvue/index.js 的代码替换掉你本地 node_modules/mpvue/index.js 的后看一下是否还会复现。

created 事件这个肯定不会再次触发的,因为你是切换页面后回到当前页面,当前页面一直存在不会销毁的。

@F-loat
Copy link
Contributor

F-loat commented Mar 26, 2018

@anchengjian 遇到一个问题,应该是类似的原因,就不新开 issue 了

页面切换大概是这样一个过程 pageA -> pageB?id=1 -> pageB?id=2 --back-> pageB?id=1
最后返回至 id=1 这个页面时,页面会一闪为 id=2 的数据,this.$root.$mp.query.id 获取到的也是 2

原生的也是没有问题的

小程序每个页面的 data 里都有一个隐藏属性 webviewId,同一个页面参数不同时 webviewId 是不同的,而参数相同时 webviewId 也是同一个,但 mpvue 似乎并没有对这个做处理,同一个页面不论参数是什么,数据都是同一份

@TianbinTobin
Copy link

mpvue返回上一页的时候出发了onUnload钩子,但是为什么不会触发vue的beforeDestroy这个钩子呢?不然可以再beforeDestroy做数据重置

@chen2gou
Copy link

chen2gou commented Apr 4, 2018

pageA -> pageB?id=1 -> back-> pageA-> -> pageB?id=2 ,pageB的onLoad里对传递参数进行了赋值,最后pageB页面子组件拿到的还是id=1,应该是渲染子组件在赋值之前就获取了残存的值,目前解决办法就是在onUnload里将值清除

@fengcen
Copy link

fengcen commented Apr 8, 2018

这个问题我也遇到了,就是之前出现过的页面,页面的初始化数据会保存,小程序原生在页面退出后重新进入数据会重新初始化,mpvue 没有。

@fengcen
Copy link

fengcen commented Apr 8, 2018

这个问题比较严重,如果所有的组件和页面都要手动 onShow 的时候初始化数据,会非常繁琐容易出错

@F-loat
Copy link
Contributor

F-loat commented Apr 10, 2018

同一个页面相互跳转的问题(例如商品详情页之间)@fangdiao 提供了一种解决思路,我做了相关实现,遇到这个问题的可以参考下 detail.vue
另外重置数据可以直接在 mounted 钩子里执行 Object.assign(this.$data, this.$options.data())

贴一下主要代码

const dataArr = []

export default {
  onLoad() {
    Object.assign(this.$data, this.$options.data())
    // fetch some data
    dataArr.push({ ...this.$data })
  },
  onUnload() {
    dataArr.pop()
    const dataNum = dataArr.length
    if (!dataNum) return
    Object.assign(this.$data, dataArr[dataNum - 1])
  },
}

@ghost
Copy link
Author

ghost commented Apr 13, 2018

之前的问题可以通过 data () return Object.assign({}, defaultData),在unload事件中重新赋值data来解决。
现在最复杂的是父级组件传递给子组件一个props,自组件中一个属性是通过computed计算而来,这样在同个路由下切换,这个computed会不执行。

@fangdiao
Copy link

是的,不会执行。我的解决办法是直接修改父级的data,再传递下去。

@whapply
Copy link

whapply commented Apr 20, 2018

想问下这个问题解决没?

@fangdiao
Copy link

@sideFlower
这个问题很早之前就解决了,也是我踩过的比较恶心人的坑。上面已经说的差不多了。关于页面切换闪一下的问题解决办法是在onLunch中清空当前页面的数据

@JasonDRZ
Copy link

@kennywho 可以使用自定义的页面跳转方案进行规避,并且能够不受wx.navigateTo路径数据传输的限制。详情见:#349

@vinceok
Copy link

vinceok commented Apr 24, 2018

从首页进入一个列表页,加载三页数据,然后再返回首页,再进入之前的列表页。之前的三页数据还在,是不是也是这个问题?

@hopperhuang
Copy link

我也遇到了页面返回的时候$root.$mp.option.query的问题,长期关注这个issue

@hopperhuang
Copy link

还有出现的一个问题就是a 页面跳转到a页面(同页面跳转),但是路由的参数变了,然后由点返回键,前一个a页面的data属性,居然是后一个a页面的data属性,然后调试工具里面appdata是一个空白页。希望同页面跳转的bug可以解决一下。

@charmtiger
Copy link

迫切希望解决此问题

@charmtiger
Copy link

@hopperhuang 我现在和你同样的问题,你现在用什么方式来处理的

@F-loat F-loat mentioned this issue May 16, 2018
@zxzhgk
Copy link

zxzhgk commented Jan 21, 2019

@longhailan 人家那个库里已经写的很清楚了,你照着步骤配置一下就可以,很简单的

@leona1112
Copy link

@longhailan 人家那个库里已经写的很清楚了,你照着步骤配置一下就可以,很简单的

我看公司项目里mpvue-loader使用的是"@f-loat/mpvue-loader": "^1.0.0",如果我按照步骤替换掉mpvue-loader,会不会出现其他问题啊,我对这个package.json不太懂

@choudac
Copy link

choudac commented Mar 1, 2019

我也要写些什么。

@hooray
Copy link

hooray commented Mar 6, 2019

近两天才开始使用 mpvue,一下就发现了这个问题以及这个 issues,所以快一年过去了,官方都没打算出面说些什么么?我觉得哪怕是打算把bug变feature,也通知大伙一声,起码可以把这个issues的广播关了 😞

@ExcellentJR
Copy link

@hooray 关注了好久了,mpvue官方并未对这类问题做出过实质性的优化,倒是一些其他的开发者自己贡献了一些比如说diff算法方面的优化,现在并不太清楚mpvue开发团队方面到底有什么样的计划,上次发布了2.0,但是基本没有性能方面或者已暴露的问题的修复,而是朝着兼容更多平台的方向去了...不好意思打扰了关注这个问题的所有人,但是真心希望官方能再给力点,大家翘首以盼呢~

@CoderEnko007
Copy link

官方还没解决这个问题吗?没有的话过几天我再来问

@algking
Copy link

algking commented Mar 21, 2019

这问题真的超级恶心...之前的版本想了个workround fix了, 这几天更新下mpvue版本, 结果依然没解决, 增量更新的实现方式, 貌似把小程序页面data的数据基本复制了一份, 内存使用还增加了.

@jimizai
Copy link

jimizai commented Apr 14, 2019

页面onLoad的时候Object.assign(this.$data, this.$options.data())初始化数据

@bravelincy
Copy link

这个问题还没解决吗?如果是data,在页面渲染之前重置data是可以,但是对于那些不依赖当前组件data的计算属性就比较麻烦一些。

@AlexSOTe
Copy link

-= =- 官方敢不敢解决一下,恶心坏我了

@superzhy
Copy link

有没有好的解决方法

@Hoby8080
Copy link

有点粗暴,直接在onUnload中,干掉实例。可以试试
onUnload() {
//解决mpvue页面实例缓存问题
Object.assign(this, null);
}

@kylvia
Copy link

kylvia commented May 16, 2019

通过this.$mp.page来拿到小程序的page实例,自己在需要的时候手动进行setData。注意之前的data赋值还是要保留,只是在额外手动赋值一下。
this.$mp.page.setData({
'$root[0].name': data[0].name,
'$root[0].avatar': data[0].avatar,
})

@palytoxin
Copy link

当页面有component,重新进入component还能显示上次进来时的状态? 整个页面都被缓存了?

@gu-fan
Copy link

gu-fan commented May 17, 2019

更新了mpvue到1.4.2
发现 mpvue-page-factory 不能用了。

@SuperChrisliu
Copy link

都已经2.0了这个问题挺严重的啊 居然没有修复,是不是还是没有想到好办法呢,

@jsydliuqing
Copy link

在 src/main.js 中添加如下代码,即可解决数据会保留的问题。
Vue.mixin({
// 记录页面回退的日志
onUnload: function() {
// Fixbug: 再次进入页面时,页面还保留上一次的旧数据(预期是清空数据)
if (this.$options.data) {
Object.assign(this.$data, this.$options.data());
}

// Fixbug-Watcher: 关闭页面时 Watcher 没有被取消订阅,再次进入页面会出现重复订阅的情况
let watcherId = -1;
if (this._watcher) {
  watcherId = this._watcher.id;
  this._watcher.teardown();
}
let i = this._watchers.length;
while (i--) {
  if (this._watchers[i].id === watcherId) {
    this._watchers[i].teardown();
  }
}

}
});

@joezhang-sh
Copy link

joezhang-sh commented Aug 3, 2019

页面onLoad的时候Object.assign(this.$data, this.$options.data())初始化数据

有些数据是在created的时候就获取并且一直想保留的,这样的话似乎还得再赋一次值。不过已经是目前最理想的解决方案了,谢谢

@OliverCN
Copy link

腾讯的那个原生小程序框架OMIX有人试过没?好像刚升级2.0,看介绍好像挺牛X的

@Shonrain
Copy link

pageA -> pageB?id=1 -> back-> pageA-> -> pageB?id=2 ,pageB的onLoad里对传递参数进行了赋值,最后pageB页面子组件拿到的还是id=1,应该是渲染子组件在赋值之前就获取了残存的值,目前解决办法就是在onUnload里将值清除

我也遇到了这个问题,解决方法是在 vuex 里面维护一个数组,每次进入一个页面的时候就将当前页面中的 data push 到 vuex 中,然后返回到上一层页面的时候根据 id 从 vuex 中的这个数组中取值,被销毁的页面的数据则从那个数组中弹出,这样不用每次返回都去请求新的数据也不会有闪动了。

@Bowennan
Copy link

Bowennan commented Dec 24, 2024 via email

@railgun20001
Copy link

railgun20001 commented Dec 24, 2024 via email

@ANT-CYJ
Copy link

ANT-CYJ commented Dec 24, 2024 via email

@Bowennan
Copy link

Bowennan commented Dec 24, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
important Valuable discussion
Projects
None yet
Development

No branches or pull requests