vue-router安装
- cdn连接 https://www.bootcdn.cn/vue-router/
- Github https://github.com/vuejs/vue-router
- npm安装方式
- npm i vue-router
vue-router简单使用以及配置
html页面(依次引入vue.js,router.js以及个人配置的app.js)
<div id="app">
<router-link to="all">全部产品</router-link>
<router-link to="/about">关于我们</router-link>
<router-link to="all">全部产品</router-link>
<router-view></router-view>
</div>
<script src="../lib/vue.js"></script>
<script src="../lib/vue-router.js"></script>
<script src="./app.js"></script>
app.js(配置文件详解)
配置每个不同的路由,每新增一个路由在routers数组内新增一个
let routers=[
{
path:"/",
component:{
template:`
<div>
<h1>你好,欢迎使用Vue-router</h1>
<p>这是示例首页</p>
</div>
`
}
},
{
path:"/about",
component:{
template:`
<div>
<h1>关于我们</h1>
<p>官网:https://cncat.cn</p>
<p>Github https://github.com/shiyuemengxiang</p>
<p>微博: @十月梦想i</p>
</div>
`
}
},
{
path:"/all",
component:{
template:`
<div>
<h1>你好,欢迎使用示例代码,产品页</h1>
<p>这是一个演示路由</p>
</div>
`
}
}
]
去实例化这个vuerouter
let router=new VueRouter({
routes:routers;//这里的routers表示上述的路由集合,routes是对象不能修改
})
new Vue({
el:"#app",
router:router;//路由
})
在html中rooter-link表示单个路由,需要进行页面渲染router-view
参数传递以及接收
html文件
<div id="app">
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<router-link to="/user/:王二蛋">王二蛋</router-link>
<router-link to="/user/:李栓柱">李栓柱</router-link>
<router-view></router-view>
</div>
<script src="../lib/vue.js"></script>
<script src="../lib/vue-router.js"></script>
<script src="./app.js"></script>
在上述中可能看到王二蛋和李栓柱这两个路由与之前的路由不太一样,我们怎么去匹配这个/:的名字呢?这个小节来介绍参数的匹配
app.js
let routers=[
{
path:"/",
component:{
template:`
<div>
<h1>这是首页</h1>
</div>
`
}
},
{
path:"/about",
component:{
template:`
<div>
<h1>这是关于我们 </h1>
<p>见到过洒家公司更加高大嘎达搜嘎圣诞节计划噶电视剧哈根达斯 可好可好看见爱迪生几个大厦广东省给大家广泛加油噶都是噶绝对是天涯U盾是他雕塑艺术元旦搜嘎U盾世园会返回法国好尬道森股份都是会议厅发的说法哈迪斯韩国人搭撒范德萨甜热热大体上压发大水月爱的人他多所绕多所一天打死人员的收入啊同意反对虽然都是亚当斯依然要的撒反对算得上vtyfradsy结婚呀多发点算得上元都是他雨点洒脱的声音突然都是 同意反对萨让对手亚当斯</p>
</div>
`}
},
{
path:"/user/:name",
component:{
template:`
<div>
<h1>我的名字是{{$route.params.name}}</h1>
<h1>我今年 {{$route.query.age}} 岁啦!!</h1>
</div>
`}
},
]
let router=new VueRouter({
routes:routers
})
new Vue({
el:"#app",
router:router
})
上述的:name很清楚就是匹配的路由参数,这个数据如何匹配呢?
$route.params.name
就可以获取到这个数据,上面的app.js中还发现了$route.query.age
这个又是什么呢?
我们看一下一个标准的url(统一资源定位符 ),
https://info.test.com/user/:王二蛋?age=18;
这个query用于查询的是url的参数!而params用于匹配顶级路由后面的参数(:后);
子路由
还看一下上述的简单的html文件
<div id="app">
<router-link to="/">首页</router-link>
<router-link to="/about">关于我们</router-link>
<router-link to="/user/:王二蛋">王二蛋</router-link>
<router-link to="/user/:李栓柱">李栓柱</router-link>
<router-view></router-view>
</div>
app.js那么我们如何匹配一个子路由呢?
let routers=[
{
path:"/",
component:{
template:`
<div>
<h1>这是首页</h1>
</div>
`
}
},
{
path:"/about",
component:{
template:`
<div>
<h1>这是关于我们 </h1>
<p>见到过洒家公司更加高大嘎达搜嘎圣诞节计划噶电视剧哈根达斯 可好可好看见爱迪生几个大厦广东省给大家广泛加油噶都是噶绝对是天涯U盾是他雕塑艺术元旦搜嘎U盾世园会返回法国好尬道森股份都是会议厅发的说法哈迪斯韩国人搭撒范德萨甜热热大体上压发大水月爱的人他多所绕多所一天打死人员的收入啊同意反对虽然都是亚当斯依然要的撒反对算得上vtyfradsy结婚呀多发点算得上元都是他雨点洒脱的声音突然都是 同意反对萨让对手亚当斯</p>
</div>
`}
},
{
path:"/user/:name",
component:{
template:`
<div>
<h1>我的名字是{{$route.params.name}}</h1>
<router-link :to="'/user/'+$route.params.name+'/more' ">更多</router-link>
<!--<router-link to="more" append>更多信息</router-link>-->
<router-view></router-view>
</div>
`},
children : [
{
path:"more",
component:{
template:`
<div>
<p>用户{{$route.params.name}}</p>
<p>这是一个详细信息,来自子路由的匹配</p>
</div>
`
}
}
]
},
]
子路由的配置很顶级路由类似,不过在每个子路由中可以定义在一个children中(数组对象),
不过这个子路由需要在顶级路由中调取,以及在顶级路由进行渲染
子路由绑定数据的两种方式
<router-link to="more" append>更多信息</router-link>
<router-link :to="'/user/'+$route.params.name+'/more' ">更多</router-link>
一个完整的路由以及子路由!
{
path:"/user/:name",
component:{
template:`
<div>
<h1>我的名字是{{$route.params.name}}</h1>
<router-link :to="'/user/'+$route.params.name+'/more' ">更多</router-link>
<!--<router-link to="more" append>更多信息</router-link>-->
<router-view></router-view>
</div>
`},
children : [
{
path:"more",
component:{
template:`
<div>
<p>用户{{$route.params.name}}</p>
<p>这是一个详细信息,来自子路由的匹配</p>
</div>
`
}
}
]
}
手动传参
在router-link是vue-router是官方内置给我们的一些组件来实现访问不同路由,那么我们如何来实现这些功能!
下面我们使用自己的一个按钮,我们绑定一个事件来实现不同路由的访问;
html
<div id="app">
<router-link to="/">首页</router-link>
<router-link to="/user/:王铁蛋">王铁蛋</router-link>
<router-link to="/user/:李栓柱">李栓柱</router-link>
<router-link to="/post">文章管理</router-link>
<button @click="surf">随机访问</button>
<router-view ></router-view>
</div>
app.js(我们指定的methods)
new Vue({
el:"#app",
router:router,
methods:{
surf:()=>{
setTimeout(()=>{
this.router.push('/post');
setTimeout(()=>{
this.router.push({name:'user',params:{name:'李栓柱'}})
},2000)
},2000)
}
}
})
视图命名
在之前我们需要使用这个router-view进行数据渲染,我们可以指定多个router-view,指定不同的name
html
<router-link to="/">首页</router-link>
<router-link to="/user">用户</router-link>
<router-link to="post">帖子</router-link>
<router-view></router-view>
<router-view name="side"></router-view>
<router-view name="content"></router-view>
app.js
路由设置项
{
path:"/user",
components:{
side:{
template:`
<ul>
<h3>帖子管理</h3>
<li>删除帖子</li>
<li>加精帖子</li>
<li>下沉帖子</li>
</ul>
`
},
content:{
template:`
<ul>
<h3>用户管理</h3>
<li>添加会员</li>
<li>禁言用户</li>
<li>设置权限</li>
</ul>
`
}
}
},
此时我们需要渲染的多个视图层,因此此时的组件(components)要用复数(s)!
打开页面会渲染这个两个!
导航守卫(导航钩子)
在实际中,比如在一个站点中出现三个模块,首页,登录,帖子管理
通常下,在用户没有登录下,我们不希望也是没有权限进入帖子管理(用户中心),此时我们就用到了导航守卫
<div id="app">
<router-link to="/">首页</router-link>
<router-link to="/login">登录</router-link>
<router-link to="/post">帖子管理</router-link>
<router-view></router-view>
</div>
在拦截组件中应该是不科学的,因此我们在路由访问前进行判断的拦截!
var router=new VueRouter({
routes:routers
})
//实例化的router对象
router.beforeEach((to, from, next)=>{
var login=false;
if(!login&& to.path=='/post'){
next('/login')
}else{
next();
}
})
router.afterEach((to,from)=>{
console.log("to:",to);
console.log("from:",from)
})
beforeEach和,afterEach表示路由访问前后的行为,参数是一个callback,callback存在三个参数,to,from和next(),
to:到哪里去(目的路由),from(当前路由),next()中间件
路由匹配
上述的导航守卫可以为我们避免一些拦截,但是这样真的好吗?我们继续看一下例子
<div id="app">
<router-link to="/">首页</router-link>
<router-link to="/login">登录</router-link>
<router-link to="/post">帖子管理</router-link>
<router-view></router-view>
</div>
首先我们假设已经登录,在帖子路由下存在子路由(帖子内容)
当我们使用上述的路由守卫,在访问路由前跳转之登录页面(/login),但是我们之间去访问子路由的帖子内容,会神奇的发现居然是无法拦截,仅能拦截帖子管理(/post),而子路由帖子内容(/post/test)则正常访问,仅能匹配(/post)进行拦截,那么我们该如何搞定这个问题呢?
我么在这个路由访问过程以及结束后,打印函数to这个对象,发现了to.matched对象,存在父级路由和具体的子路由,
我们使用some方法循环一下,把对象中的每一项return path=父级路由拦截的post,既可解决,
app.js具体代码
router.beforeEach((to, from, next)=>{
var login=false;
if(login==false && to.matched.some((item)=>{
return item.path=="/post";
})){
next('/login')
}else{
next();
}
})
router.afterEach((to,from)=>{
console.log("to:",to.matched);
console.log("from:",from)
})
转自
https://cloud.tencent.com/developer/article/1352083
Vue-router从入门到弃坑