【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向

文章目录

    • 原生实现路由
        • 实现效果:
        • 步骤:
    • Vue Router
    • 脚手架安装路由
    • 动态路由
      • 动态路由匹配⭐
      • 响应路由参数的变化
      • 捕获所有路由或 404 Not found 路由
    • 路由的匹配语法(了解)
      • sensitive与strict路由配置(了解)
      • 可选参数(了解)
    • 嵌套路由⭐
    • 编程式导航⭐
      • this.$router.push()
      • this.$router.repalce()
      • this.$router.go()
    • 命名路由(了解)
    • 命名视图(了解)
    • 重定向⭐
    • 别名

原生实现路由

Tips:路由的原理就是通过url的改变, 将相应的内容放在容器里面
点击实现页面跳转切换, 但是这和以前的页面跳转不一样, 以前是多个.html之间切换, 现在之后一个html文件, 所以我们只能进行页面中部分内筒切换(单页面引用)。动态组件每次点击url不会改变, 不考虑这种方法实现。路由每次点击页面时url会改变, 根据url的不同在页面上显示不同的内容。

实现效果:

  • url改变
  • 部分内容改变

步骤:

  1. 需要改变url的按钮, a标签, 由于一个页面内部切换所以页面不能刷新, #锚点在页面跳转时不会刷新, 同时能改变url又不会刷新
<p>
  <a href="#hot">热映a> | <a href="#cinema">影院a> |
  <a href="#wait">待映a> |
  <a href="#classic">经典电影a>
p>
  1. 需要一个存放切换内容的容器
<div id="box">div>
  1. 需要一个路由表, 就是一个数组, 里面每一项是对象, path, template
const routes = [
  {
    path: "hot",
    template: "
这是热映页面
"
, }, { path: "cinema", template: "
这是影院页面
"
, }, { path: "wait", template: "
这是待映页面
"
, }, { path: "classic", template: "
这是经典电影页面
"
, }, ];
  1. 监听url的改变, 监听hash值的改变, 通过hash值的改变触发相应的事件, 然后使用hash变量存储, 然后将hash值拿到和path作比对, 比对成功哪一项则将哪一项的template放到div容器里面
  • 拿到哈希值的方法是location.hash, 但是拿到的东西开头是带一个#, 所以要将#号去掉, 使用slice(1)方法从第二个字符串截取到末尾就拿到了哈希值
  • 注意一定要监听到hash值改变才会触发事件, 如果一直点击同一个链接则没有改变hash则不触发事件
window.addEventListener("hashchange", () => {
  // console.log("hash改变了");
  const hash = location.hash.slice(1);

  routes.forEach((item) => {
    if (item.path === hash) {
      document.querySelector("#box").innerHTML = item.template;
    }
  });
});

上述代码可见原生实现路由很麻烦, 所以vue官方提供了一个路由库Vue Router

Vue Router

官网路由https://router.vuejs.org/zh/introduction.html
路由不在脚手架安装也可以直接使用
可以直接使用cdn的方式引入路由
这里的vue3是通过CDN方式引入, 由于地址在国外可能会比较慢, 可以将代码复制到本地去引入, 注意这个网站有的cdn使用不了(可以往下找使用旧一点版本)
注意这里的vue3的使用的router4版本, 而vue2使用的是router3版本
Tips:
BootCDN极兔云官网https://www.bootcdn.cn/这个网站里面有大量的国内镜像资源, cdn是内容分发网络, 可以进入网站直接复制链接浏览器打开将源码复制下来在本地使用, 和vue的本地引入是一样的道理
HTML部分

<script src="https://unpkg.com/vue@3">script>
<script src="https://unpkg.com/vue-router@4">script>

<div id="app">
  <h1>Hello App!h1>
  <p>
    
    
    
    <router-link to="/">Go to Homerouter-link>
    <router-link to="/about">Go to Aboutrouter-link>
  p>
  
  
  <router-view>router-view>
div>

JavaScript部分

// 1. 定义路由组件.
// 也可以从其他文件导入
const Home = { template: '
Home
'
} const About = { template: '
About
'
} // 2. 定义一些路由 // 每个路由都需要映射到一个组件。 // 我们后面再讨论嵌套路由。 const routes = [ { path: '/', component: Home }, { path: '/about', component: About }, ] // 3. 创建路由实例并传递 `routes` 配置 // 你可以在这里输入更多的配置,但我们在这里 // 暂时保持简单 const router = VueRouter.createRouter({ // 4. 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式。 history: VueRouter.createWebHashHistory(), routes, // `routes: routes` 的缩写 }) // 5. 创建并挂载根实例 const app = Vue.createApp({}) //确保 _use_ 路由实例使 //整个应用支持路由。 app.use(router) app.mount('#app') // 现在,应用已经启动了!
  1. 上述代码定义了路由组件Home和About, 其中template里面的值放到容器
  2. 定义路由表routes
  3. 创建一个router实例, 这里原生的写法是使用addEventListener监听hashchange
  4. 这里是将路由表routes当做一个参数(变量)放到了路由实例里面, 实例里的routes是routes: routes的缩写, 左边的routes相当于一个选项, 不能随便更改。(由于是简写, 注意这里不能直接改routes, 如果要修改则改成routes: routes1)。这种创建实例的方法虽然没有使用addEventListener, 但是内部原理是一样的都是要监听
  5. 最后创建挂载实例多了一个app.use()方法, 这个方法在使用插件的方法一样, 意思就是把创建出来的实例router当做插件来使用

脚手架安装路由

  1. 安装脚手架,命令npm init vue@latest,记得安装router√
  2. 安装依赖, npm i 就能运行项目了

【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第1张图片

  • 安装完可以看到入口文件main.js多了两句话, 引入了router, 以及在使用路由之前app.use一下

【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第2张图片

  • 多了一个router文件和下面的index.js文件, 文件里面使用vue-router包里面解构createRouter方法创建了一个路由实例router, 创建出来之后就暴露给main.js

【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第3张图片
路由流程梳理:
在App里面加router-link和router-view标签,创建组件,这里的组件不再引入App.vue里面,而是引到路由表里面,通过每一个path去对应每一个组件。当我们点击router-link的时候路由就发生改变了,然后就会去路由表里面找对映的是哪个path,找到对应的path就去找对应的组件,将对应的组件放入router-view里面。

动态路由

动态路由匹配⭐

当我们做一个详情页面时(以猫眼电影为例子), 是根据详情页面的id去请求数据, 然后再渲染出来。
【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第4张图片
首先我们要知道如何获取到id。这是猫眼电影详情页的地址,可以看到地址栏url上有详情页的id,我们将这个id获取到,再拿这个 id做数据请求。
image.png
注意vue的路由默认是精准匹配,意思是说如果地址/后面还有东西就不能匹配到了。这里我们新建一个详情页path: “/detail/:id”,详情地址后面加上一个:id表示就是动态路由。这样我们在地址栏上写上其他东西页面也可以出来。

const router = createRouter({
  history: createWebHashHistory(import.meta.env.BASE_URL),
  // 精准匹配
  routes: [
    {
      path:"/",
      redirect:'/host'
    },
    {
      path: "/host",
      component: host,
    },
    {
      path: "/detail/:id",
      component: detail,
    },
  ],
});

获取动态路由参数, 通过this.$route.params.id获取动态路由, 这里的params.id就是路由表中的 :id

export default {
  created() {
    console.log(this.$route);
    this.id = this.$route.params.id;
  },
  watch: {
    $route(val, oldVal) {
      this.id = val.params.id;
    },
  },
};

这里的this. r o u t e 是一个对象 , 打印出来如下 , 可以看到对象里面有当前路径还有参数 i d , 我们把 t h i s . route是一个对象, 打印出来如下, 可以看到对象里面有当前路径还有参数id, 我们把this. route是一个对象,打印出来如下,可以看到对象里面有当前路径还有参数id,我们把this.route称之为当前页面的路由信息
【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第5张图片

响应路由参数的变化

Tips:这里我们添加了一个详情页2导航, 但我们在同一个路由不同参数的情况下跳转(也就是详情页跳转详情页), 这时候就无法监听到路由的改变触发相应的事件(created没有执行), 所以再次切换则不会打印。我们的需求还是一样只要地址改变就要做数据请求, 然后重新渲染。

  • 问题原因: 使用带有参数的路由时, 从/detail/23425导航到/detail/222222, 相同的组件实例将被重复使用, 因为两个路由都是同一个组件, 比起销毁在创建, 复用显得更高效。不过这也意味着生命周期钩子函数不会被调用
  • 解决问题:
    • 方法一: 我们使用watch去监听url的改变, 也就是监听$route的改变。这里需要注意watch里面的函数都可以拿到新值和旧值。再将拿到的新值给data。
    • 方法二: 使用导航守卫
<router-link to="/detail/23425">详情页|router-link>
<router-link to="/detail/222222">详情页2|router-link>
<template>
  <h2>详情-{{ $route.params.id }}</h2>
</template>
<script>
export default {
   data() {
    return {
      id: 0,
    };
  },
  created() {
    // fetch()
    console.log(this.$route);
    this.id = this.$route.params.id;
  },
  watch: {
    $route(val, oldVal) {
      //   console.log(val);
      //   console.log(oldVal);
      this.id = val.params.id;
    },
  },
};
</script>

【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第6张图片

捕获所有路由或 404 Not found 路由

  • 我们可以新建一个NotFound文件夹, 在路由表里添加path: “:pathMath(.)”, 引入NotFound组件。在vue2版本的时候直接写一个就行,这里vue3的路由4版本需要:pathMath(.)*,:表示动态参数,是什么都允许。
  • vue的路由是排他性路由: 表示路由从上往下开始匹配, 只要匹配到一个就停止。在做404页面时要把路由匹配path放在最后面, 意思是前面都没有匹配到直到匹配404。
  • react的5版本路由是包容性路由: 表示所有的都匹配, 如果匹配到多个就显示多个。

【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第7张图片

路由的匹配语法(了解)

  • :id动态路由后面可以加正则表达式(使用较少, 了解一下就好)。

sensitive与strict路由配置(了解)

  • 路由默认情况在是精准匹配,加了sensitive:true变成模糊匹配。

可选参数(了解)

  • path: "/detail/:id"后面加一个?表示动态可选路由,问号表示可加可不加正则的0和1

嵌套路由⭐

  • 顾名思义在路由里面写路由,例如当前页面有一个二级组件导航,二级组件里面又有三级组件导航,那么就需要使用路由嵌套。
  • 这里的path: "/host/today"路径可以使写成path: “today”, 相当于直接拼到/host的后面, 但是today不能再加/, 加了/表示表示根目录, 会无视前面的host
routes: [
{
      path: "/host",
      component: host,
      children: [
        {
          path: "/host/today",
          component: today,
        },
        {
          path: "/host/yesterday",
          component: yesterday,
        },
        
      ],
},
]

编程式导航⭐

Tips: 编程式导航可以用于一个导航下一级组件跳转到另一个导航下

  • 编程式导航通过js方式做跳转(通过事件)
  • router-link的跳转是声明式跳转
  • 多事情况下, router-link声明式导航和编程式导航是可以换着用。router-link会在点击时自动加上一个类型, 这个特点写导航高亮很方便。
  • 注意区分this. r o u t e 和 t h i s . route和this. routethis.router
    • this.$route表示的是当前页面的路由信息, 在获取动态参数时使用
    • this.$router表示的是整个路由实例, 在做跳转时使用

this.$router.push()

  • push方法是可以在历史记录里面追加, 它是可以后退的, 目前大部网页分都是使用push方法
  • 也可以使用对象的语法this.$router.push({ path: “/wait” });, 还有命名路由, 并加上参数, 还可以带查询参数, 还有可以带hash
<template>
  <h2>影院</h2>
  <button @click="pump">跳转到待映</button>
</template>

<script>
export default {
  methods: {
    pump() {
      this.$router.push("/wait");
      // this.$router.push({ path: "/wait" });
    },
  },
};
</script>

【Vue.js】vue3路由基础-动态路由、嵌套路由、编程式导航、重定向_第8张图片

this.$router.repalce()

replace方法是特换当前的历史记录, 后退时会跳过当前页面, 这是它与push的不同之处, 一般在登录页, 登录成功后点击历史回退时使用达到跳转首页效果

<script>
export default {
  methods: {
    pump() {
      this.$router.replace("/wait");
    },
  },
};
</script>

this.$router.go()

go方法是用于前进或者后退, 里面写整数

export default {
  methods: {
    pump() {
      this.$router.go("-1");
    },
  },
};
</script>

命名路由(了解)

在路由表中加上name属性,作用就是在做编程式导航或者router-link的时候后面可以使用对象。

命名视图(了解)

正常来说一个url对应一个组件,当一个url对应两个组件时, 我们将命名路由component改成components,在页面里面需要给router-view添加name属性。

    {
      path: "/wait",
      // component:wait
      components: {
        a: wait,
        b: wait2,
      },
  },

重定向⭐

路由重定向指的是:用户在访问地址 A 的时候,强制用户跳转到地址 C ,从而展示特定的组件页面;通过路由规则的 redirect 属性,指定一个新的路由地址,可以很方便地设置路由的重定向

routes: [
    {
      path: "/",
      redirect: "/host",
    },
    {
      path: "/host",
      component: host,
      children: [
        {
          path: "/host",
          redirect: "/host/today",
        },
        ]
    }
  ]

别名

alias表示别名,给路由导航添加两个名字,可以通过别面跳转页面。

{
      path: "/classic",
      component: classic,
      alias: "/jindian",
    },

image.png

你可能感兴趣的:(Vue.js,vue.js,javascript,前端)