Vue2 —— 学习(十一)(完结)

目录

一、路由 vue-router

(一)路由与路由器

(二)vue-router 理解

(三)SPA 理解

(四)路由 理解

(五)小案例

1.About.vue

2.Home.vue

3.index.js 

4.App.vue 

5.main.js 

(六)使用步骤

 (七)注意点

二、嵌套路由/多级路由

三、路由传参

(一)query 参数

1.to 的字符串写法

2.to 的对象写法

(二)params 参数

1.to 的字符串写法

 2.to 的对象写法

(三)detail 读取路由中参数

1.值为对象(用的非常少)

2.值为布尔值

 3.值为函数

四、命名路由

五、 的 replace 属性

(一)push 模式

(二)replace 模式

​编辑 六、编程式路由导航

七、缓存路由组件

八、新的声明周期钩子

九、路由守卫

(一)全局路由守卫

1.前置路由守卫

2.后置路由守卫

(二)独享路由守卫

(三)组件内部路由守卫

十、history 模式和 hash 模式

十一、Vue UI 组件库


一、路由 vue-router

(一)路由与路由器

路由器能让多台设备同时上网 每个网线插口都能对应一个设备 

路由器 的英文名是 router

路由器上的插口就相当于 key 我们的每个设备相当于 value  一共四个接口

那路由就是 route 

key1 +  value1 => 路由 route

key2 +  value2 => 路由

key3 +  value3 => 路由

key4 +  value4 => 路由

路由就是一组 key-value 的对应关系

多个路由需要经过路由器管理

我们编程中的路由和生活中的不一样 我们编程中的路由是为了 实现 SPA 应用(单页面应用)

之前的应用是 我们写很多网页然后得来回跳转 这就是多页面应用 不太好来回跳很烦

单页面就一个页面比较好 然后里面有导航区 和展示区 点击导航区的导航然后实现显示区的内容发生变化,但是页面没跳转,左上角没转圈,路径也能跟着变化

怎么实现的页面变化然后路径也发生变化的呢

点击导航区中的班级管理 然后我们路径中多了 /class

原来是 我们的vue 中 router 能监测到 我们路径中 /class 这样的路由

路由规则是  router /class => 班级组件  如果监测到 /class 就展示 班级组件

/class 就相当于是key 班级组件相当于 value

(二)vue-router 理解

vue 的一个插件库 专门实现 SPA 应用 npm i vue-router

Vue.use()使用

(三)SPA 理解

单页面 Web 应用,整个应用只有一个完整的页面 index.html

点击页面中的导航链接不会刷新页面 只会做页面的局部更新

数据要通过 ajax 请求获取

(四)路由 理解

一个路由就是一组映射关系

key 是路径 value 是function 或 component

路由分类 :

1.后端路由:

理解;value 是 funciton 用于处理客户端提交的请求

工作过程:服务器接收到一个请求时,根据请求路径找到匹配的函数来处理请求,返回响应数据。

2.前端路由

理解:value 是 component用于显示页面内容

工作过程:当浏览器路径改变时,对应的组件就会显示

(五)小案例

1.About.vue
<template>
  <h2>我是About的内容</h2>
</template>

<script>
export default {
  name: "About",
};
</script>

<style>
</style>
2.Home.vue
<template>
  <h2>我是Home的内容</h2>
</template>

<script>
export default {
  name: "Home",
};
</script>

<style>
</style>
3.index.js 
import VueRouter from 'vue-router'
import About from '../components/About'
import Home from '../components/Home'
export default new VueRouter({
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home
    },
  ]
})
4.App.vue 
<template>
  <div>
    <div class="row">
      <div class="col-xs-offset-2 col-xs-8">
        <div class="page-header"><h2>Vue Router Demo</h2></div>
      </div>
    </div>
    <div class="row">
      <div class="col-xs-2 col-xs-offset-2">
        <div class="list-group">
          <!-- <a class="list-group-item" href="./about.html">About</a>
          <a class="list-group-item active" href="./home.html">Home</a> -->
          <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>
        </div>
      </div>
      <div class="col-xs-6">
        <div class="panel">
          <div class="panel-body">
            <router-view></router-view>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script>
export default {
  name: "app",
};
</script>
5.main.js 
import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import router from './router/index'
Vue.use(VueRouter)
Vue.config.productionTip = false
new Vue({
  el: '#app',
  render: h => h(App),
  router: router
})

(六)使用步骤

1.安装 vue-router 命令 npm i vue-router

2.使用插件 Vue.use(VueRouter)

3.编写 router 配置项

就是在 src 文件夹中创建一个 router 文件夹 然后里面创建一个 index.js 文件里面配置路由

import VueRouter from 'vue-router'
import About from '../components/About'
import Home from '../components/Home'
export default new VueRouter({
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home
    },
  ]
})

main.js 中引入 router 然后内部 写上 router:router

import Vue from 'vue'
import App from './App.vue'
import VueRouter from 'vue-router'
import router from './router/index'
Vue.use(VueRouter)
Vue.config.productionTip = false
new Vue({
  el: '#app',
  render: h => h(App),
  router: router
})

4.实现切换

然后我们写切换组件的内容我们来到 app 组件中 得用一个特殊的标签 就是 router-link 里面再用一个 to 来表示 切换到的标签

router-link 里面能自动转换成 a 标签 所以我们得用人家的router-link 标签

<router-link class="list-group-item" to="/about">About</router-link>
<router-link class="list-group-item active" to="/home">Home</router-link>

5.指定显示内容

最后指定显示的内容到页面上该标签的位置

<router-view></router-view>

 (七)注意点

路由组件 不用我们自己写 <zujian/> 而是靠路由规则而显示的标签叫做路由组件

这些路由组件 单独放一个文件夹中 不放 conponents 中 放在 pages 中

切换显示的组件的时候 不显示的组件是被销毁了

路由组件上 有两个属性 一个是 $route 是路由属性是我们配置的每个组件都不一样

另一个是 $router 是路由器 每个网页只能由一个路由器 是所有组件共有的

二、嵌套路由/多级路由

点击导航栏 然后显示的页面中又显示 一个导航栏 再点击 路径中出现 /school/student 的类似情况就是多级路由

在路由中再配置其它的路由就是多级路由

如下是一级路由

export default new VueRouter({
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home
    },
  ]
})

多级路由就是在我们已经配置的路由里面再配置子路由,因为可能不止一个子路由 就用数组对象的形式,注意里面的 path 不用加斜杠 因为网页在寻找的时候已经自动帮我们配置了斜杆

export default new VueRouter({
  routes: [
    {
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home,
      children:[
        {
          path:'news',
          component: News,
        },
        {
          path: 'message',
          component: Message,
        }
      ]
    },
  ]
})

在写按钮时 跳转时 路径名得补全 /home/news 

<template>
  <div>
    <h2>Home组件内容</h2>
    <div>
      <ul class="nav nav-tabs">
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/news">News</router-link>
        </li>
        <li>
          <router-link class="list-group-item" active-class="active" to="/home/message">Message</router-link>
        </li>
      </ul>
      <router-view></router-view>
    </div>
  </div>
</template>

三、路由传参

(一)query 参数

跳转路由并携带 query 参数,有两种写法

跳转的时候带着参数 我们用 ajax 请求 携带query 参数实现路由传参 不一直用多级路由来写,要不然组件太多

1.to 的字符串写法

里面是字符串 然后里面套一个 模板字符串 然后 用${ } 传入数据 :是使用 js 语法来解析

<template>
  <div>
    <ul>
      <li v-for="m in messageList" :key="m.id">
        <router-link :to="`/home/message/detail?id=${m.id}$title=${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp;
      </li>
    </ul>
    <hr>
    <router-view></router-view>
  </div>
</template>

我们在子路由中通过 $route.query.id  $route.query.title 就能读取我们传入 detail 的数据

2.to 的对象写法

把 to 里面的东西写成对象的写法 有两个参数 第一个是我们要跳转的目标,第二个是我们要传入的参数,里面配置参数即可

<router-link
          :to="{
            path: '/home/message/detail',
            query: {
              id: m.id,
              title: m.title,
            },
          }">
          {{ m.title }}
        </router-link>

我们在子路由中通过 $route.query.id  $route.query.title 就能读取我们传入 detail 的数据 

用这两句 接收一下就行

(二)params 参数

也是 ajax 请求中的,我们在 路由配置时 用两个占位符占两个 params 传入参数变量

路由中声明接收 params 参数

 children:[
            {
              name:'xiangqing',
              path: 'detail/:id/:title',
              component: Detail,
            }
          ]
1.to 的字符串写法

直接拼进去

配置选择路由路径的时候 直接 在 detail 后面写上 /加变量的形式 就能传入数据了

<router-link :to="`/home/message/detail/${m.id}/${m.title}`">{{m.title}}</router-link>&nbsp;&nbsp;

我们在子路由中通过 $route.params.id  $route.params.title 就能读取我们传入 detail 的数据  

 2.to 的对象写法

和 query 参数的对象写法中类似,对象里面的第二个配置项变成了 params  而且 第一个属性不能用 path 必须用 name !!!

  <router-link
          :to="{
            name: 'xiangqing',
            params: {
              id: m.id,
              title: m.title,
            },
          }">
          {{ m.title }}
        </router-link>

我们在子路由中通过 $route.params.id  $route.params.title 就能读取我们传入 detail 的数据   

(三)detail 读取路由中参数

我们在子路由中通过 $route.params.id  $route.params.title 读取我们传入 detail 的数据   

我们在子路由中通过 $route.query.id  $route.query.title 读取我们传入 detail 的数据

但是这样很麻烦 如果要传入很多 我们得一个个写一遍 我们也能 通过计算属性简化写法,但是每个参数我们都得写一遍 也挺麻烦 所以我们需要路由中的一个全新的配置项 props

1.值为对象(用的非常少)

该对象中的所有 key-value 都会以props 的形式传给 Detail 组件

 path: 'message',
          component: Message,
          children:[
            {
              name:'xiangqing',
              path: 'detail/:id/:title',
              component: Detail,
              props:{a:1,b:'hello'}
            }
          ]

组件中也得用 props 接收然后就能用这个a b 两个属性了

 props: ["a", "b"],
2.值为布尔值

如果 值为 true 就会把路由中 组件收到的所有 params 参数 以props 的 形式传给 Detail 组件

不会理会 query 参数

 path: 'message',
          component: Message,
          children:[
            {
              name:'xiangqing',
              path: 'detail/:id/:title',
              component: Detail,
              // props:{a:1,b:'hello'}
              props:true
            }
          ]

接收一下 

  props: ["id", "title"],
 3.值为函数

有一个回调函数 里面会返回给我们 $route 我们把 query 类型数据返回 实现简写

path: 'message',
          component: Message,
          children: [
            {
              name: 'xiangqing',
              path: 'detail',
              component: Detail,
              // props:{a:1,b:'hello'}
              // props:true
              props($route) {
                return { 
                         id:$route.query.id, 
                         title:$route.query.title 
                }
              }
            }
          ]

改成 query 方式发送 

 <router-link
          :to="{
            name: 'xiangqing',
            query: {
              id: m.id,
              title: m.title,
            },
          }">
          {{ m.title }}
        </router-link>

四、命名路由

就是给路由起名字 给谁起名字 就在哪个路由上 加一个名字属性

可以在跳转的时候简化代码

给路由起名字 就是加一个配置属性 name

export default new VueRouter({
  routes: [
    {
      name:'guanyu',
      path: '/about',
      component: About
    },
    {
      path: '/home',
      component: Home,
      children:[
        {
          path:'news',
          component: News,
        },
        {
          path: 'message',
          component: Message,
          children:[
            {
              name:'xiangqing',
              path: 'detail',
              component: Detail,
            }
          ]
        }
      ]
    },
  ]
})

然后给我们跳转传参的时候 可以把 path 配置项 改成 name  配置项 然后里面写上我们要传入的路由名,就能实现 简化路由的路径写法

  <router-link
          :to="{
            name: 'xiangqing',
            query: {
              id: m.id,
              title: m.title,
            },
          }">
          {{ m.title }}
        </router-link>

五、<router-link> 的 replace 属性

路由对浏览器中浏览记录的影响

浏览器中的前进后退按钮 是根据浏览器记录 进行使用的 

使用 router-link 标签设计的 按钮 点击都会留下记录

有两种模式

(一)push 模式

保存浏览器记录 是栈的形式 点击按钮会依次将记录留在栈中 是 push 模式(默认模式)

指针指向浏览器最后的记录

点击回退 指针依次向下指

(二)replace 模式

替换当前的记录

另一种模式 replace 模式 点击新的链接 然后上一条的存在栈中的 浏览记录被删除

在 代码中 router-link 标签 中加入 一个 replace 属性就能开启  replace 模式

<router-link replace class="list-group-item" active-class="active" to="/home/news">News</router-link>

最后会回到 没被删除的记录

 六、编程式路由导航

不借助 router-link 实现路由跳转 让路由跳转更灵活

不用 router-link 标签 实现路由选择 因为 router-link 最后只能转换成 a 标签,别的就不行了,比如按钮

我们就用一个新的方法来实现

如果是按钮我们先绑定一个点击事件 pushShow(m) 我们在方法中写一个函数 也叫 pushShow(m)

oush 方式跳转

 pushShow(m) {
      this.$router.push({
        name: "xiangqing",
        query: {
          id: m.id,
          title: m.title,
        }
      });
    },

replace 方式跳转

  replaceShow(m) {
      this.$router.replace({
        name: "xiangqing",
        query: {
          id: m.id,
          title: m.title,
        }
      });
    },

this.$router.go(数字) 里面是正数 跳转往前跳转

如果是负数就往后跳转

七、缓存路由组件

让不展示的路由组件保持挂载,不被销毁

如果写在 keep-alive 里面的组件都将被缓存 如果标签里面写了 inlcude=“News” 就指明了缓存的对象不是所有都缓存,只缓存里面的 News 缓存的名字是组件名 就是我们组件中写的第一个属性     name

 <keep-alive incluede="News">
        <router-view></router-view>
      </keep-alive>

 如果要缓存多个组件 那就写成数组的形式 先规定里面使用 js 中的规则 加一个冒号 即可

 <keep-alive :incluede=["News","message"]>
        <router-view></router-view>
      </keep-alive>

八、新的声明周期钩子

路由组件独有的声明周期钩子

一个是激活的 另一个是失活的 两个钩子 当组件展示到我们眼前时就调用激活的函数

当组件被切走的时候 失活的周期就调用了

 activated(){

  },
  deactivated(){
    
  }

正常我们想写一个 文字循环减少透明度的格式,我们在 mounted 和 beforeDestoryed 两个声明周期写 但是我们我们前面实现对这个组件实现了缓存 会导致计时器关闭不了的情况

beforeDestroy() {
    clearInterval(this);
  },
  mounted() {
    this.timer = setInterval(() => {
      this.opacity -= 0.01;
      if (this.opacity <= 0) this.opacity = 1;
    }, 16);
  },

所以我们得用这两个声明周期钩子 就能成功解决了 显示的时候就显示 不显示的时候就关闭

activated() {
    console.log('显示')
    this.timer = setInterval(() => {
      this.opacity -= 0.01;
      if (this.opacity <= 0) this.opacity = 1;
    }, 16);
  },
  deactivated() {
    clearInterval(this.timer);
  },

九、路由守卫

保护路由的安全就是给访问者设置权限

(一)全局路由守卫

1.前置路由守卫

全局前置路由守卫

在初始化和切换路由之前进行调用下面的函数

能把所有的东西都给拦住

函数内部有三个参数 to from next  一个是出发的路由 一个是目的路由 next 是放行的意思

然后在里面加上跳转权限就行

router.beforeEach((to, from, next) => {
  console.log(to, from)
  if (to.path === '/home/news' || to.path === '/home/message') {
    if (localStorage.getItem('school') === 'xuexiao') {
      next()
    }
  }else{
    next()
  }
})
export default router

但是第一个判断 条件太长 我们能在路由中加一个属性,我们加一个布尔属性就行 判断路由是否用判断路由是否需要 判断权限

我们得添加在 meta 中的属性中 比如叫 isAuth 是否授权 

哪个路由需要判断权限 就给哪个路由加这个属性

 {
      name: 'guanyu',
      path: '/about',
      component: About,
      meta: {
        isAuth: true
      }
    },

然后代码就能简化一下

router.beforeEach((to, from, next) => {
  console.log(to, from)
  if (to.meta.isAuth) {
    if (localStorage.getItem('school') === 'xuexiao') {
      next()
    }
  } else {
    next()
  }
})
export default router
2.后置路由守卫

在初始化和切换路由之后进行调用下面的函数

后置路由守卫 函数中没有 next 参数,因为已经切换成功了 不需要再判断是否切换了

router.afterEach()

router.afterEach((to, from) => {
  document.title = to.meta.title || '硅谷系统'
})

(二)独享路由守卫

在路由里面单独配置守卫函数名为 beforeEnter 只有前置没有后置路由守卫

但是可以和全局路由守卫中的后置路由守卫相配合

里面的参数和全局路由守卫 一样 用法也一样

beforeEnter: (to, from, next) => {
            if (to.meta.isAuth) {
              if (localStorage.getItem('school') === 'xuexiao') {
                next()
              }
            } else {
              next()
            }
          }

(三)组件内部路由守卫

通过路由规则进入该组件时被调用

to 就是该组件 from 是来的地方

beforeRouteEnter(to, from, next) {
    if (to.meta.isAuth) {
      if (localStorage.getItem("school") === "xuexiao") {
        next();
      }
    } else {
      next();
    }
  },

通过路由规则离开该组件时被调用

to 是离开该组件前往的地方 from 是该组件

 beforeRouteLeave(to, from, next) {
    next();
  },

十、history 模式和 hash 模式

我们浏览器中 网页路径 # 和后面的东西都算作哈希值

hash 模式它不会随着 http 协议发给服务器

路由器默认进行 hash 工作模式

hash 模式

兼容性略好 转发网页路径容易非法

history 模式

没有 # 号 路径没有 hash 值

兼容性略差

需要后端人员解决 404 的问题

打包 就是把 我们写的vue 文件转会 html css js 文件

我们用 build 文件生成 dist 文件夹 里面就有这些文件

生成的 文件不能直接打开  还得放在服务器上部署 才行

十一、Vue UI 组件库

常用于 不是定制化网页的开发 因为定制化的组件比较有辨识度 容易被认为抄袭

移动端常用的 UI 组件库 Vant 、Cube UI 、Mint UI

PC 端常用的 UI 组件库 Element UI、IView UI

问题 : 组件库基于 Vue 还是 React 

是 pc 端 还是移动端

建议使用 部分引入 减少文件大小

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值