鍍金池/ 問答/PHP  HTML/ 微信小程序tab切換—swiper組件中使用slot的問題(已放棄slot方式,

微信小程序tab切換—swiper組件中使用slot的問題(已放棄slot方式,采用tab組件和swiper組件相互傳值)

題目描述

微信小程序的swiper組件中的swiper-item標(biāo)簽里使用了slot,但是現(xiàn)在slot的內(nèi)容不顯示,不知道什么原因,也有百度到swiper中不讓嵌套其他,但是這個其他包不包括slot我也不清楚,文檔上我也沒有找到相關(guān)的描述

題目來源及自己的思路

做一個tab切換的功能,content部分用swiper組件來實現(xiàn),單個頁面已經(jīng)可以實現(xiàn)。現(xiàn)在我想把這部分抽離出來做成一個可復(fù)用的組件,那就意味著內(nèi)容是動態(tài)的,我的想法是用slot來實現(xiàn),但是最后的效果一直都不對

相關(guān)代碼

調(diào)用組件的頁面:

<tab menu='{{menu}}'>
    <view class='borrow-list' id='list'>
        我是slot
    </view>
</tab>

tab組件的代碼:

<view class='tabMenu'>
    <view class='tabItem' bindtap='tabChange'>
        <view wx:for='{{menu}}' wx:key='{{index}}' id='t{{index+1}}' data-flag='{{index}}' class='{{active==("t"+(index+1)) ? "active":""}}'>{{item.text}}</view>
    </view>
    <view id='tabline' class='tabline' style='left:{{left||"91rpx"}}'></view>
</view>
<view>
    <swiper bindchange='swiperChange' current = '{{current}}' style='height:{{swiperHeight+"px"}}'>
        <swiper-item item-id='t1'>
            <slot></slot>
        </swiper-item>
    </swiper>
</view>  

這樣寫之后在console查看代碼結(jié)構(gòu)如下:
圖片描述

slot的內(nèi)容沒有插入到swiper-item中,然后我又給slot加了name,最后的結(jié)果如下:
圖片描述

問題一:swiper中slot能不能使用(文檔中哪里有體現(xiàn))
問題二:swiper中如果不能使用slot,那有什么辦法可以實現(xiàn)動態(tài)內(nèi)容部分
其實我之前還嘗試了另一個辦法,就是swiper不寫在tab組件內(nèi)寫在調(diào)用tab的頁面里,但是因為有聯(lián)動效果(滑動內(nèi)容,tab菜單動態(tài)切換;點擊tab菜單,內(nèi)容滑動變化)導(dǎo)致傳值是個問題,因為小程序沒有監(jiān)聽data變化的函數(shù)(比如watch),所以一旦我滑動內(nèi)容部分,傳給tab組件的值的變化我是監(jiān)聽不到的。如果根據(jù)這個思路,大家有解決的辦法,也可以留言~3Q~

回答
編輯回答
裸橙

你好 老鐵 謝邀,這個問題我們公司在寫公用組件庫的遇到過這個問題關(guān)于wepy動態(tài)插槽無法生成的問題,也提給官方了,坐等解決,如果你使用的是wepy這個框架時,使用slot記得對應(yīng)的name,如果動態(tài)的要生成多個的swiperitme并且有插槽位置的話,每一個slot的name記得命為不同的,原生小程序是沒有slot這個插槽的,如果想使用slot的話 推薦使用wepy或者mpvue。

2017年1月17日 18:57
編輯回答
萌小萌

已解決,解決方案如下:
我最后采用了我的問題末尾提到的思路,tab的多個標(biāo)簽是一個組件,swiper放在調(diào)用組件的page頁中,那就面臨著要解決page和組件的傳值問題,看了一篇寫vue中watch的實現(xiàn)思路的文章(地址:https://segmentfault.com/a/11...)有所啟發(fā),使用Object.defineProperty()給監(jiān)聽的屬性設(shè)置存取器屬性,存取器屬性包含set和get方法,當(dāng)屬性發(fā)生變化時,set和get自動觸發(fā)達到監(jiān)聽屬性變化的目的

代碼實現(xiàn)部分:
組件調(diào)用方式:(menu是tab的選項名稱以及id等信息,是一個數(shù)組;currentItemId是當(dāng)前swiperItem的item-id)

<tab menu='{{menu}}' currentItemId='{{currentItemId}}' bind:changeEvent='changeEvent'></tab>

page頁中swiper組件:(swiperChange中能獲取到currentItemId)

<swiper bindchange='swiperChange' current = '{{current}}' style='height:{{swiperHeight+"px"}}'>
    <swiper-item item-id='t1'>
    //內(nèi)容
    </swiper-item>
    <swiper-item item-id='t2'>
    //內(nèi)容
    </swiper-item>
</swiper>

tab組件中接收currentItemId:

/**
   * 組件的屬性列表
   */
  properties: {
    menu: {
       type: Array,
       value: null
    },
    currentItemId: {
       type: String
    }
  }

同時在tab組件中定義一個初始數(shù)據(jù)方便之后使用Object.defineProperty():

/**
   * 組件的初始數(shù)據(jù)
   */
  data: {
    copy: {}
  },

之后在組件js的methods中定義watch函數(shù),監(jiān)聽的是接收到的currentItemId

watch: function (val) { 
      let _this = this
      Object.defineProperty(_this.data, 'currentItemId', { //需要監(jiān)聽的currentItemId
        enumerable: true,
        configurable: true,
        get: function () {
          return _this.data.copy.currentItemId //此處使用的copy,其中的currentItemId字段始終與this.data.currentItemId相等,不可使用this.data.currentItemId,會造成死循環(huán)
        },
        set: function (newVal) {
          var value = _this.data.copy.currentItemId
          if (newVal === value) {
            return
          }
          //為了使this.data.currentItemId == this.data.copy.currentItemId,需要在每一次this.data.currentItemId變化的時候也就是執(zhí)行set的時候為this.data.copy賦值 使兩個字段的值始終保持一致
          _this.setData({
            copy: {
              currentItemId: newVal
            }
          })
          //這個方法計算應(yīng)該切換到哪個選項的,不是問題的重點就不貼代碼了
          _this.currCompute(_this.data.copy.currentItemId)
        }
      })
      _this.setData({
          copy: {
            currentItemId: _this.data.currentItemId
          }
      })
    }

-----------------以上完成了從page頁傳值到tab組件,tab組件中監(jiān)聽swiper的變化------------------
接下來說一下tab組件傳值到page頁,就是組件中綁定的那個自定義事件changeEvent了,再貼一次代碼:

 <tab menu='{{menu}}' currentItemId='{{currentItemId}}' bind:changeEvent='changeEvent'></tab>

當(dāng)tab組件中的選項被點擊切換的時候觸發(fā)changeEvent自定義事件,同時page頁定義changeEvent函數(shù)來接收傳過來的值(注意自定義事件名稱和觸發(fā)函數(shù)的名稱沒關(guān)系,就是懶得再起一個名稱而已)
tab組件js中的操作:

/*tab切換事件 */
    tabChange: function (e) {
      let id = e.target.id
      var data = {
        current: e.target.dataset.flag
      } 
      this.triggerEvent('changeEvent', data) //changeEvent自定義事件的名稱
    },

page頁中接收:
changeEvent: function(data) {

this.setData({
  current: data.detail.current
})

}
-----------------以上完成了從tab組件傳值到page頁的操作,如果熟悉vue中的子組件向父組件傳值,應(yīng)該可以理解的------------------

以上,多謝@師寧丶童鞋和@WsmDyj童鞋解答~

2018年8月13日 04:51
編輯回答
脾氣硬

建議自己封裝一個swiper組件,或者引用iview中的swiper

2017年5月27日 08:24