Vue 路由入门

Vue是一个单页面应用程序框架,所有功能都在一个html页面上。内容根据需求按需加载组件,提升性能和开发效率。但是也带来了比较差的SEO(无法根据具体内容提供个性化的SEO)。

问题1 : Vue又是如何做到 按需加载 更新页面的呢?

首先,要确定的就是 组件访问路径 之间的对应关系。

问题2 : 组件访问路径 的对应关系是如何确定的呢?

这就要来看看我们今天的主题 路由 了。

路由

  • 介绍

路径组件映射 关系。根据这个 映射关系,就可以知道访问的路径 应该 渲染 哪个组件

  • 作用

修改 地址栏路径时,切换显示匹配的组件

  • Vue 官方的路由插件

本文我们由浅入深,先从VueRouter开始着手,了解路由,掌握VueRouter的基本使用。

VueRouter

  • 使用
  1. 下载 VueRouter 模板到项目中。例如:3.6.5版本
javascript 复制代码
npm i [email protected]

2、引入 + 注册 + 创建路由对象

javascript 复制代码
// router/index.js文件
import Vue from 'vue'
import Router from 'vue-router' // 引入

Vue.use(Router) // 注册

const router = new Router()

3、注入,将路由对象注入到 new Vue 实例中,建立关联

javascript 复制代码
import router from './router'

new Vue({
  el: '#app',
  router,
  render: h => h(App)
})

4、创建需要的组件(views 目录),配置路由规则

javascript 复制代码
const router = new Router({
    routes: [
        {
            path: '/publish-manage',
            component: Layout,
            redirect: '/publish-manage/wechat', // 路由重定向
            meta: { title: '发布管理', icon: 'guide' },
            alwaysShow: true,
            children: [
              {
                path: 'wechat', // 地址栏的路径
                name: 'wechat',
                component: () => import('@/views/publish-manage/wechat-graphic/index'), // 异步引入组件
                meta: { title: '微信图文管理' }
              },
              {
                path: 'weibo',
                name: 'weibo',
                component: () => import('@/views/publish-manage/weibo/index'),
                meta: { title: '微博发布' }
              },
            ]
        }
    ]
})
  • 路由模块:将路由按模块拆分,利于维护。

绝对路径:@ 指代 src目录,可以用于快速引入组件。而不是一层一层./../../的形式往上查找。

  • 路由导航

    • 声明式导航 ------ 导航链接

    vue-router 提供一个全局组件 router-link,用于替换 a标签

    • router-link 语法

      <router-link to='/路径值' />

      必须传入 to 属性 来 指定路由路径值

    • router-link 高亮 自动给当前导航添加 两个类名

      router-link-active 模糊匹配(一般用的多)

      router-link-exact-active 精准匹配

    • 跳转传参

      1、传参数:to='/path?参数名=值'

      2、接收参数:$route.query.参数名

    • 动态路由传参

      1、配置动态路由

      javascript 复制代码
      {
          path: '/search/:words?', // ? 表示参数可选
          component: Search
      }

      2、配置导航链接: to='/path/参数值'

      3、接收参数:$route.params.参数名

  • 路由重定向 redirect

说明

重定向 → 匹配path后,强制跳转 path 路径 到 redirect 指向的路径

语法

javascript 复制代码
{
    path: 匹配路径,
    redirect: 重定向到的路径
}
  • 路由 404

作用:当路径找不到匹配时,给个提示页面。

位置:配在路由最后

语法path: '*'

  • 表示 任意路径,当前面的路由都没有匹配到时,命中这个。从而展示给用户自定义的404页面

路由模式

通过 hashhistory 两种方式实现前端路由,更新视图但不重新请求页面 是前端路由原理的核心之一。

  • 路由的两种模式

    • hash路由 :本质是利用URL 中的hash,路径中携带 #

    原理: 监听路由变化(onhashchange事件),只有#后面的地址发生变化,可以在 windows 对象上监听这个事件:

    javascript 复制代码
    window.onhashchange = function (e) {
      let hash = location.hash; // 通过location对象获取hash地址,地址从#开始  
    }
    // onhashchange 事件在当前url的锚部门(以#开始)

    因为 hash 发生变化的 url 都会被浏览器记录下来,从而浏览器的前进后退都可以使用。 hashchange 只能改变 # 后面的 url片段

    • history路由

    history api 给了前端完全的路由history api 可以分为两大部分:切换修改

    注意:history 模式下,可以自由的修改path,但是history 模式最终的路由都体现在 urlpathName 中,这部分是会传到服务器的,因此需要服务端对每一个可能的path值都作相应的映射当刷新时,如果服务端没有相应的响应或者资源,页面就会404

    1、切换历史状态:包括backforwardgo 三个方法

    javascript 复制代码
    history.go(-2); // 后退两次
    history.go(2); // 前进两次
    histor.back(); // 后退
    history.forward(); // 前进

    2、修改历史状态:包括 pushStatereplaceState两个方法, 这两个方法接受三个参数: stateObj, title, url

    • 两种路由模式的区别

    1、前面的 hashchange 只能修改 # 后面的 Url 片段,而 history,可以通过pushState或者 replaceState设置与当前Url同源的任意Url

    2、history 模式会将Url修改的和正常请求后端的Url一样,如果后端没有配置对应的路由处理,则会返回404错误,当用户刷新页面时,浏览器会向服务器发送请求,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。

路由跳转

有两种语法:path路径跳转 和 name命名路由跳转

javascript 复制代码
// 不带参数跳转
this.$router.push('路由路径')
this.$router.push({ path: '路由路径' })

this.$router.push({ name: '路由名' }) // 适合path路径较长的场景
// 例如:路由配置 -> { name: '路由名', path: '路由路径', component: 组件 }

// 带参数跳转

//`path路径`跳转 通过 `query传参`
this.$router.push('路由路径?参数1=参数值1&参数2=参数值2')
this.$router.push({
    path: '/路由路径',
    query: {
        参数1: 参数值1,
        参数2: 参数值2
    }
})
//取参:
      模板中 -> `$route.query.参数名`
      script行为中 -> `this.$route.query.参数名`

//`动态路由`跳转传参
this.$router.push('/路由路径/参数值')
this.$router.push({ path: '/路由路径/参数值' })
// 取参: 
      模板中 -> `$route.params.参数名`
      script行为中 -> `this.$route.params.参数名`
      
//`name命名路由` 跳转传参
this.$router.push({
    path: '路由名',
    query: {
        参数1: 参数值1,
        参数2: 参数值2
    }
})
// 取参: 
      模板中 -> `$route.query.参数名`
      script行为中 -> `this.$route.query.参数名`
      
this.$router.push({  // 只有 name命名路由 跳转有
    path: '路由名',
    params: {
        参数1: 参数值1,
        参数2: 参数值2
    }
})
// 取参: 
      模板中 -> `$route.params.参数名`
      script行为中 -> `this.$route.params.参数名`

this.$router.replace() 路由替换,与 this.$router.push 用法一致。

区别:

this.$router.push() :跳转到指定url路径,并向history栈中添加一个记录

点击回退会返回到上一个页面。

this.$router.replace() :跳转到指定url路径,但是history栈中不会有记录

点击返回会跳转到上上个页面(就是直接替换了的页面)

this.$router.go(n) : 向前或向后跳转n个页面,n可为正整数或负整数。正整数 前进,负整数后退

组件缓存keep-alive

问题: 从列表到详情,又返回列表,数据重新加载 → 希望回到原来的位置,不重新加载数据

原因: 路由跳转后,列表组件销毁了,返回回来组件又重建了,所以数据重新加载了。

解决方案: 利用keep-alive将组件缓存下来

1、keep-alive是什么?

keep-aliveVue内置组件,当它 包裹 动态组件 时,会 缓存不活动的组件实例,而不是销毁它们。

keep-alive它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。

2、keep-alive优点

在组件切换的过程中,把切换出去的组件保留在内存中,防止重新渲染DOM,可以减少加载时间喝及性能消耗,提高用户体验性。

3、keep-alive原理

created 函数调用时将需要缓存的 VNode 节点保存在 this.cache 中/在 render(页面渲染) 时,如果 VNodename 符合缓存条件(可以用 include 以及 exclude 控制),则会从 this.cache 中取出之前缓存的 VNode 进行渲染。

VNode虚拟DOM,其实就是一个JS对象

4、keep-alive使用

参数名 描述
include 字符串或正则表达式 只有名称匹配的组件才会被缓存
exclude 字符串或正则表达式 任何名称匹配的组件都不会被缓存
max 数字 最多可以缓存多少组件实例

include/exclude值 是组件中的 name 命名,而不是 路由名

javascript 复制代码
// 缓存 组件名 为 test 的组件
<keep-alive include='test'>
    <router-view />
</keep-alive>

// 缓存 组件名 为 a 或 b 的组件
<keep-alive include='a, b'>
    <router-view />
</keep-alive>

// 使用正则表达式, 需要用v-bind
<keep-alive :include='/a|b/'>
    <router-view />
</keep-alive>

// 动态判断
<keep-alive :include='/a|b/'>
    <router-view />
</keep-alive>

// 与 transition  一起使用
<transition>
    <keep-alive :include='/a|b/'>
        <router-view />
    </keep-alive>
</transition>

// 使用数组, 需要用v-bind
<keep-alive :include='["a", "b"]'>
    <router-view />
</keep-alive>

5、keep-alive触发的生命周期

  • activated 当组件被激活(使用)的时候触发 → 进入这个页面的时候触发
  • deactivated 当组件不被使用的时候触发 → 离开这个页面的时候触发

组件缓存后,就不会执行 createdmounteddestroyed等钩子函数

不同情况钩子函数执行情况:

javascript 复制代码
不同情况钩子函数执行情况:
// 不使用 keep-alive
`beforeRouteEnter` → `created` → `mounted` → `destroyed`

// 使用 keep-alive
`beforeRouteEnter` → `created` → `mounted` → `activated` → `deactivated`
// 再次进入缓存的页面,
只会触发
`beforeRouteEnter` → `activated` → `deactivated` 。`created` 和`mounted`不会再执行。
相关推荐
A_ugust__18 分钟前
Vue3.2 项目打包成 Electron 桌面应用
javascript·vue.js·electron
恋猫de小郭19 分钟前
JetBrains Terminal 又发布新架构,Android Studio 将再次迎来新终端
android·前端·flutter
夕秋一梦1 小时前
vue项目本地调试使用https
前端·vue.js·https
小破孩呦1 小时前
动态列表的数据渲染、新增、编辑等功能开发及数据处理
前端·javascript·elementui
成长ing121381 小时前
点击音效系统
前端·cocos creator
熟悉不过1 小时前
cesium项目之cesiumlab地形数据加载
前端·javascript·vue.js·cesium·webgis·cesiumlab
神经毒素2 小时前
WEB安全--XSS--DOM破坏
前端·web安全·xss
爱写代码的小朋友2 小时前
PHP+Vue 3实现增删改查(CRUD)
开发语言·vue.js·php
Selicens2 小时前
VSCode Snippets 魔改专属的 vue 代码片段
vue.js·visual studio code