当前位置: 首页 > 工具软件 > vue-api-query > 使用案例 >

Vue3.0学习 - 第二十四节,Vue3.x 中 Vue-Router 详解,vue-router路由的使用

和柏
2023-12-01

一、Vue3.x中的路由

路由可以让应用程序根据用户输入的不同地址动态挂载不同的组件。

Vue Router

npm install vue-router@next --save
npm install vue-router@4

二、Vue3.x路由的基本配置

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>
    &nbsp;
    <router-link :to="{name:'vue3-com'}">组合式 API</router-link>
     &nbsp;
    <router-link :to="{name:'news',params:{title:'我是传入的标题'},query:{desc:'我是描述'}}">NEWS</router-link>
     &nbsp;
     <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>

三、Vue3.x动态路由

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>
    &nbsp;
    <router-link :to="{name:'vue3-com'}">组合式 API</router-link>
     &nbsp;
    <router-link :to="{name:'news',params:{title:'我是传入的标题'},query:{desc:'我是描述'}}">NEWS</router-link>
     &nbsp;
     <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>

四、Vue3.x Get传值

<router-link to="/newsContent?id=2">Get传值</router-link>
this.$route.query

五、Vue3.x路由编程式导航(Js跳转路由)

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'})

六、Vue3.x路由HTML5 History 模式和 hash 模式

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模式后,发布到服务器需要配置伪静态:

HTML5 History 模式 | Vue Router

七、Vue3.x命名路由

有时候,通过一个名称来标识一个路由显得更方便一些,特别是在链接一个路由,或者是执行一些跳转的时候。你可以在创建 Router 实例的时候,在 routes 配置中给某个路由设置名称。

const router = new VueRouter({
  routes: [
     {
        path: "/Home",
        name: "Home",
        component: () =>
          import(/* webpackChunkName: "home" */ "../views/Home.vue"),
      }
  ]
})

要链接到一个命名路由,可以给 router-linkto 属性传一个对象:

<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;

 类似资料: