vue-router学习-2

举报
Studying-swz 发表于 2022/10/16 20:19:46 2022/10/16
【摘要】 1.路由嵌套案例:比如在home页面中, 我们希望通过/home/news和/home/message访问一些内容. 一个路径映射一个组件, 访问这两个路径也会分别渲染两个组件.1.创建三个组件2.配置路由index.js可以看到主要嵌套的实现,是在原有的首页的path配置下,添加属性children,然后配置被嵌套的组件以及路径//配置路由相关的信息import VueRouter fr...

1.路由嵌套

  • 案例:
    比如在home页面中, 我们希望通过/home/news和/home/message访问一些内容. 一个路径映射一个组件, 访问这两个路径也会分别渲染两个组件.
    image.png

  • 1.创建三个组件

    image.png

  • 2.配置路由index.js

    • 可以看到主要嵌套的实现,是在原有的首页的path配置下,添加属性children,然后配置被嵌套的组件以及路径
    //配置路由相关的信息
    import VueRouter from 'vue-router'
    import Vue from 'vue'
    
    // import Home from '../components/Home.vue'
    // import About from '../components/About.vue'
    // import User from '../components/User.vue'
    
    // 懒加载
    const Home = () => import('../components/Home.vue')
    const About = () => import('../components/About.vue')
    const User = () => import('../components/User.vue')
    const HomeNews = () => import('../components/HomeNews.vue')
    const HomeMessage = () => import('../components/HomeMessage.vue')
    const Profile = () => import('../components/Profile.vue')
    
    //1.通过Vue.use(插件),安装插件
    Vue.use(VueRouter)
    
    //2.创建VueRouter对象
    const routes = [
        {
            path:'',
            //redirect重定向
            redirect: '/home'
        },
        {
            path:'/home',
            component: Home,
            children:[
                {
                    path:'',
                    //redirect重定向
                    redirect: 'message'
                },
                {
                    // 这里不需要加/
                    path:'news',
                    component: HomeNews,
                },
                {
                    // 这里不需要加/
                    path:'message',
                    component: HomeMessage,
                }
            ],
            meta:{
                title:"首页"
            }
        }
    ]
    const router = new VueRouter({
        //配置路由和组件之间的应用关系
        routes,
        mode:'history',
        linkActiveClass:'active'
    })
    
    
    //3.router对象传入到Vue实例
    export default router
    

2.传递参数

  • 1.Query形式的参数传递
    • 新建组件Profile.vue

    • 参数query:以$route.query来接收

      <template>
        <div>
            <h2>我是Profile组件</h2>
            <h2>{{$route.query}}</h2>
            <h2>{{$route.query.age}}</h2>
          <router-view/>
        </div>
      </template>
      
      <script>
      export default {
        name: 'Profile',
        computed: {
            userId(){
                return this.$route.params.userId;
            }
        },
        created(){
          console.log("profile created");
        },
        destroyed(){
          console.log("profile destroyed");
        },
      }
      </script>
      
      <style>
      
      </style>
      
    • index.js路由配置

      {
          path:'/profile',
          component: Profile,
          meta:{
              title:"档案"
          }
      }
      
    • App.vue

    • 主要修改,将query以对象的形式传递

      <router-link :to ="{path:'/profile',query:{name:'why',age:18,height:1.88}}" tag="button" replace>档案</router-link>

      <template>
        <div id="app">
          <h2>我是网站的标题</h2>
          <!-- 方法一 -->
          <router-link to="/home" tag="button" replace >首页</router-link>
          <router-link to="/about" tag="button" replace>关于</router-link>
          <router-link v-bind:to ="'/user/' + userId" tag="button" replace>用户</router-link>
          <!-- <router-link to ="/profile" tag="button" replace>档案</router-link> -->
          <router-link :to ="{path:'/profile',query:{name:'why',age:18,height:1.88}}" tag="button" replace>档案</router-link>
      
          <keep-alive exclude="Profile,User">
            <router-view></router-view>
          </keep-alive>
          <h2>我是App中一些底部版本信息</h2>
        </div>
      </template>
      
  • 2.params的传递
    • 新建组件User.vue

    • 数据接收:this.$route.params.userId;

      <template>
        <div>
            <h2>我是用户界面</h2>
            <p>我是用户内容,啊哈哈</p>
            <h2>{{userId}}</h2>
          <router-view/>
        </div>
      </template>
      
      <script>
      export default {
        name: 'User',
        computed: {
            userId(){
                return this.$route.params.userId;
            }
        },
        created(){
          console.log("user created");
        },
        destroyed(){
          console.log("user destroyed");
        },
      }
      </script>
      
      <style>
      
      </style>
      
    • index.js路由配置

      {
          path:'/user/:userId',
          component: User,
          meta:{
              title:"用户"
          }
      }
      
    • App.vue

    • 主要实现:<router-link v-bind:to ="'/user/' + userId" tag="button" replace>用户</router-link>

      <template>
        <div id="app">
          <h2>我是网站的标题</h2>
          <!-- 方法一 -->
          <router-link to="/home" tag="button" replace >首页</router-link>
          <router-link to="/about" tag="button" replace>关于</router-link>
          <router-link v-bind:to ="'/user/' + userId" tag="button" replace>用户</router-link>
          <!-- <router-link to ="/profile" tag="button" replace>档案</router-link> -->
          <router-link :to ="{path:'/profile',query:{name:'why',age:18,height:1.88}}" tag="button" replace>档案</router-link>
      
          <keep-alive exclude="Profile,User">
            <router-view></router-view>
          </keep-alive>
          <h2>我是App中一些底部版本信息</h2>
        </div>
      </template>
      
      <script>
      export default {
        name: 'App',
        data(){
          return {
            userId:'lisi'
          }
        },
      }
      </script>
      
      <style>
        .active{
          color:red;
        }
      </style>
      
      

3.导航守卫

  • 问题:网页标题是通过<title>来显示的, 但是SPA只有一个固定的HTML, 切换不同的页面时, 标题并不会改变. 但是我们可以通过JavaScript来修改<title>的内容.window.document.title = ‘新的标题’. 那么在Vue项目中, 在哪里修改? 什么时候修改比较合适呢?
  • 1.普通的修改方式:
    • 我们比较容易想到的修改标题的位置是每一个路由对应的组件.vue文件中. 通过mounted声明周期函数, 执行对应的代码进行修改即可. 但是当页面比较多时, 这种方式不容易维护(因为需要在多个页面执行类似的代码).
  • 2.导航守卫:
    • 什么是导航守卫? vue-router提供的导航守卫主要用来监听监听路由的进入和离开的. vue-router提供了beforeEach和afterEach的钩子函数, 它们会在路由即将改变前和改变后触发.
  • 实现:
    • index.js路由配置

    • 首先在每个路由内配置meta属性,作为标题

      const routes = [
          {
              path:'',
              //redirect重定向
              redirect: '/home'
          },
          {
              path:'/home',
              component: Home,
              children:[
                  {
                      path:'',
                      //redirect重定向
                      redirect: 'message'
                  },
                  {
                      // 这里不需要加/
                      path:'news',
                      component: HomeNews,
                  },
                  {
                      // 这里不需要加/
                      path:'message',
                      component: HomeMessage,
                  }
              ],
              meta:{
                  title:"首页"
              }
          },
          {
              path:'/about',
              component: About,
              meta:{
                  title:"关于"
              }
          },
          {
              path:'/user/:userId',
              component: User,
              meta:{
                  title:"用户"
              }
          },
          {
              path:'/profile',
              component: Profile,
              meta:{
                  title:"档案"
              }
          }
      ]
      
    • 其次在beforeEach函数中设置导航守卫

      router.beforeEach((to, from, next) => {
         //从 from 跳转 to
         document.title = to.matched[0].meta.title;
         //console.log(to);
         next(); 
      })
      

注:更多内容,请看官网链接

4.keep-alive

  • keep-alive 是 Vue 内置的一个组件,可以使被包含的组件保留状态,或避免重新渲染。

  • 它们有两个非常重要的属性:

  • include - 字符串或正则表达,只有匹配的组件会被缓存

  • exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存

  • router-view 也是一个组件,如果直接被包在 keep-alive 里面,所有路径匹配到的视图组件都会被缓存

  • 注:主要是缓存作用,降低系统的压力,使用方法:

    <keep-alive exclude="Profile,User"> <router-view></router-view> </keep-alive>

5.tabbar案例

实现目标:

image.png

实现思路:

  • 1.如果在下方有一个单独的TabBar组件,你如何封装 自定义TabBar组件,在APP中使用 让TabBar出于底部,并且设置相关的样式

  • 2.TabBar中显示的内容由外界决定 定义插槽 flex布局平分TabBar

  • 3.自定义TabBarItem,可以传入 图片和文字 定义TabBarItem,并且定义两个插槽:图片、文字。 给两个插槽外层包装div,用于设置样式。 填充插槽,实现底部TabBar的效果

  • 4.传入 高亮图片 定义另外一个插槽,插入active-icon的数据 定义一个变量isActive,通过v-show来决定是否显示对应的icon

  • 5.TabBarItem绑定路由数据 安装路由:npm install vue-router —save 完成router/index.js的内容,以及创建对应的组件 main.js中注册router APP中加入<router-view>组件

  • 6.点击item跳转到对应路由,并且动态决定isActive 监听item的点击,通过this.$router.replace()替换路由路径 通过this.$route.path.indexOf(this.link) !== -1来判断是否是active

  • 7.动态计算active样式 封装新的计算属性:this.isActive ? {'color': 'red'} : {}

源码下载:
tabbar

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。