Vue: Vue Router

Vue Router

Vue Router 是 Vue.js 官方的路由管理器。它和 Vue.js 的核心深度集成,让构建单页面应用变得易如反掌

https://router.vuejs.org/zh/

安装

npm install vue-router --save

配置

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

// 1. 安装插件
Vue.use(VueRouter)


// 3. 配置路由
const routes = [
  {
    // 前端路由地址 (不含http信息)
    path: '/',
    name: 'Home',
    // 绑定对应组件
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/index',
    // 重定向, 意味着当访问 xx/index时,将自动重定向到 xx/ 路由
    redirect: '/'
  }
]

// 3. 创建VueRouter对象
const router = new VueRouter({
  routes,
  // 去除路由过程中间的 # 号
  mode: 'history'
})

export default router

// 4. 去main.js中导入 该router对象

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'

Vue.config.productionTip = false

new Vue({
  // 导入roter对象
  router,
  render: h => h(App)
}).$mount('#app')

使用

router-link (路由切换) 、 router-view(对应组件内容占位)

App.vue

<template>
  <div id="app">
    <div id="nav">
      <!-- 点击跳转路由 -->
      <router-link to="/">Home</router-link> |
      <router-link to="/about">About</router-link>
    </div>
    <!-- 实现router-link 切换后 占位显示的内容 -->
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
</style>

router-link 默认渲染出来的是a标签

App.vue

<template>
  <div id="app">
    <div id="nav">
      <!-- 点击跳转路由 -->
      <router-link to="/">Home</router-link> |
      <!-- tag 修改router-link 渲染的标签类型-->
      <!-- replace 点了之后不能回退左上角 -->
      <!-- active-class 指定 router-link 的类 -->
      <router-link to="/about" tag="button" replace active-class="active">About</router-link>
    </div>
    <!-- 实现router-link 切换后 占位显示的内容 -->
    <router-view/>
  </div>
</template>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
.active {
  color: red;
}
</style>

通过代码跳转路由

App.vue

<template>
  <div id="app">
    <div id="nav">
      <!-- 点击跳转路由 -->
      <router-link to="/">Home</router-link> |
      <!-- tag 修改router-link 渲染的标签类型-->
      <!-- replace 点了之后不能回退左上角 -->
      <!-- active-class 指定 router-link 的类 -->
      <router-link to="/about" tag="button" replace active-class="active">About</router-link>

      <button @click="toAbout">toAbout</button>
    </div>
    <!-- 实现router-link 切换后 占位显示的内容 -->
    <router-view/>
  </div>
</template>

<script>
export default {
  methods: {
    toAbout: function() {
      // this.$router.push('/about')
      this.$router.replace('/about')
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
.active {
  color: red;
}
</style>

动态路由

路径不确定: user/:id , :id 为不确定值

User.vue

<template>
  <div><h1>user Page {{ userId }}</h1></div>
</template>

<script>
export default {
    name: 'User',
    computed: {
        userId() {
            // $route, 当前活跃路由, params.属性 该属性为router/index.js中定义的动态路由 :userId userId为属性名
            return this.$route.params.userId
        }
    }
}
</script>

<style>

</style>

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import User from '../views/User'

// 1. 安装插件
Vue.use(VueRouter)


// 3. 配置路由
const routes = [
  {
    // 前端路由地址 (不含http信息)
    path: '/',
    name: 'Home',
    // 绑定对应组件
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/index',
    // 重定向, 意味着当访问 xx/index时,将自动重定向到 xx/ 路由
    redirect: '/'
  },
  //  动态路由
  {
    // :id 表示该路由id 部分是可变的
    path: '/user/:userId',
    name: 'User',
    component: User
  }
]

// 3. 创建VueRouter对象
const router = new VueRouter({
  routes,
  // 去除路由过程中间的 # 号
  mode: 'history'
})

export default router

// 4. 去main.js中导入 该router对象

App.vue

<template>
  <div id="app">
    <div id="nav">
      <!-- 点击跳转路由 -->
      <router-link to="/">Home</router-link> |
      <!-- tag 修改router-link 渲染的标签类型-->
      <!-- replace 点了之后不能回退左上角 -->
      <!-- active-class 指定 router-link 的类 -->
      <router-link to="/about" tag="button" replace active-class="active">About</router-link>

      <button @click="toAbout">toAbout</button>
      
      <!-- 动态绑定 需要变化的路由,  -->
      <router-link :to="`/user/${userId}`">User</router-link>
    </div>
    <!-- 实现router-link 切换后 占位显示的内容 -->
    <router-view/>
  </div>
</template>

<script>
export default {
  data() {
    return {
      userId: 1
    }
  },                             
  methods: {
    toAbout: function() {
      // this.$router.push('/about')
      this.$router.replace('/about')
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
.active {
  color: red;
}
</style>

路由懒加载

当打包构建应用时,JavaScript 包会变得非常大,影响页面加载。如果我们能把不同路由对应的组件分割成不同的代码块,然后当路由被访问的时候才加载对应组件,这样就更加高效了。

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'

// 1. 安装插件
Vue.use(VueRouter)


const User = () => import(/* webpackChunkName: "about" */ '../views/User.vue')


// 3. 配置路由
const routes = [
  {
    // 前端路由地址 (不含http信息)
    path: '/',
    name: 'Home',
    // 绑定对应组件
    component: Home
  },
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.
    
    // 路由懒加载
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
  },
  {
    path: '/index',
    // 重定向, 意味着当访问 xx/index时,将自动重定向到 xx/ 路由
    redirect: '/'
  },
  //  动态路由
  {
    // :id 表示该路由id 部分是可变的
    path: '/user/:userId',
    name: 'User',
    component: User
  }
]

// 3. 创建VueRouter对象
const router = new VueRouter({
  routes,
  // 去除路由过程中间的 # 号
  mode: 'history'
})

export default router

// 4. 去main.js中导入 该router对象

嵌套路由

1. News.vue

<template>
  <div><ul>
      <li>1</li>
      <li>1</li>
    </ul></div>
</template>

<script>
export default {
    name: "News"
}
</script>

<style>

</style>

2. router/inde.js 定义子路由

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import User from '../views/User'

// 1. 安装插件
Vue.use(VueRouter)

// 3. 配置路由
const routes = [
  {
    // 前端路由地址 (不含http信息)
    path: '/',
    name: 'Home',
    // 绑定对应组件
    component: Home,
    // 子路由
    children: [
      {
        // 子路由不需要加 /
        path: "news",
        component: () => import('../views/News')
      }
    ]
},
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.

    // 路由懒加载
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
  },
  {
    path: '/index',
    // 重定向, 意味着当访问 xx/index时,将自动重定向到 xx/ 路由
    redirect: '/'
  },
  //  动态路由
  {
    // :id 表示该路由id 部分是可变的
    path: '/user/:userId',
    name: 'User',
    component: User
  }
]

// 3. 创建VueRouter对象
const router = new VueRouter({
  routes,
  // 去除路由过程中间的 # 号
  mode: 'history'
})

export default router

// 4. 去main.js中导入 该router对象

3. Home.vue 使用子路由

<template>
  <div class="home">
    <img alt="Vue logo" src="../assets/logo.png">
    <HelloWorld msg="Welcome to Your Vue.js App"/>
        <router-link to="/news"> 子路由 user</router-link>
    <router-view></router-view>
  </div>
</template>

<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'Home',
  components: {
    HelloWorld
  }
}
</script>

参数传递

  1. params类型 user/:id -> user/100
    • this.$route.params
  2. query类型user?id=100
    • this.$route.query

$route$router

  • $router: Vue-Router对象
  • $route: 当前活跃(页面所在)路由

导航守卫(全局)

router/index.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '../views/Home.vue'
import User from '../views/User'

// 1. 安装插件
Vue.use(VueRouter)

// 3. 配置路由
const routes = [
  {
    // 前端路由地址 (不含http信息)
    path: '/',
    name: 'Home',
    // 绑定对应组件
    component: Home,
    // 子路由
    children: [
      {
        // 子路由不需要加 /
        path: "news",
        component: () => import('../views/News')
      }
    ]
},
  {
    path: '/about',
    name: 'About',
    // route level code-splitting
    // this generates a separate chunk (about.[hash].js) for this route
    // which is lazy-loaded when the route is visited.

    // 路由懒加载
    component: () => import(/* webpackChunkName: "about" */ '../views/About.vue'),
    //  定义元类数据,用于实现根据路由变换title
    meta:{
      title: "关于"
    }
  },
  {
    path: '/index',
    // 重定向, 意味着当访问 xx/index时,将自动重定向到 xx/ 路由
    redirect: '/'
  },
  //  动态路由
  {
    // :id 表示该路由id 部分是可变的
    path: '/user/:userId',
    name: 'User',
    component: User
  }
]

// 3. 创建VueRouter对象
const router = new VueRouter({
  routes,
  // 去除路由过程中间的 # 号
  mode: 'history'
})

// 导航守卫, 前置钩子
router.beforeEach((to, from, next) => {
  //  实现标题根据路由进行变化
  document.title = to.matched[0].meta.title
  next()
})
// 后置钩子
router.afterEach((to, from) => {
  console.log(to, from)
})
export default router

// 4. 去main.js中导入 该router对象

keep-alive

缓存,使组件保留状态,避免重新渲染

  • include: 只有匹配的组件被缓存
  • exclude: 匹配的组件将不被缓存

App.vue

<template>
  <div id="app">
    <div id="nav">
      <!-- 点击跳转路由 -->
      <router-link to="/">Home</router-link> |
      <!-- tag 修改router-link 渲染的标签类型-->
      <!-- replace 点了之后不能回退左上角 -->
      <!-- active-class 指定 router-link 的类 -->
      <router-link to="/about" tag="button" replace active-class="active">About</router-link>

      <button @click="toAbout">toAbout</button>
      
      <!-- 动态绑定 需要变化的路由,  -->
      <router-link :to="`/user/${userId}`">User</router-link>
    </div>
    <!-- keep-live 缓存 -->
    <keep-alive exclude="About,User">
      <!-- 实现router-link 切换后 占位显示的内容 -->
      <router-view/>
    </keep-alive>

  </div>
</template>

<script>
export default {
  data() {
    return {
      userId: 1
    }
  },                             
  methods: {
    toAbout: function() {
      // this.$router.push('/about')
      this.$router.replace('/about')
    }
  }
}
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
}

#nav {
  padding: 30px;
}

#nav a {
  font-weight: bold;
  color: #2c3e50;
}

#nav a.router-link-exact-active {
  color: #42b983;
}
.active {
  color: red;
}
</style>

作者:zy7y
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须在文章页面给出原文链接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/zy7y/p/14496707.html