1. route 和 router 的区别
-
route:当前路由对象
-
$route:用来获取路由信息【路径、query、params 等等】
-
router:VueRouter 的实例对象
-
$router:用来操作路由,如进行编程式导航跳转【push|replace】
- 她包含了所有的路由、包括路由的跳转方法、钩子函数、子对象(history)
2. vue-router 怎么重定向页面
在路由中配置 redirect 属性
3. vue-router 怎么重定向
redirect 动态的话,在回调里面写逻辑判断
4. vue-router 怎么配置 404 页面
配置 path: '*' ,并且放到最后面。因为路由是从上往下执行的
5. vue-router 切换路由,需要保存草稿的功能,怎么实现
在 beforeRouteLeave 写逻辑
6. vue-router 路由有几种模式?区别
hash 模式
-
url 路径会出现 # 号字符
-
hash 值不包括在 Http 请求中,它是交给前端路由处理的。所以改变 hash 值不会刷新页面,也不会向服务器发起请求,所以这也是单页面应用的必备
-
hash 值的改变会触发 hashchange 事件
-
当我们进行刷新操作,或者直接输入浏览器地址时
- hash 路由会加载到地址栏对应的页面
- history 路由一般会 404 报错,(因为刷新是网络请求,没有后端准备时,会报错)
history 模式
-
history 运用了浏览器的历史记录栈,提供了对历史记录进行修改的功能
-
history 模式需要后台配置支持。
- 当我们刷新,或者输入浏览器地址的时候,就一定要向服务器发起请求
- 但是,如果这个目标不在服务器上,就会返回 404
-
hash 路由支持低版本浏览器,而 history 路由是 HTML5 新增的 API
7. 如果 vue-rouer 使用 history 模式,部署时需要注意什么
服务器的 404 页面需要重定向到 index.html
8. vue-router 有哪几种导航钩子(导航守卫)
- 钩子函数种类有:全局守卫、路由守卫、组件守卫
- 全局导航钩子:beforeEach(全局前置守卫)、beforeResolve(全局解析守卫)、afterEach(全局后置钩子)
- 路由独享的守卫:beforeEnter
- 组件内的守卫:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave
9. vue-router 完整的导航解析流程是什么
- 导航被触发
- 在失活的组件里调用
beforeRouteLeave守卫 - 调用全局
beforeEach守卫 - 在复用组件里调用
beforeRouteUpdate守卫 - 调用路由配置的
beforeEnter守卫 - 解析异步路由组件
- 在被激活的组件里面调用
beforeRouteEnter守卫 - 调用全局
beforeResolve守卫 - 导航被确认
- 调用全局的
afterEach钩子 - 触发
DOM更新 - 调用
beforeRouteEnter守卫中,传给 next 的回调函数,创建好的组件实例会作为回调函数的参数传入
10. vue-router 如何响应路由参数的变化
使用 watch 监听
- 1)监听路由路由是否变化 2)或者 设置路径变化时的处理函数
- 为了实现这样的效果可以给 < router-view > 组件中添加 key
<router-view :key="$route.fullPath"></router-view>
- $route.fullPath 是完成后解析的 URL,包含其查询参数信息和 hash 完整路径
使用组件内的守卫(钩子函数) beforeRouteUpdate (to, from, next){ }
- to : Route :表示 即将进入的目标 (路由对象)
- from : Route :表示:当前导航正要离开的路由
- next (可选参数): Function: 确保
next在任何给定的导航守卫中都被严格调用一次
11. 切换到新路由时,页面要滚动到顶部,或保持原先的位置,怎么实现
使用 scrollBehavior
12. 什么场景下使用嵌套路由
在页面点击不同的选项,需要切换不同的路由,来展示不同的内容时
13. 如何获取路由传入的参数
使用 params 方式传入的参数,使用 this.$route.params 接收
使用 query 方式传入的参数,使用 this.$route.query 接收
path、fullPath、hash 同上,this.$route.(path / fullPath / hash)
14. active-class 是哪个组件的属性
router-link
15. 在 Vue 组件中怎么获取当前的路由信息
this.$route
16. 怎么动态加载路由
使用 vue-router 的 addRoutes 方法
17. 怎么实现路由的懒加载
一般使用箭头函数的方法
components: () => import (' 组件路径 ')
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
routes: [
{ path: '/login', component: () => import('@/views/login/index.vue') },
{ path: '/home', component: () => import('@/views/home/home.vue') }
]
export default router
18. 简述一下怎么写一个 Vue 路由
- 先在 page 文件夹创建一个 .vue 文件,写相关逻辑
- 在 router.js 配置路由信息
- 在相应的页面使用
19. 路由之间是怎么跳转的?
-
< router-link to=" 跳转到指定的路径 " >
-
this.$router.push( )
- 跳转到指定的 URL ,并在 history 中添加记录,点击回退,返回到上一个页面
-
this.$router.replace( )
- 跳转到指定的 URL , 但不在 history 中添加记录,点击回退,返回到上上个页面
-
this.$router.go( n )
- 向前或者向后跳转 n 个页面,n 可为正整数或负整数
20. 创建路由
第一步:创建
- 在 views 文件夹下,创建 XXX.vue 文件
第二步:引入并注册
- 在 router / index.js 文件中
// 引入最基本的两个文件 Vue 和 VueRouter
import Vue from 'vue'
import VueRouter from 'vue-router'
// 引入组件
import LoginIndex from '@/views/Login/LoginIndex.vue'
// 1. 安装插件 VueRouter
// 2. Vue.use()函数的作用:使用插件
Vue.use(VueRouter)
// routes[] 的作用:定义 hash地址 与 组件 之间的对应关系
const routes = [
// 路由重定向
{
path: '/',
redirect: '/home'
},
// 注册路由
{
path: '/login', // 自己设置的路由路径
name: 'login', // 路由名称
component: LoginIndex, // 要展示的组件(引入组件的时候,命名的)
meta: { show: true } // 路由元信息
}
]
// 创建路由实例对象
const router = new VueRouter({
// 专门存放路由配置的数组
routes
})
// 对外暴露
export default router
第三步:使用
<router-link to="/login" target="_blank"><button>登录</button></router-link>
21. 路由传参的几种写法
定义
-
params 参数:属于路径的一部分,配置路由的时候,需要占位
{ path: 'goods/:id/:title' } // 相当于 $route 上的属性使用 {{ $route.params.id }} {{ $route.params.title }}
-
query 参数:不属于路径的一部分,类似于 Ajax 中的 queryString (/home?k=v&kv=),不需要占位
// 相当于 $route 上的属性使用 {{ $route.query.id }} {{ $route.query.title }}
使用时的3种方式
-
第一种:字符串形式
-
基本语法
this.$router.push("/search/" + params参数 + "?自定义名称=" + query参数 ); this.$router.push("/search/" + this.keyword + "?k=" + this.keyword.toUpperCase()); -
第二种:模板字符串, 较为方便
-
基本语法
this.$router.push(`/search/${ params参数 }? 自定义名称 =${ query参数 }`); this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`); -
第三种:对象,常用
-
基本语法
this.$router.push( {name【可以换成 path】:"路由组件名称", params:{自定义名称:this.keyword}, query:{自定义名称:this.keyword.toUpperCase()}} ); this.$router.push({name:"search", params:{keyword:this.keyword}, query:{k:this.keyword.toUpperCase()}}); this.$router.push({path:"search", params:{keyword:this.keyword}, query:{k:this.keyword.toUpperCase()}});
代码实现
// 在Header组件中
// 业务:点击搜索按钮,跳转到搜索页面,并将相关数据传递过去
<template>
<!-- 搜索栏 -->
<input type="text" placeholder="请输入关键字" v-model="keyword" />
<button class="btn-search" @click="gotoSearch">搜索</button>
</template>
<script>
export default {
name: "",
// 数据
data() {
return {
keyword: ''
}
},
// 方法
methods: {
// 跳转到搜索页
gotoSearch() {
// 路由传参
// 第一种:字符串形式
// this.$router.push("/search/" + this.keyword + "?k=" + this.keyword.toUpperCase());
// 第二种:模板字符串
// this.$router.push(`/search/${this.keyword}?k=${this.keyword.toUpperCase()}`);
// 第三种:对象
this.$router.push({name:"search", params:{keyword:this.keyword}, query:{k:this.keyword.toUpperCase()}});
}
},
};
</script>
样式:略
// router / index.js 文件
{ // 注册组件
path: '/search/:keyword', // 接收params参数,需要进行占位
name: 'search', // 设置名称,使用对象写法时,要用上
component: Search
}
路由传参相关面试题
路由传递参数(对象写法)path 是否可以结合 params 参数一起使用?
答:路由跳转传参的时候,对象写法有两种 name | path,但是 path 写法不能和 params 参数一起使用;name 写法可以
如何指定 params 参数可传可不传?
答:如果路由要求传递 params 参数,但是你就不传,URL 会有问题;
http://localhost:8080/#/?k=QWE
// 如果硬是不传params参数,会导致页面即使跳转到了 Search页面,但是路径却没有显示 “search”
若要指定 params 参数可以传递、或者不传递,在配置路由的时候,在占位的后面加上一个问号。
代码:
// 在配置路由的文件中 router/index.js
{
path: '/search/:keyword?', // 添加 ? 指定params参数可传,可不传
name: 'search',
component: Search
}
// 在对应的组件中
this.$router.push({name:"search", query:{k:this.keyword.toUpperCase()}});
params 参数可以传递也可以不传递,但是如果传递是空串,如何解决?
- 如果传递空串会出现上诉 “search” 丢失的路径问题
- 使用 undefined 解决 路径丢失的问题
this.$router.push({name:"search", params:{keyword:'' || undefined}, query:{k:this.keyword.toUpperCase()}});
this.$router.push({name:'search', params:{keyword:''||undefined}query:{k:this.keyword.toUpperCase()}});
路由组件能不能传递 props 数据?
- 可以,有三种写法。
第一种:布尔值写法【params】【只能传 params 参数】
// 在配置路由的文件
{
path: '/search/:keyword?', // 接收params参数,需要进行占位, ? 指定params参数可传,可不传
name: 'search',
component: Search,
props: true // 将 Search 组件设置成可以接收 props数据,但是只能传params参数
}
// 在 Search 组件
<template>
<div class="body">
<h1>我是搜索页</h1>
<h2>params参数---{{keyword}}</h2>
</div>
</template>
<script>
export default {
name: '',
props: ['keyword']
}
</script>
第二种写法:对象写法【额外给路由组件传递 props,而且是固定值】
// 在配置路由的文件中
{
path: '/search/:keyword?', // 接收params参数,需要进行占位, ? 指定params参数可传,可不传
name: 'search',
component: Search,
props: { a: 1, b: 2} // 对象写法,额外给路由组件传递的值,而且是固定值
}
// 在 Search 组件
<template>
<div class="body">
<h1>我是搜索页</h1>
<h2>额外传递的值----{{a}}-----{{b}}</h2>
</div>
</template>
<script>
export default {
name: '',
props: ['a', 'b']
}
</script>
第三种写法:函数写法【最常用,可以把 params 参数、query 参数,通过 props 传递给路由组件】
// 在配置路由的文件中
{
path: '/search/:keyword?', // 接收params参数,需要进行占位, ? 指定params参数可传,可不传
name: 'search',
component: Search,
// 函数写法
props: ($route)=> {
return {
keyword: $route.params.keyword,
k: $route.query.k
};
}
}
// 在 Search 组件
<template>
<div class="body">
<h1>我是搜索页</h1>
<h2>params参数------{{keyword}}</h2>
<h2>query参数---{{k}}</h2>
</div>
</template>
<script>
export default {
name: '',
props: ['keyword', 'k']
}
</script>