06-VueRouter(V4)和ElementPlus

7/24/2022

# 一、路由的使用

# 1,第一步:安装与配置

yarn add vue-router@4
yarn add element-plus
yarn add @element-plus/icons-vue
yarn add sass
1
2
3
4

在vite.config.ts中配置别名与代理,如下:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

import path from 'path'

// Vite官方配置
export default defineConfig({
  plugins: [vue()],
  server: {
    port: 8888,
    proxy: {
      '/api': {  // 讲状态管理的时候会用到
        target: 'https://cnodejs.org/',
        changeOrigin: true
      }
    }
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'src')
    }
  }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 2,第二步:创建路由并配置规则

  • 还没有创建Layout组件
// src/router/index.js

import { createRouter, createWebHashHistory, createWebHistory } from 'vue-router'

import Layout from '@/layout/index.vue'

export const asyncRoutes = [
{
        id: 1,
        text: '学生管理',
        icon: 'Watch',
        path: '/student',
        alias: '/',     // 别名
        component: Layout,
        redirect: '/student/a',
        children: [
            { id: 11, text: '学生列表', path: '/student/a', component: () => import('@/pages/student/PageA.vue') },
            { id: 12, text: '添加学生', path: '/student/b', component: () => import('@/pages/student/PageB.vue') }
        ]
    },
  {
    id: 2,
    text: '老师管理',
    icon: 'Mouse',
    path: '/teacher',
    component: Layout,
    redirect: '/teacher/a',
    children: [
      { id: 21, text: '老师列表', path: '/teacher/a', component: () => import('@/pages/teacher/PageA.vue') },
      { id: 22, text: '添加老师', path: '/teacher/b', component: () => import('@/pages/teacher/PageB.vue') },
    ]
  },

]

const router = createRouter({
  history: createWebHashHistory(),  // 带#的hash路由模式
  // history: createWebHistory(),         // 不带#的history路由模式
  routes: [
    ...asyncRoutes,
    { path: '/*', redirect: '/' }     // 重定向
  ]
})

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

export default router
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

# 3,第三步:在main.js中注册路由和Elementui plus以及图标

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import router from "./router/index.js"

// 使用element-plus
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
// 使用字体图标  每个图标,都是一个组件
import * as ElementPlusIconsVue from '@element-plus/icons-vue'


let app = createApp(App)

// 遍历所有的图标
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
    // 全局注册组件
    app.component(key, component)
}

// 注册路由
app.use(router)
// 使用elementplus
app.use(ElementPlus)

app.mount('#app')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 4,第四步:创建对应组件

// src/layout.vue

<template>
  <el-container>
    <el-aside width="200px">
      <el-menu
        active-text-color="#ffd04b"
        background-color="#545c64"
        class="el-menu-vertical-demo"
        default-active="2"
        text-color="#fff"
      >
        <el-sub-menu :index="sub.id+''" v-for='sub in asyncRoutes' :key='sub.id'>
          <template #title>
            <el-icon>
              <component :is='sub.icon' />
            </el-icon>
            <span>{{sub.text}}</span>
          </template>
          <el-menu-item v-for='item in sub.children' :key='item.id' :index="item.id+''">
            <!-- 在路由v4中,router-link已经没有tag属性了,建议使用插槽来改变渲染节点 -->
            <!-- 为了实现跳转,下面这个写法是固定的,少一个属性都不行 -->
            <router-link :to='item.path' custom v-slot='{navigate}'>
              <div @click='navigate'>{{item.text}}</div>
            </router-link>
          </el-menu-item>
        </el-sub-menu>
      </el-menu>
    </el-aside>

    <el-container>
      <el-header>Header</el-header>
      <el-main>
        <!-- 这里是给所谓的业务页面来显示 -->
        <router-view></router-view>
      </el-main>
    </el-container>
  </el-container>
</template>

<script setup>
  import { asyncRoutes } from '@/router'
</script>

<style lang="scss" scoped>
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// src/student/PageA.vue
<template>
  <h1>student Page A</h1>
</template>

<script setup>
import { useRoute, useRouter, useLink } from "vue-router";
const route = useRoute(); // 相当于选项式组件中的this.$route.query/params/fullpath...
const router = useRouter(); // 相当于选项式组件中的this.$router.push/replace/back()

console.log("route:", route);
console.log("router:", router);
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
// src/student/PageB.vue
<template>
  <h1>student Page B</h1>
</template>
1
2
3
4
// src/teacher/PageA.vue
<template>
    <h1>teacher Page A</h1>
</template>
1
2
3
4
// src/teacher/PageB.vue
<template>
  <h1>teacher Page B</h1>
</template>
1
2
3
4
// App.vue

<template>
  <!-- 这个地方是给Layout或登录页用的 -->
  <router-view></router-view>
</template>

<script setup>
</script>

<style lang='scss'>
html,
body {
  padding: 0;
  margin: 0;
  width: 100%;
  height: 100%;
  overflow: hidden;
}
#app {
  height: 100%;
  & > .el-container {
    height: 100%;
  }
  .el-aside {
    background-color: #545c64;
  }
  .el-header {
    border-bottom: 1px solid #ccc;
    line-height: 60px;
  }
}
</style>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 二、总结

# 1,路由V4对比V3有哪些细节变化?(8条)

  • 在vue3环境中,必须要使用vue-router(v4)
  • 创建router实例的方式变了,使用 const router = createRouter({history, routes:[]})
  • 指定路由模式的属性变了,使用history属性:createWebHashHistory() / createWebHistory()
  • 路由注册,在mian.js中 app.use(router)
  • 如果是选项式组件,this.$router/this.$route可以正常使用;如果是组合式API进行开发,必须使用 useRoute、userRouter等Hooks API进行开发。
  • router-link已经没有tag属性的,可以用custom和插槽实现自定义渲染。
  • router-view新增了"插槽"功能,极其强大,参见路由文档中的伪代码,它在实现keep-alive和transition动画将变得更简单,还可以Suspense实现Loading。
  • 新增了几个组合API:useRoute / useRouter / useLink。
  • 在V4中,淘汰了router.addRoutes(),只保留了 router.addRoute(),用于实现动态权限路由设计。
Last Updated: 12/25/2022, 10:02:14 PM