初学Vue(五) -- 路由

学习列表

初学Vue(一)-- Vue简单入门

初学vue(二)-- 条件渲染、修饰符、循环

初学vue(三)-- 生命周期、过滤器、监听属性、计算属性

初学vue(四)-- axios前后端交互、组件


单页面应用程序

  • SPA : Single Page Application 单页面应用程序
  • MPA : Multiple Page Application 多页面应用程序
  • 单页 web 应用

    就是只有一个 web 页面的应用,
    是加载单个 HTML 页面,
    并在用户与应用程序交互时, 动态更新该页面的 web 应用程序

  • 区别

    • 对于传统的多页面应用程序来说, 每次请求服务器返回的都是一个完整的页面
    • 对于单页应用程序来说,

      只有第一次会加载页面,
      以后的每次请求,
      仅仅是获取必要的数据.然后,
      由页面中 js 解析获取的数据,
      展示在页面中

  • 单页面优势 :

    1. 减少了请求体积,加快页面响应速度,降低了对服务器的压力
    2. 更好的用户体验,让用户在 web app 感受 native app 的流畅, (局部刷新)
  • 单页面劣势 :

    1. 开发成本高 (需要学习路由)
    2. 不利于 SEO
  • 演示 : https://music.163.com/

介绍路由

  • 路由 : 是浏览器 URL 中的哈希值( # hash) 与 展示视图内容 之间的对应规则

    • 简单来说,路由就是一套映射规则(一对一的对应规则), 由开发人员制定规则.-
    • 当 URL 中的哈希值( # hash) 发生改变后,路由会根据制定好的规则, 展示对应的视图内容
  • 为什么要学习路由?

    • 在 web App 中, 经常会出现通过一个页面来展示和管理整个应用的功能.
    • SPA 往往是功能复杂的应用,为了有效管理所有视图内容,前端路由 应运而生.
  • vue 中的路由 : 是 hashcomponent 的对应关系, 一个哈希值对应一个组件

一 : 路由的基本使用

准备工作 (3个)

  • 安装 : npm i vue-router
  • 引入 :

// 千万注意 :引入路由一定要在引入vue之后,因为vue-router是基于vue工作的
  • 实例路由对象 + 挂载到vue上

    • 实例路由对象 : const router = new VueRouter()
    • 挂载到vue上 : new Vue({ router,data,methods })
    • 验证路由是否挂载成功, 就看打开页面,最后面有没有个 #/

具体步骤 (4个)

  • 1.入口
  • 2.路由规则
  • 3.组件
  • 4.出口
# 1. 入口
     // 方式1 : url地址为入口   调试开发用
     输入url地址 改变哈希值 `01-路由的基本使用.html#/one`    
     // 方式2 : 声明式导航 : router-link+to (见下面介绍)
# 2. 路由规则
// path : 路由路径
// component : 将来要展示的路由组件
routes: [
    { path: '/one', component: One }, 
    { path: '/two', component: Two }
]
# 3. 组件
// 使用返回值的这个组件名称
const One = Vue.component('one', {
  template: ` 
子组件 one
` }) # 4. 出口 # 总结 拿到入口哈希路径, 根据路由匹配规则,找到对应的组件,显示到对应的出口位置

二 : 由使用注意事项

  • 入口

    • 最常用的入口 是 声明式导航 router-link

首页
  • 组件
const One = {
  template: `
子组件 one
` }
  • 演示 : 多个组件匹配
One Two

三 : 入口导航菜单高亮处理

  • 点击导航 => 元素里添加了两个类
One
Two
  • 修改方式1 : 直接修改类的样式
.router-link-exact-active,
.router-link-active {
  color: red;
  font-size: 50px;
}
  • 修改方式2 : 使用存在过的类样式 => 修改默认高亮类名
const router = new VueRouter({
  routes: [],
  // 修改默认高亮的a标签的类名
  // red 是已经存在过的
  linkActiveClass: 'red'
})

四: 路由配置

4.1 动态路由 => 详情列表

导入 : 列表三个手机都要点击进去详情页, 只需要一个组件,显示不同的数据即可
# 入口
手机1
手机2
手机3

手机4  没有参数如何????

# 规则
routes: [
  // 2 . 路由规则
  { path: '/detail/:id?', component: Detail }
]

# 获取参数的三种方式
const Detail =  {
    template: `
        // 方式1 : 组件中直接读取
        
显示详情页内容....{{ $route.params.id }}
`, created() { // 方式2 : js直接读取 // 打印只会打印一次,因为组件是复用的,每次进来钩子函数只会执行一次 console.log(this.$route.params.id) }, // 方式3 : 监听路由的参数,为什么不需要深度监听,因为一个路径变化,就会对应一个对新的路由对象(地址变) watch: { $route(to, from) { console.log(to.params.id) } } }

4.2 路由对象 - $route

  • 一个路由对象 (route object) 表示当前激活的路由的状态信息,包含了当前 URL 解析得到的信息
  • 一个哈希值路径 ==> 一个路由对象
  • $route.path

    • 类型: string
    • 字符串,对应当前路由的路径,总是解析为绝对路径,如 "/foo/bar"
    • # 后面?前面的内容
  • $route.params

    • 类型: Object
    • 一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。
    • 一个 key/value 对象,包含了动态片段和全匹配片段,如果没有路由参数,就是一个空对象。
  • $route.query

    • 类型: Object
    • 参数对象
    • 一个 key/value 对象,表示 URL 查询参数。例如,对于路径 /foo?user=1,则有 $route.query.user == 1,如果没有查询参数,则是个空对象。
  • $route.hash

    • 类型: string

      当前路由的 hash 值 (带 #) ,如果没有 hash 值,则为空字符串。

  • $route.fullPath

    • 类型: string
    • 全路径
    • 完成解析后的 URL,包含查询参数和 hash 的完整路径。
# 演示 : 
detail
{ path: '/detail/:id?', component: detail } 
在组件内 created打印 this.$route
> fullPath: "/detail/4?id=001#one"
> hash : "#one"
> params : {id:'4'}
> query : {age : 21}
> path : '/detail/4'

4.3 嵌套路由 => children

导入 : url测试 parent 和child, 想让child 在 parent 中显示
  • parent 的内部 添加 :
  • 规则里添加 children
  • /child 和 child 的区别

    • 如果是/child => 那么访问就可以直接访问#/child就可以访问 子组件
    • 如果是child => 那么访问就应该访问#/parent/child才可以访问子组件
const parent = {
    template: `

parent

` } const child = { template: `

child

` } const router = new VueRouter({ routes: [ { path: '/parent', component: parent, children: [ { path: '/child', component: child } ] } ] })

4.4 命名路由

  • 有时候,通过一个名称来标识一个路由显得更方便一些,
  • 特别是在链接一个路由,或者是执行一些跳转的时候。 ===> 场景
  • 你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。 ==> 如何命名
# 命名
routes: [
    {
        path: '/parent',
        name: 'parent',
        component: parent
    }
]

# 入口链接 + 跳转  (使用 path 和 name 的转换)



点击
点击  # 忘了 带 : 原始对象类型


 fn() {
     // this.$router.push('/parent')
     this.$router.push({
         name: 'parent'
     })
 }

4.5 命名视图

导入 : 有时候想同时 (同级) 展示多个视图,

需求 : 访问 / 根目录 同时展示以下三个组件

  • 三个组件
const header = {
    template: `

header

` } const main = { template: `

main

` } const footer = { template: `

footer

` }
  • 规则
# 以前的那个方式只能显示三个 header
# 演示之前的效果 

routes: [
    {
        path: '/',
        components: {
            default: header,
            m: main,
            f: footer
        }
    }
]
  • 出口
 
 
 

4.6 重定向

redirect: '/header'
redirect: { name: 'header' }
redirect: to => {
      // console.log(to)
    return {
        name: 'about'
    }
}

4.7 组件传参

  • 原始方式使用 $route获取
# 入口
    123
# 规则
routes: [
    {
        path: '/header/:id',
        component: header,
    }
]
# 获取参数
const header = {
    template: `

header {{ $route.params.id }}

` }
  • 布尔模式
# 入口
    123

# 规则
routes: [
    {
        path: '/header/:id',
        component: header,
        // 如果 props 被设置为 true,route.params 将会被设置为组件属性
        props: true
    }
]

# 获取参数
const header = {
    // 参数 id 当成参数
    props: ['id'],
    template: `

header {{ id }}

` }
  • 对象模式
# 入口
 123

# 规则
 routes: [
     {
         path: '/header',
         component: header,
         props: { foo: '0000' }
     }
 ]
# 组件
 const header = {
        props: ['foo'],
        template: `

header {{ foo }}

` }
  • 函数模式
# 同对象模式一样
# 区别是props值不一样
 props: to => {
     return { foo: '0000' }
 }
  • 注意 : 对象模式和函数模式参数 在props里,所以声明式导航那里就不要传参了

4.8嵌套路由

实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件。

借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系。

  • 单层路由
const User = {
  template: '
User {{ $route.params.id }}
' } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ] })

这里的 是最顶层的出口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样可以包含自己的嵌套 。例如,在 User 组件的模板添加一个

  • 嵌套路由

    • 模板配置
    const User = {
      template: `
        

    User {{ $route.params.id }}

    ` }
  • 路由配置:要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置
const router = new VueRouter({
  routes: [
    { path: '/user/:id', component: User,
      children: [
        {
          // 当 /user/:id/profile 匹配成功,
          // UserProfile 会被渲染在 User 的  中
          path: 'profile',
          component: UserProfile
        },
        {
          // 当 /user/:id/posts 匹配成功
          // UserPosts 会被渲染在 User 的  中
          path: 'posts',
          component: UserPosts
        }
      ]
    }
  ]
})

注意,以 / 开头的嵌套路径会被当作根路径。 这让你充分的使用嵌套组件而无须设置嵌套的路径。

五 : 路由进阶

5.1 元信息

  • 规则声明
 routes: [
     {
         path: '/header',
         component: header,
         meta: {
            title: 'XXXX'
         }
     }
 ]
  • 获取
 created() {
    document.title = this.$route.meta.title
 }
  • 作用 :
  • 在路由导航的时候,可以用作判断

5.2 编程式导航

const one = {
    template: ` 
`, methods: { handleClick(type) { if (type == 'back') { // 返回 this.$router.back() } else if (type == 'push') { // 跳转 有历史记录 this.$router.push('/two') } else { // 替换 没有历史记录 this.$router.replace('/two') } } } } const two = { template: `

two

` }

5.3 导航守卫

router.beforeEach((to, from, next) => {
    // 访问 login

    if (to.name == 'login') {
        // 下一步
        next()
    } else {
        // 停止跳转
        next(false)
        // 跳转到下一步
        next({ name: 'login' }) 或者 使用路径  next('/login')
    }
})

你可能感兴趣的:(初学Vue(五) -- 路由)