请选择 进入手机版 | 继续访问电脑版
 找回密码
 立即注册
搜索

技术分享 list组件崩溃的还有另一个原因:同时使用for、if的一个bug

4
回复
278
查看
[复制链接]

5

主题

18

帖子

115

积分

 楼主| 2019-7-12 17:34:30 显示全部楼层 |阅读模式
本帖最后由 管理员 于 2019-7-12 18:04 编辑

使用过list组件的开发人员都知道,list中的list-item组件在使用for、if的时候务必要保证当前item的唯一性,否则会导致渲染奔溃。

我整理出一个最精简的含有list组件的demo,这是一个有问题的demo:
  1. <template>
  2.   <div>
  3.     <list class="items">
  4.       <block for="{{(k,v) in productList}}">
  5.         <list-item type="{{'product-'+v.tags.length}}" class="item">
  6.           <text class="title">{{v.title}}</text>
  7.           <text class="tags" for="{{(k2,v2) in v.tags}}" if="{{k2<3}}">
  8.             <span class="v">{{v2}}</span>
  9.           </text>
  10.         </list-item>
  11.       </block>
  12.     </list>
  13.   </div>
  14. </template>

  15. <script>
  16. export default {
  17.   private: {
  18.     productList: [
  19.       {
  20.         title: 'this is a',
  21.         tags: [
  22.           'a1', 'a22', '', 'a4', 'a5'
  23.         ]
  24.       },
  25.       {
  26.         title: 'this is b',
  27.         tags: [
  28.           'b1', 'b2', 'b3', 'a4', 'b5'
  29.         ]
  30.       },
  31.       {
  32.         title: 'this is c',
  33.         tags: [
  34.           'c1', 'c2', 'c3', 'c4', 'c5'
  35.         ]
  36.       }
  37.     ]
  38.   },
  39. }
  40. </script>

  41. <style lang="less" scoped>
  42. .items {
  43.   width: 100%; height: 100%; flex-direction: column; background-color: #f8f8f8;
  44.   .item {
  45.     flex-direction: column;
  46.     background-color: #fff;
  47.     margin: 10px;
  48.     padding: 10px;
  49.     .title {
  50.       font-weight: bold;
  51.     }
  52.     .tags {
  53.       flex-direction:row;
  54.       .v {
  55.         background-color: #f6f6f6; padding: 0 10px; margin: 10px;
  56.       }
  57.     }
  58.   }
  59. }
  60. </style>
复制代码



运行后,会发现,一上来就奔溃了,查下dom渲染结构会发现,会发现,出 无限输出a2,直至内存溢出,挂了。

解决方案:
1、前端上去更改模版上的for、if的关系:
  1. <template>
  2.   <div>
  3.     <list class="items">
  4.       <block for="{{(k,v) in productList}}">
  5.         <list-item type="{{'product-'+v.tags.length}}" class="item">
  6.           <text class="title">{{v.title}}</text>
  7.           <text class="tags" for="{{(k2,v2) in v.tags}}">
  8.             <block if="{{k2<3}}">
  9.               <span class="v">{{v2}}</span>
  10.             </block>
  11.           </text>
  12.         </list-item>
  13.       </block>
  14.     </list>
  15.   </div>
  16. </template>
复制代码



2、后端去修正返回的原始数据,或者前端拿到后,预处理一下数据,把空字符串变成 空格,也能避免:

  1. <script>
  2. export default {
  3.   private: {
  4.     productList: [
  5.       {
  6.         title: 'this is a',
  7.         tags: [
  8.           'a1', 'a22', ' ', 'a4', 'a5'
  9.         ]
  10.       },
  11.       {
  12.         title: 'this is b',
  13.         tags: [
  14.           'b1', 'b2', 'b3', 'a4', 'b5'
  15.         ]
  16.       },
  17.       {
  18.         title: 'this is c',
  19.         tags: [
  20.           'c1', 'c2', 'c3', 'c4', 'c5'
  21.         ]
  22.       }
  23.     ]
  24.   },
  25. }
  26. </script>
复制代码








这是我踩过的坑,希望后来的人可以避免,或者期待官方可以尽快修复这种问题。















回复

使用道具 举报

5

主题

18

帖子

115

积分

 楼主| 2019-7-12 17:55:21 显示全部楼层
编辑器真难用,不支持code
回复

使用道具 举报

1

主题

2

帖子

15

积分

2019-7-15 15:36:00 显示全部楼层
<block if="{{k2<3}}">
              <span class="v">{{v2}}</span>
            </block>

把if改成show呢     listitem 是原生的安卓组件   必须要保持内部的dom节点一致      
回复

使用道具 举报

5

主题

18

帖子

115

积分

 楼主| 2019-7-17 16:01:21 显示全部楼层
tiantianhappy 发表于 2019-7-15 15:36
{{v2}}
            

改成 show 不能解决问题。因为 这块子数组循环里的个数是不确定的,
回复

使用道具 举报

5

主题

18

帖子

115

积分

 楼主| 2019-7-25 15:04:56 显示全部楼层
tiantianhappy 发表于 2019-7-15 15:36
{{v2}}
            

过了很多天之后,回来再回答你的问题。你说的方案是可以的,不过这么改:

  1. <text class="v" show="{{k2<4}}"> {{v2}}</text>
复制代码
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册