【Vue Router】004-嵌套路由

1.4 嵌套路由(尚未解决)

1.4.1 概述

在实际应用场景中,一个界面 UI 通常由多层嵌套的组件组合而成, URL 中的各段也按某种结构对应嵌套的各层组件,比如每个用户页面下面都有 profile 和 posts 两个子组页面,路径 /user/:id 映射到对应的 User 组件,根据 ID 的不同显示不同的用户信息,ID 为 1 的用户点击 user/1/profile ,将在用户 1 的视图中渲染 profile 组件,点击 user/1/posts ,将在用户 1 的视图中渲染 posts 组件。

1.4.2 改造 Book.vue 组件(尚未解决)

第一步:创建 books.js 文件

用于模拟从后端请求到的图书的数据,真实场景中使用 Ajax 从后端请求数据

export default [
  { id: 1, title: 'Java 无难事', desc: '让你的 Java 学习再无难事!' },
  { id: 2, title: 'VC++ 深入理解', desc: '畅销 10 多年的图书!' },
  { id: 3, title: 'Servlet/JSP 深入理解', desc: '经典 JSP 图书!' }
]

第二步:修改 Books.vue 组件

<template>
  <div>
    <h3>图书列表</h3>
    <ul>
      <li v-for='book in books' :key="book.id">
        <router-link :to="'/book/' + book.id">{{ book.title }}</router-link>
      </li>
    </ul>
    <!-- 路由视图 -->
    <router-view />
  </div>
</template>

<script>
// 导入数据
import books from '@/assets/js/books.js'

export default {
  setup () {
    return { books }
  }
}
</script>

<style>
</style>

第三步:创建 Book.vue 组件

用户展示图书的具体信息

<template>
  <div>
    <p>图书id:{{ book.id }}</p>
    <p>书名:{{ book.title }}</p>
    <p>说明:{{ book.desc }}</p>
  </div>
</template>

<script>
// 导入数据
import books from '@/assets/js/books.js'
// 导入路由
import { useRoute } from 'vue-router'
// 导入监听器
import { watch } from 'vue'

export default {
  setup () {
    // 拿到路由
    const route = useRoute()
    // 从 books 中找到当前 id 的图书信息
    let book = books.find(item => item.id === route.params.id)
    // 监听参数中 id 的变化,更新图书信息
    watch(() => route.params.id, currentValue => {
      console.log(currentValue)
      book = books.find(item => item.id === currentValue)
    })
    return { books, book }
  }
}
</script>

<style>
</style>

第四步:修改 index.js 文件

import { createRouter, createWebHashHistory } from 'vue-router'
import Study from '../views/Study.vue'
import Home from '../views/Home.vue'
import News from '../views/News.vue'
import Books from '../views/Books.vue'
import Videos from '../views/Videos.vue'
import Book from '../views/Book.vue'
const routes = [
  {
    path: '/',
    component: Study,
    redirect: '/home',
    children: [
      {
        path: '/home',
        component: Home
      }, {
        path: '/news',
        component: News
      }, {
        // 本来我们就使用嵌套路由了,咋这里我们再次向下嵌套
        path: '/books',
        component: Books,
        children: [
          { path: '/books/:id', component: Book }
        ]
      }, {
        path: '/videos',
        component: Videos
      }
    ]
  }
]

const router = createRouter({
  history: createWebHashHistory(),
  routes
})

export default router

第五步:修改 Study.vue

<template>
  <router-link to="/">主页</router-link>
  <router-link to="/news">新闻</router-link>
  <router-link to="/books">图书</router-link>
  <router-link to="/videos">视频</router-link>
  <div>=================</div>
  <router-view />
</template>

<script>
export default {
  el: 'Study'
}
</script>

<style>
</style>

第六步:运行结果,踩坑

这么写 book = books.find(item => item.id === route.params.id) 找不到对应的图书数据,但是这么写 book = books.find(item => item.id === 1) 可以找到,离谱的是 console.log(route.params.id) 的输出结果是 1 ,也就是说使用真实的数字它就能找到,使用变量代替数字它就找不到!离谱!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1cmglvr8-1641036386276)(image-20210622102742667.png)]

将参数改成 1

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-76skqpCq-1641036386277)(image-20210622102930390.png)]

第七步:问题代码记录

<template>
  <div>
    <p>图书id:{{ book }}</p>
    <p>书名:{{ book }}</p>
    <p>说明:{{ book }}</p>
  </div>
</template>

<script>
// 导入数据
import books from '@/assets/js/books.js'
// 导入路由
import { useRoute } from 'vue-router'
// 导入监听器
import { watch, reactive } from 'vue'

export default {
  setup () {
    // 拿到路由
    const route = useRoute()
    // 从 books 中找到当前 id 的图书信息
    let book = reactive({})
    console.log('打印route.params.id: ' + route.params.id)
    console.log('find 中使用 route.params.id')
    book = books.find(item => item.id === route.params.id)
    console.log('查找图书结果:' + book)
    // 监听参数中 id 的变化,更新图书信息
    watch(() => route.params.id, currentValue => {
      console.log('当前值:' + currentValue)
      book = books.find(item => item.id === currentValue)
    })
    return { books, book }
  }
}
</script>

<style>
</style>

第八步:尝试解决问题(尚未解决)

上一篇:sql_demo


下一篇:今天踩了一个基础坑