Рассмотрим пример где нам будет нужно создать дочерние роутеры. В этом примере мы будем выводить полную информацию о посте со сменой URL, например есть пост http://localhost:8080/post/7/, мы сделаем переход на страницу http://localhost:8080/post/7/full при нажатии на кнопку.
Создадим страницу для вывода полной информации поста.
fullpost.vue
<template>
<div>
<h3>Name Post: Hello World</h3>
<h4>Date Post: 2023-01-14</h4>
</div>
</template>
<script></script>
Зарегистрируем новые views и добавим дочерние роуты.
router.js
/* jshint ignore:start */
import {createRouter, createWebHistory} from "vue-router"
import home from "@/views/home.vue"
import about from "@/views/about.vue"
import post from "@/views/post.vue"
import fullpost from "@/views/fullpost.vue"
export default createRouter ({
history: createWebHistory(),
routes: [
{
path: "/",
component: home
},
{
path: "/about/",
component: about
},
{
path: "/post/:id",
component: post,
children: [
{
path: "full", //localhost:8080/post/5/full
component: fullpost,
name: "fullpost"
}
]
}
]
})
Добавим на страницу поста кнопку для перемещения на fullpost views, и укажем где будет рендериться информация из fullpost.vue тегом <router-view></router-view>.
post.vue
<template>
<div>
<h1>POST: {{ id }}</h1>
<button class="btn btn-sm btn-info" @click="goBackToPosts">Back</button>
<br><br>
<router-link
class="btn btn-sm btn-info"
:to="'/post/' + id + '/full'"
>
Full post
</router-link>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
id: this.$route.params.id
}
},
watch: {
$route(toRoute) {
this.id = toRoute.params.id
}
},
methods: {
goBackToPosts() {
this.$router.push("/about/")
}
}
}
</script>
В примере выше один из вариантов оформления router-link.
первый вариант
<router-link
class="btn btn-sm btn-info"
:to="'/post/' + id + '/full'"
>
Full post
</router-link>
Есть второй вариант.
второй вариант
<router-link
class="btn btn-sm btn-info"
:to="{name: 'fullpost', params: {id: id}}"
>
Full post
</router-link>
Для передачи данных через URL используется параметр query. Рассмотрим его работу на примере.
post.vue
<template>
<div>
<h1>POST: {{ id }}</h1>
<button class="btn btn-sm btn-info" @click="goBackToPosts">Back</button>
<br><br>
<router-link
class="btn btn-sm btn-info"
:to="{ name: 'fullpost', params: { id: id }, query: {name: 'Hello World', date: '2023-01-14'} }"
>
Full post
</router-link>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
id: this.$route.params.id
}
},
watch: {
$route(toRoute) {
this.id = toRoute.params.id
}
},
methods: {
goBackToPosts() {
this.$router.push("/about/")
}
}
}
</script>
fullpost.vue
<template>
<div>
<h3>Name Post: {{ $route.query.name }}</h3>
<h4>Date Post: {{ $route.query.date }}</h4>
</div>
</template>
<script></script>
Это используется для скроллинга к определенному элементу на экране, перемещение по якорям.
fullpost.vue
<template>
<div>
<h3>Name Post: {{ $route.query.name }}</h3>
<h4>Date Post: {{ $route.query.date }}</h4>
<div class="blackblcok"></div>
<h5 id="scroll">Content</h5>
<div class="blackblcok"></div>
<h5>Footer</h5>
</div>
</template>
<script></script>
<style scoped>
.blackblcok {
width: 100px;
height: 1000px;
background-color: #000000;
}
</style>
В post.vue мы используем параметр hash указывая якорь.
post.vue
<template>
<div>
<h1>POST: {{ id }}</h1>
<button class="btn btn-sm btn-info" @click="goBackToPosts">Back</button>
<br><br>
<router-link
class="btn btn-sm btn-info"
:to="{ name: 'fullpost', params: { id: id }, query: {name: 'Hello World', date: '2023-01-14'}, hash: '#scroll' }"
>
Full post
</router-link>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
data() {
return {
id: this.$route.params.id
}
},
watch: {
$route(toRoute) {
this.id = toRoute.params.id
}
},
methods: {
goBackToPosts() {
this.$router.push("/about/")
}
}
}
</script>
В router.js мы используем параметр scrollBehavior для перемещения. Параметр return используется для переноса по умолчанию.
router.js
/* jshint ignore:start */
import {createRouter, createWebHistory} from "vue-router"
import home from "@/views/home.vue"
import about from "@/views/about.vue"
import post from "@/views/post.vue"
import fullpost from "@/views/fullpost.vue"
export default createRouter ({
history: createWebHistory(),
routes: [
{
path: "/",
component: home
},
{
path: "/about/",
component: about
},
{
path: "/post/:id",
component: post,
children: [
{
path: "full", //localhost:8080/post/5/full
component: fullpost,
name: "fullpost"
}
]
}
],
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: "#scroll",
}
}
return {
top: 700
}
}
})
Для редиректа с помощью vue-router используется redirect, как в примере ниже.
router.js
/* jshint ignore:start */
import { createRouter, createWebHistory } from "vue-router"
import home from "@/views/home.vue"
import about from "@/views/about.vue"
import post from "@/views/post.vue"
import fullpost from "@/views/fullpost.vue"
export default createRouter({
history: createWebHistory(),
routes: [
{
path: "/",
component: home
},
{
path: "/about/",
component: about
},
{
path: "/post/:id",
component: post,
children: [
{
path: "full", //localhost:8080/post/5/full
component: fullpost,
name: "fullpost"
}
]
},
{
path: "/none/",
redirect: "/about/"
},
],
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: "#scroll",
}
}
return {
top: 700
}
}
})
Для создания 404 страницы создается компонент страницы, в router.js настраивается переадресация на эту страницу при всех несуществующих адресах.
erorpage.vue
<template>
<div>
<h1>Not Page</h1>
</div>
</template>
<script></script>
<style scoped>
h1 {
color: red;
}
</style>
router.js
/* jshint ignore:start */
import { createRouter, createWebHistory } from "vue-router"
import home from "@/views/home.vue"
import about from "@/views/about.vue"
import post from "@/views/post.vue"
import fullpost from "@/views/fullpost.vue"
import erorpage from "@/views/erorpage.vue"
export default createRouter({
history: createWebHistory(),
routes: [
{
path: "/",
component: home
},
{
path: "/about/",
component: about
},
{
path: "/post/:id",
component: post,
children: [
{
path: "full", //localhost:8080/post/5/full
component: fullpost,
name: "fullpost"
}
]
},
{
path: "/none/",
redirect: "/about/"
},
{
path: "/:catchAll(.*)",
component: erorpage
}
],
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: "#scroll",
}
}
return {
top: 700
}
}
})
Рассмотрим два примера. В первом мы будем проверять разрешено ли переходить на другую страницу.
router.js
/* jshint ignore:start */
import { createRouter, createWebHistory } from "vue-router"
import home from "@/views/home.vue"
import about from "@/views/about.vue"
import post from "@/views/post.vue"
import fullpost from "@/views/fullpost.vue"
import erorpage from "@/views/erorpage.vue"
export default createRouter({
history: createWebHistory(),
routes: [
{
path: "/",
component: home
},
{
path: "/about/",
component: about
},
{
path: "/post/:id",
component: post,
children: [
{
path: "full", //localhost:8080/post/5/full
component: fullpost,
name: "fullpost",
beforeEnter(to, from, next) {
console.log("beforeEnter")
let i = 0
if (i == 0) {
console.log("пользователю позволено перейти на страницу")
next(true)
} else {
next(false)
console.log("пользователю не позволено перейти на страницу")
}
}
}
]
},
{
path: "/none/",
redirect: "/about/"
},
{
path: "/:catchAll(.*)",
component: erorpage
}
],
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: "#scroll",
}
}
return {
top: 700
}
}
})
fullpost.vue
<template>
<div>
<h3>Name Post: {{ $route.query.name }}</h3>
<h4>Date Post: {{ $route.query.date }}</h4>
<div class="blackblcok"></div>
<h5 id="scroll">Content</h5>
<div class="blackblcok"></div>
<h5>Footer</h5>
</div>
</template>
<script>
export default {
beforeRouteEnter(to, from, next) {
console.log("beforeRouterEnter")
next(true) //разрешен переход на страницу
//next(false) //не разрешен переход на страницу
}
}
</script>
<style scoped>
.blackblcok {
width: 100px;
height: 1000px;
background-color: #000000;
}
</style>
Во втором примере мы будем спрашивать подтверждение прежде чем покинуть страницу.
post.vue
<template>
<div>
<h1>POST: {{ id }}</h1>
<button class="btn btn-sm btn-info" @click="goBackToPosts">Back</button>
<br><br>
<router-link
class="btn btn-sm btn-info"
:to="{ name: 'fullpost', params: { id: id }, query: {name: 'Hello World', date: '2023-01-14'}, hash: '#scroll' }"
>
Full post
</router-link>
<hr>
<router-view></router-view>
</div>
</template>
<script>
export default {
beforeRouteLeave(to, from, next) {
console.log("beforeRouteLeave")
//next(false) //не разрешено уходить со страницы
//next(true) //разрешено уходить со страницы
if (window.confirm("Вы уверены что хотите выйти?")) {
next (true)
} else {
next (false)
}
},
data() {
return {
id: this.$route.params.id
}
},
watch: {
$route(toRoute) {
this.id = toRoute.params.id
}
},
methods: {
goBackToPosts() {
this.$router.push("/about/")
}
}
}
</script>
Ленивая загрузка позволяет подгружать определенные роуты только тогда, когда они будут запрошены пользователем. Это позволяет делать проект с большим количеством роутеров оптимизированным, что позволяет делать постепенную погрузку элементов и влияет на скорость загрузки.
Разберем на примере.
router.js
/* jshint ignore:start */
import { createRouter, createWebHistory } from "vue-router"
import home from "@/views/home.vue"
//import about from "@/views/about.vue"
//import post from "@/views/post.vue"
import fullpost from "@/views/fullpost.vue"
import erorpage from "@/views/erorpage.vue"
const about = () => import("@/views/about.vue")
const post = () => import("@/views/post.vue")
export default createRouter({
history: createWebHistory(),
routes: [
{
path: "/",
component: home
},
{
path: "/about/",
component: about
},
{
path: "/post/:id",
component: post,
children: [
{
path: "full", //localhost:8080/post/5/full
component: fullpost,
name: "fullpost",
beforeEnter(to, from, next) {
console.log("beforeEnter")
let i = 0
if (i == 0) {
console.log("пользователю позволено перейти на страницу")
next(true)
} else {
next(false)
console.log("пользователю не позволено перейти на страницу")
}
}
}
]
},
{
path: "/none/",
redirect: "/about/"
},
{
path: "/:catchAll(.*)",
component: erorpage
}
],
scrollBehavior(to, from, savedPosition) {
if (to.hash) {
return {
el: "#scroll",
}
}
return {
top: 700
}
}
})