【vuejs路由】vuejs 路由基础入门实战操作详细指南

官方文档

https://router.vuejs.org/zh-cn/

用 Vue.js + vue-router 创建单页应用,是非常简单的。使用 Vue.js ,我们已经可以通过组合组件来组成应用程序,当你要把 vue-router 添加进来,我们需要做的是,将组件(components)映射到路由(routes),然后告诉 vue-router 在哪里渲染它们。

hash 和 history模式

默认hash模式:

以#/开始匹配,这种叫作哈希模式(hash)

HTML5 History 模式:

/开始,就是我们常见的方式没有 # 符号

<a href= "/" >首页</a>
<a href= "/work" >工作</a>

我们此时使用a标签来切换比较麻烦,每次更改路由模式的时候,需要单独改a标签里面herf的链接

在vue里面提供了一个更好的方式,来解决这个问题

<router-link to= "/" >home主页</router-link>
  <router-link to= "/work" >我的工作</router-link>

<router-view/>

每次切换路由的时候,里面的内容都依靠 来显示在页面上
只有页面有导航的地方,打算让组件显示在页面上,必须写这个标签

<template>
   <div id= "app" >
     <router-link to= "/" >home主页</router-link>
     <router-link to= "/work" >我的工作</router-link>
     <router-view> 这个标签用来显示页面内容
   </router-view></div>
</template>

router-link 默认解析成a标签

<a href= "#/" class= "router-link-active" >home主页</a>
<a href= "#/work" class= "router-link-exact-active router-link-active" >我的工作</a>

给导航添加激活样式

通过css里面设置

.router-link-active{
     background-color : red
}

当我们单独设置激活样式的时候,根路由 / 永远都会匹配到样式

我们可以在标签中添加 exact 方式来解决永远都会匹配到跟路径样式问题

直接加在标签属性上
<router-link exact= "" to= "/" >home主页</router-link>

我们自己来给导航添加自定义class名字

通过 设置 active-class属性值 改变默认的激活样式类

<router-link to= "/work" active-class= "starkwang" >我的工作</router-link>

统一更改激活样式

在 router/index.js里面设置 linkExactActiveClass属性

export default new Router({
     // mode: 'history',
     mode: 'hash' ,
     linkExactActiveClass: 'shudong' , //通过设置这个属性值,给所有的激活样式,添加统一的类
 
 
当我们统一设置后,每次激活的路由标签,都带着自己设置的这个shudong类
<a href= "#/work" class= "shudong starkwang" >我的工作</a>

使用属性 tag 统一更改路由编译后的标签名字 -> <li> </li>

默认编译的标签名字是 a

     <router-link to= "/stark" tag= "li" >我的Stark</router-link>
 
更改完后的dom
<li class= "shudong router-link-active" >我的Stark</li>

路由嵌套 chidren

使用方式

{
     path: '/about' // 这是一级路由
     component: About,
     children: [{  // 里面是嵌套路由
             path: 'blog' //如果在这个嵌套
             name: 'blog' ,
             component: Blog
         },
         {
             path: '/info' ,
             name: 'info' ,
             component: Info
         }
     ]
}

如果在这个嵌套里面的path:” 留空,默认会显示这个组件

http: //localhost:8080/#/about
此时会把 这个默认留空的嵌套路由组件显示出来,也就是上面的blog 组件显示出来

如果嵌套路由里面的path:’blog’ 写具体的路由,则访问的时候必须匹配

必须是这个路由精准匹配
 
http: //localhost:8080/#/about/blog
 
这样才会把这个blog嵌套路由组件显示出来

以 / 开头的嵌套路径会被当作根路径。

这让你充分的使用嵌套组件而无须设置嵌套的路径。

         {
         path: '/about' // 这是一级路由
         component: About,
         children: [{  // 里面是嵌套路由
                 path: 'blog' //如果在这个嵌套
                 name: 'blog' ,
                 component: Blog
             },
             {
                 path: '/info' , // 以 / 开头的嵌套路径会被当作跟路径
                 name: 'info' ,
                 component: Info
             }
         ]
     }
 
访问方式:
http: //localhost:8080/#/info

如果去掉/ 此时去掉了 ‘/info’ -> ‘info’

     {
         path: '/about' // 这是一级路由
         component: About,
         children: [{  // 里面是嵌套路由
                 path: 'blog' //如果在这个嵌套
                 name: 'blog' ,
                 component: Blog
             },
             {
                 path: 'info' , // 此时去掉了 '/info'  -> 'info'
                 name: 'info' ,
                 component: Info
             }
         ]
     }
 
   访问方式:
http: //localhost:8080/#/about/info

你会发现,children 配置就是像 routes 配置一样的路由配置数组,所以呢,你可以嵌套多层路由。

此时,基于上面的配置,当你访问 /about/info 时,about 的出口是不会渲染任何东西,这是因为没有匹配到合适的子路由。

重定向

使用方式 path:’*’

这个 * 是匹配上面没有找到的路径,会到这里
可以直接写:component: NotFound,

redirect 这是一个函数,里面有参数 to
to 打印出来是一个对象
{name: undefined, meta: {…}, path: “/aaa”, hash: “”, query: {…}, …}

通过 to.path 可以获取当前用户访问的路径,来写一些逻辑跳转下面是使用详细方式

{
     path: '*' ,
     // component: NotFound,
     redirect: (to) => {
         console.log(to);
         if (to.path === '/aaa' ) {
             return '/work'
         } else if (to.path === '/bbb' ) {
             return '/info'
         } else {
             return '/'
         }
     }
}

最后附上所有路由文件代码

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Work from '@/components/Work'
import Stark from '@/components/Stark'
 
Vue.use(Router)
const UserProfile = { template: `<div> 我是profile 组件 </div>` };
const UserPosts = { template: `<div> 我是UserPosts 组件 </div>` };
const Blog = { template: `<div> 我是Blog 组件 </div>` };
const Info = { template: `<div> 我是Info 组件 </div>` };
const NotFound = { template: `<div>404 您访问的页面不存在 </div>` };
const About = { template: `<div> 我是About组件 <router-view> </router-view> </div>` };
const User = {
     // template: '<div>User {{ $route.params.id }}</div>'
     template: ' <div class="user"> \
             <h2><a name="13"></a> User {{ $route.params.id } } </h2> \
             <router-view> </router-view> \
             </div>'
}
 
export default new Router({
     // mode: 'history',
     mode: 'hash' ,
     linkExactActiveClass: 'shudong' ,
     routes: [{
             path: '/' ,
             name: 'Hello' ,
             component: HelloWorld
         },
         {
             path: '/work' ,
             name: 'Work' ,
             component: Work
         },
         {
             path: '/stark' ,
             name: 'stark' ,
             component: Stark
         },
         // { path: '/user/:id', component: User }
         {
             path: '/user/:id' ,
             component: User,
             children: [{
                     // 当 /user/:id/profile 匹配成功,
                     // UserProfile 会被渲染在 User 的 <router-view> 中
                     path: 'profile' ,
                     component: UserProfile
                 },
                 {
                     // 当 /user/:id/posts 匹配成功
                     // UserPosts 会被渲染在 User 的 <router-view> 中
                     path: 'posts' ,
                     component: UserPosts
                 }
             ]
         },
         {
             path: '/about' ,
             component: About,
             children: [{
                     path: 'blog' ,
                     name: 'blog' ,
                     component: Blog
                 },
                 {
                     path: '/info' ,
                     name: 'info' ,
                     component: Info
                 }
             ]
         },
         {
             path: '*' ,
             // component: NotFound,
             redirect: (to) => {
                 console.log(to);
                 if (to.path === '/aaa' ) {
                     return '/work'
                 } else if (to.path === '/bbb' ) {
                     return '/info'
                 } else {
                     return '/'
                 }
             }
         }
     ]
})

路由传参

传一个参数

在路由里面的path: '/user/:stark'   这个冒号后面跟的字符串相当于 key
在组件里面使用 this .$route.params.stark 来获取这个value的值
访问方式:
 
http: //localhost:8080/#/user/wang
 
wang 就是console.log( this .$route.params.stark) 值
 
在后面跟 ?号
可以 写wang 或不写 后面的参数
如果不跟?号 ,必须写这个参数

如果想传多个参数

在路由里面添加多个key
path: '/user/:stark?/:name?
 
访问方式
http: //localhost:8080/#/user/wang/stark
 
打印结果 console.log( this .$route.params)
{stark: "wang" , name: "shudong" }
   {
     path: '/user/:stark?/:name?' ,
     name: 'user' ,
     component: User
},

案例:

user 组件

<template>
     <div>
         <router-link :to= "'/user/' + item.id" v- for = "item in userList" >{{item.username}} </router-link>
         <div>
                 <p> 姓名:{{userInfo.username}}</p>
                 <p> 爱好:{{userInfo.hobby}}</p>
                 <p> 性别:{{userInfo.sex}}</p>
         </div>
     </div>
</template>
 
<script>
     let data = [
         {
             id:1,
             tip: 'vip' ,
             username: 'luchang' ,
             sex: '男' ,
             hobby: 'coding'
         },
         {
             id:2,
             tip: 'vip' ,
             username: 'guomian' ,
             sex: '男' ,
             hobby: '女'
         },
         {
             id:3,
             tip: 'common' ,
             username: 'zhangming' ,
             sex: '男' ,
             hobby: 'bug'
         },
     ]
     export default {
         data(){
             return {
                 userList:data,
                 userInfo: ''
             }
         },
         watch:{
             $route(){
                 this .getData();
             }
         },
         created(){
             this .getData();
         },
         methods:{
             getData(){
                 // let id = this.$route;
                 console.log( this .$route);
                 let id = this .$route.params.userId;
                 if (id){
                     this .userInfo = this .userList.filter((item)=>{
                         return item.id == id;
                     })[0]
                 }
                 console.log( this .userInfo);
                 // console.log(this.$route.params.stark);
             }
         }
     }
</script>

路由

import Vue from 'vue'
import Router from 'vue-router'
import HelloWorld from '@/components/HelloWorld'
import Work from '@/components/Work'
import Stark from '@/components/Stark'
import User from '@/components/User'
 
Vue.use(Router)
const UserProfile = { template: `<div> 我是profile 组件 </div>` };
const UserPosts = { template: `<div> 我是UserPosts 组件 </div>` };
const Blog = { template: `<div> 我是Blog 组件 </div>` };
const Info = { template: `<div> 我是Info 组件 </div>` };
const NotFound = { template: `<div>404 您访问的页面不存在 </div>` };
const About = { template: `<div> 我是About组件 <router-view> </router-view> </div>` };
const Users = {
     // template: '<div>User {{ $route.params.id }}</div>'
     template: ' <div class="user"> \
             <h2><a name="15"></a> User {{ $route.params.id } } </h2> \
             <router-view> </router-view> \
             </div>'
}
 
export default new Router({
     // mode: 'history',
     mode: 'hash' ,
     linkExactActiveClass: 'shudong' ,
     routes: [{
             path: '/' ,
             name: 'Hello' ,
             component: HelloWorld
         },
         {
             path: '/work' ,
             name: 'Work' ,
             component: Work
         },
         {
             path: '/user/:userId?/:name?' ,
             name: 'user' ,
             component: User
         },
         {
             path: '/stark' ,
             name: 'stark' ,
             component: Stark
         },
         // { path: '/user/:id', component: User }
         {
             path: '/users/:id' ,
             component: Users,
             children: [{
                     // 当 /user/:id/profile 匹配成功,
                     // UserProfile 会被渲染在 User 的 <router-view> 中
                     path: 'profile' ,
                     component: UserProfile
                 },
                 {
                     // 当 /user/:id/posts 匹配成功
                     // UserPosts 会被渲染在 User 的 <router-view> 中
                     path: 'posts' ,
                     component: UserPosts
                 }
             ]
         },
         {
             path: '/about' ,
             component: About,
             children: [{
                     path: 'blog' ,
                     name: 'blog' ,
                     component: Blog
                 },
                 {
                     path: '/info' ,
                     name: 'info' ,
                     component: Info
                 }
             ]
         },
         {
             path: '*' ,
             // component: NotFound,
             redirect: (to) => {
                 // console.log(to);
                 if (to.path === '/aaa' ) {
                     return '/work'
                 } else if (to.path === '/bbb' ) {
                     return '/info'
                 } else {
                     return '/'
                 }
             }
         }
     ]
})

原文地址:https://segmentfault.com/a/1190000011612365

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值