這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 背景 項目當中如果做新增/修改/刪除等等操作通常情況下都需要刷新數據或者刷新當前頁面. 思路 (1)如果頁面簡單,調用介面刷新數據即可. (2)如果頁面複雜,需要調用多個介面或者通知多個子組件做刷新,可以採用刷新當前頁面的方式 下麵整理了 ...
這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
背景
項目當中如果做新增/修改/刪除等等操作通常情況下都需要刷新數據或者刷新當前頁面.
思路
-
(1)如果頁面簡單,調用介面刷新數據即可.
-
(2)如果頁面複雜,需要調用多個介面或者通知多個子組件做刷新,可以採用刷新當前頁面的方式 下麵整理了4種方式來實現刷新當前頁面,每種方式的思路不同,各有優缺點
實現
方式1-通過location.reload和$router.go(0)方法
(a)概述
通過location.reload
和$router.go(0)
都可以實現頁面刷新,它利用瀏覽器刷新功能,相當於按下了f5
鍵刷新頁面
優點:足夠簡單
缺點:會出現頁面空白,用戶體驗不好
(b)代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js" type="application/javascript"></script> <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue-router/3.5.3/vue-router.min.js" type="application/javascript"></script> <style> * {padding:0;margin:0;} .container { padding: 10px;display: flex;flex-basis: auto;height: 100vh;box-sizing: border-box;} .aside{ width:200px;background-color: #d3dce6; } .main { flex: 1; } </style> </head> <body> <div id="app"> <router-view></router-view> </div> </body> <script> //框架頁 let Layout = { created() { console.log('框架頁載入') }, template: ` <div class="container"> <div class="aside">左側菜單</div> <div class="main"><router-view></router-view></div> </div> ` } //首頁 let Home = { template: ` <div> 首頁 <button @click="onClick">刷新</button> </div> `, created() { console.log('首頁載入') }, methods: { onClick(){ // 通localtion.reload或者this.$router.go(0)實現整體刷新頁面,會出現頁面閃爍 // location.reload() this.$router.go(0) } }, } //路由配置 let router = new VueRouter({ routes: [ {path: '/', component: Layout, children:[ {path: '', component: Home} ]} ] }) Vue.use(VueRouter) //根組件 new Vue({ router, el: '#app' }) </script> </html>
(c)預覽
方式2-通過空白頁面
(a)概述
通過$router.replace
方法,跳轉一個空白頁面,然後再調回之前頁面,它利用vue-router
切換頁面會把頁面銷毀並新建新頁面的特性
優點:不會出現頁面空白,用戶體驗好
缺點:地址欄會出現快速切換的過程
(b)代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js" type="application/javascript"></script> <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue-router/3.5.3/vue-router.min.js" type="application/javascript"></script> <style> * {padding:0;margin:0;} .container { padding: 10px;display: flex;flex-basis: auto;height: 100vh;box-sizing: border-box;} .aside{ width:200px;background-color: #d3dce6; } .main { flex: 1; } </style> </head> <body> <div id="app"> <router-view></router-view> </div> </body> <script> //框架頁 let Layout = { created() { console.log('框架頁載入') }, template: ` <div class="container"> <div class="aside">左側菜單</div> <div class="main"><router-view></router-view></div> </div> ` } //首頁 let Home = { template: ` <div> 首頁 <button @click="onClick">刷新</button> </div> `, created() { console.log('首頁載入') }, methods: { onClick(){ //使用replace跳轉後不會留下 history 記錄,並通過redirect傳遞當前頁面的路徑 this.$router.replace(`/blank?redirect=${this.$route.fullPath}`) } }, } //空白頁面 let Blank = { created(){ console.log('空白頁載入') //重新跳回之前的頁面 this.$router.replace(this.$route.query.redirect) }, template: ` <div></div> ` } //路由配置 let router = new VueRouter({ routes: [ {path: '/', component: Layout, children:[ {path: '', component: Home} ]}, //配置空白頁面的路由 {path: '/blank', component: Layout, children:[ {path: '', component: Blank} ]} ] }) Vue.use(VueRouter) //根組件 new Vue({ router, el: '#app' }) </script> </html>
(c)預覽
方式3-通過provide和inject
(a)概述
通過在父頁面的<router-view></router-view>
上添加v-if的控制
來銷毀和重新創建頁面的方式刷新頁面,並且用到provide
和inject
實現多層級組件通信方式,父頁面通過provide
提供reload
方法,子頁面通過inject
獲取reload
方法,調用方法做刷新
優點:不會出現頁面空白,地址欄會不會出現快速切換的過程,用戶體驗好
缺點:實現稍複雜,涉及到provide
和inject
多層級組件間的通信,和v-if
控制組件創建和銷毀,和$nextTick
事件迴圈的應用
(b)代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js" type="application/javascript"></script> <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue-router/3.5.3/vue-router.min.js" type="application/javascript"></script> <style> * {padding:0;margin:0;} .container { padding: 10px;display: flex;flex-basis: auto;height: 100vh;box-sizing: border-box;} .aside{ width:200px;background-color: #d3dce6; } .main { flex: 1; } </style> </head> <body> <div id="app"> <router-view></router-view> </div> </body> <script> //框架頁 let Layout = { template: ` <div class="container"> <div class="aside">左側菜單</div> <!-- 通過v-if實現銷毀和重新創建組件 --> <div class="main"><router-view v-if="isRouterAlive"></router-view></div> </div> `, created() { console.log('框架頁載入') }, // 通過provide提供reload方法給後代組件 provide(){ return { reload: this.reload } }, data(){ return { isRouterAlive: true } }, methods: { async reload(){ this.isRouterAlive = false //通過this.$nextTick()產生一個微任務,在一次dom事件迴圈後,重新創建組件 await this.$nextTick() this.isRouterAlive = true } } } //首頁 let Home = { template: ` <div> 首頁 <button @click="onClick">刷新</button> </div> `, created() { console.log('首頁載入') }, //通過inject獲取祖先元素的reload方法 inject: ['reload'], methods: { onClick(){ this.reload() } }, } //路由配置 let router = new VueRouter({ routes: [ {path: '/', component: Layout, children:[ {path: '', component: Home} ]} ] }) Vue.use(VueRouter) //根組件 new Vue({ router, el: '#app' }) </script> </html>
(c)預覽
方式4-通過給router-view綁定key屬性
(a)概述
通過在父頁面的<router-view></router-view>
上綁定和切換key
屬性,來銷毀和重新創建頁面的方式刷新頁面,具體的方式是指定key的值為$route.fullPath
,通過在子頁面通過this.$router.push(this.$route.path+'?t='+Date.now())
來改變$route.fullPath
的值,從而刷新頁面
優點:不會出現頁面空白,並且代碼簡單 缺點:地址欄出現隨機參數
(b)代碼
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue/2.6.14/vue.js" type="application/javascript"></script> <script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/vue-router/3.5.3/vue-router.min.js" type="application/javascript"></script> <style> * {padding:0;margin:0;} .container { padding: 10px;display: flex;flex-basis: auto;height: 100vh;box-sizing: border-box;} .aside{ width:200px;background-color: #d3dce6; } .main { flex: 1; } </style> </head> <body> <div id="app"> <router-view></router-view> </div> </body> <script> //框架頁 let Layout = { template: ` <div class="container"> <div class="aside">左側菜單</div> <!-- 通過:key綁定$router.fullPath值,當fullPath發生改變,觸發組件重新渲染 --> <div class="main"><router-view :key="$route.fullPath"></router-view></div> </div> `, created() { console.log('框架頁載入') } } //首頁 let Home = { template: ` <div> 首頁 <button @click="onClick">刷新</button> </div> `, created() { console.log('首頁載入') }, methods: { onClick(){ this.$router.push(`${this.$route.path}?t=${Date.now()}`) } }, } //路由配置 let router = new VueRouter({ routes: [ {path: '/', component: Layout, children:[ {path: '', component: Home} ]} ] }) Vue.use(VueRouter) //根組件 new Vue({ router, el: '#app' }) </script> </html>