Vue基础第七天

116 阅读2分钟

Vue基础第七天

vue-Router路由

简介与基本使用

什么是路由

设备和ip的映射关系

1653303826715

接口和服务的映射关系

1653303865383

路径和组件的映射关系

1653303891750

使用场景:

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

优点:

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

缺点:

  • 开发成本高
  • 首次加载会慢一点,不利于seo

基本使用

路由-组件分类

vue文件分为2类,一个是页面组件,一个是复用组件,本质并无区别

页面组件-页面展示-配合路由用

复用组件-展示数据/常用于复用

1653304299190

配置router

vue-router文档

  1. 安装router

    npm i vue-router
    
  2. 在main.js文件里引入库

    import VueRouter from 'vue-router'
    
  3. 安装这个库

    Vue.use(VueRouter)
    
  4. 创建一个实例

    const router = new VueRouter({
      // 这里可以有配置对象
      //有个属性叫routes是路由配置表,指定url=>组件的配对
      routes,
      //模式,减去路径上的#号
      mode: 'history'
    })
    
  5. 挂载到new Vue根实例上

    new Vue({
      // 4.挂载到new Vue根实例上
      router,
      render: h => h(App),
    }).$mount('#app')
    
    
使用router
  1. 引入组件对象

    import Find from '@/views/Find.vue'
    
  2. 创建路由规则数组

    const routes = [
      {
        path: "/find",
        component: Find
      },
    ]
    
  3. 在组件中使用

    <router-view></router-view
    

声明式导航

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

基本使用

  1. vue-router提供了一个全局组件 router-link
  2. router-link实质上最终会渲染成a链接 to属性等价于提供 href属性(to无需#)
  3. router-link提供了声明式导航高亮的功能(自带类名)
<template>
  <div>
    <div class="footer_wrap">
      <router-link to="/find">发现音乐</router-link>
      <router-link to="/my">我的音乐</router-link>
      <router-link to="/part">朋友</router-link>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
export default {};
</script>

<style scoped>
/* 省略了 其他样式 */
.footer_wrap .router-link-active{
  color: white;
  background: black;
}
</style>

传参

在router-link上的to属性传值,语法如下:

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

对应页面接受传过来的值

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

1653395935653

重定向和模式

匹配到path后,强制切换到目标path上

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

例如:网页默认打开,匹配路由"/",强制切换到"/find"上

const routes = [
  {
    path: "/", // 默认hash值路径
    redirect: "/find" // 重定向到/find
    // 浏览器url中#后的路径被改变成/find-重新匹配数组规则
  }
]

模式

修改路由在地址栏的模式(去除#号,好看而已)

const router = new VueRouter({
  routes,
  mode: "history" // 打包上线后需要后台支持, 模式是hash
})

编程式导航

用js来跳转

语法:

this.$router.push({
    path: "路由路径", // 都去 router/index.js定义
    name: "路由名"
})

基本使用

{
    path: "/find",
    name: "Find",
    component: Find
},
{
    path: "/my",
    name: "My",
    component: My
},
{
    path: "/part",
    name: "Part",
    component: Part
},
<template>
  <div>
    <div class="footer_wrap">
      <span @click="btn('/find', 'Find')">发现音乐</span>
      <span @click="btn('/my', 'My')">我的音乐</span>
      <span @click="btn('/part', 'Part')">朋友</span>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
// 目标: 编程式导航 - js方式跳转路由
// 语法:
// this.$router.push({path: "路由路径"})
// this.$router.push({name: "路由名"})
// 注意:
// 虽然用name跳转, 但是url的hash值还是切换path路径值
// 场景:
// 方便修改: name路由名(在页面上看不见随便定义)
// path可以在url的hash值看到(尽量符合组内规范)
export default {
  methods: {
    btn(targetPath, targetName){
      // 方式1: path跳转
      this.$router.push({
        // path: targetPath,
        name: targetName
      })
    }
  }
};
</script>

传参

语法:

this.$router.push({
    path: "路由路径"
    name: "路由名",
    query: {
    	"参数名": 值
    }
    params: {
		"参数名": 值
    }
})

// 对应路由接收   $route.params.参数名   取值
// 对应路由接收   $route.query.参数名    取值

例子:

<template>
  <div>
    <div class="footer_wrap">
      <span @click="btn('/find', 'Find')">发现音乐</span>
      <span @click="btn('/my', 'My')">我的音乐</span>
      <span @click="oneBtn">朋友-小传</span>
      <span @click="twoBtn">朋友-小智</span>
    </div>
    <div class="top">
      <router-view></router-view>
    </div>
  </div>
</template>

<script>
// 目标: 编程式导航 - 跳转路由传参
// 方式1:
// params => $route.params.参数名
// 方式2:
// query => $route.query.参数名
// 重要: path会自动忽略params
// 推荐: name+query方式传参
// 注意: 如果当前url上"hash值和?参数"与你要跳转到的"hash值和?参数"一致, 爆出冗余导航的问题, 不会跳转路由
export default {
  methods: {
    btn(targetPath, targetName){
      // 方式1: path跳转
      this.$router.push({
        // path: targetPath,
        name: targetName
      })
    },
    oneBtn(){
      this.$router.push({
        name: 'Part',
        params: {
          username: '小传'
        }
      })
    },
    twoBtn(){
      this.$router.push({
        name: 'Part',
        query: {
          name: '小智'
        }
      })
    }
  }
};
</script>

嵌套和守卫

嵌套

一级路由下在嵌套一层路由

1653396161105

路由配置嵌套
// routes 配置中添加
  {
    // 1. path 路径 / 开头
    path: '/find',
    // 2. component 组件
    component: Find,
    redirect: '/find/ranking',
    // 嵌套子路由
    children: [
      // 依旧是 path 跟 component 的配对
      // 不要加斜杠, 因为需要改上一层拼接在一起
      // 如果加了, 就需要在根路径进行访问
      {
        path: 'ranking',
        component: Ranking
      },
      {
        path: 'recommend',
        component: Recommend
      },
      {
        path: 'songlist',
        component: SongList
      },
    ]
  },
页面挂载点嵌套

在需要显示children 的页面中添加二级挂载点 这里是 /views/Find.vue

<template>
  <div>
    <router-link class="myLink" to="/find/ranking">排行榜</router-link>
    <router-link class="myLink" to="/find/songlist">歌单</router-link>
    <router-link class="myLink" to="/find/recommend">推荐</router-link>

    <!-- 显示二级路由组件需要一个挂载点 -->
    <router-view></router-view>
  </div>
</template>

导航守卫

// router 创建实例之后
// 可以往这个 router 路由实例添加导航守卫(路由守卫)
// 全局前置, 所有页面跳转之前都会经过
router.beforeEach((to, from, next)=>{
  console.log('到达了导航守卫');
  // 拦住了必须放行, 默认这个函数可以接收到三个参数
  // to 目的地, from 来源, next 放行回调函数
  console.log(to);
  console.log(from);
  // 如果你来到了我的音乐但是有没有token就要跳转到登录页
  if (to.path === '/my' && !localStorage.getItem('token')) {
    // 这个 next 可以再里面带上 path 进行跳转
    next('/login')
  }else {
    next()
  }
})