Роутинг с vue-router на VueJS3 часть вторая

Здесь первая.

Вложенные роуты

Рассмотрим пример где нам будет нужно создать дочерние роутеры. В этом примере мы будем выводить полную информацию о посте со сменой 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

Для передачи данных через 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
		}
	}
})

 

Так же с моим портфолио можно ознакомиться на любой из представленной социальной сети, на своих страницах я публикую посты о своих работах, заданиях и целях.

Для связи со мной можно воспользоваться любой социальной сетью,
или написать на почту:

С моим резюме можно ознакомиться по ссылке:

© 2020-2024 Портфолио Юдина Александра г.Пенза. Все права защищены