1. 什么是前端路由
- 路由在我们网站开发中非常常见
- 比如我们在学习html基本内容的时候学到的在一个地方设置锚链接,这个锚链接就是我们的前端路由,他会在地址栏中在所有url后面加上一个#井号,这样就可以保证所有的跳转只会在前端进行,而且Vue中的跳转不限于只是页面的滚动,展示指定的位置等等
- 我们将这个锚链接后面的内容称为哈希地址,这个哈希地址会指向一个位置,在我们点击的时候会根据url的改变去执行跳转的动作
- 在Vue中我们可以通过这种方式实现前端页面间进行跳转,而不用向服务器请求新的页面
- 这种方式也可以为页面传递参数,我们可以通过这种方式将一些特定的数据传输给其他页面
- 后端路由是用来分配后端资源的,而前端路由是用于页面之间跳转的
- 在spa应用程序中通过这种哈希的方式来实现页面的切换的方式我们就称为前端路由
2. Vue中实现路由
- 我们在Vue中实现路由需要用到Vue-router这一库,他也是依赖Vue的,因此需要在Vue导入完之后才能使用
- 安装命令为:npm install vue-router
- 之后在页面直接引用即可
- 使用Vue-router的方式一共有以下几个步骤:
-
- 引入包资源
-
- 创建一个路由对象,因为当我们在页面中引用它的资源包的是时候我们的Vue身上就有了一个Vue-router的构造函数,叫做VueRouter,也就是说我们需要用创建对象的方式来创建这个对象,当我们把资源包引进来之后我们的URL地址后面就会出现一个井号,后期我们将会使用这个特性来匹配路由规则
-
- 在创建的路由对象身上传入路由配置对象,也就是构建我们的路由表,其中有几个参数,第一个是routes对象,这个配置对象就是表示路由匹配规则,我们可以把我们定义的规则写道这个对象内部,这是个数组对象,其中的元素都是一个个对象,例如
{path:"/login",component:loginComp}
其中这里展示出来的两个属性是必须要的,也就是说我们需要直到路由名称,并且知道路由指向的组件
-
- 将创建好的路由对象挂载到我们的Vue实例身上,我们这时候可以将Vue实例中的route对象设置为我们定义的路由对象
-
- 在html页面中为路由对象留下一个占位符,使用这个标签来实现占位
-
- 使用超链接来进行切换,只要在超链接的herf属性中添加路由的地址,便可以在占位的地方展示路由的内容,注意,在herf中添加的时候需要在前面加上一个井号,如:
登陆组件展示
这样的方式来完成我们的设置
-
- 之后Vue将会监听url的变化,如果出现路由的话就便将路由所指向的内容展示到特定位置
html
登陆组件
注册组件
// 创建模板字符串变量,在这里必须要用这种方式创建完一次,之后再Vue实例上面构建一次
let logincomp = {
template: "#loginTemp",
data: function () {
return {
userName: 'xxxxx'
}
}
}
let registcomp = {
template: "#registTemp"
}
//创建路由对象
let router = new VueRouter({
//路由匹配规则
routes: [{
path: '/login',
component: logincomp
},
{
path: '/regist',
component: registcomp
}
]
})
let vm = new Vue({
el: '#app',
data: {
message: "yerts"
},
//注册组件
components: {
logincomp,
registcomp
},
//注册路由
router: router,
})
- 这里我们会想,只用在html文件里面声明一次,然后再Vue实例里面挂载不就可以了吗,但是我们发现这样做的话路由就会提示组件没有被声明,因此需要先将组件定义好,然后在Vue实例里面再挂载,再进行其他数据绑定操作
- 之后如果有父组件想要给子组件传值的话,也可以将内容直接放在router-view这个标签里面
3. router-link的使用
- 在上面的例子中我们每次给url地址加上跳转链接的时候都需要一个a链接,并且在href的前面加上#来实现跳转,这样做其实是很麻烦的,而且我们也控制其被选中的高亮提示也比较麻烦,因此vue-router提供了它自己的解决方案,就是router-link标签,这个标签类似于超链接标签,有自己的被选中类,我们可以通过设置这个类的样式轻松实现对被选中的标签的定制
- router-link它自带#在前面,因此使用这个会大大减少我们的工作量,只需要在其to属性上加上我们的路由地址即可完成跳转
html
- 我们可以控制router-link身上的router-link-active类来设置其被选中的样式
- 我们也可以通过设置其tag属性来改变其被渲染到页面的时候展示的标签的类型
- 同样我们也可以根据自己的需求来给这个类更改名称
- 我们可以在路由的配置选项中将linkActiveClass更改为我们自己想要的名称,之后我们对这个名称设置类的样式即可
直接给选中类设置样式
.router-link-active {
background-color: aquamarine;
}
设置路由对象的激活属性
//创建路由对象
let router = new VueRouter({
//路由匹配规则
routes: [{
path: "/",
redirect: '/login'
}, {
path: '/login',
component: logincomp
},
{
path: '/regist',
component: registcomp
}
],
linkActiveClass: "myActive"
})
.myActive {
background-color: aquamarine;
}
- 我们也可以在路由容器外部加上transition标签,添加我们的切换动画
- 用动画的mode属性完成先出去后进来等效果
4. 前端中的重定向redirect
- 在一些页面的首页默认进来的时候展示的内容会是一些我们在路由对象中已经定义过的一些内容
- 如果我们监听根路径的时候同样让其指向我们想要展示的组件的话会产生一个两个链接都指向同一个地方的错觉
- 为了解决这个问题,我们可以在路由配置表里面将根路径指向的内容上加一个redirect选项,并且将其值设置为我们想指向的内容
- 这样的话我们访问首页的话会自动跳转到login页面
5. 在路由里面定义参数
通过router-link中的to中加上参数来传递参数
- 定义路由的参数有两种方式
- 第一种是在路由的链接中在后面加上
/login?id=123&name=yerts
这类参数,这样的话就可以在组件内部通过this.$router.qurey.id
或者this.$router.qurey.name
来获取路由链接传递的参数,并且直接可以在组件内部使用这两个变量
登陆组件
{{userName}}----{{userId}}----{{parentMessage}}
注册组件
// 创建模板字符串变量,在这里必须要用这种方式创建完一次,之后再Vue实例上面构建一次
let logincomp = {
template: "#loginTemp",
data: function () {
return {
userName: 'xxxxx',
userId: 0
}
},
created: function () {
this.userName = this.$route.query.userName
this.userId = this.$route.query.userId
},
props: ["parentMessage"]
}
let registcomp = {
template: "#registTemp"
}
//创建路由对象
let router = new VueRouter({
//路由匹配规则
routes: [{
path: "/",
redirect: '/login'
}, {
path: '/login',
component: logincomp
},
{
path: '/regist',
component: registcomp
}
],
linkActiveClass: "myActive"
})
let vm = new Vue({
el: '#app',
data: {
message: "yerts",
messageForSon: "info"
},
//注册组件
components: {
logincomp,
registcomp
},
//注册路由
router: router,
})
- 这样操作带来的好处就是不用修改我们的path匹配规则,只需要在我们的link-to中加入我们的参数即可
- 同时也可以做到从一个路由获取数据发送到一个组件
通过params来传递参数
- 我们也可以在路由匹配规则中加上占位符,让路由在进行跳转的时候强制加上参数,一般占位符要写在我们的路由后面,并且都是冒号开头,后面跟跟上我们参数的名字如path:
'/login/:userName'
也就是说将来我们的login斜线后面的内容作为id来解析出来再后期进行使用
- 之后在进行跳转的时候我们在to属性的后面跟一个id就可以了
- 但是怎么将解析到的内容用到我们组件内部呢?
- 我们这个时候就可以使用$route对象的params属性了,这个属性里面就存放了我们解析得到的内容
登陆组件
{{userName}}----{{userId}}----{{parentMessage}}
{{userName}}
注册组件
let registcomp = {
template: "#registTemp",
data() {
return {
userName: ''
}
},
created() {
this.userName = this.$route.params.userName
},
}
//创建路由对象
let router = new VueRouter({
//路由匹配规则
routes: [{
path: "/",
redirect: '/login'
}, {
path: '/login',
component: logincomp
},
{
path: '/regist/:userName',
component: registcomp
}
],
linkActiveClass: "myActive"
})
6. children实现路由的嵌套
- 要知道当前我们创建的所有路由的规则都是平级的,也就是没有实现一个路由下面又嵌套了另一个路由这种
- 这种情况下我们需要在路由规则里面实现路由的嵌套
- 也就是说这样创建的都是平级的
// 定义一个账户组件
let account = {
template: "#accountTemp",
data() {
return {
}
},
methods: {
},
}
// 定义一个登陆组件
let login = {
template: "#loginTemp",
data() {
return {
}
},
methods: {
}
}
// 定义一个注册组件
let regist = {
template: "#registTemp",
data() {
return {
}
},
methods: {
},
}
// 定义路由规则
let router = new VueRouter({
routes: [{
path: "/",
redirect: '/account',
},
{
path: "/account",
component: account
},
{
path: '/login',
component: login
},
{
path: '/regist',
component: regist
}
],
linkActiveClass: 'myActive'
})
// 实例化一个vm实例
let vm = new Vue({
el: "#app2",
methods: {
},
data: {
},
comments: {
account,
login,
regist
},
router: router
})
Account
登陆
注册
- 现在我们要通过路由匹配规则中的children属性来添加子路由
- 在配置children属性的时候我们不用在path属性中加上一个斜线表示路由,直接加规则名称就可以了
- 之后的路由都会在父路由的基础上加上子路由作为后缀
- 我们也需要在组件内部为router-link跟router-view留出空位,以便之后的内容会展示在其位置
let router = new VueRouter({
routes: [{
path: "/",
redirect: '/account'
},
{
path: "/account",
component: account,
children: [{
path: 'login',
component: login
}, {
path: 'regist',
component: regist
}]
}
],
linkActiveClass: 'myActive'
})
// 实例化一个vm实例
let vm = new Vue({
el: "#app2",
methods: {
},
data: {
},
comments: {
account,
login,
regist
},
router: router
})
Account
账户组件
登陆
注册
7. 使用命名视图实现经典布局
- 我们发现之前我们使用的内容均为一个页面上面只显示一个组件,但是实际开发中一个页面会有很多组件
- 但是要知道我们所学的路由匹配规则中component只允许放一个内容
- 因此对component的操作就显得尤为重要,因此我们把我们的component升级为了components,这样我们就可以同时存放多个组件了
- 但是这样一想又来了一个问题,那就是怎么组织这些组件的位置,
- 因此我们在router-view的基础上对他的name属性进行了改造,我们可以把我们想要展示的组件指定一个属性,并把这个属性添加到name的参数里面,这样就可以完成我们的命名视图了
- 在components中有一个特殊的属性,那就是default属性了,这个属性对应的组件应当是只要又没有带name属性的router-view都要去展示的组件,下面将给出实现源码
// 定义头部组件
let header = {
template: "#headerTemp",
data() {
return {
}
},
methods: {
},
}
// 定义左侧组件
let leftPart = {
template: "#leftTemp",
data() {
return {
}
},
methods: {
}
}
// 定义右侧组件
let rightPart = {
template: "#rightTemp",
data() {
return {
}
},
methods: {
},
}
// 定义路由规则
let router = new VueRouter({
routes: [{
path: "/",
components: {
default: header,
left: leftPart,
right: rightPart
}
}
],
linkActiveClass: 'myActive'
})
// 实例化一个vm实例
let vm = new Vue({
el: "#app2",
methods: {
},
data: {
},
comments: {
header,
leftPart,
rightPart
},
router: router
})
左边
右边