自学内容网 自学内容网

Vue3的学习(二)路由

路由

简单路由案例:

在router文件夹下的index.ts文件中:

import {createRouter,createWebHistory} from 'vue-router'
import Car from '@/components/Car.vue'
import Person from '@/components/learning/Person.vue'
import Water from '@/components/learning/Water.vue'

const router = createRouter({
    history:createWebHistory(),//路由器的工作模式
    routes:[
        {
            path:'/home',
            component:Car
        },
        {
            path:'/news',
            component:Person
        },
        {
            path:'/about',
            component:Water
        }
    ]
})

export default router

配置路由规则,createWebHistory是指定路由的工作模式,routes中的每个元素都是一个配置好的路由,其中path是路由的路径,component是该路由对应的组件

main.ts:

import './assets/main.css'

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'

const app = createApp(App)
app.use(router)
app.mount('#app')

挂载app组件之前,要让其配置上路由,使用.use(router)

app.vue:

其中RouterLink标签是用于定位路由的,to就是指定按下该dom后路径会跳向哪个,active-class是指定当为当前路由时,该dom会应用上该class,可以用于指定路由激活时的样式

RouterView就是路由指定的组件的展示区,展示当前路由对应的那个component组件

<script setup lang="ts">
import router from './router'

import { RouterView,RouterLink} from 'vue-router';
</script>

<template>
    <div class="app">
      <h2 class="title">vue路由测试</h2>
      <!-- 导航区 -->
      <div class="navigate">
        <RouterLink to="/home" active-class="active">首页</RouterLink>
        <RouterLink to="/news" active-class="active">新闻</RouterLink>
        <RouterLink to="/about" active-class="active">关于</RouterLink>
      </div>
      <!-- 展示区 -->
      <div class="main-content">
        <RouterView></RouterView>
      </div>
    </div>
</template>

<style scoped>
/* App */
.title {
    text-align: center;
    word-spacing: 5px;
    margin: 30px 0;
    height: 70px;
    line-height: 70px;
    background-image: linear-gradient(45deg, gray, white);
    border-radius: 10px;
    box-shadow: 0 0 2px;
    font-size: 30px;
  }
  .navigate {
    display: flex;
    justify-content: space-around;
    margin: 0 100px;
  }
  .navigate a {
    display: block;
    text-align: center;
    width: 90px;
    height: 40px;
    line-height: 40px;
    border-radius: 10px;
    background-color: gray;
    text-decoration: none;
    color: white;
    font-size: 18px;
    letter-spacing: 5px;
  }
  .navigate a.active {
    background-color: #64967E;
    color: #ffc268;
    font-weight: 900;
    text-shadow: 0 0 1px black;
    font-family: 微软雅黑;
  }
  .main-content {
    margin: 0 auto;
    margin-top: 30px;
    border-radius: 10px;
    width: 90%;
    height: 400px;
    border: 1px solid;
  }
</style>

注意点

  • 路由组件通常存放在pages或views文件夹,一般组件通常存放在components文件夹。
    • 路由组件,靠路由的规则渲染出来的组件,即放在routes的元素的component配置项中的组件
  • 通过点击导航,消失后的组件默认是被卸载掉的,需要的时候再加载

to的第二种写法

to属性里面可以直接写路径,也可以写作一个对象的写法:

<RouterLink :to="{path:'/about'}" active-class="active">关于</RouterLink>

命名路由

给路由命名在routes的路由元素中加一个配置项name,指定名称

const router = createRouter({
    history:createWebHistory(),//路由器的工作模式
    routes:[
        {
        name:'ergouHome',
            path:'/home',
            component:Car
        }
    ]
})

然后to的第二种写法对象写法中,就可以指定这个name去指定路由

<RouterLink :to="{name:'ergouHome'}" active-class="active">首页</RouterLink>

路由器工作模式

  • history模式:

    • 优点:url更加美观,不带有#,更接近传统的网站url

    • 缺点:后期项目上线,需要服务端配合处理路径问题,否则刷新会有404错误

    • 使用方式,导入createWebHistory,在createRouter中加入:

      const router = createRouter({
          history:createWebHistory(),//history模式
          routes:[
              //……………………
          ]
      })
      
  • hash模式

    • 优点:兼容性好,因为不需要服务器端进行处理路径

    • 缺点:url带有#不美观,且在seo优化方面相对较差

    • 使用:

      const router = createRouter({
          history:createWebHashHistory(),//hash模式
          routes:[
              //……………………
          ]
      })
      

嵌套路由

路由的嵌套即在路由组件中继续使用其他路由组件,层层嵌套

在router的index.ts中,要在要配置嵌套路由的路由配置中加上children配置项(数组),其中的元素就是指定一个一个嵌套的子路由组件。子路由组件中的path前面不要加”/”,例:

const router = createRouter({
    history:createWebHistory(),//路由器的工作模式
    routes:[
        {
            path:'/news',
            component:News,
            children:[
                {
                    path:'detail',
                    component:Detail
                }
            ]
        }
    ]
})

在父路由组件中,加上RouterView标签,并配置好RouterLink标签(其中的to要写完整的路径,比如上方的要展示Detail组件,path就要写作/news/detail)

<template>
  <div class="news">
    <ul>
        <li v-for="news in newList" :key="news.id">
            <RouterLink to="/news/detail">{{ news.title }}</RouterLink>
        </li>
    </ul>

    <div class="newsContent">
      <RouterView></RouterView>
    </div>
  </div>
</template>

路由传参之query参数

用query参数可以添加或者获取路径上的param参数列表,即路径上的?后面的kv信息。以达到路由传参的

添加:添加一般由父路由组件指定参数信息:有两种写法:

  • 第一种:字符串中的参数值占位

        <ul>
            <li v-for="news in newList" :key="news.id">
              <!-- 第一种写法 -->
              <RouterLink :to="`/news/detail?id=${news.id}&title=${news.title}`">{{ news.title }}</RouterLink>
            </li>
        </ul>
    

    但是第一种方式不方便,且观感上不美观。建议使用第二种方式

  • 第二种,使用对象式写法

        <ul>
            <li v-for="news in newList" :key="news.id">
                <!-- 第二种写法:将to写作对象的形式 -->
                <RouterLink :to="{
                  // path:'/news/detail',
                  name:'detail',
                  query:{
                    id:news.id,
                    title:news.title,
                    content:news.content
                  }
                }">{{ news.title }}</RouterLink>
            </li>
        </ul>
    

获取:子路由组件获取query的参数值

<template>
  <ul class="news-list">
    <li>编号:{{ route.query.id }}</li>
    <li>标题:{{ route.query.title }}</li>
    <li>内容:{{ route.query.content }}</li>
  </ul>
</template>

<script lang="ts" name="About" setup>
   import { useRoute } from 'vue-router';
   let route = useRoute()
</script>

用useRoute就可以获取到地址上的各个参数的参数值,这些参数值都是存于query参数中,所以获取要使用 route.query.参数名。

路由传参之params参数

params参数是将参数值直接以路径的形式存在路径当中

要让路由不会将路径上的值视为真正的路径,就要在router中的index.ts中的路由配置中指定好参数名:

const router = createRouter({
    history:createWebHistory(),//路由器的工作模式
    routes:[
        {
            name:'about',
            path:'/about',
            component:News2,
            children:[
                {
                    path:'detail2/:id/:title/:content',
                    name:'detail2',
                    component:Detail2
                }
            ]
        }
    ]
})

添加参数:

    <ul>
        <li v-for="news in newList" :key="news.id">
          <!-- 第一种写法 -->
            <!-- <RouterLink :to="`/about/detail2/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink> -->
          <!-- 第二种写法 -->
           <RouterLink :to="{
            name:'detail2',//此时只能使用指定name来指定路由的写法
            params:{
              id:news.id,    //此处的名称要根据路由中指定的参数名来
              title:news.title,
              content:news.content
            }
           }">{{ news.title }}</RouterLink>
        </li>
    </ul>

但是这种方式不能传入数组类型的数据

如果想让参数可传可不传,在参数名后加上一个?

获取参数:

<template>
  <ul class="news-list">
    <li>编号:{{ route.params.id }}</li>
    <li>标题:{{ route.params.title }}</li>
    <li>内容:{{ route.params.content }}</li>
  </ul>
</template>

<script lang="ts" name="About" setup>
   import { useRoute } from 'vue-router';
   let route = useRoute()
</script>

路由传参之路由的props配置

  • 第一种写法:将所有的params参数信息多一份转换为给子路由组件的props配置项的参数。(只能用于params参数)

在子路由组件的路由配置中加上props配置项,直接让其值为true。

const router = createRouter({
    history:createWebHistory(),//路由器的工作模式
    routes:[
        {
            name:'about',
            path:'/about',
            component:News2,
            children:[
                {
                    path:'detail2/:id/:title/:content',
                    name:'detail2',
                    component:Detail2,
                    props:true
                }
            ]

        }
    ]
})

如此Detail2组件就会多三个props参数id、title、content。

<template>
  <ul class="news-list">
    <li>编号:{{ route.params.id }}</li>
    <li>标题:{{ route.params.title }}</li>
    <li>内容:{{ route.params.content }}</li>

    <hr>
    <li>编号:{{ id }}</li>
    <li>标题:{{ title }}</li>
    <li>内容:{{ content }}</li>
  </ul>
</template>

<script lang="ts" name="About" setup>
   import { useRoute } from 'vue-router';
   let route = useRoute()
   defineProps(['id','title','content'])
</script>

<style>
    .news-list{
        list-style: none;
        padding-left: 20px;
    }
    .news-list>li{
        line-height: 30px;
    }
</style>
  • 第二种写法:函数式写法,可以获取route并使用,也就是那个useRoute()的返回值
const router = createRouter({
    history:createWebHistory(),//路由器的工作模式
    routes:[
        {
            name:'news',
            path:'/news',
            component:News,
            children:[
                {
                    name:'detail',
                    path:'detail',
                    component:Detail,
                    props(route){
                        return {//也可以直接return route.query
                            id:route.query.id,
                            title:route.query.title,
                            content:route.query.content
                        }
                    }
                }
            ]
        }
    ]
})

这里的route参数接收的就是useRoute()的返回值的那个route,因为第一种写法不能使用在query参数的使用上,但是第二种写法都可以适用,也可以自己return想要的props参数。return返回的参数就会变成给子路由组件的props参数。

  • 第三种写法:对象式写法,可以自己决定将什么作为props参数给路由组件。
props:{
  a:100,
  b:200,
  c:'abc'
}

但是这种写法写死了,不灵活,建议使用第一种或者第二种。

replace属性

<RouterLink :to="…… ……" replace>…… ……</RouterLink>

push模式就是将浏览器历史记录以栈的形式存储,新点开的页面状态加到栈顶,replace模式就是将新点开的页面状态替换掉当前页面状态到栈顶。

要让某个路由是replace模式的,在对应的RouterLink标签上加上replace属性即可。

编程式导航

编程式路由导航就是脱离<RouterLink>实现路由跳转。

要实现这种方式,使用useRouter(注意是useRouter,不是useRoute),例:

<template>
  <div class="home">
    <img src="<http://www.atguigu.com/images/index_new/logo.png>">
  </div>
</template>

<script lang="ts" setup>
    import { onMounted } from 'vue';
    import { useRouter } from 'vue-router';

    const router = useRouter()//注意,不是useRoute,是useRouter
    onMounted(()=>{
        setTimeout(()=>{
            router.push('/news')
        },5000)
    })
</script>

调用router的push函数,传入要跳转的路由,就可以实现不使用RouterLink的方式来跳转路由。

push函数中还可以写做对象的写法,说白了就是,to中怎么写,push的参数中就怎么写。

<template>
  <div class="news">
    <ul>
        <li v-for="news in newList" :key="news.id">
          <!-- 第一种写法 -->
            <!-- <RouterLink :to="`/about/detail2/${news.id}/${news.title}/${news.content}`">{{ news.title }}</RouterLink> -->
          <!-- 第二种写法 -->
           <RouterLink :to="{
            name:'detail2',//此时只能使用指定name来指定路由的写法
            params:{
              id:news.id,    //此处的名称要根据路由中指定的参数名来
              title:news.title,
              content:news.content
            }
           }">{{ news.title }}</RouterLink>
           <button @click="showNewsDetail(news.id,news.title,news.content)">查看新闻</button>
        </li>
    </ul>

    <div class="newsContent">
      <RouterView></RouterView>
    </div>
  </div>
</template>

<script lang="ts" setup>
    import { reactive } from 'vue';
    import { RouterView ,RouterLink,useRouter} from 'vue-router';

    const newList = reactive([
        {id:'new01',title:'很好的抗癌食物',content:'西兰花'},
        {id:'new02',title:'如何一夜暴富',content:'做梦'},
        {id:'new03',title:'如何赚大钱',content:'学it'},
        {id:'new04',title:'好消息',content:'放假了'}
    ])

    const router = useRouter()
    function showNewsDetail(id:string,title:string,content:string){
      router.push({
        name:'detail2',
        params:{
          id:id,
          title:title,
          content:content
        }
      })
    }
</script>

如果想要使用replace模式,将push换成replace函数就行,写法一样。

重定向

在route包下的index.ts中,要加上重定向,加上一个路由元素,使用redirect属性,例:

const router = createRouter({
    history:createWebHistory(),//路由器的工作模式
    routes:[
        {
            name:'ergouHome',
            path:'/home',
            component:Home
        },
        {
            name:'news',
            path:'/news',
            component:News,
            children:[
                {
                    name:'detail',
                    path:'detail',
                    component:Detail,
                    props(route){
                        return {
                            id:route.query.id,
                            title:route.query.title,
                            content:route.query.content
                        }
                    }
                }
            ]
        },
        {
            name:'about',
            path:'/about',
            component:News2,
            children:[
                {
                    path:'detail2/:id/:title/:content',
                    name:'detail2',
                    component:Detail2,
                    props:true
                }
            ]
        },
        { //重定向
            path:'/',
            redirect:'/home'
        }
    ]
})

当配置了重定向的时候,当路径为其path的时候,就会跳转到redirect指定的那个路由


原文地址:https://blog.csdn.net/2302_79468488/article/details/142857262

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!