草庐IT

Vue3【Vue路由概念、项目引入路由、集成Vue路由 、编程式导航、带参数的动态路由匹配 、嵌套路由、重定向和别名、命名视图、不同的历史模式​】(十)-全面详解(学习总结---从入门到深化)

童小纯 2023-06-27 原文

 

👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者
📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶
📧如果文章知识点有错误的地方,请指正!和大家一起学习,一起进步👀
🔥如果感觉博主的文章还不错的话,请👍三连支持👍一下博主哦
🍂博主正在努力完成2023计划中:以梦为马,扬帆起航,2023追梦人 

Vue路由概念

Vue Router 是 Vue.js 的官方路由。它与 Vue.js 核心深度集成,让用 Vue.js 构建单页应用变得轻而易举

单页面应用也称为SPA(Single Page Application),它主要是网页的界面渲染在一个静态的页面上,当用户要从当前界面跳到另一个界面的时候,在这个过程中,不需要重新加载整个页面,所以页面之间的切换十分快速

多页面在进行页面切换时十分缓慢,在路由进行跳转的时候会加载所有的资源,而且页面重复代码多

对比之下,单页面原理是JavaScript动态修改内容而已,资源只需要局部的刷新,因此SPA具有极高的流畅度,有利于提升用户体验 

单页面VS多页面 

路由作用 

页面与页面之前的切换,是通过不同的地址访问的,地址对应着要显示的组件。而实现这个页面切换显示的功能就是路由的作用

项目引入路由 

用 Vue + Vue Router 创建单页应用非常简单:通过 Vue.js,我们已经用组件组成了我们的应用。当加入 Vue Router 时,我们需要做 的就是将我们的组件映射到路由上,让 Vue Router 知道在哪里渲 染它们 

安装路由 

npm install vue-router@4 --save

实现路由功能

import { createApp } from 'vue'
import App from './App.vue'
import { createRouter,createWebHashHistory } from "vue-router"
import Home from "./pages/Home.vue"
import About from "./pages/About.vue"
const routes = [
   {
        path:"/",
        component:Home
   },
   {
        path:"/about",
        component:About
   }
]
const router = createRouter({
    // 路由地址访问方式 # /
    // 内部提供了 history 模式的实现。为了简单起见,我们在这里使用 hash 模式
    history: createWebHashHistory(),
    routes
})
const app = createApp(App)
app.use(router)
app.mount('#app')
<template>
    <h3>Home首页</h3>
</template>
<template>
    <h3>About关于页面</h3>
</template>
<template>
    <!-- 路由匹配到的组件将渲染在这里 -->
    <router-link to="/">Home</router-link>
    <router-link to="/about">About</router-link>
    <router-view></router-view>
</template>

router-view

router-view 将显示与 url 对应的组件。你可以把它放在任何地方,以适应你的布局

router-link 

请注意,我们没有使用常规的 a 标签,而是使用一个自定义组件 router-link 来创建链接。 这使得 Vue Router 可以在不重新加载页面的情况下更改 URL,处理 URL 的生成以及编码我们将在后面看到如何从这些功能中获益

实时效果反馈

1.在Vue路由中,实现页面跳转下列是哪一个:

A router

B router-view

C router-link

D createRouter 

集成Vue路由 

如果文件全部放在主入口文件中是不合理的,所以我们需要提取成 为独立的路由文件新项目可以直接选择集成路由在其中 

import { createRouter,createWebHashHistory } from "vue-router"
import Home from "../pages/Home.vue"
import About from "../pages/About.vue"
const routes = [
   {
        path:"/",
        component:Home
   },
   {
        path:"/about",
        component:About
   }
]
const router = createRouter({
    history: createWebHashHistory(),
    routes
})
export default router
import { createApp } from 'vue'
import App from './App.vue'
import router from "./router"
const app = createApp(App)
app.use(router)
app.mount('#app')

编程式导航

除了使用 < router-link >  创建 a 标签来定义导航链接,我们还可以借助 router 的实例方法,通过编写代码来实现

在 Vue 实例中,你可以通过 $router 访问路由实例。因此你可以调用 this.$router.push  

选项式API 

<template>
    <h3>Home首页</h3>
    <button @click="clickHandler">跳转到About页面</button>
</template>
<script>
 export default {
    methods:{
        clickHandler(){
            this.$router.push("/about")
       }
   }
}
</script>

组合式API

<template>
    <h3>About关于页面</h3>
    <button @click="clickHandler">跳转到首页</button>
</template>
<script setup>
import { useRouter } from 'vue-router'
const router = useRouter()
function clickHandler(){
    router.push("/")
}
</script>

实时效果反馈

1.在Vue路由中,下列那个可以实现编程式导航跳转:

A this.$router.push()

B this.push()

C push()

D $router.push()

带参数的动态路由匹配 

很多时候,我们需要将给定匹配模式的路由映射到同一个组件。例 如,我们可能有一个 User 组件,它应该对所有用户进行渲染,但用 户 ID 不同。在 Vue Router 中,我们可以在路径中使用一个动态字段来实现,我们称之为 路径参数 

// router/index.js
const routes = [
   {
        path:"/",
        component:Home
   }
    ...
   {
        path:"/details/:name",
        component:Details
   }
]
<template>
    <h3>列表</h3>
    <ul>
        <li v-for="(item,index) in user.names" :key="index">
            <router-link :to="'/details/' + item">{{ item }}</router-link>
        </li>
    </ul>
</template>
<script setup>
  import { reactive } from "vue"
  const user = reactive({
     names:["iwen","ime","frank"]
})
</script>

选项式API

<template>
    <h3>详情</h3>
    <p>{{ name }}</p>
</template>
<script>
  export default {
    data(){
        return{
            name:""
       }
   },
    mounted(){
        this.name = this.$route.params.name
   }
}
</script>

组合式API

<template>
    <h3>详情</h3>
    <p>{{ name }}</p>
</template>
<script setup>
  import { useRoute } from "vue-router"
  import { ref } from "vue"
  const route = useRoute()
  const name = ref("")
  name.value = route.params.name;
</script>

可选参数

{
    path:"/details/:name?",
    component:Details
}

实时效果反馈

1.在Vue路由中,可以获取页面跳转传递的参数是:

A router

B params

C this.params

D this.$route.params

嵌套路由 

一些应用程序的 UI 由多层嵌套的组件组成。在这种情况下,URL 的 片段通常对应于特定的嵌套组件结构

<template>
    <h3>新闻</h3>
    <router-link to="/news/sport">Sport</router-link> |
    <router-link to="/news/yule">Yule</router-link>
    <router-view></router-view>
</template>
<template>
    <h3>体育新闻</h3>
</template>
<template>
    <h3>娱乐新闻</h3>
</template>
{
    path:"/news",
        component:News,
            children:[
               {
                    path:"sport",
                    component:SportNews
               },
               {
                    path:"yule",
                    component:YuleNews
               }
           ]
}

重定向和别名

重定向 

重定向也是通过 routes 配置来完成

{
    path:"/news",
        component:News,
            redirect:"/news/sport",
                children:[
                   {
                      path:"sport", component:SportNews
                   },
                   {
                        path:"yule", component:YuleNews
                   }
               ]
}

别名

重定向是指当用户访问 /home 时,URL 会被 / 替换,然后匹配成 / 。那么什么是别名呢

{
    alias:"yl",
    path:"yule",
    component:YuleNews
}

 命名路由

除了 path 之外,你还可以为任何路由提供 name 。这有以下优点 

{
    name:"About",
    path:"/about",
    component:About
}
this.$router.push({
 name:"About"
})
<router-link :to="{ name:'Details',params:{ name:item } }">{{ item }}</router-link>

命名视图

有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一 个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图, 而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默 认为 default 

const routes = [
   {
       name:"Home",
       path:"/",
       components:{
           default:Home,
           // 它们与 `<router-view>` 上的 `name` 属性匹配
           AD
       }
   },
   {
       name:"About",
       path:"/about",
       components:{
           default:About,
           AD
       }
   }
]
<template>
    <router-link to="/">Home</router-link> |
    <router-link to="/about">About</router-link>
    <router-view></router-view>
    <router-view name="AD"></router-view>
</template>

不同的历史模式

在创建路由器实例时, history 配置允许我们在不同的历史模式中进行选择 

Hash 模式 

hash 模式是用 createWebHashHistory() 创建的

import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
  history: createWebHashHistory(),
  routes: [
    //...
 ],
})

HTML5 模式

createWebHistory() 创建 HTML5 模式,推荐使用这个模式

import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
  history: createWebHistory(),
  routes: [
    //...
 ],
})

当使用这种历史模式时,URL 会看起来很 "正常",例如 https://example.com/user/id 。漂亮!

不过,问题来了。由于我们的应用是一个单页的客户端应用,如果没有适当的服务器配置,用户在浏览器中直接访问 https://example.com/user/id ,就会得到一个 404 错误。这就丑了。

不用担心:要解决这个问题,你需要做的就是在你的服务器上添加 一个简单的回退路由。如果 URL 不匹配任何静态资源,它应提供与 你的应用程序中的 index.html 相同的页面。漂亮依旧!

具体参考地址:

https://router.vuejs.org/zh/guide/essentials/history-mode.h tml#html5-%E6%A8%A1%E5%BC%8F 

导航守卫 

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

全局前置守卫 

你可以使用 router.beforeEach 注册一个全局前置守卫,当一个导航触发时,就会触发全局前置守卫

router.beforeEach((to, from, next) => {
    // 返回 false 以取消导航
    next()
})

 全局解析守卫

你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似

router.beforeResolve((to,from,next) => {
    next()
})

 全局后置钩子

你可以直接在路由配置上定义 beforeEnter 守卫,在导航结束之后触发

router.afterEach((to,from) => {
    
})

 路由独享的守卫

你可以直接在路由配置上定义 beforeEnter 守卫, beforeEnter 守卫 只在进入路由时触发

{
    name: "List",
    path: "/list",
    component: List,
        beforeEnter:(to,from) => {
            return true;
   }
}

 组件内的守卫

你可以在路由组件内直接定义路由导航守卫

<template>
    <h3>Home首页</h3>
</template>
<script>
  export default {
    beforeRouteEnter(to, from){
        // 在渲染该组件的对应路由被验证前调用
        // 不能获取组件实例 `this` !
        // 因为当守卫执行时,组件实例还没被创建!
        console.log(to,from)
        beforeRouteUpdate(to,from){
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 
        `/users/:id`,在 `/users/1` 和 `/users/2` 之间
        跳转的时候,
        // 由于会渲染同样的 `UserDetails` 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 因为在这种情况发生的时候,组件已经挂载好了,导航守卫可以访问组件实例 `this`
   },
    beforeRouteLeave(to,from){
        // 在导航离开渲染该组件的对应路由时调用
        // 与 `beforeRouteUpdate` 一样,它可以访问组件实例 `this`
   }
}
</script>

 完整的导航解析流程

有关Vue3【Vue路由概念、项目引入路由、集成Vue路由 、编程式导航、带参数的动态路由匹配 、嵌套路由、重定向和别名、命名视图、不同的历史模式​】(十)-全面详解(学习总结---从入门到深化)的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby-on-rails - Rails 编辑表单不显示嵌套项 - 2

    我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib

  3. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  4. ruby - 将散列转换为嵌套散列 - 2

    这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[

  5. ruby 正则表达式 - 如何替换字符串中匹配项的第 n 个实例 - 2

    在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg

  6. ruby - 匹配未转义的平衡定界符对 - 2

    如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。

  7. ruby-on-rails - 项目升级后 Pow 不会更改 ruby​​ 版本 - 2

    我在我的Rails项目中使用Pow和powifygem。现在我尝试升级我的ruby​​版本(从1.9.3到2.0.0,我使用RVM)当我切换ruby​​版本、安装所有gem依赖项时,我通过运行railss并访问localhost:3000确保该应用程序正常运行以前,我通过使用pow访问http://my_app.dev来浏览我的应用程序。升级后,由于错误Bundler::RubyVersionMismatch:YourRubyversionis1.9.3,butyourGemfilespecified2.0.0,此url不起作用我尝试过的:重新创建pow应用程序重启pow服务器更新战俘

  8. ruby-on-rails - 新 Rails 项目 : 'bundle install' can't install rails in gemfile - 2

    我已经像这样安装了一个新的Rails项目:$railsnewsite它执行并到达:bundleinstall但是当它似乎尝试安装依赖项时我得到了这个错误Gem::Ext::BuildError:ERROR:Failedtobuildgemnativeextension./System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/rubyextconf.rbcheckingforlibkern/OSAtomic.h...yescreatingMakefilemake"DESTDIR="cleanmake"DESTDIR="

  9. ruby-on-rails - 如何使辅助方法在 Rails 集成测试中可用? - 2

    我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel

  10. ruby - 匹配大写字母并用后续字母填充,直到一定的字符串长度 - 2

    我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种

随机推荐