路由的配置
既然说到了路由,第一步肯定是和组件一样的,需要先进行配置,这里的配置我建议是在router
目录下在创建个index.js
文件,里面来放置路由的配置内容。
javascript
// 0. 导入 Vue 和 VueRouter,要调用 Vue.use(VueRouter)
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
// 1. 定义 (路由) 组件。
// 可以从其他文件 import 进来
//注意哈,这里路由组件不是在component目录下的,而是在vies目录下。
import Foo from "./views/Foo.vue";
import Bar from "./views/Bar.vue";
// 2. 定义路由
// 每个路由应该映射一个组件。 其中"component" 可以是
// 通过 Vue.extend() 创建的组件构造器,
// 或者,只是一个组件配置对象。
// 我们晚点再讨论嵌套路由。
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 3. 创建 router 实例,然后传 `routes` 配置
// 你还可以传别的配置参数, 不过先这么简单着吧。
export default new VueRouter({
mode:'history', // 这个history作用说白了就是路径不用加'#'了。
routes // (缩写) 相当于 routes: routes
})
另外,我们还需要在main.js
文件里面注入路由,即:
xml
<template>
<div id="app">
<h1>Hello App!</h1>
<p>
<!-- 使用 router-link 组件来导航. -->
<!-- 通过传入 `to` 属性指定链接. -->
<!-- <router-link> 默认会被渲染成一个 `<a>` 标签 -->
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<!-- 路由出口 -->
<!-- 路由匹配到的组件将渲染在这里 -->
<!-- App.vue 中的 <router-view></router-view> 是路由的最高级出口 -->
<router-view></router-view>
</div>
</template>
添加路由
我们写网页时,肯定还需要添加更多的路由,那么添加路由非常简单,看下图即可:
javascript
// 1. 将要用到的组件从其他文件 import 进来
import Foo from './views/Foo.vue';
import Bar from './views/Bar.vue';
import User from './views/User.vue';
// 2. 定义路由,每个路由应该映射一个组件
// 添加路径即在 routes 数组中增加新的成员
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar },
// 新增一项
{ path: '/user', component: User }
];
// 3. 创建 Router 实例,然后传 `routes` 配置
export default new VueRouter({
mode:'history', // 这个history作用说白了就是路径不用加'#'了。
routes // (缩写) 相当于 routes: routes
})
当然啦,嫌弃上面麻烦我们还有更简单的方法,看代码:
javascript
const routes = [
{ path: '/foo', component: () => import('./views/Foo.vue') },
{ path: '/bar', component: () => import('./views/Bar.vue') },
{ path: '/user', component: () => import('./views/User.vue') }
];
命名路由
有时候我们在<router-link to="/foo"></router-link>
标签中会发现使用to
属性太过于麻烦,我们可以给某个路由设置名称:
javascript
// 0. 导入 Album、List、Add、Empty 三个组件
// 1. 定义路由
const routes = [
{ path: '/foo',
name: 'fooName',
component: () => import('./views/Foo.vue')
}
];
通过命名跳转:
xml
<!-- to 的值是一个对象而不是字符串,所以要在 to 前加 : -->
<!-- 这里依旧是外双内单 -->
<router-link :to="{name: 'fooName'}">Go to Foo</router-link>
路由布局的管理
我们在写项目有的时候只有功能区的组件发生了变化:
首先,我们肯定是需要先定义嵌套路由
yaml
// 0. 导入 Album、List、Add 三个组件
const routes = [
{
path: '/album',
component: Album,
// children 属性可以用来配置下一级路由(子路由)
children: [
{ path: 'list', component: List },
{ path: 'add', component: Add }
]
}
];
我们看下例子,配合<router-view></router-view>
使用即可:
App.vue 组件:
xml
<template>
<div id="app">
<h1>Hello App!</h1>
<p>
<router-link to="/album/list">Go to Album List</router-link>
|
<router-link to="/album/add">Go to Album Add</router-link>
</p>
<!-- 路由匹配到的组件将渲染在这里 -->
<!-- 在本例中为 Album.vue 组件 -->
<!-- 在本例子中对应的是第一层路由-->
<router-view></router-view>
</div>
</template>
Album.vue 组件:
xml
<template>
<div id="album">
<div class="banner">banner</div>
<!-- 路由匹配到的组件将渲染在这里 -->
<!-- 在本例中为 List.vue 组件或 Add.vue 组件 -->
<!-- 在本例子中对应的是第二层路由-->
<router-view></router-view>
</div>
</template>
根路径
在上面的定义嵌套路由
例子中,我们可以将子路由更改为以下效果也是一样的:
lua
//下面的两种情况其实是一样的。
path: 'list'
path: '/album/list'
空的子路由
如果我们在/album
的路径下依旧想要渲染一些东西,那么我们就可以在嵌套路由里面再添加一个空的子路由,如下所示:
yaml
// 0. 导入 Album、List、Add、Empty 三个组件
const routes = [
{
path: '/album',
component: Album,
// children 属性可以用来配置下一级路由(子路由)
children: [
// 空的子路由
{ path: '', component: Empty },
{ path: 'list', component: List },
{ path: 'add', component: Add }
]
}
];
动态路由
动态路由说白了就是多个路径都映射到了同一个组件中
。像/user/123
和/user/456
等等,后面的id就是添加的参数,我们看个例子就懂了:
javascript
import User from "./views/User.vue";
const routes = [
// id 就是路径参数,别忘记加冒号
{ path: '/user/:id', component: User }
]
我们可以用this.$route.params.参数名称
来获取路径参数值。
访问404页面
如果用户输入的url不属于我们注册的任意一个路由,那么我们可以写一个 404 NotFound 组件渲染。
javascript
import NotFound from "./views/NotFound.vue";
const routes = [
{
// 使用通配符(*)会匹配所有路径
path: '*',
component: NotFound
}
]
另外,要确保上述含有通配符的路由放在了最后。
使用$route读取匹配到的路径值
我们可以在使用通配符(*)的路由下使用$route.params.pathMatch
来获取当前路径,比如我们这里输入的URL是http://localhost:8081/non-existing/file
,那么结果就如下所示:
csharp
this.$route.params.pathMatch // '/non-existing/file'
页面跳转
我们之前的编程式导航中都是使用<router-link>
来创建导航链接外,还可以写在JS用router.push()
来实现页面跳转,直接看代码:
arduino
router.push('user')
router.push('/user')
注意哈,里面是有根路径/
的,所以这两种方法实现的功能完全不一样。
router.push()的参数为描述地址的对象
php
// 对象
// 这种写法和字符串类型的参数一样
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
另外,第三个参数与其说是增加,不如说是修改,例如
localhost:8080/?plan=A
,而我们使用router.push({ path: 'register', query: { plan: 'B' }})
,它会变成:localhost:8080/?plan=B
。而不是像前面两者直接增加。
看着不是很容易理解,我们可以将下面的参数形式改成:
css
router.push({ path: 'user/123'})
router.push({ path: 'user?plan=private'})
这里的方法同样也适用于
<router-link>
的:to
属性哦。
页面跳转后如何获取参数
假设我们访问本地工程的一个地址http://localhost:8080/user/123?name=userName#abc
,对应的$route如下:
csharp
// $route
{
// 路由名称
name: "user",
meta: {},
// 路由path
path: "/user/123",
// 网页位置指定标识符
hash: "#abc",
// window.location.search
query: {name: "userName"},
// 路径参数 user/:userId
params: {userId: "123"},
fullPath: "/user/123?name=userName#abc"
}
这样一来,我们就可以通过$route.name
、$route.path
等来获取了。
别名和重定向
我们只需要搞定两个概念,首先什么是别名,别名就是两个名字都指向同一个路由
,看代码:
css
const routes: [
{
path: '/layout',
// 别名定为 /
alias: '/',
component: ()=> import('@/pages/nest/Layout.vue'),
children: [
{ path: 'home', component: Home },
{ path: 'courseall', component: CourseAll },
{ path: 'coursedetail/:courseId', component: CourseDetail }
]
}
];
那么接下来我们将使用重定向将/home
改成/
。
这个概念不好说,我们直接看代码:
css
const routes: [
{
path: '/layout',
alias: '/',
// 重定向到 /home
redirect: '/home',
component: ()=> import('@/pages/nest/Layout.vue'),
children: [
{ path: 'home', component: Home },
{ path: 'courseall', component: CourseAll },
{ path: 'coursedetail/:courseId', component: CourseDetail }
]
}
];
这样子一来,现在的路由就变了:
这里我们需要知道,当我们路径使用path
/layout
时,url会显示成重定向后的url:/home
,如果在URL输入的是别名/
,那么依旧会重定向,但是url不变。
监听路由
说到监听路由,我可以让大家先看下下面这张图:
从图片中我们可以看出,肯定是需要通过监听路由的变化来实现对应的效果。
监听路由$route的变化
监听的话,绝对就需要用到我们的侦听器watch
了,下面代码里面的$route就表示当前路由。
css
//当前路由发生了变化,那么触发侦听器。
watch: {
$route(to,from){
console.log(to, from);
}
}
// 或者
watch: {
$route: {
handler: function(to,from) {
console.log(to,from);
},
// 深度观察监听
deep: true
}
},
网络请求async与await
我们在JS里面使用fetch
来请求数据,看代码:
javascript
fetch(
'https://www.done.kim/api/m/f4-11-1-1'
)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
因为fetch
返回的是一个promise
对象,所以我们请求数据的时候使用了then
来采用平铺式回调的方式,这样一来就允许我们在数据返回之后再进行response.json()
处理。
但是问题也来了,因为每个步骤都是异步的,并且依赖上一个步骤的结果,那么
then
链会非常长。这时候,就需要我们的async
和await
出马了。
"异步"async
javascript
async function asyncFn() {
return {
"company": "优课达",
"slogan": "学的比别人好一点"
};
}
const result = asyncFn();
console.log(result);
上面的代码返回的也是一个promise
对象,那这和fetch
区别是什么。关键就在于await
关键字。
"等待异步"await
await
关键字的作用就是等待异步任务的完成,并会阻塞后面的代码。
scss
async function getAsyncFn() {
//await关键字只能出现在async修饰的函数中,否则会报错。
const result = await asyncFn();
console.log(result);
}
getAsyncFn();
多个请求并发执行Promise.all
如果要完成多个请求并发执行,那么就可以使用Promise.all
:
javascript
async function asyncFn1() {
return "优课达";
}
async function asyncFn2() {
return "学的比别人好一点";
}
async function getAsyncFn() {
const result = await Promise.all([asyncFn1(), asyncFn2()]);
console.log(result);
}
getAsyncFn();
vue中的async和await的使用以及api的传参
xml
<script>
export default {
data: function() {
return {
course: []
};
},
//mouted钩子函数作用就是初始化页面完成后,再对DOM节点进行相关操作。
async mounted() {
await this.getCourse();
},
methods: {
async getCourse() {
// 从路径中获取课程 id
const courseId = this.$route.params.courseId
// 在接口地址后传入参数 id
const res = await fetch('https://www.done.kim/api/m/getcourse?id=' + courseId);
const myJson = await res.json();
this.course = myJson.data;
}
}
}
</script>
到此,基本整理完毕。