背景介绍
下面展示的截图是“图书详情”页,点击“相关图书”中的图片之后,还会跳转到这个页面,只是参数不同。
点击右下角“借阅此书”,会弹出一个 popup 组件,该组件的显示与否,由组件内部的 “show” 属性控制。
预期表现
进入“图书详情”页面后,点击“借阅此书”,显示 popup;跳转到下一个“图书详情”页后再返回当前页,popup 仍可正常显示。
Bug情况
在每一次进入“图书详情”页后,popup 都正常显示。
正常情况下,"show”为true时,应该显示popup( console 中的打印内容为 selecteComponent 获取到的该 popup 组件的引用):
但是当点击“相关图书”中的图书链接之后跳转到新的页面再返回,popup 不再显示,即使此时该组件的“show”属性值为true:
复现路径
点击“相关图书”中的图书链接之后跳转到新的页面,再返回,再点击“借阅此书”,popup 不再显示
最简复现Demo
/components/panel/index.wxml
<view class="popup {{ show ? 'popup--show' : '' }}"> <view class="popup__mask" bindtap="onTapMask" /> <view class="popup__container"> <slot></slot> </view></view> |
/components/panel/index.wxss:
.popup__mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; z-index: 10; background: rgba(0, 0, 0, 0.7); display: none;}.popup__container { position: fixed; bottom: 0; width: 100%; /* width: 100vw; */ background: white; transform: translateY(150%); transition: all 0.4s ease; z-index: 11;}.popup--show .popup__container { transform: translateY(0);}.popup--show .popup__mask { display: block;} |
/components/panel/index.js:
/** * 底部弹出菜单 */Component({ properties: { // 点击背景是否自动关闭,默认是 tappableMask: { type: Boolean, value: true } }, data: { show: false }, methods: { show: function() { this.setData({ show: true }) }, close: function() { this.setData({ show: false }) }, onTapMask: function() { if (this.data.tappableMask) { this.close() } } }}) |
/pages/book-detail/index.wxml:
<button type="primary" bindtap="onShowPopup">借阅此书</button><popup id="popup" > 内容</popup> |
/pages/book-detail/index.js:
onShowPopup: function() { var popup = this.selectComponent("#popup") console.log(popup) popup.show() }, |
我的解决办法
将“show”作为组件的属性,由父组件控制:
/components/panel/index.js:
/** * 底部弹出菜单 */Component({ properties: { // 点击背景是否自动关闭,默认是 tappableMask: { type: Boolean, value: true }, show: { type: Boolean, value: false } }, methods: { close: function() { this.setData({ show: false }) }, onTapMask: function() { if (this.data.tappableMask) { this.close() } } }}) |
/pages/book-detail/index.wxml:
<button type="primary" bindtap="onShowPopup">借阅此书</button><popup id="popup" show="{{isPopupShow}}" > 内容</popup> |
/pages/book-detail/index.js:
Page({ data: { isPopupShow: false } onShowPopup: function() { this.setData({isPopupShow: true}) }}) |
但是会造成一个问题,就是在从新的图书详情页返回后,AppData窗口失效:
以上是我遇到的一个 bug,感谢解答。
另一个问题:组件的数据绑定的逻辑
当组件的属性是父组件的data中的一个属性时,组件properties中的这个属性,和父组件data中的那个属性的关系是什么?以下是困扰我的现象:
在上面我提供的解决方案中,子组件 popup 将 show 通过 setData 设为 false 时,父组件中的 isPopupShow 依然为 true,但此时 popup 组件不显示; 当父组件的 isPopupShow 为 true 时,再次在父组件中通过 setData 将 isPopupShow 设为 true(也就是说这个属性的值没有变),popup组件依然会显示。
在第二个情况里,既然 isPopupShow 的值没有变,那为什么子组件还会响应更新?这个逻辑到底是什么?双向绑定还是各自的作用域?
