Представление маршрутизатора продолжает отображать информацию о компоненте даже после перехода на другой компонент

#vue.js #vue-component #vue-router #vuejs3

Вопрос:

Я изучаю VueJS, создавая практическое приложение, и я застрял в точке, где внутри Authors компонента у меня есть список авторов. Я хочу иметь возможность нажать на элемент списка и перейти к AuthorDetail компоненту, пока все в порядке. Проблема возникает, когда я использую панель навигации вверху для перехода к другому виду, например Home , или About компонент AuthorDetail остается видимым (он должен исчезнуть!).

Код внутри App.vue

 <template>
  <div id="nav">
    <router-link to="/">Home</router-link> |
    <router-link to="/authors">Authors</router-link> | 
    <router-link to="/about">About</router-link>
  </div>
  <router-view />
</template>

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  max-width: 480px;
  margin: auto;
  border: 1px solid #2c3e50;
  border-radius: 5px;
  padding: 20px;
}

#nav {
  padding: 10px;
  border-bottom: 1px solid #e2e2e2;
  margin-bottom: 30px;

  a {
    font-weight: bold;
    color: #2c3e50;

    amp;.router-link-exact-active {
      color: #42b983;
    }
  }
}
</style>

 

Код в router/index.js

 import { createRouter, createWebHistory } from "vue-router";
import Home from "../views/Home.vue";
import Authors from "../views/Authors.vue";
import AuthorDetail from "../views/AuthorDetail.vue";

const routes = [
  {
    path: "/",
    name: "Home",
    component: Home,
  },
  {
    path: "/authors",
    name: 'Authors',
    component: Authors
  },
  {
    path: "/authors/:id",
    name: "AuthorDetail",
    component: AuthorDetail
  },
  {
    path: "/about",
    name: "About",
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () =>
      import(/* webpackChunkName: "about" */ "../views/About.vue"),
  },
];

const router = createRouter({
  history: createWebHistory(process.env.BASE_URL),
  routes,
});

export default router;

 

Код внутри Authors компонента.

 <template>
    <div>
        <h1>Authors</h1>
        <p>Most Popular Authors (TheTestRequest API)</p>

        <div class="authors-list" :key="author.id" v-for="author in authors">
            <router-link :to="{ name: 'AuthorDetail', params: { id: author.id}}">
                <AuthorCard @click="showAuthor(author.id)" :author="author"></AuthorCard>
            </router-link>
        </div>
    </div>
</template>

<script>
    import AuthorCard from '@/components/AuthorCard'

    export default {
        name: "Authors",
        components: {
            AuthorCard
        },
        data(){
            return {
                authors: []
            }
        },
        methods: {
            async fetchAuthors(){
                const res = await fetch('https://thetestrequest.com/authors')
                const data = await res.json()
                return data
            },
            showAuthor(authorId){
                console.log("Author Clicked", authorId);
            }
        },
        async created() {
            this.authors = await this.fetchAuthors()
        },
    }
</script>

<style lang="scss" scoped>
    .authors-list {
        margin-top: 2em;
        // transition: box-shadow .3s;

        a {
            text-decoration: none;
            color: black;
        }
    }
</style>

 

Примечание: Я использую thetestrequest.com чтобы получить данные для этого практического приложения.

Образцы пользовательского интерфейса:

домашняя страница

Страница авторов

Авторская страница

Домашняя страница с проблемой

Ответ №1:

Оказывается, в консоли была ошибка, которая помогла мне решить проблему.

Ошибка:

 AuthorDetail.vue?0959:6 Uncaught (in promise) TypeError: Cannot read property 'avatar' of null
    at Proxy.eval (AuthorDetail.vue?0959:6)
    at renderComponentRoot (runtime-core.esm-bundler.js?5c40:1168)
    at componentEffect (runtime-core.esm-bundler.js?5c40:5214)
    at reactiveEffect (reactivity.esm-bundler.js?a1e9:42)
    at effect (reactivity.esm-bundler.js?a1e9:17)
    at setupRenderEffect (runtime-core.esm-bundler.js?5c40:5167)
    at mountComponent (runtime-core.esm-bundler.js?5c40:5126)
    at processComponent (runtime-core.esm-bundler.js?5c40:5084)
    at patch (runtime-core.esm-bundler.js?5c40:4690)
    at componentEffect (runtime-core.esm-bundler.js?5c40:5287)
 

Поэтому простой v-if="avatar" AuthorDetail шаблон проверки внутри сделал для меня трюк.