vue-路由的使用

路由的使用

vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用。vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来。传统的页面应用,是用一些超链接来实现页面切换和跳转的。在vue-router单页面应用中,则是路径之间的切换,也就是组件的切换。本文将以示例的形式来介绍vue-router的各个特性,一共包含6个示例,每个示例都有乞丐版,前5个示例有皇帝版。
乞丐版是将所有代码混杂在一起的HTML页面,皇帝版是基于vue-webpack-simple模板构建的。

命名路由

一 什么是命名路由

1.官方文档:https://router.vuejs.org/zh/guide/essentials/named-routes.html

就是在routers配置路由名称的时候给路由定义不同的名字,这样做的好处就是可以在使用router-link的to属性跳转路由的时候传一个对象从而实现与router.push一样的效果:

<router-link :to ="{name:'user',params:{userId:123}}">User</router-link>

等同于

router.push({name:'user',params:{userId:123}})

给路由起个名字,这样可以方便我们在使用路由的时候, 简写路径

  • 给路由定义不同的名字,根据名字进行匹配
  • 给不同的router-view定义名字,router-link通过名字进行对应组件的渲染。

命名视图

二 什么是命名视图?

1.官方文档:https://router.vuejs.org/zh/guide/essentials/named-views.html
简单的说就是,给不同的router-view定义不同的名字,通过名字进行对应组件的渲染

给出了一级视图以外的其他视图起名字, 这样可以区分不同级别的路由使用不同级别的视图

  • index.js
import Vue from 'vue'
import Router from 'vue-router'
import Goodlists from '@/Goodlists/goods'
import Title from '@/Goodlists/title'
import Img from '@/Goodlists/img'
import Cart from '@/Goodlists/cart'
Vue.use(Router)
export default new Router({
  routes: [
    {
      path: '/goods',
      name: 'Goodlists',
      components:{
        default:Goodlists,
        title:Title,
        image:Img,
      } 
     } 
  ]
})
  • App.vue
<template>
  <div id="app">
    <img src="./assets/logo.png">
    <router-view></router-view>
    <router-view name="title" class="left"></router-view>
    <router-view name="image" class="right"></router-view>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</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;
}
.left,.right{
    float: left;
    width:48%;
    text-align: center;
    border:1px solid red
}
</style>

动态路由 & 路由传参 & 路由接参

  • vue cli3 配置反向代理 20分钟
  • 在根目录下面新建一个 vue.config.js
// vue.config.js中可以默认直接使用 http-proxy-middleware
module.exports = {
devServer: {
proxy: {
'/douban': { // /douban 是一个标记
target: 'http://api.douban.com', // 目标源
changeOrigin: true, // 修改源
pathRewrite: {
'^/douban': ''
}
},
'/siku': {
target: 'https://android.secoo.com',
changeOrigin: true,
pathRewrite: {
'^/siku': ''
}
}
}
}
}
  • 路由的传参 10分钟
<router-link :to = "{name: 'list',params: {id: xxx}, query: {xxx:xxx}}"></router-link>
  • 路由的接参
  • 我们发现凡是使用了路由的组件,我们统称为: 路由组件
  • 路由组件身上会自动添加一个 $route的数据
id: this.$route.params.id
query: this.$route.query.xxx
  • 编程式导航 5分钟
  • push
  • this.$router.push('/home')
  • this.$router.push({name,params,query})
  • push可以将我们的操作存放到浏览器的历史记录
  • replace
  • this.$router.replace(’/home’)
  • this.$router.replace({name,params,query})
  • replace没有将我们的操作存放到浏览器的历史记录, 效果为返回了二级
  • 业务:
  • 按钮的返回
  • push
  • replace
  • back
  • go

路由进阶部分 – 导航守卫( 路由守卫 )

  1. 作用: — 类似 【保安】
  • 守卫路由
  • 举例: 携带数据进
  • 举例: 事情完成才能出
  1. 导航守卫一共有三种形式
- A: 全局导航守卫
  1. 全局前置守卫 router.beforeEach(fn)
  2. fn中有三个参数
  3. 全局的解析守卫
  4. 在 2.5.0+ 你可以用 router.beforeResolve 注册一个全局守卫。这和 router.beforeEach 类似,区别是在导航被确认之前,同时在所有组件内守卫和异步路由组件被解析之后,解析守卫就被调用。
  5. 必须保证整个项目的守卫和异步路由组件解析完成
  6. 全局的后置守卫
  • 可以做一些用户友好提示
- B: 路由独享守卫
  • 写在路由表中的守卫钩子
  • 针对的是和当前路由相关的,那么其他与之不相关的路由,它是无法监听它的变化情况的
- C: 组件内守卫
  • 组件内的前置守卫 beforeRouteEnter((to,from,next)=>{})
  • 导航进入组件时,调用
  • this是访问不到的,如果非要访问this ,必须通过 next(vm=>{})访问
  • 因为组件此时没有创建,所以没有this
  • 案例: 数据预载(进入组件前就获得数据)
next(vm => { //vm指的就是组件
const result = JSON.parse(res.data.slice(7,-1)).rp_result.categorys
vm.$set(vm.category,'categorys',result)
})
  • 组件内的后置守卫
  • 当好离开组件时,调用
  • this是可以访问到
  • 组件内的更新守卫( 路由传参和路由的接参 )
  • 在当前路由改变,但是该组件被复用时调用
  • 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
  • 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
  • 可以访问组件实例 this
  1. 功能: 导航守卫可以监听路由变化情况
  2. 名词
  • 前置: 要进入当前路由
  • 后置: 要离开当前路由
  1. 关于next的使用
  • next() 等价于 next( true ) 表示可以从当前路由跳转到目标路由
  • next( false ) 表示不通过, 表示从当前路由跳转不到目标路由
  • next(’/login’) 等价于 next({path:’/login’}) 跳转指定的路由
  • next(’/login’) 等价于 next({path:’/login’,params,query})
  • next( fn ) 数据预载
  1. 业务: 当我们进入到一个项目的首页时,但是当我们没有注册账号时,它主动跳转到了注册/登录页
router.beforeEach((to,from,next)=>{
const name = localStorage.getItem('name')
if( name || to.path === '/login' ){
//如果有 / --> /home
next()
}else{
next('/login')
}
})
  1. 路由导航守卫
    3中类型 7个路由监听钩子
  • 业务:
  • 监听整个项目的路由变化情况 全局的前置守卫
  • 监听某个路由的变化情况 路由的独享守卫
  • 监听的路由组件的路由变化情况 组件内的导航守卫

1.路由

  1. 路由激活
  • A: 自己书写一个类名或是使用第三方给的类名
  • B;在router-link组件身上添加一个 active-class 的属性
<router-link to = "/home" active-class = "active"/>
  1. 路由的缓存
  • 在router-link组件上添加一个属性 keep-alive
<router-link to = "/home" keep-alive></router-link>
  1. 路由的动画
  • A:先安装 animate.css 可以模块化引入 yarn add animate.css
  • B: 在main.js中引入 import 'animate.css'
  • C:将router-view 组件用transition组件包裹
  • D: 在transition组件身上添加 enter-active-class 和 leave-active-class
<transition
enter-active-class="animated slideInLeft"
leave-active-class="animated slideOutLeft"
mode="out-in"
name = "router"
>
<router-view></router-view>
</transition>
  1. 路由的数据预载(导航完成前获取数据)
  • 核心
  1. next( vm => { Vue.set(vm.dataAttr,key,value) })
  2. next( vm => { vm.setDate(vm.dataAttr,value )})
  • 以上两个方法的区别是
  • 第一种方法
next(vm => { //vm指的就是组件
const result = JSON.parse(res.data.slice(7,-1)).rp_result.categorys
vm.$set(vm.category,'categorys',result)
})
//data中数据要这样定义
data () {
return {
data: {
category: null
}
}
}
  • 第二种方法( 官网 )
next(vm => vm.setData(vm.dataAttr, value))
data () {
return {
category: null
}
}
  1. 路由的懒加载
  2. 概念: 指的是,对应的路由加载对应的路由组件—按需加载路由
  3. Vue异步组件
  4. webpack的代码分割
const routerLaayLoad = ( comName ) => {
return () => {
import (/* webpackChunkName: "view-[request]" */ `../components/pages/${view}.vue`)
}
}
const routes = [
{
path: '/',
redirect: '/home'
},
{
path: '/home',
component: () => {
},
children: [
{
path: 'food',
components: {
second: routerLayLoad('home/Food')
},
name: 'food'
}
]
},
{
path: '/category',
component: routerLayLoad('Category'),
/* children: [
{
path: 'list/:id',
component: List,
name: 'list'
}
] */
},
{
path: '/list/:id',
component: routerLayLoad('List'),
name: 'list'
},
{
path: '/login',
component: routerLayLoad('Login')
},
{
path: '/reg',
component: routerLayLoad('Reg')
},
{
path: '/mine',
component: routerLayLoad('Mine')
},
{
path: '/error',
component: routerLayLoad('Error')
},
{
path: '**',
redirect: '/error'
}
]

猜你喜欢

转载自blog.csdn.net/xuwei1215225/article/details/89674179