Vue.js学习笔记(五)(vue-router)

1.后端路由阶段


  • 流程:用户在浏览器中输入url→发送给服务器解析→通过jsp(java serve page)把网页(包含html,css,java(java作用:从数据库中读取数据并将数据动态地放在页面中))渲染好→将网页传给浏览器(传过去的网页只有html和css)
  • 后端渲染(服务端渲染):后端通过jsp/php等技术把页面渲染好了
  • 后端路由:后端处理url映射到不同的页面

2.前后端分离阶段


  • 简述:此时后端只负责提供数据,不负责任何阶段的内容,服务器分为静态资源服务器和提供api接口的服务器
  • 流程:用户在浏览器中输入url→从静态资源服务器中获取对应网页的js html css代码→浏览器执行js代码,向api接口服务器请求数据→api服务器返回大量数据→网页中其他js代码生成带有数据的标签→通过js代码渲染到网页
  • 前端渲染:浏览器中显示的网页的大部分内容都是由前端的js代码在浏览器中执行,最终渲染出来的网页

3.SPA页面


  • 区别于前后端分离:此时也有静态资源服务器,前后端分离阶段中每个url对应一套js html css,spa中只有一套js html css
  • 流程:用户输入url→从静态资源服务器中获取所有js html css代码→根据用户不同的操作抽取对应的 一部分 html css js到页面中,不会向静态资源服务器中再请求资源(前后端分离阶段会)
    前端路由:用于映射url和相应要渲染的资源(根据用户操作如点击生成不同的url)

4.运行一个vue-router小demo


  • 我的步骤:

    • 1.在router文件夹里面创建index.js,创建router实例
    • 2.创建对应组件 并建立映射关系
    • 3.在main.js里面导入有映射关系的index.js,挂载router实例(这样才可以在所有组件中使用 $router ,等同于操作Vue.prototype.$router)
    • 4.将main.js所解析的App.vue template里写上router-link表签
  • 标准步骤:

    • 1.导入路由对象,并且调用 Vue.use(VueRouter)
    • 2.创建路由实例,并且传入路由映射配置
    • 3.在Vue实例中挂载创建的路由实例
    • 4.创建路由组件 并 配置路由映射: 组件和路径映射关系(我在第二步先做也没问题)
    • 5.使用路由: 通过<router-link/><router-view>

5.路由的默认路径


  • 意义:打开网站默认显示主页
  • 用法(默认访问home):
const routes = [
  {
    
    
    path: '',  //缺省是默认的意思
    redirect: "/home" //redirect是重定向, 也就是将默认路径重定向到/home的路径下
  },
  {
    
    
    path: "/home",
    component: home
  },
  {
    
    
    path: "/about",
    component: about
  }
];

6.history模式


  • 意义:非history模式中url里面含有 # 号
    在这里插入图片描述
  • 用法:创建路由实例的时候,属性里面添加 mode 属性即可
const router = new VueRouter({
    
    
  routes,
  mode: "history"
});

7.router-link的一些属性


  • 改变router-link样式:tag=其他标签
  • 取消history.pushState()模式,采用history.replace()模式:replace
  • <router-link>对应的路由匹配成功时, 会自动给当前元素设置一个router-link-active的class, 设置active-class可以改变配对成功的元素的样式
  • 举例:
App.vue:
<template>
  <div id="app">
    <router-link to="/about" tag="button" replace active-class="active">关于</router-link>
    <router-link to="/home" tag="button" replace active-class="active">首页</router-link>
    <router-view></router-view>
  </div>
</template>
  • 效果:
    在这里插入图片描述

8.用代码转跳路由


  • 用法:
this.$router.push("address")/this.$router.replace("address")
<template>
  <div id="app">
    <router-view></router-view>
    <button @click="homeClick">首页</button>
    <button @click="aboutClick">关于</button>
  </div>
</template>

<script>
export default {
     
     
  name: 'App',
  methods: {
     
     
    homeClick() {
     
     
      console.log("homeClick");
      this.$router.push("/home");   //等同于pushState,可以换成replace
    },
    aboutClick() {
     
     
      console.log("aboutClick");
      this.$router.push("/about");
    }
  }
}
</script>
  • 效果和普通转跳一致

9.动态路由


  • 意义:组件页template里获取 当前路由页面的参数
  • 步骤:
    • 1.注册User组件并建立动态映射
    • 2.App.vue 里面 link-router v-bind动态绑定to属性
    • 3.$route.params获取当前路由页面的参数
User.js:
<template>
  <div>
    <h2>我是User</h2>
    <h2>{
   
   {this.$route.params.userId}}</h2>
  </div>
</template>
  • 效果:
    在这里插入图片描述

10.路由懒加载


  • 意义:上面第3点说到:前端路由阶段,从静态资源服务器中获取所有js html css(获取的都是js,拿到再解析)代码。所有js文件一起获取量大,效率低,所以希望当路由被访问的时候才加载对应组件(js)
  • 写法:将import转化为箭头函数的写法,其他无需改变,重新打包可以看到每个组件占一个js文件(dist/static/js)
// import Home from "../components/Home";
// import About from "../components/About";
// import User from "../components/User";

const Home = () => import("../components/Home");
const About = () => import("../components/About");
const User = () => import("../components/User");

11.二级路由


  • 意义:在home页面中, 我们希望通过/home/news和/home/message访问一些内容
  • 步骤:
    • 1.创建对应页面并建立映射关系
    • 2.在home.vue里面写router-link
  • 代码:
Home.vue:
<template>
    <div>
      <h2>我是Home</h2>
      <router-link to="/home/news">新闻</router-link>
      <router-link to="/home/message">消息</router-link>
      <router-view> </router-view>
    </div>
</template>
  • 结果:
    在这里插入图片描述

12.参数传递方式


  • 方式一:通过to属性的query传递参数
  • 意义:这样页面可以访问url中的query参数(参考url组成)
  • 方式:router-link to属性中传入query参数,组件页面再通过$route.query访问
  • 代码:
App.vue
    <router-link :to="{
      path:'/profile',
      query:{
        height: 188,
        weight: 140,
        age :19
      }
    }" tag="button" replace active-class="active">用户</router-link>
Profile.vue:
<template>
  <div>
    <h2>我是Profile</h2>
    <ul>
      <li>{
   
   {$route.query.age}}</li>
      <li>{
   
   {$route.query.weight}}</li>
      <li>{
   
   {$route.query.height}}</li>
    </ul>
  </div>
</template>
  • 效果:
    在这里插入图片描述
    在这里插入图片描述
  • 方式二:用$router.push传值
  • 代码:
App.vue:
<button @click="profileClick">档案</button>
profileClick() {
      this.$router.push({
        path: "/profile",
        query: {
          height: 188,
          weight: 140,
          age: 19
        }
      })
    }
Profile.vue:
<template>
  <div>
    <h2>我是Profile</h2>
    <ul>
      <li>{
   
   {$route.query.age}}</li>
      <li>{
   
   {$route.query.weight}}</li>
      <li>{
   
   {$route.query.height}}</li>
    </ul>
  </div>
</template>

效果同上

13.$route$router的区别


  • $router:为VueRouter实例,可以认为是全局的路由对象,包含了所有路由的对象和属性,无论在哪里打印都一样
  • $router:为当前router跳转对象,包含当前url解析得到的数据,里面可以获取name、path、query、params等
    在当前路由页面打印:
    在这里插入图片描述
    $router可以看做是建立映射关系时创建的routes数组里的当前页面对应对象的扩充
const routes = [
  {
    
    
    path: "/user/:userId",
    component: User
  },
  {
    
    
    path: "/profile",
    component: Profile
  }   //就是这个对象的扩充
];  

14.全局导航守卫


  • 介绍:导航守卫主要用来监听监听路由的进入和离开的
  • 意义:有一个需求,用户转跳页面的时候页面标题也相应改变,通常情况联想到在页面(组 件)生命周期函数中加载的时候改变标题,但是还有一种更好的方法,就是全局路由守卫方法,在index.js里面调用vue-router提供的beforeEach钩子函数, 它们会在路由即将改变前和改变后触发.(router就是全局)
    写法:
index.js:
//导航钩子的三个参数解析:
//to: 即将要进入的目标的路由对象.
//from: 当前导航即将要离开的路由对象.
//next: 调用该方法后, 才能进入下一个钩子
router.beforeEach((to, from, next) => {
    
    
  next();                 //这个规定要写,不写转跳异常
  document.title = to.matched[0].meta.title; 
  // to是route路由对象,所以所有参数都是在route里面取出来的,matched[0]因为有子组件时to.meta.title为空         
  console.log(to);
});
  • 打印结果:
    在这里插入图片描述

15.keep-alive的作用


  • 意义:有一个需求,用户转跳页面再返回原来页面的时候,希望页面内容是转跳前的内容
    方法:在home.vue(转跳前组件)中添加beforeRouteLeave方法(离开导航守卫)记录转跳出去前页面的最终路径,用一个变量保存,返回时,actived周期函数调用this.$router.push(this.path);,转跳最终路径,注意actived在有keep-alive的情况下才能回调
  • 代码:
App.vue:
    <keep-alive>
      <router-view> </router-view>
    </keep-alive>
Home.vue:
<script>
    export default {
    
    
      name: "home",
      activated() {
    
    
        console.log("home activated");
        this.$router.push(this.path);
      },
      deactivated() {
    
    
        console.log("home deactivated");
      },  //失活周期函数,也要加上,不加报错
      beforeRouteLeave (to, from, next) {
    
    
        next();
        this.path = this.$route.path;
      },
      data(){
    
    
        return{
    
    
          path: "/home/news"
        }
      }
    }
</script>
  • 效果:
    在这里插入图片描述
  • keep-alive 有两个非常重要的属性:
    include - 字符串或正则表达,只有匹配的组件会被缓存
    exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
    <keep-alive include="Home">
      <router-view> </router-view>
    </keep-alive>

16.属性传值props和路由搭配使用举例


  • 意义:点击触发页面转跳和活跃路由颜色改变
  • 代码:
App.vue:
<tab-bar-item path="/home" activeColor="pink"> </tab-bar-item>

TabBarItem.vue:
<template>
  <div class="tab-bar-item" @click="itemClick">
    <div v-if="!isActive"><slot name="item-image"> </slot></div>
    <div v-else><slot name="item-image-active"> </slot></div>
    <div :style="isActive ? {
       
       color: activeColor}: {
       
       }"><slot name="item-text"> </slot></div>
    <!--v-if和v-else 作用于图片激活情况,:style作用于文字颜色样式-->
  </div>
</template>

<script>
  export default {
     
     
    name: "TabBarItem",
    data(){
     
     
      return{
     
     
        // isActive: true
      }
    },
    methods: {
     
     
      itemClick(){
     
     
        this.$router.push(this.path);
      }
    },
    props: {
     
     
      path:{
     
     
        type: String
      },
      activeColor: {
     
     
        type: String
      }
    },
    computed:{
     
     
      isActive(){
     
     
        return this.$route.path == this.path;
      }
    }
  }
</script>
  • 代码逻辑:封装好的组件标签属性里传值(props用法,每个标签传值不同),组件内部收到值并可以使用,作为判断活跃的依据,再进行下一步操作

猜你喜欢

转载自blog.csdn.net/qq_43249043/article/details/107128410