一、背景
在開發項目的過程中,有時修改后台的數據變化可能不會及時更新到頁面上,此時就需要我們刷新頁面更新數據,但是直接調用刷新window.location.reload()可能對操作的體驗不是很好,所以就需要下面的方法。
列舉個場景,比如修改主體content內容,我想要刷新主體部分的組件,但是不刷新title和aside組件,怎么實現呢?
實現方法就是在想要刷新的組件中封裝一個方法,當需要刷新頁面時直接調用這個方法就可以無痕跡刷新這個組件(頁面)!
代碼:
1、在app.vue中封裝方法,此時調用可以刷新整個系統(整個頁面)
<template> <div class="app-file"> <router-view v-if="isRouterAlive"></router-view> </div> </template> <script> export default { provide() { return { reloadAll: this.reloadAll } }, data() { return { isRouterAlive: true } }, methods: { reloadAll() { this.isRouterAlive = false this.$nextTick(() => { this.isRouterAlive = true }) } } } </script> <style lang="scss" scoped> </style>
2、第二部,在想要實現刷新方法的組件引用及調用
3、這樣在調用就可以實現我們想要的效果,同理,也可應用到其他組件,如開頭所列舉的場景:
這樣就可以實現選擇性的刷新頭部,側邊導航欄的組件了!
二、原理
provide/inject這對選項需要一起使用,以允許一個祖先組件向其所有子孫后代注入一個依賴,不論組件層次有多深,並在其上下游關系成立的時間里始終生效。
provide / inject 是在 VUE 2.2.0 的版本新增的 類型: provide: Object | () => Object provide 選項應該是一個對象或返回一個對象的函數。該對象包含可注入其子孫的 property。在該對象中你可以使用 ES2015 Symbols 作為 key,但是只在原生支持 Symbol 和 Reflect.ownKeys 的環境下可工作 inject: Array<String> | { [key:string]: string | symbol | Object }
提示:provide
和 inject
綁定並不是可響應的。這是刻意為之的。然而,如果你傳入了一個可監聽的對象,那么其對象的 property 還是可響應的。
例子:
我們可以看到 breadcrumb.vue 父組件中,通過 provide 向子孫組件提供了當前vue的實例。而breadcrumb-item.vue子組件中,通過inject屬性訪問了父組件中提供的elBreadcrumb的值,即當前vue的實例。這樣我們就可以不用通過$parent一級一級的去訪問了。
使用場景:vue有$parent屬性可以讓子組件訪問父組件。但子孫組件想要訪問祖先組件就比較困難。這時候可以通過provide/inject來實現跨級訪問祖先組件的數據。
參考官網:https://cn.vuejs.org/v2/api/#provide-inject
末尾部分引自:https://www.jianshu.com/p/c4ee6006994c