当前位置:   article > 正文

vue路由---超级详细,通俗易懂(完整版)_vue 菜单路由培训讲解

vue 菜单路由培训讲解

vue路由—超级详细,通俗易懂

生活中的路由

设备和ip的映射关系

在这里插入图片描述

后端路由

接口和服务的映射关系

在这里插入图片描述

前端路由

路径和组件的映射关系

为什么使用路由

在一个页面里,切换业务场景

vue单页面应用(SPA):所有的功能在一个html页面上实现

优点:

  • 整体不刷新页面,用户体验好
  • 数据传递容易,开发效率高

缺点:

  • 开发成本高(需要学习专门只是)
  • 首次加载比较慢,不利于SEO

vue-router介绍

vue集成路由

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

vue-router模块包,它和vue.js深度集成

定义映射规则-----模块化—提供2个内置全局组件

路由-组件分类

.vue文件分2类,一个页面组件,一个是复用组件

.vue文件本质无区别

src/views(pages)文件夹 —页面组件—配合路由使用

src/components文件夹 —复用组件(展示数据–复用)

在这里插入图片描述

总结:views下的页面组件,配合路由切换;components下的一般引入到views下的vue中复用展示数据

vue-router使用

安装
yarn add vue-router@3.5.1
或者
npm i add vue-router@3.5.1
  • 1
  • 2
  • 3
导入路由

src下创建router/index.js

import Vue from 'vue'
// 1导入路由 
import VueRouter from 'vue-router'
// 引入组件
// import Home from '../views/Home'
// import Login from '../views/Login'
// import Register from '../views/Register'

// 2 使用路由插件
// 在vue中  使用vue的插件  需要调用Vue.use()
Vue.use(VueRouter)

// 3 创建vue路由规则
const routes = [
  // 路径和组件的映射关系
  {
    path: '/',
    // component: Home,
    // 路由懒加载
    component: () => import('../views/Home'),
  },
  {
    path: '/login',
    component: () => import('../views/Login'),
  },
  {
    path: '/register',
    component: () => import('../views/Register'),
  },
]

// 4创建路由对象  传入规则
const router = new VueRouter({
  // routes: routes,
  routes,
})

// 导出路由对象
export default router
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
关联到vue实例
import router from './router'

Vue.config.productionTip = false

new Vue({
  router,
  render: (h) => h(App),
}).$mount('#app')
// .$mount挂载到 id="app"的元素上  相当于el选项
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
路由出口

App.vue

<router-view></router-view>
  • 1

声明式导航

使用全局组件 router-link来替代a标签

  • vue-router提供了一个全局组件 router-link
  • router-link 实质上最终会渲染成a链接,to属性等价于提供href属性(to无需#)
  • router-link提供了声明式导航高亮的功能(自带类名)
<template>
  <div>
    <div class="nav">
      <router-link to="/">首页</router-link>
      <router-link to="/login">登陆</router-link>
      <router-link to="/register">注册</router-link>
    </div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {}
</script>

<style scoped>
.nav {
  display: flex;
  width: 400px;
  justify-content: space-around;
}

.router-link-exact-active {
  color: red;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

重定向

强制切换到目标path上

  • 网页打开url默认hash值是 / 路径
  • redirect 是设置要重定向到那个路由路径

需求:网页默认打开, 匹配路由 ‘/’ 强制切换到 ‘/home’上

const routes = [
  {
    path: '/',
    redirect: '/h ome', //重定向到  /home
  },
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

总结: 强制重定向后,还会重新来数组中匹配一次规则

路由-404页面

如果路由hash值没有和数组里规则匹配

默认给一个404页面

路由最后,path匹配 *(任意路径) --前面都不匹配,就匹配最后这个,显示对应的组件

  • 创建NotFound页面

    <template>
      <div>404</div>
    </template>
    
    <script>
    export default {}
    </script>
    
    <style scoped></style>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 修改路由配置

    const routes = [
         // 写在最后
      // {
      //   path: '*',
      //   redirect: '/home',
      // },
      {
        path: '*',
        component: () => import('../views/NotFound'),
      },
    ]
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

**总结:**如果路由未命中任何规则,给出一个兜底的404页面

路由模式设置

修改路由在地址栏的模式

hash路由 : 地址栏URL中的#符号 http://localhost:3000/#/abc ,不会被包括在HTTP请求中,对后端完全没有影响,改变hash不会重新加载页面

history路由:http://localhost:3000/abc(需要服务器支持,否则找的是文件夹)

​ 利用了HTML5 新增的pushState() 和replaceState()方法

// 4创建路由对象  传入规则
const router = new VueRouter({
  // routes: routes,
  routes,
  mode: 'history', //默认是hash
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

vue路由-编程式导航

编程式导航:用js代码跳转

声明式导航:router-link实现跳转

语法:

this.$router.push({
    path:"路由路径",
    name:"路由名"
})
  • 1
  • 2
  • 3
  • 4

router/index.js 路由规则里,给路由起名字

const routes = [
  // 路径和组件的映射关系
  {
    path: '/home',
    name: 'home',
    component: () => import('../views/Home'),
  },
  {
    path: '/login',
    name:"login",
    component: () => import('../views/Login'),
  },
  {
    path: '/register', 
    name:"register",
    component: () => import('../views/Register'),
  },

]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

App.vue中router-link换成span,配合js的编程式导航跳转

编程式导航: js方式跳转路由
语法:
this. r o u t e r . p u s h ( p a t h : " 路由路径 " ) t h i s . router.push({path:"路由路径"}) this. router.push(path:"路由路径")this.router.push({name:“路由名”})
注意:
虽然用name跳转,但是url的hash值还是切换path路径值
场景
方便修改,name路由名(在页面上看不见,随便修改)
path可以在url的hash值看到(尽量符合组件内规范)

<template>
  <div>
    <div class="nav">
      <!-- <router-link to="/">首页</router-link>
      <router-link to="/login">登陆</router-link>
      <router-link to="/register">注册</router-link> -->
      <span @click="goTo('/home', 'home')">首页</span>
      <span @click="goTo('/login', 'login')">登录</span>
      <span@click="goTo('/register', 'register')">注册</span@click=>
    </div>
    <router-view></router-view>
  </div>
</template>

<script>

/* 
编程式导航:  js方式跳转路由
语法:
this.$router.push({path:"路由路径"})
this.$router.push({name:"路由名"})
注意:
虽然用name跳转,但是url的hash值还是切换path路径值
场景
方便修改,name路由名(在页面上看不见,随便修改)
path可以在url的hash值看到(尽量符合组件内规范)
*/
export default {
  methods: {
    goTo(targetPath,targetName) {
      this.$router.push({
        // path:targetPath
        name:targetName
      })
    }
  },
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

嵌套路由

在现有的一级路由下,再嵌套二级路由

在这里插入图片描述

  • 创建需要用的所有组件
    • src/views/Find.vue ----发现音乐
    • src/views/My.vue—我的音乐
    • src/views/Second/Recommend.vue —发现音乐/推荐页面
    • src/views/Second/Ranking.vue —发现音乐/排行榜
    • src/views/Second/SongList.vue —发现音乐/歌单页面
  • main.js 配置2级路由
    • 一级路由由path从/开始定义
    • 二级路由往后path 直接写名字 ,无需 / 开头
    • 二级路由在上级路由的children数组里编写路由信息对象
  • 说明
    • App.vue 的router-view 负责发现音乐 和我的音乐页面 切换
    • Find.vue的router-view负责发现音乐下的三个页面切换
配置路由规则
const routes = [
  {
    path: '/',
    redirect: '/find', //重定向到  /home
  },
  {
    path: '/find',
    redirect: '/find/recommend',
    component: () => import('../views/Find'),
    children: [
      {
        path: 'recommend',
        component: () => import('../views/Second/Recommend'),
      },
      {
        path: 'ranking',
        component: () => import('../views/Second/Ranking'),
      },
      {
        path: 'songlist',
        component: () => import('../views/Second/SongList'),
      },
    ],
  },
  {
    path: '/my',
    component: () => import('../views/My'),
  },
  {
    path: '*',
    component: () => import('../views/NotFound'),
  },
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
App.vue写路由出口

App.vue 的router-view 负责发现音乐 和我的音乐页面 切换

<template>
  <div>
    <div class="nav">
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
    </div>
    <router-view></router-view>
  </div>
</template>

<script>
export default {}
</script>

<style scoped>
.nav {
  display: flex;
  width: 400px;
  justify-content: space-around;
}
</style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
Find.vue写二级路由出口

Find.vue的router-view负责发现音乐下的三个页面切换

<template>
  <div>
    <div class="nav_main">
      <router-link to="/find/recommend">推荐</router-link>
      <router-link to="/find/ranking">排行榜</router-link>
      <router-link to="/find/songlist">歌单</router-link>
    </div>
    <div style="1px solid red">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {}
</script>

<style scoped>
.nav_main {
  background-color: red;
  color: white;
  padding: 10px 0;
}
.nav_main a {
  text-align: center;
  text-decoration: none;
  color: white;
  margin: 7px 20px;
  padding: 0px 15px;
  height: 20px;
  display: inline-block;
  line-height: 20px;
}
.nav_main a:hover {
  background-color: brown;
}

.nav_main .router-link-exact-active {
  background-color: brown;
}
</style>

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42

**总结:**嵌套路由,找准在那个页面里写router-view和对应的规则里写children

声明式导航–类名区别

router-link 自带的2个类名的区别是什么

router-link-active(模糊匹配) url中hash值,包含href属性值这个路径

router-link-exact-active(精确匹配) url中hash值路径,与href属性值完全相同,设置此类名

在这里插入图片描述

路由传参

跳转路由时 可以给路由对应的组件内传参

声明式导航

router-link 上的to属性,语法格式

/path?参数名=值
/path/值  ------需要路由对象提前配置   path:'/path/:参数名'
  • 1
  • 2

对应的页面组件接收传递过来的值

$route.query.参数名
$route.params.参数名
  • 1
  • 2

router/index.js

// 3 创建vue路由规则
const routes = [
  {
    path: '/',
    redirect: '/list', //重定向到  /home
  },
  {
    path: '/list',
    component: () => import('../views/List'),
  },
  {
    path: '/part',
    component: () => import('../views/Part'),
  },
  {
    path: '/detail/:name',
    component: () => import('../views/Detail'),
  },
  {
    path: '*',
    component: () => import('../views/NotFound'),
  },
]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

List.vue

<template>
  <div>
    <router-link to="/part?name=小川">朋友--小川</router-link>
    <router-link to="/detail/小妞">朋友--小妞</router-link>
    <router-link :to="'/part?name=' + n1">朋友--{{ n1 }}</router-link>
    <router-link :to="'/detail/' + n1">朋友--{{ n1 }}</router-link>
  </div>
</template>
<script>
export default {
  data() {
    return {
      n1: '花姐',
      n2: '露露',
    }
  },
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

Part.vue

<template>
  <div>
    <p>关注明星</p>
    {{ $route.query.name }}
    <hr />
    {{ name }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: '',
    }
  },
  created() {
    // 创建完成  第一次操作data中数据  执行一次
    this.name = this.$route.query.name
    console.log(this.name)
  },
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

Detail.vue

<template>
  <div>
    detail
    {{ $route.params.name }}
    <hr />
    {{ name }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      name: '',
    }
  },
  created() {
    this.name = this.$route.params.name
  },
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

编程式导航

语法:

query/params 任选一个

this.$router.push({
    path:"路由路径",
    name:"路由名",
    query:{
        "参数名":"值"
    },
    params:{
        "参数名":"值"
    }
})
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

List.vue

<template>
  <div>
    <router-link to="/part?name=小川">朋友--小川</router-link>
    <router-link to="/detail/小妞">朋友--小妞</router-link>
    <router-link :to="'/part?name=' + n1">朋友--{{ n1 }}</router-link>
    <router-link :to="'/detail/' + n1">朋友--{{ n1 }}</router-link>

    <hr />
    <span @click="oneFn">朋友--小川</span>
    <span @click="twoFn">朋友--小妞</span>
    <span>朋友--{{ n1 }}</span>
    <span>朋友--{{ n1 }}</span>
  </div>
</template>

<script>
export default {
  data() {
    return {
      n1: '花姐',
      n2: '露露',
    }
  },
  methods: {
    oneFn() {
      this.$router.push({
        path: '/part',
        query: {
          // name: '小川',
          name: this.n2,
        },
      })
    },
    twoFn() {
      // path会自动的忽略params
      // this.$router.push({
      //   name: 'detail',
      //   params: {
      //     name: '小妞',
      //   },
      // })
      this.$router.push('/detail/' + this.n1)
    },
  },
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

路由守卫

https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

ue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航。这里有很多方式植入路由导航中:全局的,单个路由独享的,或者组件级的。

全局前置守卫

需求:在跳转路由前,判断用户是否登录,登录了才能跳转到“我的音乐“页面,未登录弹窗提示

在路由对象上使用固定的方法 beforeEach

路由跳转"之前" 先执行这里,决定是否跳转
router.beforeEach((to,from ,next)=>{
to 要跳转到的路由 (路由对象信息) 目标
from 从哪里跳转的路由(路由对象信息) 来源
next 函数体, next() 才会让路由正常的跳转切换, next(false)在原地停留 next(“路由路径”) 强制修改到另一个路由路径上
不调用next 页面留在原地
})

// 1 在路由对象上使用固定的方法 beforeEach
/* 
路由跳转"之前" 先执行这里,决定是否跳转
router.beforeEach((to,from ,next)=>{
to  要跳转到的路由 (路由对象信息)  目标
from 从哪里跳转的路由(路由对象信息)  来源
next  函数体, next() 才会让路由正常的跳转切换,  next(false)在原地停留  next("路由路径") 强制修改到另一个路由路径上
不调用next 页面留在原地
})


*/
// 在跳转路由前,判断用户是否登录,登录了才能跳转到“part“页面,未登录弹窗提示
const isLogin = false //登陆状态 (未登陆)
router.beforeEach((to, from, next) => {
  // console.log(to)
  // console.log(from)
  if (to.path === '/part' && isLogin === true) {
    alert('请登陆')
    next(false)
  } else {
    next() //正常放行
  }
})

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Vant组件库

https://vant-contrib.gitee.io/vant/v2/#/zh-CN/

vant 轻量、可靠的移动端 Vue 组件库

安装
yarn add vant@latest-v2 -S
  • 1
导入所有的组件

main.js中导入

// 导入所有的组件
import Vant from 'vant'
import 'vant/lib/index.css'

Vue.use(Vant)
  • 1
  • 2
  • 3
  • 4
  • 5

使用组件

<van-button type="primary">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>
  • 1
  • 2
  • 3
  • 4
  • 5
手动按需引入

只引入使用的组件

在不使用插件的情况下,可以手动引入需要的组件。—每一个组件中引入

import Button from 'vant/lib/button';
import 'vant/lib/button/style';
  • 1
  • 2

注册 --使用

<template>
  <div>
    <van-button type="primary">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>
  </div>
</template>

<script>
import Button from 'vant/lib/button'
import 'vant/lib/button/style'
export default {
  components: {
    // VanButton: Button,
    [Button.name]: Button,
  },
}
</script>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
自动按需引入组件

babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。

安装插件

yarn add babel-plugin-import -D
  • 1

babel.config.js配置,重新启动项目

module.exports = {
  plugins: [
    ['import', {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    }, 'vant']
  ]
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

组件中使用

<template>
  <div>
    <van-button type="primary">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>
    <van-icon name="chat-o" />
    <van-icon name="https://b.yzcdn.cn/vant/icon-demo-1126.png" />
  </div>
</template>

<script>
export default {}
</script>

<style scoped></style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

babel-plugin-import 是一款 babel 插件,它会在编译过程中将 import 的写法自动转换为按需引入的方式。

安装插件

yarn add babel-plugin-import -D
  • 1

babel.config.js配置,重新启动项目

module.exports = {
  plugins: [
    ['import', {
      libraryName: 'vant',
      libraryDirectory: 'es',
      style: true
    }, 'vant']
  ]
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

组件中使用

<template>
  <div>
    <van-button type="primary">主要按钮</van-button>
    <van-button type="info">信息按钮</van-button>
    <van-button type="default">默认按钮</van-button>
    <van-button type="warning">警告按钮</van-button>
    <van-button type="danger">危险按钮</van-button>
    <van-icon name="chat-o" />
    <van-icon name="https://b.yzcdn.cn/vant/icon-demo-1126.png" />
  </div>
</template>

<script>
export default {}
</script>

<style scoped></style>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/269399
推荐阅读
相关标签
  

闽ICP备14008679号