vue-router
认识路由
路由就是通过互联的网络把信息从源地址传输到目的地址的活动。
后端渲染
通过jsp 直接在服务器解析,服务器渲染好HTML页面,通过url直接返回对应的页面。
后端路由
后端处理URL和页面的之间的映射关系。
前后端分离(前端渲染)
后端只负责提供数据,不负责任何阶段的内容。
前端路由
SPA页面:单页面富应用。整个网页只有一个html网页。
URL的hash
URL的hash也就是锚点(#),本质上就是改变window.location的href属性。
我们可以直接通过赋值location.hash来改变herf,但是页面不刷新。
地址栏会这样显示。
这种方法相当于入栈。
相当于出栈,返回上一次的页面。后入先出。
另一种方法加锚点
地址栏会这样显示。
replaceState不能返回页面
go(-1)相当于back,返回上一层
forward()相当于forward(),前进一层
安装和使用vue-router
安装
如果在创建项目时,已经创建了,就不用安装了。
npm install vue-router --save
在模块化工程中使用他(因为他是一个插件,所以可以通过vue.use()来安装路由功能)
第一步:导入路由对象,并且调用vue.use(vueRouter)
第二步:创建路由实例,并且传入路由映射配置
第三步:在Vue实例中挂载创建的路由实例
index.js
//导入一下vue,因为要用
import Vue from 'vue'
//导入路由
import Router from 'vue-router'
//导入要插件页
import HelloWorld from '@/components/HelloWorld'
//第一步,通过vue.use(插件)安装插件
Vue.use(Router)
//第二步,创建路由对象,并导出
export default new Router({
//routes配置组件和路由之间的应用关系
routes: [
//在这里配置映射关系,也可以单独抽离出去写
{
path: '/',
name: 'HelloWorld',
component: HelloWorld
}
]
})
main.js文件
import Vue from 'vue'
import App from './App'
//下面这个路径少了index.js,原因是他会自动选择index.js导入
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
//增强语法相当于router:router,挂载路由实例
router,
render: h => h(App)
})
使用Vue-router的步骤
第一步:创建路由组件
第二步:配置路由映射:组件和路径映射关系
第三步:使用路由:通过
<router-link to="/Home"></router-link>
<router-view></router-view>
创建组件
About.vue
<template>
<div>
<h2>我是关于</h2>
<p>哈哈哈哈</p>
</div>
</template>
<script>
export default ({
name:"About"
})
</script>
<style scoped>
</style>
home.vue
<template>
<div>
<h2>我是首页</h2>
<p>哈哈哈哈</p>
</div>
</template>
<script>
export default ({
name:"Home"
})
</script>
<style scoped>
</style>
index.js
导入组件,并且配置路由映射关系
//导入一下vue,因为要用
import Vue from 'vue'
//导入路由
import Router from 'vue-router'
//导入组件
import Home from '../components/Home.vue'
import About from '../components/About.vue'
//第一步,通过vue.use(插件)安装插件
Vue.use(Router)
//创建路由对象
export default new Router({
//routes配置组件和路由之间的应用关系
routes: [
//在这里配置映射关系,也可以单独抽离出去写,一个映射就是一个对象
{
path: '/Home',
//name: 'HelloWorld',
component: Home
},
{
path: '/About',
//name: 'HelloWorld',
component: About
}
]
})
main.js文件中要注册路由组件
import Vue from 'vue'
import App from './App'
//下面这个路径少了index.js,原因是他会自动选择index.js导入
import router from './router'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
//增强语法相当于router:router
router,
render: h => h(App)
})
App.vue中使用组件
<template>
<div id="app">
<router-link to="/Home">首页</router-link>
<router-link to="/About">关于</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App'
}
</script>
<style>
</style>
我是首页
哈哈哈
这是<router-view></router-view>
的作用,点击会切换。
路由的默认配置
默认情况下,进入首页,我们希望<router-view>
渲染首页内容。但是我们默认没有显示首页组件,必须用户点击才可以。
解决这种问题,只需多配置一个映射即可。
{
path: '/',
//redirect是重定向的意思,将根目录定向到/Home路径下,
//这就会有直接显示<router-view>的效果了
redirect: '/Home'
},
路由默认跳转方式为hash方式,非常难看。
修改方式:
在index.js文件中加入mode:'history'
router-link属性的补充
<router-link to='/home' tag='li'>
1.tag: tag可以指定<router-link>之后渲染成什么组件, 比如上面的代码会被渲染成一个<li>元素, 而不是<a>,也可以渲染成一个button标签。
2.replace: replace不会留下history记录, 所以指定replace的情况下, 后退键返回不能返回到上一个页面中
3.active-class: 当<router-link>对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active
的class, 设置active-class可以修改默认的名称.
这里默认生成了一个router-link-active类选择器,可以给他加属性,比如字体设为红色,这就是原生js中的排他思想。
这个类名有点长。可以在传入mode的时候一起传入一个linkActiveClass:‘active’,此时就会生成一个类名为active的选择器。
修改路由跳转
连点会报错,
vue-router 动态路由的使用
在页面的path路径可能是不确定的,比如我们进入用户界面,比如我们希望的路径
User/aaa或User/bbb,除了前面的user外,我们后面还跟上了ID.
注意这里动态绑定了一个数据
{
path: '/User/:UserId',
//name: 'HelloWorld',
component: User
}
这句话动态拼接,给to绑定来一个V-bind
<template>
<div id="app">
<router-link to="/Home" tag="button">首页</router-link>
<router-link to="/About" tag="button">关于</router-link>
<router-link :to="'/User/'+UserId" tag="button">用户页</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'App',
data () {
return {
UserId:"lisi"
}
},
组件User.vue的代码
<template>
<div>
<h2>我是用户页</h2>
<p>我是用户的相关信息,嘿嘿嘿</p>
<h2>{{UserId}}</h2>
</div>
</template>
<script>
export default {
name:'User',
computed: {
UserId(){
//params为参数的意思,router与route 不一样
//router 是路由器,是配置一些路由的
//route 是活跃的路由,当前谁活跃,拿选谁
return this.$route.params.UserId
}
}
}
</script>
<style>
</style>
路由的懒加载
//导入组件
//懒加载方式
const Home = () =>
import ('../components/Home.vue')
const About = () =>
import ('../components/About.vue')
const User = () =>
import ('../components/User.vue')
嵌套路由
比如在home页面中,我们希望通过/home/news和/home/message访问一些内容。一个路由映射一个组件,访问这两个路径也会分别渲染两个组件。
index.js文件中配置
{
path: '/Home',
//name: 'HelloWorld',
component: Home,
children: [{
path: '',
redirect: 'news'
},
{
path: 'news',
component: HomeNews
},
{
path: 'message',
component: HomeMessage
}
]
},
并导入所需的组件
const HomeNews = () =>
import ('../components/HomeNews.vue')
const HomeMessage = () =>
import ('../components/HomeMessage.vue')
整体为:
//导入一下vue,因为要用
import Vue from 'vue'
//导入路由
import Router from 'vue-router'
//导入组件
//懒加载方式
const Home = () =>
import ('../components/Home.vue')
const About = () =>
import ('../components/About.vue')
const User = () =>
import ('../components/User.vue')
const HomeNews = () =>
import ('../components/HomeNews.vue')
const HomeMessage = () =>
import ('../components/HomeMessage.vue')
//第一步,通过vue.use(插件)安装插件
Vue.use(Router)
//创建路由对象
export default new Router({
//routes配置组件和路由之间的应用关系
routes: [
//在这里配置映射关系,也可以单独抽离出去写,一个映射就是一个对象
//比较特殊的路径配置到上面
{
path: '/',
//redirect是重定向的意思,将根目录定向到/Home路径下,这就会有直接显示<router-view>的效果了
redirect: '/Home'
},
{
path: '/Home',
//name: 'HelloWorld',
component: Home,
children: [{
path: '',
redirect: 'news'
},
{
path: 'news',
component: HomeNews
},
{
path: 'message',
component: HomeMessage
}
]
},
{
path: '/About',
//name: 'HelloWorld',
component: About
},
{
path: '/User/:UserId',
//name: 'HelloWorld',
component: User
}
],
mode: 'history',
linkActiveClass: 'active'
})
在Home.vue组件中
<template>
<div>
<h2>我是首页</h2>
<p>哈哈哈哈</p>
<router-link to="/Home/news">新闻</router-link>
<router-link to="/Home/message">消息</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default ({
name:"Home"
})
</script>
<style scoped>
</style>
注意
路径的写法,与该代码所写的位置
<router-link to="/Home/news">新闻</router-link>
<router-link to="/Home/message">消息</router-link>
<router-view></router-view>
效果如下图
vue-router参数传递
index.js步骤:
引入组件
const Profile = () =>
import ('../components/Profile.vue')
配置路由映射关系,这是第一种配置方式,下面是第二种方式
{
path: '/Profile',
//name: 'HelloWorld',
component: Profile
}
在App.vue中这样配置
<router-link :to="{path:'/Profile',query:{name:'大灰狼',age:18,height:1.88}}">档案</router-link>
query内容为
注意
1.如果不使用v-bind的绑定的话,to不会认识对象。
2.不加**/**的话,会进行页面内容的叠加。
3.如果我们有大量的数据要传的话,用query,
这样拿到传递的参数
<h2>{{$route.query.name}}</h2>
导航守卫
在路由映射配置增加name
{
path: '/Profile',
name: '档案',
component: Profile,
}
前置钩子,(前置守卫)
然后增加守卫,那到name
router.beforeEach((to, from, next) => {
//从form跳到to
document.title = to.name
// document.title = to.matched[0].name
上边这句话是拿到嵌套路由的标题
next()
//一定要有next()这个函数
})
注意
next()的用法非常多。
1.next(false):中断当前导航,如果url改变了,,那么url就会地址就会重置到from路由对应的地址。
2.next(’/’):当前页面被中断,跳到一个不同的页面,比如next('/login')
跳到登录页面。
3.next(error):跳到错误页
路由独享守卫
可以在路由配置上直接定义 beforeEnter守卫:
但是这个为何进入不会显示页面原本的内容
{
path: '/About',
name: '关于',
component: About,
beforeEnter: (to, from, next) => {
console.log('我进来了!');
//这里如果不加next(),就不会往下走,控制台打印数据了,但是界面不会显示内容。
next()
}
},
打开这个路由的时候,直接打印我进来了。
组件内的守卫
可以在组件内直接定义以下路由导航守卫:
beforeRouteEnter
beforeRouteUpdate
beforeRouteLeave
keep-alive的使用
router-view是一个(view-router)组件,如果直接被包在keep-alive里面,所有路径匹配到的视图组件都会被缓存。
keep-alive是vue的内置组件,可以使被包含的组件保留状态,避免重新渲染。
keep-alive的两个重要属性
include:字符串或正则表达式,只有匹配的组件才会被渲染。
exclude:字符串或者正则表达式,任何匹配的组件都不会被渲染。
<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似
,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在父组件链中。
当组件在 <keep-alive> 内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数
将会被对应执行。
\color{red}{注意:只有当组件在 <keep-alive> 内被切换,才会有activated 和 deactivated
这两个钩子函数}
通过描述我们知道,它会缓存不活动的组件,而不是销毁。这样组件之间的切换就能保存上个组件的状态,
而不是切换之后又得重新操作。
作者:酸辣土豆丝g
链接:https://www.jianshu.com/p/0272c0fe9392
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
<keep-alive exclude="Profile,User"><router-view></router-view></keep-alive>
注意
如果我们想实现跳转到别的页面,回来还是显示消息界面,而不是显示新闻界面。这个需求我们应该怎么做?
在home.vue中添加下面这段生命周期函数
这段函数的意思是:离开时,自动记录活跃的路由路径,然后赋值给path。然后
activated () {
this.$router.push(this.path).catch(err=>err)
},
beforeRouteLeave (to, from, next) {
console.log(this.$route.path);
this.path=this.$route.path
next()
},