Vue js 路由到另一个页面后不会重新渲染页面高度

Posted

技术标签:

【中文标题】Vue js 路由到另一个页面后不会重新渲染页面高度【英文标题】:Vue js does not re-render the page height after routing to another page 【发布时间】:2019-02-24 12:52:17 【问题描述】:

亲爱的开发者你好!

我是 Vue.js 的新手,我现在正在努力解决一个视觉问题。 通过 <b-dropdown-item @click="go_login">Login</b-dropdown-item> 将用户从 navbar 导航到上一页时 go_login() =

go_login: function () this.$router.push('/login')

页面路由到 login 组件,但页面高度没有更新。如果您改用href="/login" 或直接在浏览器地址栏中输入地址,则不会发生这种情况,但我不想(不喜欢)使用href

我错过了什么?

我的代码:

路由器/index.js

import Vue from 'vue'
import Router from 'vue-router'
import store from '../store/store'
import userLogin from '../views/userLoginPage'
import landingPage from '../views/landingPage'
import admin from '../views/admin'
import userRegistration from '../views/userRegistration'
import userPasswordReset from '../views/userPasswordReset'
import pageNotFound from '../views/404'
import userProfile from '../views/userProfile'

Vue.use(Router)

// checks if user is authenticated and allowed to se the page
const ifAuthenticated = (to, from, next) => 
  if (store.getters.isAuthenticated) 
    next()
    return
  
  next('/login')


/**
 * icon names can be found on fontawesome page
 * for example https://fontawesome.com/icons/volume-up?style=solid
 */
export default new Router(
  mode: 'history',
  routes: [
    
      path: '/',
      name: 'landingPage',
      component: landingPage,
      props: msg: 'Welcome to Tonefeed!', icon: 'volume-up'
    ,
    
      path: '/login',
      name: 'userLogin',
      component: userLogin,
      props: msg: 'Sign in', icon: 'key'
    ,
    
      path: '/profile',
      name: 'userLProfile',
      component: userProfile,
      props: msg: 'Profile', icon: 'user',
      beforeEnter: ifAuthenticated
    ,

    // for testing purposes guests are not allowed to see this page
    
      path: '/admin',
      name: 'bootstrapExamples',
      component: admin,
      props: msg: 'Admin', icon: 'user-ninja',
      beforeEnter: ifAuthenticated
    ,
    
      path: '/register',
      name: 'register',
      component: userRegistration,
      props: msg: 'Registration', icon: 'pen-alt'
    ,
    
      path: '/password-reset',
      name: 'userPasswordReset',
      component: userPasswordReset,
      props: msg: 'Password reset', icon: 'unlock'
    ,
    
      path: '/404',
      name: 'pageNotFound',
      component: pageNotFound,
      props: msg: '404', icon: 'exclamation-triangle'
    ,
    // if url is unknown => redirect to 404
    
      path: '*',
      redirect: '/404'
    
  ],
  scrollBehavior (to, from, savedPosition) 
    return  x: 0, y: 0 
  
)

components/navigationBar.vue

<template>
  <b-navbar :class="'classA navbar-dark': scrollPosition < 64, 'classB navbar-light': scrollPosition > 64"
            toggleable="md">

    <b-navbar-toggle target="nav_collapse"></b-navbar-toggle>

    <b-navbar-brand>
      <font-awesome-icon :icon="icon"></font-awesome-icon>
      Tonefeed
    </b-navbar-brand>

    <b-collapse is-nav id="nav_collapse">

      <b-navbar-nav>
        <b-nav-item>Column 1</b-nav-item>
        <b-nav-item>Column 2</b-nav-item>
      </b-navbar-nav>

      <!-- Right aligned nav items -->
      <b-navbar-nav class="ml-auto">

        <b-nav-form>
          <b-form-input size="sm" class="mr-sm-2" type="text" placeholder="Search"/>
          <button
            :class="'button btn btn-outline-primary btn-sm': scrollPosition < 64, 'button btn btn-outline-secondary btn-sm': scrollPosition > 64">
            Search
          </button>
        </b-nav-form>

        <b-nav-item-dropdown text="Lang" right>
          <b-dropdown-item>EN</b-dropdown-item>
          <b-dropdown-item>DE</b-dropdown-item>
          <b-dropdown-item href="/login">RU</b-dropdown-item>
        </b-nav-item-dropdown>

        <b-nav-item-dropdown text="User" right>
          <b-dropdown-item @click="go_profile">Profile</b-dropdown-item>
          <b-dropdown-item @click="go_home">Logout</b-dropdown-item>
          <b-dropdown-item @click="go_login">Login</b-dropdown-item>
          <b-dropdown-item @click="go_register">Register</b-dropdown-item>
        </b-nav-item-dropdown>
      </b-navbar-nav>

    </b-collapse>
  </b-navbar>
</template>

<script>
export default 
  name: 'navBar',
  data () 
    return 
      scrolled: false,
      scrollPosition: null
    
  ,
  props: 
    icon: String
  ,
  methods: 
    go_login: function () 
      this.$router.push('/login')
    ,
    go_home: function () 
      this.$store.dispatch('AUTH_LOGOUT')
        .then(() => 
          this.$router.push('/')
        )
    ,
    go_register: function () 
      this.$router.push('/register')
    ,
    go_profile: function () 
      this.$router.push('/profile')
    ,
    handleScroll () 
      this.scrolled = window.scrollY > 0
      this.scrollPosition = window.scrollY
    
  ,
  mounted () 
    window.addEventListener('scroll', this.handleScroll)
  ,
  destroy () 
    window.removeEventListener('scroll', this.handleScroll)
  

</script>

<style>
  .classA.navbar-dark 
    position: fixed;
    width: 100%;
    background: transparent;
    transition: .5s ease-in-out;
  

  .classB.navbar-light 
    position: fixed;
    width: 100%;
    background: white;
    transition: .5s ease-in-out;
  

  .topnav a:hover 
    background-color: white;
    color: black;
  
</style>

App.vue

<template>
  <div class="container-fluid">
    <div>
      <navigationBar v-bind:icon="icon"></navigationBar>
    </div>
    <div id="app" class="container">
      <router-view :key="$route.fullPath"></router-view>
    </div>
  </div>
</template>

<script>
import navigationBar from './components/navigationBar'

export default 
  name: 'app',
  data () 
    return 
      icon: 'volume-up'
    
  ,
  components: 
    navigationBar: navigationBar
  ,
  // if token expires the user should log out
  created: function () 
    this.axios.interceptors.response.use(undefined, function (err) 
      return new Promise(function (resolve, reject) 
        if (err.status === 401 && err.config && !err.config.__isRetryRequest) 
          // if you ever get an unauthorized, logout the user
          this.$store.dispatch('AUTH_LOGOUT')
          // you can also redirect to /login if needed !
        
        throw err
      )
    )
  

</script>

<style lang="scss">
  @import './styles/custom-bootstrap.scss';
  @import '../node_modules/bootstrap/scss/bootstrap.scss';

  body 
    background: url("./assets/overlay2.png"), url("./assets/overlay3.svg");
    background-position: top left, center center;
    background-size: auto, cover;
    background-attachment: fixed;
  

  .container-fluid
    padding: 0;
    display: flex;
    flex-direction: column;
  

  #app 
    padding-top: 4rem;
  

  a, a:hover 
    color: white;
    text-decoration: none;
  
</style>

【问题讨论】:

【参考方案1】:

我认为您面临的问题是由于您使用时页面没有刷新:(因为它是单页应用程序)

this.$router.push('/login')

当您使用 href 导航时,它会刷新页面的整个内容,直接输入 url 也是如此。

所以为了让组件采用你应该使用的实际宽度和高度:

location.reload(); // in the components life cycle hook

请说明这是否适合您。

【讨论】:

很高兴为您提供帮助。 :)

以上是关于Vue js 路由到另一个页面后不会重新渲染页面高度的主要内容,如果未能解决你的问题,请参考以下文章

Vue JS 组件重新附加或缓存

嵌套反应路由器组件不会在页面重新加载时加载/渲染?

VueJS - V-for 在数据更新后不会重新渲染,需要刷新页面才能看到更改

怎样保证js在页面元素渲染完后再执行

React 和 antd:路由器不会重新渲染组件

vue修改数据,刷新当前页面,重新渲染页面数据