Vue aktualisiert die aktuelle Seite

Hintergrund

Wenn Sie Vorgänge im Projekt hinzufügen/ändern/löschen, müssen Sie normalerweise die Daten aktualisieren oder die aktuelle Seite aktualisieren.

Gedankengang

  • (1) Wenn die Seite einfach ist, rufen Sie einfach die Schnittstelle auf, um die Daten zu aktualisieren.

  • (2) Wenn die Seite komplex ist und mehrere Schnittstellen aufrufen oder mehrere Unterkomponenten zur Aktualisierung benachrichtigen muss, können Sie die Methode zum Aktualisieren der aktuellen Seite verwenden. Die folgenden drei Methoden werden aussortiert, um die Aktualisierung der aktuellen Seite zu erreichen. Jede Methode hat eine andere Ideen und hat seine eigenen Vor- und Nachteile.

erreichen

Methode 1 – über die Methode location.reload und $router.go(0).

(a) Überblick

Die Seitenaktualisierung kann sowohl durch als location.reloadauch erreicht werden $router.go(0), es verwendet die Browser-Aktualisierungsfunktion, was dem Drücken der f5Taste zum Aktualisieren der Seite entspricht.
Vorteile : Einfach genug
Nachteile : Es werden leere Seiten angezeigt, und die Benutzererfahrung ist nicht gut

(b) Code

<!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) Vorschau

Verknüpfung

Weg 2 - Über eine leere Seite

(a) Überblick

Springen Sie durch die $router.replaceMethode zu einer leeren Seite und rufen Sie dann die vorherige Seite auf. Es verwendet vue-routerdie Funktion, dass das Wechseln von Seiten die Seite zerstört und eine neue Seite erstellt.
Vorteile : Es gibt keine leeren Seiten, und die Benutzererfahrung ist gut
Nachteile : Es wird ein schneller Wechsel im Adressleistenprozess geben

(b) Code

<!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) Vorschau

Verknüpfung

Methode 3 - durch Bereitstellen und Injizieren

(a) Überblick

通过在父页面的<router-view></router-view>上添加v-if的控制来销毁和重新创建页面的方式刷新页面,并且用到provideinject实现多层级组件通信方式,父页面通过provide提供reload方法,子页面通过inject获取reload方法,调用方法做刷新
优点:不会出现页面空白,地址栏会不会出现快速切换的过程,用户体验好
缺点:实现稍复杂,涉及到provideinject多层级组件间的通信,和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)预览

链接

Guess you like

Origin juejin.im/post/7188103333440127037