关于vue里面的路由,类别有导航路由、编程式路由、单容器路由、嵌套路由、命名路由等。当然这些路由并不全是对立的,他们有的也是可以一块使用的,比如单容器路由里面可以用到导航、编程式路由、命名路由以及其他路由;关于vue路由之间的传参主要有两种方式,一种是params传参,另一种是query传参。
由于要传递数据,这里分享一个后台接口:请求数据接口
-
vue路由
在写路由之前一定首先要引入vue.js和vue-router.min.js文件,如果请求数据用axios方式,还需要引入axios.min.js文件。
1.导航路由:指在<router-link></router-link>标签中通过to属性中“/路径”(在path路径中配置过)跳转到其他页面的路由。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/axios.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/vue-router.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
.router-link-active{
color: orangered;
}
</style>
</head>
<body>
<div id="out">
<h1>路由</h1>
<!--导航标签-->
<!--to="/home" 导航路由-->
<router-link to="/home" tag="span">首页</router-link>
<router-link to='/about/222' tag="span">关于</router-link>
<router-link to="/other" tag="span">其他</router-link>
<hr />
<!--路由容器-->
<router-view></router-view>
</div>
<!--组件模板-->
<template id="home">
<div>
<h1>首页</h1>
</div>
</template>
<template id="about">
<div>
<h1>about</h1>
<p>{{aa}}</p>
</div>
</template>
<template id="other">
<div>
<h1>other</h1>
</div>
</template>
</body>
<script type="text/javascript">
//注册组件
var Home={
template:'#home'
}
var About={
template:'#about',
data:function(){
return{
aa:""
}
},
mounted(){
this.aa = this.$route.params.id
}
}
var Other={
template:'#other'
}
//路由规则定义
var routes=[
{path:'/home',component:Home},
{path:'/about/:id',component:About},
{path:'/other',component:Other},
{path:'*',redirect:'/home'}
]
//实例化路由对象
var router=new VueRouter({
routes:routes
})
//挂载路由
var vm=new Vue({
el:'#out',
router:router
})
</script>
</html>
注:a.导航样式用给类名为router-link-active写,因为router-link标签点击哪一个会默认给其添加该类名;
b.可用tag属性设置router-link的取代标签,当不设置的时候router-link默认是a标签 。如:<router-link to="/" tag="p"></router-link> router-link标签将会被p标签替换;
c.上述代码还用到了params传参,具体是导航路由中to属性中“/路径”后面通过加“/参数”来传递,然后在路由配置规则时在path路径中用“/:自定义属性名”(如/:id)来接收。之后可以在路由挂载时候渲染到页面------通过this.$route.params.自定义属性名---取到传进来的参数,赋值给一个变量,通过双括号插值法写入页面。
d.路由的重定向在配置路由规则时要配一下,可提高用户体验。方法是:{path:"*",redirect:"/index"},定哪后面就配哪。
e.路由规则配完之后,别忘记实例化路由对象及挂载路由,否则视图也不会展示。
f.路由路径由 <router-link></router-link>标签配置,标签内 to属性值规定改标签,指向的path路径。路由对应视图 通过加载组件 加载到<router-view></router-view>上
2.编程式路由:指以动态的创建方式通过router.push('/路径')(路径在路由规则的path中也配过)来实现跳转页面的路由。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>单容器路由</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/axios.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/vue-router.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
.router-link-active{
color: orangered;
}
</style>
</head>
<body>
<div id="out">
<h1>路由</h1>
<!--导航标签-->
<!--导航路由-->
<router-link to="/home" tag="span">首页</router-link>
<router-link to='/about' tag="span">关于</router-link>
<router-link to="/other" tag="span">其他</router-link>
<hr />
<!--路由容器-->
<router-view></router-view>
</div>
<template id="home">
<div>
<h1>首页</h1>
<button @click="tap()">请求数据</button>
<button @click="tap1()">去关于页面</button>
<ul>
<li v-for="(item,i) in arr"><router-link :to="'/detail/'+item.pid" tag="span">{{item.pname}}</router-link></li>
</ul>
</div>
</template>
<template id="about">
<div>
<h1>about</h1>
</div>
</template>
<template id="other">
<div>
<h1>other</h1>
</div>
</template>
<template id="detail">
<div>
<h1>detail</h1>
<img :src="deta"/>
</div>
</template>
</body>
<script type="text/javascript">
var Home={
template:'#home',
data:function(){
return{
arr:[]
}
},
methods:{
tap(){
axios({
url:"http://jx.xuzhixiang.top/ap/api/productlist.php"
}).then(function(data){
this.arr = data.data.data
}.bind(this))
},
tap1(){
//编程式路由
router.push("/about")
}
}
}
var About={
template:'#about',
}
var Other={
template:'#other'
}
var Detail={
template:'#detail',
data:function(){
return{
deta:""
}
},
mounted(){
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:this.$route.params.id}
}).then(function(data){
this.deta = data.data.data.pimg
}.bind(this))
}
}
// 路由规则定义
var routes=[
{path:'/home',component:Home},
{path:'/about',component:About},
{path:'/other',component:Other},
{path:'/detail/:id',component:Detail},
{path:'*',redirect:'/home'}
]
// 实例化路由对象
var router=new VueRouter({
routes:routes
})
//挂载
var vm=new Vue({
el:'#out',
router:router
})
</script>
</html>
注:a.上述代码里面有编程式路由,但是更重要的是它还是一个单容器路由。
b. 另外它还用到了axios请求数据,还有params传参。
c.params传参------传参路径 :to="'/index/'+item.pid" ;存储路径参数 path:“/index/:id;获取 $route.params.id
d.axios传参方式-------params:{id:this.$route.params.id} ,跟url路径写一块,没有参数传时可以这样写-------params:{callback:''};多个参数传递时可以--------params:{goodsID:a.params.id,callback:''}。没有写方式时是get请求方式,可以添加上去method:"get"。通过then链式调用的是一个成功回调。
3.单容器路由:只有一个容器的路由,组件里面没有子路由的路由。写法可参看上面的代码,都是单容器路由。
4.嵌套路由:有父级路由和子级路由组成,子级路由嵌套在组件模板里面展示的路由。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>嵌套路由</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/axios.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/vue-router.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
.router-link-active{
color: orangered;
}
</style>
</head>
<body>
<div id="out">
<h1>路由</h1>
<!--导航标签-->
<router-link to="/home" tag="span">首页</router-link>
<router-link to='/about' tag="span">关于</router-link>
<router-link to="/other" tag="span">其他</router-link>
<hr />
<!--路由容器-->
<router-view></router-view>
</div>
<template id="home">
<div>
<h1>首页</h1>
<button @click="tap()">请求数据</button>
<ul>
<li v-for="(item,i) in arr"><router-link :to="'/detail/'+item.pid" tag="span">{{item.pname}}</router-link></li>
</ul>
<!--子路由-->
<router-view></router-view>
</div>
</template>
<template id="about">
<div>
<h1>about</h1>
</div>
</template>
<template id="other">
<div>
<h1>other</h1>
</div>
</template>
<template id="detail">
<div>
<h1>detail</h1>
<img :src="deta"/>
</div>
</template>
</body>
<script type="text/javascript">
var Home={
template:'#home',
data:function(){
return{
arr:[]
}
},
methods:{
tap(){
axios({
url:"http://jx.xuzhixiang.top/ap/api/productlist.php"
}).then(function(data){
this.arr = data.data.data
}.bind(this))
}
}
}
var About={
template:'#about',
}
var Other={
template:'#other'
}
var Detail={
template:'#detail',
data:function(){
return{
deta:""
}
},
mounted(){
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:this.$route.params.id}
}).then(function(data){
this.deta = data.data.data.pimg
}.bind(this))
},
//不监听的话会只更新一次,再点击视图就不会再更新
watch:{
'$route'(a){
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:a.params.id}
}).then(function(data){
this.deta = data.data.data.pimg
}.bind(this))
}
}
}
// 路由规则定义
var routes=[
{path:'/home',component:Home,
children:[{path:'/detail/:id',component:Detail}]},
{path:'/about',component:About},
{path:'/other',component:Other},
{path:'*',redirect:'/home'}
]
// 实例化路由对象
var router=new VueRouter({
routes:routes
})
//挂载
var vm=new Vue({
el:'#out',
router:router
})
</script>
</html>
注:a. 1)父级路由
<router-link to="/home">首页</router-link>
<router-link to=“/user”>用户</router-link>
<router-view></router-view>
子路由
<template id="user">
<div>
<router-link to="user/username">去子路由</router-link>
<!--子路由视图显示的地方-->
<router-view></router-view>
</div>
</template>
2) 子路由配置
{
path:'/user',component:User,
'children':[ /*定义自组件的路由*/
{ path:'username',component:UserName, /*注意:子路由前面的斜杠*/ }
]
},其他步骤一样
b.'children':[ {path:':aa',component:aaa} ] 通过$route.params.aa取值
c.同路由内,视图切换通过watch检测路由参数更改,即watch:{'$route'(to,from){}},否则视图只更新一次
d.子路由 重定向路径--默认显示 {path:‘/about’,redirect:‘/about/0’} 意思:当路径为/about 时 自动指向 /about/0
5.命名路由:路径的另一种定义方式,绑定属性to 对象name的值为设置的路由路径。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>命名路由,params传参</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/axios.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/vue-router.min.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
.router-link-active{
color: orangered;
}
</style>
</head>
<body>
<div id="out">
<h1>路由</h1>
<!--导航标签-->
<router-link to="/home" tag="span">首页</router-link>
<!--命名路由-->
<router-link :to="{name:'about'}" tag="span">关于</router-link>
<router-link :to="{name:'other'}" tag="span">其他</router-link>
<hr />
<!--路由容器-->
<router-view></router-view>
<router-view name="other"></router-view>
</div>
<template id="home">
<div>
<h1>首页</h1>
<button @click="tap()">请求数据</button>
<ul>
<!--params传参-->
<li v-for="(item,i) in arr"><router-link :to="'/detail/'+item.pid" tag="span">{{item.pname}}</router-link></li>
</ul>
<!--子路由-->
<router-view></router-view>
</div>
</template>
<template id="about">
<div>
<h1>about</h1>
</div>
</template>
<template id="other">
<div>
<h1>other</h1>
</div>
</template>
<template id="detail">
<div>
<h1>detail</h1>
<img :src="deta"/>
</div>
</template>
</body>
<script type="text/javascript">
var Home={
template:'#home',
data:function(){
return{
arr:[]
}
},
methods:{
tap(){
axios({
url:"http://jx.xuzhixiang.top/ap/api/productlist.php"
}).then(function(data){
this.arr = data.data.data
}.bind(this))
}
}
}
var About={
template:'#about',
}
var Other={
template:'#other'
}
var Detail={
template:'#detail',
data:function(){
return{
deta:""
}
},
mounted(){
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:this.$route.params.id}
}).then(function(data){
this.deta = data.data.data.pimg
}.bind(this))
},
//不监听的话会只更新一次,再点击视图就不会再更新
watch:{
'$route'(a){
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:a.params.id}
}).then(function(data){
this.deta = data.data.data.pimg
}.bind(this))
}
}
}
// 路由规则定义
var routes=[
{path:'/home',component:Home,
children:[{path:'/detail/:id',component:Detail}]},
{path:'/about',name:"about",components:{default:About,'other':Other}},
{path:'/qita',name:"other",component:Other},
{path:'*',redirect:'/home'}
]
// 实例化路由对象
var router=new VueRouter({
routes:routes
})
//挂载
var vm=new Vue({
el:'#out',
router:router
})
</script>
</html>
注: a.命名路由写法<router-link :to=“{name:‘index’}”>首页</router-link>
b.name属性设置路由视图名字--无名字默认default <router-view name=‘page’></router-view>
c.多个视图都要加载 { path:'/index',name:'index',components:{default:index,page:about} }
- 路由传参
1、params传参:通过path路径传参,在路由配置规则中用/:id接收(id可以是其他自定义属性名),用$route.params.id获取。params传参方式用于传单个参数。
2、query传参:通过query:{ id:item.qid}对象的形式传参,可以传多个参数,也是写在to属性中。用this.$route.query.id来获取。
对于params传参上面路由都有用到,下面以命名路由为例,写了query传参的嵌套和单容器两种方式。
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>命名路由、query传参不同页面</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/axios.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/vue-router.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
.router-link-active{
color: paleturquoise;
}
</style>
</head>
<body>
<div id="out">
<!--命名路由-->
<router-link :to="{name:'home'}" tag="span">首页</router-link>
<router-link :to="{name:'list'}" tag="span">列表</router-link>
<router-link :to="{name:'other'}" tag="span">其他</router-link>
<!--路由容器-->
<router-view></router-view>
</div>
<!--组件模板-->
<template id="home">
<div>
<h2>首页</h2>
</div>
</template>
<template id="list">
<div>
<h2>列表数据</h2>
<!--遍历展示-->
<ul>
<li v-for="item in arr"><router-link :to="{name:'other',query:{id:item.pid}}" tag="span">{{item.pname}}</router-link></li>
</ul>
</div>
</template>
<template id="other">
<div>
<h2>其他</h2>
<p>{{detail}}</p>
</div>
</template>
</body>
<script type="text/javascript">
//组件注册
var Home = {
template:"#home"
}
var List = {
template:"#list",
data:function(){
return{
arr:[]
}
},
mounted(){
var _this = this;
axios({
url:"http://jx.xuzhixiang.top/ap/api/productlist.php"
}).then(function(data){
_this.arr = data.data.data
})
}
}
var Other = {
template:"#other",
data:function(){
return{
detail:[]
}
},
mounted(){
// console.log(this.$route.query.id)
var _this = this;
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:this.$route.query.id}
}).then(function(data){
// console.log(data.data.data)
_this.detail = data.data.data.pdesc
})
}
}
//配置路由规则
var routes = [
{path:"/jia",name:"home",component:Home},
{path:"/liebiao",name:"list",component:List},
{path:"/qita",name:"other",component:Other}
]
//实例化
var router = new VueRouter({
routes:routes
})
//路由挂载
var vm = new Vue({
el:"#out",
router:router
})
</script>
</html>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>命名路由、query传参(嵌套路由)</title>
<script src="../js/vue.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/axios.min.js" type="text/javascript" charset="utf-8"></script>
<script src="../js/vue-router.js" type="text/javascript" charset="utf-8"></script>
<style type="text/css">
.router-link-active{
color: paleturquoise;
}
</style>
</head>
<body>
<div id="out">
<!--命名路由-->
<router-link :to="{name:'home'}" tag="span">首页</router-link>
<router-link :to="{name:'list'}" tag="span">列表</router-link>
<router-link :to="{name:'other'}" tag="span">其他</router-link>
<!--路由容器-->
<router-view></router-view>
</div>
<!--组件模板-->
<template id="home">
<div>
<h2>首页</h2>
</div>
</template>
<template id="list">
<div>
<h2>列表数据</h2>
<!--遍历展示-->
<ul>
<li v-for="item in arr"><router-link :to="{name:'detail',query:{id:item.pid}}" tag="span">{{item.pname}}</router-link></li>
</ul>
<router-view></router-view>
</div>
</template>
<template id="other">
<div>
<h2>其他</h2>
</div>
</template>
<template id="detail">
<div>
<h2>详情</h2>
<p>{{detail}}</p>
</div>
</template>
</body>
<script type="text/javascript">
//组件注册
var Home = {
template:"#home"
}
var List = {
template:"#list",
data:function(){
return{
arr:[]
}
},
mounted(){
var _this = this;
axios({
url:"http://jx.xuzhixiang.top/ap/api/productlist.php"
}).then(function(data){
_this.arr = data.data.data
})
}
}
var Other = {
template:"#other",
}
var Detail = {
template:"#detail",
data:function(){
return{
detail:""
}
},
mounted(){
var _this = this;
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:_this.$route.query.id}
}).then(function(data){
_this.detail= data.data.data.pdesc
})
},
watch:{
'$route'(a){
var _this = this;
axios({
url:"http://jx.xuzhixiang.top/ap/api/detail.php",
params:{id:a.query.id}
}).then(function(data){
_this.detail= data.data.data.pdesc
})
}
}
}
//配置路由规则
var routes = [
{path:"/jia",name:"home",component:Home},
{path:"/liebiao",name:"list",component:List,
children:[
{path:"/detail",name:"detail",component:Detail}
]
},
{path:"/qita",name:"other",component:Other}
]
//实例化
var router = new VueRouter({
routes:routes
})
//路由挂载
var vm = new Vue({
el:"#out",
router:router
})
</script>
</html>