我们来学习一下Vue路由的一种全新跳转方式: 编程式路由导航
按照之前的的学习来说,我们一直都离不开<router-link>
;我们失去了它我们就没办法去里面写to
属性了从而就不能实现路由的跳转了
如果我们就不写<router-link>
属性我们能不能进行路由跳转?
也就是这些导航项万一拿的是button
写的怎么办
那我们从头开始
1.最初的样子
main.js
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'//引入vue-router插件
import router from './router/index'//引入用vue-router构造函数创建的router配置
Vue.config.productionTip = false
Vue.use(VueRouter)//使用vue-router插件
new Vue({
router,
render: h => h(App)
}).$mount('#app')
App.vue
<template>
<div>
<HelloWorld></HelloWorld>
</div>
</template>
<script>
import HelloWorld from './components/HelloWord.vue'
export default {
name:'App',
components:{HelloWorld},
}
</script>
<style>
</style>
添加vue-router属性
npm i vue-router
src > 创建router > index.js
//必须引入的插件,可以调用里面的构造函数
import VueRouter from "vue-router"
//这里是自己的路由组件,根据自己创建的组件来引入
//调用(创建)构造函数并暴露
export default new VueRouter({
routes:[
{}
]
})
src > 创建pages(存放路由组件) > About.vue And Home.vue
About.vue
<template>
<div>
<h2>你好,欢迎来到About路由组件</h2>
</div>
</template>
<script>
export default {
name:'About',
components:{},
}
</script>
<style scoped>
</style>
Home.vue
<template>
<div>
<h2>你好,欢迎来到Home路由组件</h2>
</div>
</template>
<script>
export default {
name: 'Home',
components:{},
}
</script>
<style scoped>
</style>
添加一个普通组件 component > HelloWorld.vue
<template>
<div>
<h2>你好,这里是名为Hello World的一个普通组件</h2>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
components:{},
}
</script>
<style scoped>
</style>
2.添加俩个路由组件
router > index.js
//必须引入的插件,可以调用里面的构造函数
import VueRouter from "vue-router"
//这里是自己的路由组件,根据自己创建的组件来引入
import Home from '../pages/Home.vue'
import About from '../pages/About.vue'
//调用(创建)构造函数并暴露
export default new VueRouter({
routes:[
{
path: '/home',
component: Home,
},
{
path: '/about',
component: About
}
]
})
在App中来一个
<router-link>
<template>
<div>
<HelloWorld></HelloWorld>
<!--引入跳转-->
<router-link to="/home">Home</router-link>
<router-link to="/About">About</router-link>
<!--显示内容-->
<router-view></router-view>
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'
export default {
name: 'App',
components:{HelloWorld},
}
</script>
<style>
</style>
3.创建News、Message、消息1、消息2、消息3
News.vue
<template>
<div>
<h2>你好,欢迎来到News路由组件</h2>
</div>
</template>
<script>
export default {
name: 'News',
components:{},
}
</script>
<style scoped>
</style>
修改 router > index.js(这里涉及到了路由的嵌套详情)
//必须引入的插件,可以调用里面的构造函数
import VueRouter from "vue-router"
//这里是自己的路由组件,根据自己创建的组件来引入
import Home from '../pages/Home.vue'
import About from '../pages/About.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
//调用(创建)构造函数并暴露
export default new VueRouter({
routes:[
//想在哪里进行二次跳转,就写在个配置里(用children)
{
path: '/home',
component: Home,
children:[
{
path: 'news',//注意路由底层给你加了'/'如果自己加'/'有可能还显示不出效果
component:News,
},
{
path: 'message',
component: Message,
}
]
},
{
path: '/about',
component: About
}
]
})
Message.vue
<template>
<div>
<h2>你好,欢迎来到Message路由组件</h2>
</div>
</template>
<script>
export default {
name: 'Message',
components:{},
}
</script>
<style scoped>
</style>
Home.vue(路由里面是Home的子路由所以是在Home里面添加)
<template>
<div>
<h2>你好,欢迎来到Home路由组件</h2>
<hr />
<!-- 子路由的写法(没有命名路由) -->
<router-link to="/home/news">News</router-link>
<router-link to="/home/message">Message</router-link>
<router-view></router-view>
</div>
</template>
<script>
export default {
name: 'Home',
components:{},
}
</script>
<style scoped>
</style>
4.创建消息跳转
修改router > index.js(命名路由详情)和(路由params详情)
//必须引入的插件,可以调用里面的构造函数
import VueRouter from "vue-router"
//这里是自己的路由组件,根据自己创建的组件来引入
import Home from '../pages/Home.vue'
import About from '../pages/About.vue'
import News from '../pages/News.vue'
import Message from '../pages/Message.vue'
import Detail from '../pages/Detail.vue'
//调用(创建)构造函数并暴露
export default new VueRouter({
routes:[
//想在哪里进行二次跳转,就写在个配置里(用children)
{
path: '/home',
component: Home,
children:[
{
path: 'news',//注意路由底层给你加了'/'如果自己加'/'有可能还显示不出效果
component:News,
},
{
path: 'message',
component: Message,
//添加的地方开始
children:[
{
name: 'xiangqing',//命名路由
path: 'detail/:id/:name',
component: Detail
}
]
//添加的地方结束
}
]
},
{
path: '/about',
component: About
}
]
})
修改 Message.vue
<template>
<div><template>
<div>
<h2>你好,欢迎来到Message路由组件</h2>
<ul>
<li v-for="n in newMsg" :key="n.id">
<router-link :to="`/home/message/detail/${n.id}/${n.name}`">{{n.name}}</router-link>
</li>
</ul>
<router-view></router-view>
</div>
</template>
<script>
import {nanoid} from 'nanoid'//npm i nanoid
export default {
name: 'Message',
components:{},
data() {
return {
newMsg:[
{
id:nanoid(),
name: '消息1'
},
{
id:nanoid(),
name: '消息2'
},
{
id:nanoid(),
name: '消息3'
},
]
}
},
}
</script>
<style scoped>
</style>
<h2>你好,欢迎来到Message路由组件</h2>
<ul>
<li v-for="n in newMsg" :key="n.id">
<router-link :to="`/home/message/detail/${n.id}/${n.name}`">{{n.name}}</router-link>
</li>
<router-view></router-view>
</ul>
</div>
</template>
<script>
import {nanoid} from 'nanoid'//npm i nanoid
export default {
name: 'Message',
components:{},
data() {
return {
newMsg:[
{
id:nanoid(),
name: '消息1'
},
{
id:nanoid(),
name: '消息2'
},
{
id:nanoid(),
name: '消息3'
},
]
}
},
}
</script>
<style scoped>
</style>
Detail.vue
<template>
<div>
<ul>
<li>邮件的id:{{$route.params.id}}</li>
<li>邮件名称:{{$route.params.name}}</li>
</ul>
</div>
</template>
<script>
export default {
name: 'Detail',
components:{},
mounted(){
//console.log(this.$route)
}
}
</script>
<style>
</style>
变成props传值
修改 router > index.js
export default new VueRouter({
routes:[
{
...
children:[
{...},
{
path: 'message',
component: Message,
children:[
{
name: 'xiangqing',
path: 'detail/:id/:name',
component: Detail,
props($route){//修改为query的props
return {id: $route.query.id, name: $route.query.name}
}
}
]
}
]
}
]
})
5.不依赖于<router-link>
的编程式路由导航
修改 Message.vue
<li v-for="n in newMsg" :key="n.id">
....
<button @click="pushShow">push查看</button><!--先写push查看-->
<button>replace查看</button>
</li>
methods:{
pushShow(){
//这里要等价于之前的name、传值功能
//请出一个所有组件都能看的到,整个应用只有一个的人 $router
console.log(this.$router)//router:路由器:有指挥权
}
}
路由器其实是VueRouter
的实例对象
VueRouter {app: Vue, apps: Array(1), options: {…}, beforeHooks: Array(0), resolveHooks: Array(0), …}
afterHooks: []
app: Vue {_uid: 0, _isVue: true, $options: {…}, _renderProxy: Proxy, _self: Vue, …}
apps: [Vue]
beforeHooks: []
fallback: false
history: HashHistory {router: VueRouter, base: '', current: {…}, pending: null, ready: true, …}
matcher: {match: ƒ, addRoute: ƒ, getRoutes: ƒ, addRoutes: ƒ}
mode: "hash"
options: {routes: Array(2)}
resolveHooks: []
currentRoute: (...)
[[Prototype]]: Object
其实最有用的没有放在自生,放在了VueRouter的缔造者(原型对象)上了
VueRouter {app: Vue, apps: Array(1), options: {…}, beforeHooks: Array(0), resolveHooks: Array(0), …}
.....
[[Prototype]]: Object
addRoute: ƒ addRoute(parentOrRoute, route)
addRoutes: ƒ addRoutes(routes)
afterEach: ƒ afterEach(fn)
back: ƒ back()
beforeEach: ƒ beforeEach(fn)
beforeResolve: ƒ beforeResolve(fn)
forward: ƒ forward()
getMatchedComponents: ƒ getMatchedComponents(to)
getRoutes: ƒ getRoutes()
go: ƒ go(n)
init: ƒ init(app /* Vue component instance */)
match: ƒ match(raw, current, redirectedFrom)
onError: ƒ onError(errorCb)
onReady: ƒ onReady(cb, errorCb)
push: ƒ push(location, onComplete, onAbort)
replace: ƒ replace(location, onComplete, onAbort)
resolve: ƒ resolve( to, current, append )
constructor: ƒ VueRouter(options)
currentRoute: (...)
get currentRoute: ƒ ()
[[Prototype]]: Object
我们用push
就可以实现路由的跳转,并且是对历史记录的push
修改Message.vue
<li v-for="n in newMsg" :key="n.id">
....
<button @click="pushShow(n)">push查看</button><!--先写push查看-->
<button>replace查看</button>
</li>
methods:{
pushShow(n){
//这里要等价于之前的name、传值功能
//请出一个所有组件都能看的到,整个应用只有一个的人 $router
//console.log(this.$router)//router:路由器:有指挥权
this.$router.push({
path: '/homemessage/detail',
query:{//跟to的对象写法里面的配置一模一样
id: n.id,
name: n.name
}
})
}
}
6.再写一个replace
<li v-for="n in newMsg" :key="n.id">
....
<button @click="pushShow(n)">push查看</button><!--先写push查看--> <button @click="replaceShow(n)">replace查看</button>
</li>
replaceShow(n){
this.$router.replace({
name: 'xiangqing',
params:{
id: n.id,
name: n.name,
}
})
}
7.后退前进
一般组件 HelloWorld.vue
<template>
<div>
<h2>你好,这里是名为Hello World的一个普通组件</h2>
<button @click="back">后退</button>
<button @click="forward">前进</button>
</div>
</template>
<script>
export default {
name: 'HelloWorld',
components:{},
methods:{
back(){
//this.$router中的back就是回退
this.$router.back()
},
forward(){
//this.$router中的forward就是前进
this.$router.forward()
},
},
}
</script>
<style scoped>
</style>
你完全可以借助路由器去操作整个历史记录
还有一个API
console.log(this.$router)
VueRouter {app: Vue, apps: Array(1), options: {…}, beforeHooks: Array(0), resolveHooks: Array(0), …}
.....
[[Prototype]]: Object
addRoute: ƒ addRoute(parentOrRoute, route)
addRoutes: ƒ addRoutes(routes)
afterEach: ƒ afterEach(fn)
back: ƒ back()
beforeEach: ƒ beforeEach(fn)
beforeResolve: ƒ beforeResolve(fn)
forward: ƒ forward()
getMatchedComponents: ƒ getMatchedComponents(to)
getRoutes: ƒ getRoutes()
go: ƒ go(n)
init: ƒ init(app /* Vue component instance */)
match: ƒ match(raw, current, redirectedFrom)
onError: ƒ onError(errorCb)
onReady: ƒ onReady(cb, errorCb)
push: ƒ push(location, onComplete, onAbort)
replace: ƒ replace(location, onComplete, onAbort)
resolve: ƒ resolve( to, current, append )
constructor: ƒ VueRouter(options)
currentRoute: (...)
get currentRoute: ƒ ()
[[Prototype]]: Object
这个API就是go
这个go
有什么作用?
<button @click="test">
测试一下API-go
</button>
test(){
//go中得传入一个数字,如果是正数(正3,往前走3步,连点三下前进),如果是负数(负4,往后退4步,连点4下后退)
this.$router.go(-2)
}
总结
编程式路由导航
1.作用:不借助<router-link>
实现路由跳转,让路由跳转更加灵活
2.具体编码:
this.$router.push({
name:'xiangqing',
params:{
id: xxx,
name: xxx
}
})
this.$router.replace({
path: '/homemessage/detail',
query:{
id: xxx,
name: xxx,
}
})
this.$router.back()//后退
this.$router.forward()//前进
this.$router.go()//按照正负数 前进/后退 几步
3.具体用到的API
-
push:this.$router.push
-
replace:this.$router.replace
-
back:this.$router.back
-
forward:this.$router.forward
-
go: this.$router.go