最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 利用“抽象组件”去封装瀑布流【小程序】

    正文概述 掘金(TomLu)   2020-12-11   488

    利用“抽象组件”去封装瀑布流【小程序】

    No1 文档概念部分

    小程序官方文档对抽象节点的说明

    插槽和抽象节点的不同在于粒度上的不同。插槽的话,只需要去写HTML片段。但抽象节点,是需要程序员去定义自己的组件。

    所以抽象组件会比插槽,更加灵活!因为它把选择权交给了我们,我们自行定义内存节点的样式,抽象节点来做里面的逻辑处理就行!

    No2 核心算法

    算法其实还蛮简单的,之前我自己实现的算法是,根据index,奇数一边偶数一边。

    <view class="water-flow-container" wx:if="{{data.length!==0}}">
      <view id="left">
        <block wx:for="{{Object}}" wx:if={{index%2=0}} wx:key="index"></block>
      </view>
      <view class="water-column">
        <view id="right" >
        <block wx:for="{{Object}}" wx:if={{index%2=1}} wx:key="index"></block>
        </view>
      </view>
    </view>
    

    但这会样其实非常不合理!会容易一边长一边短。

    我们的希望根据left的节点和right的节点的高度,分别为leftData和rightData添加数据。

    // 我们先得到id为left和right的节点多高
    const a=wx.createSelectorQuery().in(this);
    this.columnNodes=a.selectAll("#left, #right")
    this.columnNodes.boundingClientRect().exec(h=>{
        const r=h[0]
        this.data.leftHeight=r[0].height, 
        this.data.rightHeight=r[1].height
        console.log(r[0].height,r[1].height)
    }
    
    // 哪边矮就加给哪边
    this.data.leftHeight > this.data.rightHeight ?
    this.data.rightData.push(data[e]):
    this.data.leftData.push(data[e]),
    this.setData({
      rightData: this.data.rightData,
      leftData: this.data.leftData
    })
    

    这里要注意一下,这里肯定是要遍历的,要一个节点一个节点的来,但不能用For循环,因为For是几乎同一时间触发里面的代码块。而我们必须等待视图层渲染成功后,才接着添加新数据的操作!!!

    这个时间点在setData的第二个参数里,有回调函数!

    this.setData({
              rightData: this.data.rightData,
              leftData: this.data.leftData
    },()=>{
      // 接着循环
      fun()
    })
    

    这样我们就直接写成递归就行啦!

     _render(data,e){
       data.length>e 
       && 0!==this.data.Object.length 
       && this.columnNodes.boundingClientRect().exec(h=>{
        const r=h[0]
        this.data.leftHeight=r[0].height, this.data.rightHeight=r[1].height
        this.data.leftHeight > this.data.rightHeight ?
        this.data.rightData.push(data[e]):
        this.data.leftData.push(data[e]),
        this.setData({
          rightData: this.data.rightData,
          leftData: this.data.leftData
        },()=>{
          this._render(data,++e)
        })
      })
    }
    

    No3 具体代码

    1.创建抽象组件

    // components/water-flow/index.wxml
    <view class="water-flow-container" wx:if="{{data.length!==0}}">
      <view class="water-column" style="margin-right:{{columnGap}}">
        <view id="left" >
        <block wx:for="{{leftData}}" wx:key="index">
          <water-flow-item data="{{item}}"></water-flow-item>
        </block>
        </view>
      </view>
      <view class="water-column">
        <view id="right" >
        <block wx:for="{{rightData}}" wx:key="index">
          <water-flow-item  data="{{item}}"></water-flow-item>
        </block>
        </view>
      </view>
    </view>
    
    // components/water-flow/index.json
    {
      "component": true,
      "componentGenerics": {
        "water-flow-item": true
      }
    }
    
    // components/water-flow/index.wxss
    .water-flow-container{
      display:flex;
      width:100%;
      box-sizing:border-box;
      background:0 0
    }
    .water-column{flex:1}
    
    // components/water-flow/index.js
    Component({
      properties: {
        Object: Object,
        columnGap: {
          type: String,
          value: '15rpx'
        }
      },
    
      data: {
        leftData:[],
        rightData:[]
      },
    
      attached(){this._init()},
    
      methods: {
        _init(){
          this._select()
        },
    
        _select(){
          const a=wx.createSelectorQuery().in(this);
          this.columnNodes=a.selectAll("#left, #right")
          this._render(this.data.Object,0)
        },
    
        _render(data,e){
           data.length>e 
           && 0!==this.data.Object.length 
           && this.columnNodes.boundingClientRect().exec(h=>{
            const r=h[0]
            this.data.leftHeight=r[0].height, this.data.rightHeight=r[1].height
            this.data.leftHeight > this.data.rightHeight ?
            this.data.rightData.push(data[e]):
            this.data.leftData.push(data[e]),
            this.setData({
              rightData: this.data.rightData,
              leftData: this.data.leftData
            },()=>{
              this._render(data,++e)
            })
          })
        }
      }
    })
    

    2.创建我们自定义的water-item

    // components/water-item/index.wxml
    <view class="life-container">
      <image class="life-img" src="{{data.image}}" mode='widthFix'/>
    </view>
    
    // components/water-item/index.wxss
    .life-container {
      box-shadow: 0px 8rpx 20rpx 0px rgba(9, 36, 66, 0.04) !important;
      margin: 0 0 17rpx 0;
      padding: 0 0 100rpx 0;
      border-radius: 16rpx !important;
      width: 355rpx !important;
      background-color: white !important;
    }
    
    .life-img {
      border-radius: 16rpx 16rpx 0 0 !important;
      width: 355rpx !important;
    }
    
    // components/water-item/index.js
    properties: {
       data:Object
    },
    

    3.页面引用

    // pages/index/index.wxml
    <view style="margin: 13rpx 14rpx 0 14rpx">
      <water-flow generic:water-flow-item="water-item" Object="{{demo}}"/>
    </view>
    
    // pages/index/index.js
    // 数据
    Page({
      data: {
        demo:[
          {
            image: 'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/16ab3222427f4201bf0e069098a38c57~tplv-k3u1fbpfcp-watermark.image',
            title: '显瘦中长款系带风衣',
            describe: '111111',
            count: '888',
            delCount: '666'
          },{
          image: 'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/273dc740d51d419c86b6d8ffb9c51250~tplv-k3u1fbpfcp-watermark.image',
          title: '显瘦中长款系带风衣',
          describe: '22222222',
          count: '888',
          delCount: '666'
        },{
          image: 'https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/c955cfd0598a4825907aa4e8122ba754~tplv-k3u1fbpfcp-watermark.image',
          title: '显瘦中长款系带风衣',
          describe: '333333333',
          count: '888',
          delCount: '666'
        }
        ,{
          image: 'https://p9-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/0b6b701c6d6d4c60b87b84b99a132541~tplv-k3u1fbpfcp-watermark.image',
          title: '显瘦中长款系带风衣',
          describe: '333333333',
          count: '888',
          delCount: '666'
        },
        {
          image: 'https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/febff6310a5f41a0b8e7ad14c485ed28~tplv-k3u1fbpfcp-watermark.image',
          title: '显瘦中长款系带风衣',
          describe: '333333333',
          count: '888',
          delCount: '666'
        },
        {
          image: 'https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/7c3f4a83e30a47d791c1fbd8ae6f6783~tplv-k3u1fbpfcp-watermark.image',
          title: '显瘦中长款系带风衣',
          describe: '333333333',
          count: '888',
          delCount: '666'
        }
      ]
      }
    })
    

    起源地下载网 » 利用“抽象组件”去封装瀑布流【小程序】

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元