Vue3---基础10(路由)

写一个最基本的路由导航

下载、创建、使用路由

下载路由

npm i vue-router

创建路由

        先在 src 内去创建一个 router 文件夹

        在文件夹内创建一个 index 文件

        

        index.ts 内代码

// 创建一个路由器,并暴露出去
// 引入createRouter
import { createRouter, createWebHistory } from "vue-router"
// 引入可能要呈现的组件
import Home from '@/components/Home.vue'
import News from '@/components/News.vue'
import About from '@/components/About.vue'
import Mine from '@/components/Mine.vue'

// 创建路由器
const router = createRouter({
    history:createWebHistory(),
    routes: [
        {
            path:'/home',
            component:Home
        },
        {
            path:'/news',
            component:News
        },
        {
            path:'/about',
            component:About
        },
        {
            path:'/mine',
            component:Mine
        },

    ]
})

// 暴露 router 出去
export default router

使用路由

        在 mian.ts 文件内,去引入、注册路由

        mian.ts 代码

// 引入createApp用于创建应用
import { createApp } from 'vue'
// 引入App根组件
import App from './App.vue'
// 引入Router路由器
import router from './router'

// 创建一个应用
const app = createApp(App)
// 使用路由器
app.use(router)
// 挂载整个应用到容器中
app.mount('#app')

实现导航切换

        示例:

        在App.vue文件内,引入 RouterView, RouterLink 实现 路由跳转

        App.vue 代码

<template>
    <div class="app">
        <!-- 导航区 -->
        <div class="nav">
            <RouterLink to="/home" active-class="active">首页</RouterLink>
            <RouterLink to="/mine" active-class="active">我的</RouterLink>
        </div>
        <!-- 展示区 -->
        <div class="main">
            <RouterView></RouterView>
        </div>
    </div>
</template>

<script lang="ts" setup namae="App">
    import { RouterView, RouterLink } from 'vue-router'

</script>

        使用 RouterLink 标签去包裹要跳转的路径,类似于 a标签

        使用 to 去填写要跳转的具体路径                类似于 href=“”

        使用 RouterView ,让页面中展示跳转的内容

        active-class 是当前所在路由的css样式,类似于 active

        

注意的点

        1. 路由组件通常放在 pages 或 views 文件夹,一般组件通常放在 component 文件夹内

        2. 通过点击导航,视觉效果上“消失”了的路由组件,默认是被销毁掉的,需要的时候再去挂载

路由器工作模式

1. history 模式

        Vue2:        mode:'history'

        Vue3:        history:createWebHistory()

        React:       BrowserRouter

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

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

const router = createRouter({
    history:createWebHistory(),
    /******/
})

2. hash 模式

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

        缺点:URL 带有 # 不太美观,且在 SEO 优化方面相对较差

const router = createRouter({
    history:createWebHashHistory(),
    /******/
})

 to的两种写法

        第一种:字符串写法

        第二种:对象写法

// 第一种
<RouterLink to="/home" active-class="active">首页</RouterLink>
// 第二种    可以用path 也可以用name
<RouterLink :to="{path:'/home'}" active-class="active">首页</RouterLink>
<RouterLink :to="{name:'/shouye'}" active-class="active">首页</RouterLink>

嵌套路由

        就是在第一层路由的基础上加上它的子路由

        示例代码:

{
    name:'myNews',
    path:'/news',
    component:News,
    children:[
        {
            path:'detail',
            component:newsDetail,
        }
    ]
},

注意:children 内的 path 路径不需要带 '/'

路由传参

query传参

示例代码:

第一种方式

                父组件

<template>
  <div class="person">
    <!-- 导航区 -->
    <ul>
      <li v-for="item in newsList" :key="item.id">
        <!-- 第一种写法 -->
        <RouterLink active-class="active" :to=" `/news/detail?id=${item.id}&title=${item.title}&content=${item.content}`">{{ item.title }}</RouterLink> 
      </li>
    </ul>
    <!-- 展示区 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
</div>
</template> 

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

let newsList = reactive([
  {id: '001', title: '歌手张杰在武汉连开三场演唱会!', content:'近日,歌手张杰将在武汉连开三场演唱会!'},
  {id: '002', title: '此为第二个新闻', content:'2222222222'},
  {id: '003', title: '此为第三个新闻', content:'3333333333'},
  {id: '004', title: '此为第四个新闻', content:'4444444444'},
])
</script>

                子组件

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

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

</template>

第二种方式

                父组件

<template>
  <div class="person">
    <!-- 导航区 -->
    <ul>
      <li v-for="item in newsList" :key="item.id">
        <!-- 第二种写法 -->
        <RouterLink 
          :to="{
            path:'newsDetail',
            query: {
              id:item.id,
              title:item.title,
              content:item.content,
            }
          }">
        </RouterLink>
      </li>
    </ul>
    <!-- 展示区 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
</div>
</template> 

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

let newsList = reactive([
  {id: '001', title: '歌手张杰在武汉连开三场演唱会!', content:'近日,歌手张杰将在武汉连开三场演唱会!'},
  {id: '002', title: '此为第二个新闻', content:'2222222222'},
  {id: '003', title: '此为第三个新闻', content:'3333333333'},
  {id: '004', title: '此为第四个新闻', content:'4444444444'},
])
</script>

        子组件

<script setup lang="ts">
  import { toRefs } from 'vue';
  import { useRoute } from 'vue-router'
  let route = useRoute()
  let { query } = toRefs(route)
  console.log('route', route);

</script>

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

</template>

        两种方式区别就是 前面讲到的 to的两种写法

第一种:是通过  ··  和 ? 去拼接字符串的,在路径后接上?去传递值

第二种:是通过  query 传递值

params传参

注意:

        使用 params 传参时,需要提前在规则中去占位     

        如果某个参数是不一定要传的,可以在规则中形参名后面加上 ? 表示非必传 

第一种

        父组件

<template>
  <div class="person">
    <!-- 导航区 -->
    <ul>
      <li v-for="item in newsList" :key="item.id">
        <!-- 第一种写法 -->
        <RouterLink active-class="active" :to=" `/news/detail/${item.id}/${item.title}/${item.content}`">{{ item.title }}</RouterLink>
      </li>
    </ul>
    <!-- 展示区 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
</div>
</template> 

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

let newsList = reactive([
  {id: '001', title: '歌手张杰在武汉连开三场演唱会!', content:'近日,歌手张杰将在武汉连开三场演唱会!'},
  {id: '002', title: '此为第二个新闻', content:'2222222222'},
  {id: '003', title: '此为第三个新闻', content:'3333333333'},
  {id: '004', title: '此为第四个新闻', content:'4444444444'},
])
</script>

        子组件

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

</template>

<script setup lang="ts">
  import { toRefs } from 'vue';
  import { useRoute } from 'vue-router'
  let route = useRoute()
  let { params } = toRefs(route)
  console.log('route', route);

</script>

        router文件

// 创建路由器
const router = createRouter({
    history:createWebHistory(),
    routes: [
        ...
        {
            name:'myNews',
            path:'/news',
            component:News,
            children:[
                {
                    name: 'newsDetail',
                    path:'detail/:id/:title/:content',
                    component:newsDetail,
                }
            ]
        },
        ...
    ]
})

        使用字符串去跳转时,参数与参数之间是用  /  分割的

        

第二种

        父组件

<template>
  <div class="person">
    <!-- 导航区 -->
    <ul>
      <li v-for="item in newsList" :key="item.id">
        <!-- 第二种写法 -->
        <RouterLink 
          :to="{
            name:'newsDetail',
            params: {
              id:item.id,
              title:item.title,
              content:item.content,
            }
          }">
        </RouterLink>
      </li>
    </ul>
    <!-- 展示区 -->
    <div class="news-content">
      <RouterView></RouterView>
    </div>
</div>
</template> 

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

let newsList = reactive([
  {id: '001', title: '歌手张杰在武汉连开三场演唱会!', content:'近日,歌手张杰将在武汉连开三场演唱会!'},
  {id: '002', title: '此为第二个新闻', content:'2222222222'},
  {id: '003', title: '此为第三个新闻', content:'3333333333'},
  {id: '004', title: '此为第四个新闻', content:'4444444444'},
])
</script>

        params 传参时, to选择用对象写法,就要用name配置项,不能用 path ,不然会报错

props配置

        作用:让路由组件更方便收到参数(可以将路由参数作为 props 传递给组件)

router文件内代码:

// 创建路由器
const router = createRouter({
    history:createWebHistory(),
    routes: [
        ...
        {
            name:'myNews',
            path:'/news',
            component:News,
            children:[
                {
                    name: 'newsDetail',
                    path:'detail/:id/:title/:content',
                    component:newsDetail,
                    
                    // 第一种写法,将路由收到的所有 params 参数作为props传给路由组件
                    // props:true

                    // 第二种写法,函数写法,可以自己决定将什么作为 props 给路由组件
                    props(route) {
                        return route.query
                    }

                    // 第三种写法,对象写法,可以自己决定将什么作为 props 给路由组件
                    // props:{
                    //     id: 123,
                    //     title: 'props',
                    //     content: '内容~'
                    // }
                
                }
            ]
        },
        ...
    ]
})

组件内代码

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

</template>

<script setup lang="ts">
  import { defineProps } from 'vue';
  defineProps(['id', 'title', 'content'])

</script>

props配置有三种

第一种是  props:true,这种是只能传 params的值

第二种是函数写法,可以传递 params 也可以传递 query的值

第三种是对象写法,值只能写固定的,很少用

在组件内用 defineProps 属性,去接收值

格式:defineProps(['id', 'title', 'content'])

可以直接在模版内去使用 id  title等

replace属性

1. 作用:控制路由跳转时操作浏览器历史记录的模式

2. 浏览器的历史记录有两张写入方式:分别为 push 和 replace

        push 是追加历史记录(默认值)

        replace 是替换当前记录

3. 开启 replace 模式

<RouterLink replace ............>News</RouterLink >

        使用此属性可以覆盖记录,无法回跳

编程式导航

        脱离 <RouterLink>实现路由跳转

实现简单的跳转

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

const router = useRouter()

onMounted(()=>{
    setTimeout(() => {
        router.push('/news')
    },2000)
})
</script>

        引入 useRouter,然后用常量接收,最后  .push 去跳转

携带参数跳转

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

const router = useRouter()

interface NewsInter {
  id: string,
  title: string,
  content: string,
}

function showNewsDetail(item:NewsInter) {
  router.push({
    name:'newsDetail',
    params: {
      id:item.id,
      title:item.title,
      content:item.content,
    }
  })
}

</script>

路由重定向

实现原理:在路由文件,一级路由后加上重定向代码。如下 

{
    path:'/',
    redirect:'/home'
}

就能实现 进入页面就能重定向到 home 页

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值