Vue中解决路由切换,组件不更新问题的方法

Vue Router可以实现路由的切换,也就是组件之间的切换,它不同于传统页面的切换,所以在使用的时候经常会出现路由已经切换,但是组件没有更新的问题(只要实现对页面的刷新,组件就会重新进行加载):

一、 问题呈现

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
 <script src="./lib/vue-2.4.0.js"></script>
 <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
  <div id="app">
    <router-link to="/login?id=10">登录</router-link>
    <router-link to="/register">注册</router-link>
    <router-view></router-view>
  </div>
  <script>
    var login = {
     
     
      template:'<h1>登录组件</h1>',
      created () {
     
     
        console.log(this.$route)
      }
    }
    var register = {
     
     
      template:'<h1>注册组件</h1>',
    }
    var routerObj = new VueRouter({
     
     
      routes:[
        {
     
     path:'/login',component:login},
        {
     
     path:'/register',component:register},
        {
     
     path:'/',redirect: '/login'}
      ]
    })
    new Vue({
     
     
      el:'#app',
      data:{
     
     },
      methods: {
     
     },
      components: {
     
     
        login,
        register
      },
      router:routerObj
    })
  </script>
</body>
</html>

页面效果是这样的:
在这里插入图片描述
我们想要的结果是:点击登录,路由切换到/login?id=10,从而可以获取到this.$route.query.id = 10,但是,一现在点击之后,没有输出结果------这就是我们所说的路由切换后,组件不更新的问题
在这里插入图片描述

二、 解决办法①

<router-view :key="key"></router-view>增加一个不同的:key值,这样vue就会识别这是不同的<router-view>了。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
 <script src="./lib/vue-2.4.0.js"></script>
 <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
  <div id="app">
    <router-link to="/login?id=10">登录</router-link>
    <router-link to="/register">注册</router-link>
    <router-view :key="key"></router-view>
  </div>
  <script>
    var login = {
     
     
      template:'<h1>登录组件</h1>',
      created () {
     
     
        console.log(this.$route)
      }
    }
    var register = {
     
     
      template:'<h1>注册组件</h1>',
    }
    var routerObj = new VueRouter({
     
     
      routes:[
        {
     
     path:'/login',component:login},
        {
     
     path:'/register',component:register},
        {
     
     path:'/',redirect: '/login'}
      ]
    })
    new Vue({
     
     
      el:'#app',
      data:{
     
     },
      methods: {
     
     },
      components: {
     
     
        login,
        register
      },
      computed: {
     
     
        key (){
     
     
          return this.$route.path + Math.random();
        }
      },
      router:routerObj
    })
  </script>
</body>
</html>

现在,我们再次点击登录,console就会有结果,获取到query的值了
在这里插入图片描述

三、 解决办法②

<router-view v-if="routerAlive"></router-view>增加一个不同v-if值,来先摧毁<router-link>,然后再重新创建<router-link>起到刷新页面的效果。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
 <script src="./lib/vue-2.4.0.js"></script>
 <script src="https://unpkg.com/vue-router/dist/vue-router.js"></script>
</head>
<body>
  <div id="app">
    <router-link to="/login?id=10" @click="routerRefresh">登录</router-link>
    <router-link to="/register" @click="routerRefresh">注册</router-link>
    <router-view v-if="changeRouter"></router-view>
  </div>
  <script>
    var login = {
     
     
      data () {
     
     
        return {
     
     
          changeRouter:true
        }
      },
      methods: {
     
     
        routerRefresh(){
     
     
          this.changeRouter=false;
          this.$nextTick(()=>{
     
     
            this.changeRouter=true;
          })
        }
      },
      template:'<h1>登录组件</h1>',
      created () {
     
     
        console.log(this.$route)
      }
    }
    var register = {
     
     
      template:'<h1>注册组件</h1>',
    }
    var routerObj = new VueRouter({
     
     
      routes:[
        {
     
     path:'/login',component:login},
        {
     
     path:'/register',component:register},
        {
     
     path:'/',redirect: '/login'}
      ]
    })
    new Vue({
     
     
      el:'#app',
      data:{
     
     },
      methods: {
     
     },
      components: {
     
     
        login,
        register
      },
      computed: {
     
     
        key (){
     
     
          return this.$route.path + Math.random();
        }
      },
      router:routerObj
    })
  </script>
</body>
</html>
  • 给vue组件绑定事件时候,必须加上.native,否则会认为监听的是来自Item组件自定义的事件
  • this.$nextTick( [callback] )的用法是:将回调延迟到下次 DOM 更新循环之后执行。在修改数据之后立即使用它,然后等待 DOM 更新。它跟全局方法 Vue.nextTick一样,不同的是回调的 this 自动绑定到调用它的实例上。
methods: {
    
    
  routerRefresh(){
    
    
  //修改数据
    this.changeRouter=false;
    // DOM 还没有更新
    this.$nextTick(()=>{
    
    
    // DOM 现在更新了
    // `this` 绑定到当前实例
      this.changeRouter=true;
    })
  }
},

$route 和 $router的区别

  1. $router是Vue Router的实例方法,可以认为是全局的路由对象,包含了所有路由的对象和属性。
    在这里插入图片描述

  2. $route是一个跳转的路由对象,可以认为是当前组件的路由管理,指当前激活的路由对象,包含当前url解析得到的数据,可以从对象里获取一些数据。如name、path、query、params等。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/PILIpilipala/article/details/110139718