- , 17 8月 2021
- 作者 847954981@qq.com
- 前端学习
Vue值Router(路由)2
在路由中,我们除了可以在 <router-link>中写入a标签来定义导航链接,还可以借助 Router实例方法,通过编程代码来实现
编程式导航
两种代码样式
声明式 | 编程式 |
---|---|
<router-link :to=”…”> | router.push(…) |
router.push使用方法
一、router.push的参数为字符串路径
router.push方法是参数可以是一个字符串路径
代码语言:javascript复制router.push('user')
router.push('/user')
router.push('user') router.push('/user')router.push('user') router.push('/user')
下面详细说明上面两种写法的不同,主要是跳转后 url 的变化不同:
原 url | localhost:8080 | localhost:8080/home |
---|---|---|
router.push(‘user’)跳转后的 url | localhost:8080/user | localhost:8080/home/user |
router.push(‘/user’)跳转后的 url | localhost:8080/user | localhost:8080/user |
因为 /
意味着匹配根路由,所以 '/user'
这样的写法不管原路径 localhost:8080/??
中的 ??
是什么,跳转后 url 都会变为 localhost:8080/user
。
二、router.push 的参数为描述地址的对象
router.push 方法的参数可以是一个描述地址的对象:
代码语言:javascript复制// 对象
// 这种写法和字符串类型的参数一样
router.push({ path: 'home' })
// 命名的路由
router.push({ name: 'user', params: { userId: '123' }})
// 带查询参数,变成 /register?plan=private
router.push({ path: 'register', query: { plan: 'private' }})
只提供 path
值的参数和字符串类型的参数是一样的。这里就不再说了。我们主要看一下后两种写法。
{ name: 'user', params: { userId: '123' }}
- 对应的命名路由为:
{ path:'user/:userId', name:'user' }
; - 跳转后 url:
localhost:8080/user/123
; - 取参数:
$route.params.userId
;
{ path: 'register', query: { plan: 'private' }}
- 对应的路由为:
{ path:'register' }
; - 跳转后 url:
localhost:8080/register?plan=private
; - 取参数:
$route.query.plan
;
小结一下参数传递的对应规则:
- name 对应 params,路径形式:user/123;
- path 对应 query,路径形式:user?id=123;
如果使用 path 进行页面跳转的时候,写 params 进行传参会被忽略:
代码语言:javascript复制// params 会被忽
router.push({ path: 'user', params: { userId: '123' }})
可以换成下面的写法:
代码语言:javascript复制router.push({ path: 'user/123'})
同样的规则也适用于 router-link
组件的 to
属性。
页面跳转后如何获取参数
例如工程
代码语言:javascript复制// $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"
}
我们以http://localhost:8080/user/123?name=userName#abc
地址来访问
可以通过 route.query、route.params、
重定向与别名
别名
别名指两个名字指向一个路由:
代码语言:javascript复制const routes: [
// 定义 alias 属性
{ path: '/a', alias: '/b', component: A }
];
即访问 /a 和 /b 都会渲染 A
重定向
重定向指的是路由跳转,如 /a 重定向到 /b ,即访问 /a 时,url自动跳转到 /b 并匹配 /b路由
代码语言:javascript复制const routes: [
// 定义 redirect 属性,将 /a 重定向到 /b
{ path: '/a', redirect: '/b' }
]
监听路由
当头部标签切换时,路径也会发生变化,我们需要监听路径变化来改变标签样式,或者加载对应的内容。
我们利用 watch 和 $router 来完成监听
代码语言:javascript复制watch: {
$route(to,from){
console.log(to, from);
}
}
// 或者
watch: {
$route: {
handler: function(to,from) {
console.log(to,from);
},
// 深度观察监听
deep: true
}
},
定义点击事件:
代码语言:javascript复制<script>
export default {
methods: {
// 点击 tab 时会执行 changeTab 方法
changeTab(type) {
// 使用 Router 实例方法改变路径参数
this.$router.push({ query: { type: type } });
}
}
};
</script>
更新标签样式
代码语言:javascript复制<script>
export default {
watch: {
$route(to, from) {
// 路由变化了就执行更新样式的方法
this.updateTab();
console.log(to, from);
}
},
methods: {
changeTab(type) {
this.$router.push({ query: { type: type } });
},
// 更新样式的方法
updateTab() {
this.tabList.map(menu => {
menu.active = menu.type === this.$route.query.type;
});
}
}
};
</script>
因为我们此时默认路径开始没有参数type,所以默认选择第一个,但当路径默认有初始参数,我们就需要马上更新样式
代码语言:javascript复制<script>
export default {
methods: {
// ...
updateTab() {
if (!this.$route.query.type) {
return;
}
this.tabList.map(tab => {
tab.active = tab.type === this.$route.query.type;
})
}
}
};
</script>
网络请求 async与 await
在js中,我们进行网络请求都是通过:
代码语言:javascript复制fetch(
'https://www.fastmock.site/mock/b73a1b9229212a9a3749e046b1e70285/f4/f4-11-1-1'
)
.then(function(response) {
return response.json();
})
.then(function(myJson) {
console.log(myJson);
});
因为fetch是一个promise对象,无等待,所以对返回数据进行操作时要添加大量then。
所以我们使用 async(异步)和await(等待异步)
使用async前我们需要声明一个异步function
代码语言:javascript复制async function asyncFn() {
return {
"company": "优课达",
"slogan": "学的比别人好一点"
};
}
const result = asyncFn();
console.log(result);
async返回的也是一个promise对象,但其与fetch区别在有着await
await
用于等待一个异步方法执行的完成,它会阻塞后面的代码,等着 Promise 对象 resolve *,然后得到 resolve 的值,作为 await 表达式的运算结果:
async function getAsyncFn() {
const result = await asyncFn();
console.log(result);
}
getAsyncFn();
注意的是 await只能出现在 async函数中
多个请求并发执行
如要是多个请求并发执行 可以使用 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();
请求参数:
代码语言:javascript复制<script>
export default {
data: function() {
return {
courseList: []
};
},
async mounted() {
// 在生命周期 mounted 中调用获取课程信息的方法
await this.queryAllCourse();
},
methods: {
// 在 methods 对象中定义一个 async 异步函数
async queryAllCourse() {
// 在 fetch 中传入接口地址
const res = await fetch('https://www.fastmock.site/mock/2c5613db3f13a5c02f552c9bb7e6620b/f5/api/queryallcourse');
// 将文本体解析为 JSON 格式的promise对象
const myJson = await res.json();
// 获取返回数据中的 data 赋值给 courseList
this.courseList = myJson.data;
}
}
}
</script>
传递参数:
代码语言:javascript复制<script>
export default {
data: function() {
return {
course: []
};
},
async mounted() {
await this.getCourse();
},
methods: {
async getCourse() {
// 从路径中获取课程 id
const courseId = this.$route.params.courseId
// 在接口地址后传入参数 id
const res = await fetch('https://www.fastmock.site/mock/2c5613db3f13a5c02f552c9bb7e6620b/f5/api/getcourse?id=${' courseId '}');
const myJson = await res.json();
this.course = myJson.data;
}
}
}
</script>