路由可以让应用程序根据用户输入的不同地址动态挂载不同的组件。
npm install vue-router@next --save
npm install vue-router@4
1、安装路由模块
npm install vue-router@next --save
2、新建组件
src/views/Home.vue
<template>
<div>
<h1>home组件</h1>
<br>
<h1>{{book.title}}</h1>
<h1>{{book.author}}</h1>
<h1>{{book.year}}</h1>
<hr>
<h2>{{allTitle}}</h2>
<button @click="setTitle('我是传入的数据')">设置数据</button>
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
interface Book {
title: String;
author: String;
year: Number;
}
var book: Book = {
title: "vue3 typescript",
author: "vue Team",
year: 2020,
};
export default defineComponent({
data() {
return {
book,
};
},
setup() {
return {};
},
computed: {
allTitle(): string {
return "wellcome.text = " + this.book.title;
},
},
methods: {
setTitle(name:string): void {
this.book.title = name;
this.book.year = 2021
},
},
});
</script>
<style scoped lang="scss">
</style>
src/views/News.vue
<template>
<div class="news">
<p v-html="newtitle"></p>
</div>
</template>
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
import { useRoute } from "vue-router";
export default defineComponent({
setup() {
// let $router = useRouter()
let $route = useRoute();
let newtitle = ref<string | string[]>("2021");
onMounted(() => {
console.log("News onMounted params = ", $route.query.desc);
newtitle.value =
"title:" + $route.params.title + "<br />描述" + $route.query.desc;
});
return {
newtitle,
};
},
});
</script>
<style scoped>
.news {
white-space: "pre";
}
</style>
src/views/vue3com.vue
<template>
<h1>组合式api</h1>
<h2>名字:{{name}}</h2>
<h2>描述:{{desc}}</h2>
<h2>时间:{{year1}}</h2>
<button @click="setNamechange">改变name</button>
<hr>
<h2>名字:{{book2.name}}</h2>
<h2>描述:{{book2.desc}}</h2>
<h2>时间:{{book2.year}}</h2>
<hr>
<h2>名字:{{book3.name}}</h2>
<h2>描述:{{book3.desc}}</h2>
<h2>时间:{{book3.year}}</h2>
</template>
<script lang="ts">
import { defineComponent, reactive, ref, toRefs } from "vue";
interface Book {
name: String | number;
desc: String;
year?: number;
setNamechange?():void
}
export default defineComponent({
setup() {
let year1 = ref<string | number>("2021");
console.log("ssssss", year1.value);
// 第一种方式
const book1: Book = reactive({
name: year1.value,
desc: "vue3 进阶学习加油",
setNamechange(){
this.name = "我是新设置的"
}
});
// 第二种方式
const book2 = reactive<Book>({
name: "vue3--typeScript",
desc: "学习ts加油",
year: 2020,
});
// 第三种方式
const book3 = reactive({
name: "vue3--typeScript-第三种方式",
desc: "ts类型第三种方式",
year: 2022,
}) as Book;
return {
...toRefs(book1),
book2,
book3,
year1,
};
},
});
</script>
<style scoped>
</style>
src/views/layout.vue
<template>
<div>
<router-link to="/Home">home</router-link>
<router-link :to="{name:'vue3-com'}">组合式 API</router-link>
<router-link :to="{name:'news',params:{title:'我是传入的标题'},query:{desc:'我是描述'}}">NEWS</router-link>
<button @click="$router.push({name:'news',params:{title:'点击传入标题'},query:{desc:'::我是描述'}})">click</button>
</div>
<!-- <Home msg="Welcome to Your Vue.js + TypeScript App"/> -->
<div class="router-view">
<router-view />
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "App",
components: {},
});
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
.router-view{
/* width: 100%;
height: 900px; */
}
.active{
text-decoration: none;
color: red;
font-weight: 700;
}
</style>
3、配置路由
新建src/router/index.ts 配置路由
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "layout",
redirect: "/Home",
component: () => import("../views/Layout.vue"),
children: [
{
path: "/Home",
name: "Home",
component: () =>
import(/* webpackChunkName: "home" */ "../views/Home.vue"),
},
{
path: "/vue3-com",
name: "vue3-com",
component: () =>
import(/* webpackChunkName: "others" */ "../views/vue3com.vue"),
alias:"/vue3" //路由别名
},
{
path: "/news/:title",
name:"news",
component: () => import(/* webpackChunkName: "others" */ "../views/News.vue"),
alias: ['/news-list/:title', '/ne/:title']
},
],
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
linkActiveClass: "active", //当路由激活时添加class到路由上router-link
});
export default router;
4、挂载路由
在main.ts中挂载路由
import { createApp } from 'vue'
import App from './App.vue'
import router from './routes'
// createApp(App).mount('#app')
const app = createApp(App)
//挂载路由
app.use(router)
app.mount('#app')
5、渲染组件
App.vue中通过router-view渲染组件
<template>
<div>
<router-view />
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
name: "App",
components: {},
});
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
1、配置动态路由
{
path: "/news/:title",
name:"news",
component: () => import(/* webpackChunkName: "others" */ "../views/News.vue"),
}
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "layout",
redirect: "/Home",
component: () => import("../views/Layout.vue"),
children: [
{
path: "/Home",
name: "Home",
component: () =>
import(/* webpackChunkName: "home" */ "../views/Home.vue"),
},
{
path: "/vue3-com",
name: "vue3-com",
component: () =>
import(/* webpackChunkName: "others" */ "../views/vue3com.vue"),
alias:"/vue3" //路由别名
},
{
path: "/news/:title",
name:"news",
component: () => import(/* webpackChunkName: "others" */ "../views/News.vue"),
alias: ['/news-list/:title', '/ne/:title']
},
],
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
linkActiveClass: "active", //当路由激活时添加class到路由上router-link
});
export default router;
2、路由跳转
<template>
<div>
<router-link to="/Home">home</router-link>
<router-link :to="{name:'vue3-com'}">组合式 API</router-link>
<router-link :to="{name:'news',params:{title:'我是传入的标题'},query:{desc:'我是描述'}}">NEWS</router-link>
<button @click="$router.push({name:'news',params:{title:'点击传入标题'},query:{desc:'::我是描述'}})">click</button>
</div>
<!-- <Home msg="Welcome to Your Vue.js + TypeScript App"/> -->
<div class="router-view">
<router-view />
</div>
</template>
3、获取路由
this.$route.params
vue3.x组合式api 获取路由
<script lang="ts">
import { defineComponent, onMounted, ref } from "vue";
import { useRoute } from "vue-router";
export default defineComponent({
setup() {
// let $router = useRouter()
let $route = useRoute();
let newtitle = ref<string | string[]>("2021");
onMounted(() => {
console.log("News onMounted params = ", $route.query.desc);
newtitle.value =
"title:" + $route.params.title + "<br />描述" + $route.query.desc;
});
return {
newtitle,
};
},
});
</script>
<router-link to="/newsContent?id=2">Get传值</router-link>
this.$route.query
this.$router.push({ path: 'news' })
this.$router.push({
path: '/newsContent/495'
});
this.$router.push({ path: '/newscontent', query:{aid:14} }
this.$router.push({ path: '/newscontent/123'})
6.1、 hash 模式
import { createRouter, createWebHashHistory } from 'vue-router'
const router = createRouter({
history: createWebHashHistory(),
routes: [
//...
],
})
http://localhost:8080/#/user
http://localhost:8080/#/news
如果想把上面的路由改变成下面方式:
http://localhost:8080/news
http://localhost:8080/user
6.2、 HTML5 History 模式
import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(),
routes: [
//...
]
})
**注意:**开启Html5 History模式后,发布到服务器需要配置伪静态:
有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes
配置中给某个路由设置名称。
const router = new VueRouter({
routes: [
{
path: "/Home",
name: "Home",
component: () =>
import(/* webpackChunkName: "home" */ "../views/Home.vue"),
}
]
})
要链接到一个命名路由,可以给 router-link
的 to
属性传一个对象:
<router-link :to="{name:'news',params:{title:'我是传入的标题'},query:{desc:'我是描述'}}">NEWS</router-link>
这跟代码调用 router.push()
是一回事:
this.$router.push({name:'news',params:{title:'点击传入标题'},query:{desc:'::我是描述'}})
这两种方式都会把路由导航到 /news/xxxx
路径。
this.$router.push({name:'content',query:{aid:222}})
重定向也在routes
配置中完成。要从重定向/a
到/b
:
const routes = [{ path: '/', redirect: '/Home' }]
重定向也可以针对命名路由:
const routes = [{ path: '/home', redirect: { name: 'news' } }]
甚至使用函数进行动态重定向:
const routes = [
{
// /search/screens -> /search?q=screens
path: '/search/:searchText',
redirect: to => {
// the function receives the target route as the argument
// we return a redirect path/location here.
return { path: '/search', query: { q: to.params.searchText } }
},
},
{
path: '/search',
// ...
},
]
相对重定向: 也可以重定向到相对位置:
const routes = [
{
path: '/users/:id/posts',
redirect: to => {
// the function receives the target route as the argument
// return redirect path/location here.
},
},
]
重定向是指用户访问时/home
,URL将被替换/
,然后与匹配/
。但是什么是别名?
别名/
as/home
表示用户访问时/home
,URL保持不变/home
,但将被匹配,就像用户正在访问时一样/
。
以上内容可以在路由配置中表示为:
const routes = [{ path: '/', component: Homepage, alias: '/home' }]
别名使您可以自由地将UI结构映射到任意URL,而不受配置的嵌套结构的约束。使别名以a开头,/
以使路径在嵌套路由中是绝对的。您甚至可以将两者结合起来,并为数组提供多个别名:
{
path: "/vue3-com",
name: "vue3-com",
component: () =>
import(/* webpackChunkName: "others" */ "../views/vue3com.vue"),
alias: ['/vue3', '/vue3xx']
},
如果您的路线包含参数,请确保将其包含在任何绝对别名中:
{
path: "/news/:title",
name:"news",
component: () => import(/* webpackChunkName: "others" */ "../views/News.vue"),
alias: ['/news-list/:title', '/ne/:title']
}
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "layout",
redirect: "/Home",
component: () => import("../views/Layout.vue"),
children: [
{
path: "/Home",
name: "Home",
component: () =>
import(/* webpackChunkName: "home" */ "../views/Home.vue"),
},
{
path: "/vue3-com",
name: "vue3-com",
component: () =>
import(/* webpackChunkName: "others" */ "../views/vue3com.vue"),
alias:"/vue3" //路由别名
},
{
path: "/news/:title",
name:"news",
component: () => import(/* webpackChunkName: "others" */ "../views/News.vue"),
alias: ['/news-list/:title', '/ne/:title']
},
],
},
];
const router = createRouter({
history: createWebHashHistory(),
routes,
linkActiveClass: "active", //当路由激活时添加class到路由上router-link
});
export default router;