使用 initScroll/provide

2019-10-01 12:38:12

今天的場景是,在後台否些頁面中,有一個選擇顯示頁數的功能(element-ui 的 el-pagination 組件),該組件(el-pagination) 上有這個事件 @size-change="handleSizeChange,所以當你切換頁數時,會觸發 handleSizeChange 這個方法,然後改變要顯示的頁數,去 call api,重新獲得資料。

而我們要初始化 scrollTop,就在這個呼叫 api 之後的 then 裡面去操作。

後來發現 scroll bar 是長在父父父...組件的 <section class="app-main"> 裡面,可以用 document.duerySelector('.app-main') 去取得該元素,但是這樣重複的代碼太多,如果用 this.$parent.$parent..也太麻煩。this.$emit 先不考慮。

使用 provide / inject 可以輕鬆的實現跨级访问祖先组件的数据

總之,父組件提供給任意子組件指向自身的 this 的 initScroll 方法,而子組件可透過 inject: ['initScroll'] 引用這個在遙遠祖宗上的方法,在子組件自身上簡單的呼叫 this.initScroll() 即可使用。

provide 寫法一

// 父組件

export default {
  name: 'AppMain',
  methods: {
    initScroll() {
      this.$el.scrollTop = 0
      this.$el.scrollLeft = 0
    }
  },
  provide() { // 父组件中返回要传给下级的数据
    return {
        initScroll: this.initScroll
    }
  }
}
</script>

<!-- 某個或多個很遠的子組件 -->
<script>
export default {
  inject: ['initScroll'],
  data() {
    return {}
  },
  methods: {
    handleSizeChange(val) {
      this.requestData.pageSize = val
      this.$store.dispatch('xxxxxxxxxxx', this.requestParams).then(() => {
        this.initScroll()
      })
    },
  }
}
</script>

參考文章

https://segmentfault.com/a/1190000013592099 https://gist.github.com/davestewart/54b6823a76500fdcdd918fc5ce575d4c https://oychao.github.io/2017/12/06/vue/01_vue_communication/ https://juejin.im/post/5c983d575188252d9a2f5bff