第一次使用路由:
什么是:路由?
Vue的router插件功能类似<a></a>
标签,但更为强大的是可以实现不跳转页面
通过调用组件模板来更新页面内容
[原理
]:页面在渲染时将[router-link]
渲染成a标签,通过to属性
指定连接URL ,这就像是[herf],之后再利用[router-view]路由的出口
,路由匹配到的组件将渲染这里
完成一整个router渲染大致分为4步:↓
==========HTML=========
<div id="app">
<router-link to="/back">Back</router-link>
<router-link to="/go">GO</router-link>
<router-view></router-view>
</div>
上面在Vue视图内建立了两个路由链接router-link,地址就是"/back"和"/go" 当然是虚拟的 只是为了链接到指定模板
以及router-view 路由视图让路由连接到的内容显示在这里
下面再看JS部分
===========JS===========
第一步:定义(路由)组件模板
const Go={template:`<h1>Go</h1>`};
const Back={template:`<h1>Back</h1>`};
一般模板与router-link标签成一一对应关系
第二步:定义路由配置
每一个路由都定义一个组件
const routes=[
{path:"/go",component:Go},
{path:"/back",component:Back}
];
格式就是个数字包对象,每一个对象都是一个路由配置
"path"就是路由地址,再由地址访问指定模板,用"componentent"属性找到对应的模板
第三部:创建一个router的实例,将定义的ronter的配置传给它
const router=new VueRouter({
routes
<--routes:routes在对象中属性名和变量相同可以简写成routes-->
当然定义路由配置的过程也可以在这里完成
//routers=[
// {path:"/go",component:Go},
// {path:"/back",component:Back}
// ];
})
第四步:最后将router实例配置到Vue实例中
const app=new Vue({
router,
el:"#app"
})
这样初步的基本(乞丐版)路由就完成了
在页面上就会出现两个a标签点击分别渲染显示对应的模板内容:Go&Back ;
了解了路由的基本工作流程后,下面再来看看路由的动态创建
动态创建
注意!
这里要说的是当路由参数从/user/1
到/user/2
的时候,原来的组件实例会被复用
,因为这两个渲染同一个组件,这样比销毁再创建更加节省性能,不过这样也以为这组建的生命周期的钩子函数不会再被调用
可以通过路由模板组件的
watch
属性来监听指定路由对象的变化;
在看例子之前先了解一下路由实例$route
里面的几个属性
$route.path
类型:String 对应当前路由的路径 总是解析为绝对路径 例如:"/user/info"
$route.params
类型:Object 包含了动态片段和全匹配片段 如果路路由没有参数就是个空对象
$route.query
类型:Object 查询参数 例如:/user/info?name=aa {name:"aa"}
$route.query.name=="aa"
$route.hash
类型:String 当前路由的哈希值(带着#) 没有就是空字符串
$route.fullPath
类型:String 完整的url
$route.name
类型:String 当前路由的名字
===========HTML==============
<div id="app">
<router-link to="/user/1">用户1</router-link>
<router-link to="/user/2">用户2</router-link>
<router-view></router-view>
</div>
=============JS==============
cont User={
模板中拼接的"{{$route.params.id}}"的这个params是路由实例的一个属性表示/user/后面的值(也可以理解为后面的参数)
template:"<h2>用户{{$route.params.id}}</h2>",
通过路由模板组件的`watch`属性来监听指定路由对象的变化
watch:{
$route (to,from){
console.log(to,from)
在点击"用户2"时这里可以看到打印出的两个对象:to里面的地址就是点击连接后要去的地址"/user/2",from里面则是之前的"/user/1"
}
}
};
const router=new VueRouter({
router:[
{name:"r1",path:"/user/:id",component:User}
]
":id就是/user/后面的值 通过id的匹配来决定连接哪个模板"
});
const app=new Vue({
router,
el:"#app"
});
路由的嵌套
路由通过嵌套可以实现一些二级或多级路由渲染(
一个路由渲染完后里面还可以有一个路由
)实现思路与Vue组件嵌套类似
在模板里面再写[router-link]标签,然后再给里面这个路由配置和模板
是通过路由地址的匹配来实现渲染对应的模板
===========HTML==========
<div id="app">
<p>
<router-link to="/user/JS4/index">首页</router-link>
<router-link to="/user/JS4/pre">报价</router-link>
<router-link to="/user/JS4/me">个人</router-link>
</p>
</div>
============JS=============
const User={template:`<div><h2>XX手机网<h2><transition></transition>`}
const userIndex={template:`<h3>首页推荐</h3>`};
const userPre={templat:`<h3>报价中心</h3>`};
const userMe={templat:`<h3>个人账户</h3>`};
创建了3个模板
const router=new VueRouter({
routes:[{
//":class"会将/user/JS4 里面的JS4 赋给class;
path:"/user/:class",component:User,
chlidren:[
{path:"index",component:userIndex},
{path:"pre",component:userPre},
{path:"me",component:userMe},
当/user/:class/me匹配成功 将userMe渲染到User的router-view中
]
}]
});
const app=new Vue({
router,
el:"#app"
})
编程式导航(常用
)
除了使用router-link创建a标签来定义导航链接,还可以借助router实例中提供的方法,通过编程式来实现导航链接
[router.push(url)
]
实质上当你点击router-link的时候,to后面的填的地址,就相当于调用router.push(to后面填的地址)来导航到不用的URL,这时需要用router.push方法 向history栈添加一个新的记录,当用户点击浏览器的返回按钮时,可以返回到上一个历史记录(就相当于原生中的window.history.pushState)
==============HTML================
<div id="app">
<button @click="getIndex">首页</button>
<button @click="getInfo">详情页</button>
<router-view></router-view>
</div>
==============JS==================
const index={template:"<h1>首页信息</h1>"};
const info={template:"<h1>详情页信息</h1>"};
const router=new VueRouter({
routes:[
{name:"index",path:"/index/:id",component:index},
{name:"index",path:"/info",component:info}
]
});
下面先介绍几个router.push的几个用法
1.router.push("/index") 写在在外面可在载入页面时直接对应组件渲染
2.router.push({path:"/index"})跟上面效果一样
3.router.push({name:"index",params:{id:123}}) 可不传地址利用配置路由的name属性找到对应配置
4.router.push({path:"/index",query:{h:"hello"}})带查询参数
new Vue({
el:"#app",
router,
methods:{
getIndex(){
这里用第一种方法
router.push({name:"index"});
还有一种方法:router.replace,跟router.push一样,只有一个不同就是不会向history栈中添加记录而好似直接替换掉之前的记录,所以不会在浏览器留下记录(无法返回和前进),这跟原生中window.history.replaceState一样
//router.replace({name:"index"});
},
getInfo(){
这里用第二种方法
router.push({path:"/info",query:{h:"hello",w:"word"}})
},
go(){
router.go(1);
这里所使用的"router.go()"方法与原生window.history.go()方法一样,控制前进或者后退多少条history条记录
例子:
1.router.go(-1) 后退一步 相当原生history.back()
2.router.go(1) 前进一步 相当原生的history.forward()
3.router.go(3) 前进三步
}
}
})
命名视图
官方:
有时候想同时(同级)展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar(侧导航) 和 main(主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。
[一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置(带上 s)
]
================HTML======================
<div id="app">
<h1>店员</h1>
<div>
<router-link to="/group1">一号店</router-link>
<router-link to="/group2">二号店</router-link>
</div>
<router-view name="a"></router-view>
<router-view name="b"></router-view>
<router-view></router-view>
</div>
=================JS========================
const person1={template:"<div>段斌</div>"};
const person2={template:"<div>刘亚</div>"};
const person3={template:"<div>朱寒</div>"};
const person4={template:"<div>康丽</div>"};
const person5={template:"<div>宁远</div>"};
const person6={template:"<div>程丽</div>"};
以上6个模板分两组显示
const router=new VueRouter({
routes:[
{path:"/group1",components:{
default:person1,
a:person2,
b:person3
}},
{path:"/group2",components:{
default:person4,
a:person5,
b:person6
}}
]
});
new Vue({router}).$mount("#app")
重定向
这个非常好理解,设定两个路由标签A和B,此时给A的path地址重定向到B身上,此时A.path=B.path,点击A渲染B的内容
核心就是[路由对象上的redirect属性
]
看例子↓
==============HTML==============
<div id="app">
<router-link to="/a">AA</router-link>
<router-link to="/b">BB</router-link>
<router-view></router-view>
<div>
===============JS==============
const A={template:"<h1>AAAAAAA</h1>"};
const B={template:"<h1>BBBBBBB</h2>"};
这里用三种方法(基本都一样)来实现,但重定向操作必须写在前面
第一种:将path为"/a"的路由,重定向到path为"/b"的路由
const router=new VueRouter({
routes:[
{path:"/a",redirect:"/b"},
{path:"/a",component:A},
{path:"/b",component:B}
]
});
第二种:将path为"/a"的路由,重定向到name为BB的路由
const router=new VueRouter({
routes:[
{path:"/a",redirect:{name:"BB"}},
{name:"AA",path:"/a",component:A},
{name:"BB",path:"/b",component:B}
]
});
第三种:将path为"/a"的路由,定向到路由对象path为"/b"的路由对象
const router = new VueRouter({
routes:[
{path:"/a",redirect: to=>{
//接受目标路由作为参数
//return的内容就是重定向的路径(可以是字符串也可以是对象)
console.log(to);
return "/b"
}},
{path:"/a",component:A},
{path:"/b",component:B}
]
});
new Vue({
router
}).$mount("#app")