Vue2-Vue-router学习笔记

141 阅读4分钟

1.基础概念

  1. vue-router是vue 的一个插件库,专门用来实现 SPA 应用
  • 路由:route:一组key-value的对应关系
  • 路由器:router
  1. 对 SPA 应用的理解
  • 单页 Web 应用(single page web application,SPA)。
  • 整个应用只有一个完整的页面。
  • 点击页面中的导航链接不会刷新页面,只会做页面的局部更新。
  • 数据需要通过 ajax 请求获取。
  1. 什么是路由?
  • 一个路由就是一组映射关系(key - value)
  • key 为路径, value 可能是 function 或 component
  1. 路由分类
  • 后端路由:
    • 理解:value 是 function, 用于处理客户端提交的请求。
    • 工作过程:服务器接收到一个请求时, 根据请求路径找到匹配的函数来处理请求, 返回响应数据。
  • 前端路由:
    • 理解:value 是 component,用于展示页面内容。
    • 工作过程:当浏览器的路径改变时, 对应的组件就会显示。
  1. vue-router的使用:
  • 下载安装vue-router
npm install vue-router
  • router文件下index.js配置
// 该文件专门用于创建整个应用的路由器
import VueRouter from 'vue-router';

const router = new VueRouter({
  routes: [
    {
      path: '/',
      redirect: "/home",
  },
    {
      path: '/about',
      component: ()=>import( "@/components/About.vue"),
    },
    {
      path: '/home',
      component: ()=>import( "@/components/Home.vue"),
    },
  ]
})
export default router;

main.js中引入:(vue2) Vue.use(VueRouter)应用插件

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import router from './router/index'
// 关闭vue的生产提示
Vue.config.productionTip = false

// 应用插件
Vue.use(VueRouter)
// 创建vm
new Vue({
  render: h => h(App),
  router: router
}).$mount('#app')

使用router-link 实现切换

   
       <!-- Vue中router-link实现路由切换 -->
       <router-link class="list-group-item " active-class='active' to="/about">About</router-link>
       <router-link class="list-group-item " active-class='active' to="/home">Home</router-link>

指定展示位置

  <!-- 路由器的视图:指定组件呈现的位置 -->
              <router-view></router-view>

注意点:

  • 路由组件切换时,组件都被销毁了,需要时再去挂载。
  • 每个组件都有自己的$route属性,里面存储着自己的路由信息
  • 整个应用只有一个router,可以通过$router属性获取到

2.嵌套路由(多级路由)

image.png

3.路由携带的参数

image.png 在组件打印$route

export default {
  name: "Detail",
  mounted() {
    console.log(this.$route);
  }
}

image.png 获取query里面的数据(接收参数)

<div>
    <ul>
      <li>{{ $route.query.id }}</li>
      <li>{{ $route.query.title }}</li>
    </ul>
  </div>

image.png 两种携带参数的不同写法:

 <li v-for="item in messageList" :key="item.id">
        <!-- 跳转路由,并携带query参数,to 的字符串写法 -->
        <!-- <router-link :to='`/home/message/detail?id=${item.id}&title=${item.title}`'>{{ item.title }}</router-link> -->

        <!--  跳转路由,并携带query参数,to 的对象写法 -->
        <router-link :to="{
          path: '/home/message/detail',
          query: {
            id: item.id,
            title: item.title
          }
        }">
          {{ item.title }}</router-link>
      </li>

4.命名路由

作用:简化路由跳转 image.png

5.params参数

  1. 声明接收params image.png
  2. 使用 image.png
  3. 传递参数
 <!-- 跳转路由,并携带params参数,to 的字符串写法 -->
        <router-link :to='`/home/message/detail/${item.id}/${item.title}`'>{{ item.title }}</router-link>

注意:路由携带配置项params时,若使用to对象的写法,则不能使用path配置项,必须使用name配置。 image.png 4. 接收参数

 <li>{{ $route.params.id }}</li>
      <li>{{ $route.params.title }}</li>

5.路由的props

作用:让路由组件更方便的收到参数

  1. 写法一:用的少
  • props的第一种写法,值为对象,该对象中的所有key-value都会以props的形式传给Detail组件 image.png
  1. 写法二:布尔值
  • props第二种写法:值为对象,若布尔值为真,就会把该路由组件收到的所有params参数(不会理会query参数),以props的形式传给Detail组件

image.png

  1. 写法三:函数写法:props接收$route参数 image.png
//第三种写法,值为函数
          // props($route) {
          //   return { id: $route.params.id, title: $route.params.title }
          // }
          props({ params: { id, tilte } }) {//从$route解构出params,再从params解构出id,title
            return { id, tilte }
          }

6.router-link的模式

  1. 默认模式,push模式

  2. replace模式,点击时都会把栈顶的元素给替换掉。

  • 作用:控制路由跳转时,操作浏览器的历史记录的模式
  • 浏览器的默认历史记录有两种方式:push和replace,push是追加历史记录,replace是替换当前的记录。路由跳转时候,默认为push。
 <router-link replace class="list-group-item " active-class='active' to="/about">About</router-link>

7.编程式,路由导航

  1. 作用:不借助<router-link>实现路由跳转,让路由跳转更加灵活。
  2. 具体编码
      // $router的两个API
      this.$router.push({
        name: 'xiangqing',
        params: {
          id: item.id,
          title: item.title
        }
      })
      
       this.$router.replace({
        name: 'xiangqing',
        params: {
          id: item.id,
          title: item.title
        }
      })
      this.$router.forward();//前进
      this.$router.back()//后退
      this.$router.go()//可前进也可以后退

keep-alive缓存路由组件

 <!-- 1.缓存多个 -->
      <keep-alive :include="['News', 'Message']"></keep-alive>
      <!-- 2.缓存一个路由组件 -->
      <keep-alive include="News">
        <router-view></router-view>
      </keep-alive>

8.路由守卫

image.png 1.前置路由守卫:beforeach:

  • 判断方式一
// 全局前置路由守卫:每次路由切换之前被调用
router.beforeEach((to, from, next) => {
  // console.log(to,from,next);
  if (to.path == '/home/news' || to.path == '/hoem/message') {
    if (localStorage.getItem('school') == 'atguigu') {
      next();//继续往下走
    } else {
      console.log("无权限");
    }

  } else {
    next();
  }

  • 判断方式二: image.png
  1. 后置路由守卫

image.png

  1. 独享路由守卫 beforeEnter: image.png
  2. 组件内路由守卫
  beforeRouteEnter(to,from,next) {
    //
    console.log("app-enter");
    next();
  },
  //  2.通过路由规则离开该组件时被调用
  //  beforeRouteLeave(){

  //  }

9.hash模式和history模式

image.png

  1. 对于一个url来说,什么是hash值?-#及其后面的内容就是hash值
  2. hash值不会包含在 HTTP 请求中,即: hash值不会带给服务器。
  3. hash模式:
  • 地址中永远带着#号,不美观
  • 若以后将地址通过第三方手机app分享,若app校验严格,则地址会被标记为不合法
  • 兼容性较好。

image.png 4.history模式:

  • 地址干净,美观。
  • 兼容性和hash模式相比略差
  • 应用部署上线时需要后端人员支持,解决刷新页面服务端404的问题

image.png

9.element-ui组件库

地址

1. 全局引入

import Vue from 'vue'; 
import ElementUI from 'element-ui'; 
import 'element-ui/lib/theme-chalk/index.css'; 
import App from './App.vue';

Vue.use(ElementUI);
new Vue({ 
el: '#app',
render: h => h(App)
});

2. 按需引入

借助 babel-plugin-component,我们可以只引入需要的组件,以达到减小项目体积的目的。

首先,安装 babel-plugin-component:

npm install babel-plugin-component -D

然后,将 babel.config.js 修改为:

module.exports = {
  presets: [
    '@vue/cli-plugin-babel/preset',
    ["@babel/preset-env", { "modules": false }]
  ],
  plugins: [
    [
      "component",
      {
        "libraryName": "element-ui",
        "styleLibraryName": "theme-chalk"
      }
    ]
  ]
}


image.png

接下来,如果你只希望引入部分组件,比如 Button 和 Select,那么需要在 main.js 中写入以下内容:


import Vue from 'vue';
//会自动解析样式
import { Button, Select } from 'element-ui';
import App from './App.vue';

Vue.component(Button.name, Button);
Vue.component(Select.name, Select);
/* 或写为
 * Vue.use(Button)
 * Vue.use(Select)
 */

new Vue({
  el: '#app',
  render: h => h(App)
});