1. 程式人生 > >微信小程式wepy框架中父元件與子元件通訊和互動

微信小程式wepy框架中父元件與子元件通訊和互動

官網上描述:
這裡寫圖片描述

$broadcast

$broadcast事件是由父元件發起,所有子元件都會收到此廣播事件,除非事件被手動取消。事件廣播的順序為廣度優先搜尋順序。

$emit

$emit與$broadcast正好相反,事件發起元件的所有祖先元件會依次接收到$emit事件。

$invoke

$invoke是一個頁面或元件對另一個元件中的方法的直接呼叫,通過傳入元件路徑找到相應的元件,然後再呼叫其方法。

$emit例子:

子元件中選擇平臺(‘全平臺’, ‘愛奇藝’, ‘騰訊’, ‘優酷’),通知父元件此時選中的平臺是誰,用來通知父元件控制指標是否可以被選中(當為全平臺時,不可選中資源等級)

子元件程式碼:

<picker @change="bindPickerChange" value="{{platformIndex}}" range="{{platformArray}}">
            <view style="display: flex;align-items: center" >
                <view>{{platformArray[platformIndex]}}</view>
                <view class="iconfont icon-xiajiantou" style="margin-left:10rpx;font-size: 30rpx;color: gray" ></view>
            </view>
 </picker>

methods = {
    bindPickerChange (e) {
        console.log('切換平臺')
        this.platformIndex = e.detail.value
        this.$emit('platformChoose',this.platformArray[this.platformIndex]);
    }
  }

data = {
    platformArray: ['全平臺', '愛奇藝', '騰訊', '優酷'],
    platformIndex: 0,
  };

父元件程式碼:

events = {
    platformChoose(platform,event){
        console.log('此時子元件選擇的平臺是',platform)
        this.platform = platform
    }
}

當切換子元件中當平臺時:
這裡寫圖片描述
當切換子元件中的平臺為全平臺,在父元件中選擇指標會提示:
這裡寫圖片描述

$invoke例子:
子元件中呼叫介面獲取列表資料,負責控制頁面正在載入的進度是否顯示,使用者在父元件內滑到底部觸發載入下一頁資料,在子元件頁面顯示

子元件程式碼:

<block wx:for="{{filmData}}" wx:for-item="category" wx:key="*this">
        <view style="height:100px">{{category.name}}</view>
</block>      
<view class="weui-loadmore" hidden="{{isHideLoadMore || filmData.length===0}}">
        <view class="weui-loading"></view>
        <view class="weui-loadmore__tips">正在載入</view>
</view>

data = {
      page: 1,
      isHideLoadMore: true,
      totalPage: 1,
      filmData: []
}

onReachBottomCom() {
    this.isHideLoadMore = false;
    ++this.page;
    if (this.page > (this.totalPage / 10 + 1)) {
        this.isHideLoadMore = true;
        this.$apply();
        wx.stopPullDownRefresh();
    } else {
        this.getlistData(); //獲取下一頁資料
    }
};

async getlistData () {
    try {
      let apiParams = JSON.stringify({
        'url': '/listData',
        'method': 'POST',
        'params': {
           // *** 其他引數
          'page': this.page,
          'pageLineCount': 10,
        }
      })
      let res = await api.api_post(apiParams)
      console.log('listData 列表',res)
      if (!res.data.hasOwnProperty('status')) {
          let data = this.filmData.concat(res.data.listData)
          this.filmData = data
          this.totalPage = res.data.totalPage
          this.$apply()
      }
    } catch (e) {
      console.log(e)
    }
  };

父元件程式碼:

onReachBottom() {
    this.$invoke('子元件名稱', 'onReachBottomCom', '');
};

app.wepy:

 'window': {
    'onReachBottomDistance': 400,
}

當在父元件內觸底重新整理時:
這裡寫圖片描述
當在父元件內呼叫子元件獲取列的方法後,得到下一頁資料:
這裡寫圖片描述

$broadcast例子:
父元件某個變數發生改變,通知所有子元件執行某個方法,例當元件切換tabs時,當切換為全網大盤時,所有圖表重新重新整理顯示:

父元件程式碼:

<view class="home page">
     <view class="tabs-change">
        <view class="tabs_item {{chooseShowPage==='全網大盤'?'':'click-color1'}}" bindtap="typeChange('全網大盤')" >
            全網大盤
        </view>
        <view class="tabs_item {{chooseShowPage==='排行榜'?'':'click-color1'}}" bindtap="typeChange('排行榜')">
            排行榜
        </view>
    </view>
    <i-toast id="toast" />
    <grail :chooseShowPage.sync="chooseShowPage" :tvType="tvType" wx:if="{{chooseShowPage==='全網大盤'}}"/>
    <rankingList :tvType="tvType" wx:if="{{chooseShowPage==='排行榜'}}"/>
</view>

methods = {
    typeChange (type) {
      this.chooseShowPage = type
      this.updateShowPage()
    }
  };

async updateShowPage () {
    try {
      await new Promise(resolve => {
        setTimeout(() => {
          resolve('async await test...')    
        }, 1000)
      })
      this.$broadcast('chooseShowPage', this.chooseShowPage)   //必須是非同步執行廣播事件,原理和小程式頁面重新整理和canvas重繪的先後機制有關,否則圖表不顯示
      this.$apply()
    } catch (e) {
      console.log(e)
    }
  }

子元件程式碼:

events = {
	chooseShowPage (newValue) {
          if (newValue==='全網大盤') {
              chart.setOption(this.option)
          }
      }
  }