路由
- 1.mvvm 框架是什么?
- 2.vue-router 是什么?它有哪些组件
- 3.active-class 是哪个组件的属性?
- 4.怎么定义 vue-router 的动态路由? 怎么获取传过来的值?
- 5.vue-router 有哪几种导航钩子?
- 6.`$route` 和 `$router` 的区别
- 7.vue-router的两种模式
- 8.vue-router实现路由懒加载( 动态加载路由 )
- 9.重定向页面
- 10.怎么配置404页面
- 11. 导航守卫流程
- 12.路由导航守卫和Vue生命周期钩子函数的执行顺序?
- 13.导航守卫三个参数的含义
- 14.afterEach 钩子中可以使用 next()?
- 15.全局导航守卫有哪些
- 16.组件内使用的导航守卫有哪些
- 17.对router-link的了解
- 18.在组件中监听路由参数变化
- 19.嵌套路由的使用
- 20.命名视图
- 21.获取路由传参
- 22.路由跳转的方式
- 23.使用history模式部署要注意什么
- 24.route和router区别
- 25.说一下你在vue中踩过的坑
1.mvvm 框架是什么?
答:vue是实现了双向数据绑定的mvvm框架,当视图改变更新模型层,当模型层改变更新视图层。在vue中,使用了双向绑定技术,就是View的变化能实时让Model发生变化,而Model的变化也能实时更新到View。
2.vue-router 是什么?它有哪些组件
答:vue用来写路由一个插件。router-link、router-view
3.active-class 是哪个组件的属性?
答:vue-router模块的router-link组件。children数组来定义子路由
4.怎么定义 vue-router 的动态路由? 怎么获取传过来的值?
答:在router目录下的index.js文件中,对path属性加上/:id。使用router对象的params.id。
5.vue-router 有哪几种导航钩子?
答:三种,
第一种: 是全局导航钩子:router.beforeEach(to,from,next),作用:跳转前进行判断拦截。
第二种: 组件内的钩子
第三种: 单独路由独享组件
6.$route
和 $router
的区别
答:$router
是VueRouter
的实例,在script标签中想要导航到不同的URL,使用 $router.push
方法。返回上一个历史history
用 $router.to(-1)
$route
为当前router
跳转对象。里面可以获取当前路由的name,path,query,parmas
等。
7.vue-router的两种模式
答:
hash模式: 即地址栏URL
中的#
符号;
// 监听hash变化,点击浏览器的前进后退会触发
window.addEventListener('hashchange', function(event){
let newURL = event.newURL; // hash 改变后的新 url
let oldURL = event.oldURL; // hash 改变前的旧 url
},false)
history模式: window.history
对象打印出来可以看到里边提供的方法和记录长度。利用了 HTML5 History Interface
中新增的pushState()
和 replaceState()
方法。(需要特定浏览器支持)。
8.vue-router实现路由懒加载( 动态加载路由 )
答:三种方式
第一种: vue
异步组件技术 ==== 异步加载,vue-router
配置路由 , 使用vue的异步组件技术 , 可以实现按需加载 .但是,这种情况下一个组件生成一个js文件。
第二种: 路由懒加载(使用import)。
第三种: webpack
提供的require.ensure()
,vue-router
配置路由,使用webpack
的require.ensure
技术,也可以实现按需加载。这种情况下,多个路由指定相同的chunkName
,会合并打包成一个js文件。
9.重定向页面
第一种:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' } // 可以是路径
]
})
第二种:
const router = new VueRouter({
routes: [
{ path: '/a', redirect: { name: 'foo' }} // 也可以是组件名
]
})
第三种:
const router = new VueRouter({
routes: [
{
path: '/a',
redirect: to =>{
const { hash, params, query } = to
if (query.to === 'foo') {
return { path: '/foo', query: null }
}else{
return '/b'
}
}
}
]
})
10.怎么配置404页面
const router = new VueRouter({
routes: [
{
path: '*', redirect: {path: '/'}
}
]
})
11. 导航守卫流程
- 导航被触发。
- 在失活的组件里调用离开守卫
beforeRouteLeave(to,from,next)
。 - 调用全局的
beforeEach( (to,from,next) =>{} )
守卫。 - 在重用的组件里调用
beforeRouteUpdate(to,from,next)
守卫。 - 在路由配置里调用
beforeEnter(to,from,next)
路由独享的守卫。 - 解析异步路由组件。
- 在被激活的组件里调用
beforeRouteEnter(to,from,next)
。 - 在所有组件内守卫和异步路由组件被解析之后调用全局的
beforeResolve( (to,from,next) =>{} )
解析守卫。 - 导航被确认。
- 调用全局的
afterEach( (to,from) =>{} )
钩子。 - 触发
DOM
更新。 - 用创建好的实例调用
beforeRouteEnter
守卫中传给next
的回调函数
beforeRouteEnter(to, from, next) {
next(vm => {
//通过vm访问组件实例
})
},
12.路由导航守卫和Vue生命周期钩子函数的执行顺序?
路由导航守卫都是在Vue实例生命周期钩子函数之前执行的。
13.导航守卫三个参数的含义
to:即将要进入的目标 路由对象。
from:当前导航正要离开的路由对象。
next:函数,必须调用,不然路由跳转不过去。
next():
进入下一个路由。
next(false):
中断当前的导航。
next('/')或next({ path: '/' }) :
跳转到其他路由,当前导航被中断,进行新的一个导航。
14.afterEach 钩子中可以使用 next()?
不可以,不接受next参数
15.全局导航守卫有哪些
router.beforeEach:全局前置守卫。
router.beforeResolve:全局解析守卫。
router.afterEach:全局后置钩子。
import VueRouter from 'vue-router';
const router = new VueRouter({
mode: 'history',
base: '/',
routes,
// 新页面滚动到顶部
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition;
} else {
return { x: 0, y: 0 };
}
}
router.beforeEach((to, from, next) => {
//...
next();
})
router.beforeResolve((to, from, next) => {
//...
next();
})
router.afterEach((to, from) => {
//...
});
16.组件内使用的导航守卫有哪些
beforeRouteLeave:在失活的组件里调用离开守卫。
beforeRouteUpdate:在重用的组件里调用,比如包含的组件。
beforeRouteEnter:在进入对应路由的组件创建前调用。
beforeRouteLeave(to, from, next) {
//...
},
beforeRouteUpdate(to, from, next) {
//...
},
beforeRouteEnter(to, from, next) {
//...
},
17.对router-link的了解
<router-link>
是Vue-Router的内置组件,在具有路由功能的应用中作为声明式的导航使用。
<router-link>
有8个props,其中几个作用是:
- to:必填,表示目标路由的链接。当被点击后,内部会立刻把 to 的值传到router.push(),所以这个值可以是一个字符串或者是描述目标位置的对象。
<router-link to="home">Home</router-link><router-link :to="'home'">Home</router-link><router-link :to="{ path: 'home' }">Home</router-link><router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link><router-link :to="{ path: 'user', query: { userId: 123 }}">User</router-link>
注意path存在时params不起作用,只能用query
replace
:默认值为false,若设置的话,当点击时,会调用router.replace()
而不是router.push()
,于是导航后不会留下 history 记录。append
:设置 append 属性后,则在当前 (相对) 路径前添加基路径。exact
:是否精确匹配,默认为false。
<!-- 这个链接只会在地址为 / 的时候被激活 -->
<router-link to="/" exact></router-link>
- event
:声明可以用来触发导航的事件。可以是一个字符串或是一个包含字符串的数组,默认是click。
18.在组件中监听路由参数变化
有两种方法可以监听路由参数的变化,但是只能用在包含<router-view />
的组件内。
第一种 watch
watch: {
'$route'(to, from) {
//这里监听
},
},
第二种 beforeRouteUpdate
beforeRouteUpdate (to, from, next) {
//这里监听
},
19.嵌套路由的使用
比如管理系统,顶部栏和左侧菜单栏是全局通用的,那就应该放在父路由,而右下的页面内容部分放在子路由。
//app.vue
<template>
<div>
<router-view/>
</div>
</template>
//layout.vue
<template>
<div>
<div>
//...头部导航
</div>
<div>
//...侧边栏导航
</div>
<div>
//...主内容
<router-view/>
</div>
</div>
</template>
20.命名视图
比如想同级展示多个视图,而不是嵌套展示。例如项目首页,有头部导航,侧边栏导航、主内容区域。头部导航、侧边栏导航我们不想用组件方式引入,想用视图方式展示。那么这个首页上,就有三个视图,头部导航视图,侧边栏导航视图、主内容区域视图同级展示。
//layout.vue
<template>
<div>
<div>
//...头部导航
<router-view name='header'></router-view>
<div>
//...侧边栏导航
<router-view name='sider'></router-view>
</div>
<div>
//...主内容
<router-view/>
</div>
</div>
</template>
如果 router-view 没有设置name,那么默认为default。一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (记得加上s)。
//router.js
function load(component) {
return resolve => require([`views/${component}`], resolve);
}
const routes=[
{
path: '/',
redirect: '/home',
name: 'layout',
component: load('layout'),
children: [
{
path: '/home',
name: 'home',
components: {
default: load('main'),
header: load('header'),
sider: load('sider')
},
meta: {
title: '首页'
},
},
]
}
]
21.获取路由传参
- query:
this.$route.push({
path:'/home',
query:{
userId:123
}
})
- params:
- 首先要在地址上做配置
{ path: '/home/:userId', name: 'home', component: load('home'), meta: { title: '首页' }, },
- 访问传参
const userId = '123' this.$router.push({ name: 'home', params: { userId } })
- 浏览器地址:
http://localhost:8036/home/123
(4) 获取方式:this.$route.params.userId
路由传参
- 路由配置
// 路由配置
{
path: '/detail/:id',
name: 'Detail',
component: () => import('./Detail.vue')
}
// 路由跳转
let id = 1
this.$router.push({ path: '/detail/${id}'})
// 获取参数
this.$route.params.id
- URL 虽然不显示我们的传参,但是是可以在子组件获取参数的。当然也有问题:会存在刷新丢失参数。若想不丢失,需和方案一路由配置一样。原因是第二种方式传参是上一个页面 push 函数中携带的,刷新没有 push 的动作。
// 路由配置
{
path: '/detail',
name: 'Detail',
component: () => import('./Detail.vue')
}
// 路由跳转
let id = 1
this.$router.push({ name: 'Detail', params: { id: id } })
// 获取参数
this.$route.params.id
- 路由配置
// 路由配置
{
path: '/detail',
name: 'Detail',
component: () => import('./Detail.vue')
}
// 路由跳转
let id = 1
this.$router.push({ name: 'Detail', query: { id: id } })
// 获取参数
this.$route.query.id
22.路由跳转的方式
- 声明式 通过使用内置组件
<router-link :to="/home">
来跳转 - 编程式 通过调用router实例的push方法
router.push({ path: '/home' })
或replace方法router.replace({ path: '/home' })
this.$touter.go(n)
向前或者后跳转n个页面,n可以是正数也可以是负数
23.使用history模式部署要注意什么
要注意404的问题,因为在history模式下,只是动态的通过js操作window.history来改变浏览器地址栏里的路径,并没有发起http请求,当直接在浏览器里输入这个地址的时候,就一定要对服务器发起http请求,但是这个目标在服务器上又不存在,所以会返回404。
所以要在Ngnix中将所有请求都转发到index.html上就可以了。
24.route和router区别
route是“路由信息对象”,包括path,params,hash,query,fullPath,matched,name等路由信息参数。
而router是“路由实例对象”,包括了路由的跳转方法,钩子函数等。
25.说一下你在vue中踩过的坑
1、第一个是给对象添加属性的时候,直接通过给data里面的对象添加属性然后赋值,新添加的属性不是响应式的
【解决办法】通过Vue.set(对象,属性,值)这种方式就可以达到,对象新添加的属性是响应式的
2、 在created操作dom的时候,是报错的,获取不到dom,这个时候实例vue实例没有挂载
【解决办法】通过:Vue.nextTick(回调函数进行获取)