Vue 嵌套路由 路由导航守卫 页面滚动处理 axios axios拦截器 全局配置 all方法

vue-day07

1-路由

1.1-嵌套路由

  • 定义路由规则

    /router/index.js

    const routes=[
        // 嵌套路由
        // 父路由
        {
            path:'/login',
            component:Login,
            meta:{
                title:'登录页面'
            },
            // 子路由
            children:[
                {
                    path:'/login/user',
                    component:User,
                    meta:{
                        title:'普通用户登录页面'
                    }
                },
                {
                    path:'/login/enterprise',
                    component:Enterprise,
                    meta:{
                        title:'企业用户登录页面'
                    }
                }
            ]
        }
    ]
    
  • 添加二级路由出口(在一级路由组件中添加)

    pages/Login.vue

    <template>
      <div>
        <h1>登录页面</h1>
        <router-link class="nav-btn" to="/login/user">普通用户</router-link>
        <router-link class="nav-btn" to="/login/enterprise">企业用户</router-link>
        <hr>
        <!-- 二级路由出口(二级路由占位符) -->
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
      created() {
        // 通过操作真实dom, 实现更新页面标题
        document.title = this.$route.meta.title;
      }
    };
    </script>
    <style>
    </style>
    

1.2-路由导航守卫

1.2.1-全局守卫

  • 全局前置守卫

    • 执行时机: 页面跳转之前, 被触发
    • 特点: 具备拦截页面跳转的功能
    // 添加全局前置守卫
    router.beforeEach((to,from,next)=>{
        // 动态设置页面标题
        document.title=to.meta.title;    
        // console.log(to,from);
        // to: 即将前往的页面路由对象
        // from: 即将离开的页面路由对象
        // next: 方法, 可以实现页面跳转, 默认必须调用一次next
        // 放行本次路由跳转
        next();
    });
    
  • 全局解析守卫(2.5.0版本之后新增)

    • 执行时机: 页面跳转之前, 全局前置钩子beforeEach执行之后, 被触发
    • 特点: 不具备拦截页面跳转的功能
    router.beforeResolve ((to,from,next)=>{
        // console.log(to,from);
        // to: 即将前往的页面路由对象
        // from: 即将离开的页面路由对象
        // next: 方法, 可以实现页面跳转, 默认必须调用一次next
        // 放行本次路由跳转
        next();
    });
    
  • 全局后置钩子

    • 执行时机: 页面跳转完成之后, 被触发
    • 特点: 不具备拦截页面跳转的功能
    // 全局后置钩子
    router.afterEach((to, from) => {
      // 动态设置页面标题
      document.title = to.meta.title;
      // to:即将前往的页面路由对象
      // from: 即将离开的页面路由对象
      console.log('afterEach');
    });
    

1.2.2-路由独享守卫

  • 特点: 具备拦截页面跳转的功能
  • 执行时机: 在页面跳转之前, 全局前置守卫beforeEach执行之后, 自动触发
  • 生效范围: 只对当前路由对象对应的页面跳转起作用
const routes = [
    {
        path: '/',
        component: Home,
        meta: {
          title: '网站首页'
        },
        // 路由独享守卫: 全局前置守卫执行之后, 被触发
        beforeEnter(to,from,next){
            // to: 即将前往的页面路由对象
            // from: 即将离开的页面路由对象
            // next: 方法, 可以实现页面跳转, 默认必须调用一次next
            // console.log('beforeEnter');
            // 默认情况下, next方法必须调用
            next();
        }
      }
]

1.2.3-组件内的守卫

1.2.3.1-特点
  • 具备拦截页面跳转的功能, 所以如果显示声明了组件内的导航守卫钩子, 一定要手动调用next方法, 否则页面无法正常显示
1.2.3.2-钩子函数
  • beforeRouteEnter
    • 执行时机: 路由组件被渲染之前
    • 注意: 不能使用this关键字获取组件实例对象
  • beforeRouteUpdate
    • 执行时机: 动态路由对应的组件, 由于动态参数发生改变被重复渲染的时候, 自动触发
  • beforeRouteLeave
    • 执行时机: 导航离开该组件的对应路由时调用
export default{
      beforeRouteEnter (to, from, next) {
        // 在渲染该组件的对应路由被 confirm 前调用
        // 不!能!获取组件实例 `this`
        // 因为当守卫执行前,组件实例还没被创建
          next(vm=>{
              // 通过vm获取组件实例对象
              console.log(vm);
          })
      },
      beforeRouteUpdate (to, from, next) {
        // 在当前路由改变,但是该组件被复用时调用
        // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
        // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
        // 可以访问组件实例 `this`
          next();
      },
      beforeRouteLeave (to, from, next) {
        // 导航离开该组件的对应路由时调用
        // 可以访问组件实例 `this`
        next();
      }
}

1.3-页面滚动处理

// 4-创建路由实例
const router = new Router({
  // 路由规则数组
  routes,
  // 指定路由模式
  mode: 'hash',
  // 自定义路由导航链接高亮类名
  linkActiveClass: 'active',
  // 控制组件页面滚动条的位置   
  scrollBehavior(){
      return {x:0,y:100}
  }
});

1.4-404路由

const routes=[
     // 404路由
  {
    path:'*',
    component:NotFound,
    meta: {
      title: '404页面'
    }
  }
]

1.5-使用嵌套路由改造后台管理系统

  • 路由文件

    router/index.js

    // 1-导入路由模块
    import Vue from 'vue'
    import VueRouter from 'vue-router';
    
    // 2-注册插件
    Vue.use(VueRouter);
    
    // 3-创建路由规则
    // 导入页面组件
    import Main from '../pages/Main';
    import Goods from '../pages/Goods';
    import Order from '../pages/Order';
    import User from '../pages/User';
    import Layout from '../pages/Layout';
    
    
    const routes = [{
      path: '/',
      component: Layout,
      children: [{
          path: '/main',
          component: Main,
          meta: {
            title: '管理中心'
          }
        },
        {
          path: '/goods',
          component: Goods,
          meta: {
            title: '商品管理'
          }
        },
        {
          path: '/user',
          component: User,
          meta: {
            title: '会员管理'
          }
        },
        {
          path: '/order',
          component: Order,
          meta: {
            title: '订单中心'
          }
        }
      ]
    }];
    
    // 4-创建路由对象
    const router = new VueRouter({
      routes,
      mode: 'hash',
      linkActiveClass: 'active'
    });
    
    // 5-导出路由实例对象
    export default router;
    
    
  • 根组件

    App.vue

    <template>
      <div>
        <!-- 一级:路由出口 -->
        <router-view></router-view>
      </div>
    </template>
    
    <script>
    export default {
    };
    </script>
    
    <style>
    
    </style>
    
  • 布局组件

    Layout.vue

    <template>
      <div class="container">
        <div class="left">
          <ul class="navbar">
            <!-- 启用路由严格匹配模式 -->
            <router-link tag="li" to="/main">管理中心</router-link> 
            <router-link tag="li" to="/goods">商品管理</router-link> 
            <router-link tag="li" to="/user">会员管理</router-link> 
            <router-link tag="li" to="/order">订单管理</router-link> 
          </ul>
        </div>
        <div class="right">
          <!-- 头部 -->
          <Header></Header>
          <div class="content">
            <!-- 二级路由占位符 -->
            <router-view></router-view>
          </div>
          <!-- 底部 -->
          <Footer />
        </div>
      </div>
    </template>
    
    <script>
    // 1-导入页组件
    // 导入功能组件
    import Header from "../components/Header";
    import Footer from "../components/Footer";
    
    export default {
      // 2-注册组件
      components: {
        Header,
        Footer
      },
      data() {
        return {
          // 页面组件名称
          page: "Order"
        };
      },
      methods: {
        // 切换页面
        changePage(page) {
          this.page = page;
        }
      }
    };
    </script>
    
    <style>
    *{
      padding: 0;
      margin: 0;
      box-sizing: border-box;
    }
    .container {
      background-color: #ddd;
      /* vh:相对单位; 100vh=屏幕的高度  1vh==1/100屏幕高度; viewport height */
      height: 100vh;
      display: flex;
    }
    /* 左侧导航栏 */
    .container .left {
      width: 226px;
      background: #00152a;
    }
    .left .navbar li {
      list-style: none;
      line-height: 50px;
      color: #fff;
      text-align: center;
      cursor: pointer;
    }
    .left .navbar li:hover {
      background: #0077b8;
    }
    .left .navbar li.active {
      background: #0077b8;
    }
    
    .container .right {
      flex: 1;
      display: flex;
      flex-direction: column;
    }
    .right .header {
      height: 60px;
      line-height: 60px;
      text-align: center;
      background: #fff;
    }
    .right .content {
      margin: 10px;
      background: #fff;
      height: 300px;
      text-align: center;
      flex: 1;
    }
    .right .footer {
      line-height: 60px;
      text-align: center;
      background: #fff;
    }
    </style>
    

2-axios

2.0-原生js发送ajax请求的步骤

  • 创建一个XMLHttpRequest对象

    const xhr=new XMLHttpRequest();
    
  • 设置请求行

    xhr.open('请求方式GET/POST','数据接口地址');
    
  • 发送请求

    xhr.send();
    
  • 监听服务器的响应

    xhr.onreadystatechange=function(){
        if(xhr.readyState===4&&xhr.status==200){
        	console.log('请求被响应',xhr.responseText);   	
        	console.log('请求被响应',xhr.responseXML,);   	
        }
    }
    

2.1-axios的介绍

  • axios是基于ES6中promise的一个第三方的http类库

2.1.1-安装

npm i axios -S

2.2-axios发送数据请求

2.2.1-get请求

import axios from 'axios';
axios({
    // 指定数据接口
    url:'',
    // 指定数数据提交方式为GET
    method:'GET',
    // get请求的参数
    params:{
        
    }
}).then(res=>{
    console.log(res);
})
// 专门用来发送get请求的方法
axios.get('接口地址',{
    // get请求的参数
    params:{
        
    }
}).then(res=>{
    // 成功处理函数
})

2.2.1-post请求

import axios from 'axios';
axios({
    // 指定数据接口
    url:'',
    // 指定数数据提交方式为GET
    method:'POST',
    // POST请求的参数
    data:{
        
    }
}).then(res=>{
    console.log(res);
})
// 专门用来发送post请求的方法
axios.post('接口地址',{
    // 直接书写请求体: 需要提交给数据接口的参数
    name:'',
    age:''
}).then(res=>{
    // 成功处理函数
})

2.3-拦截器

2.3.1-请求拦截器

// 请求拦截器
// req: 系统自动注入, 包含了和请求相关的一些数据对象
axios.interceptors.request.use(function(req){
    // console.log(req,'interceptors.request');
    // console.log(req.headers);
    // 添加自定义请求头
    req.headers.token='12345678';
    // 一定要有返回值
    return req;    
});

2.3.2-响应拦截器

//  响应拦截器
// response: 系统自动注入的参数, 包含和响应相关的数据对象
axios.interceptors.response.use(function(response){
    // console.log(response,'interceptors.response');
    // response.data是服务端返回的真实数据
    return response.data;
});

2.4-axios的全局配置

  1. 全局配置基础域名(baseURL)

    axios.defaults.baseURL='http://localhost:3000/api';
    
  2. 配置请求头

    // 配置请求头
    axios.defaults.headers.auth='abc';
    

2.5-axios.all()方法

  • 作用: 批量执行数据请求
  • 返回值: 数组
  • 参数: 数组
export default {
     methods:{
        //  获取分类列表
        async getCates(){
         const res=await axios({
            url:'/getcate',
            method:'GET',
            params:{
              name:'张三',
              age:20
            }
          });
          return res.data;
        },
        // 获取轮播图数据
        async getBanners(){
          const res=await axios.get('/getbanner',{
            // get请求参数
            params:{
              name:'lisi',
              age:20
            }
          });
          return res.data;
        }
      },
  created(){
    // this.getCates();
    // this.getBanners();
    axios.all([this.getCates(),this.getBanners()]).then(res=>{
      // 数组的解构赋值
      const [cates,banners]=res;
      // 更新数据
      if(cates.code===200){
          this.cates=cates.list;
      }
      if(banners.code===200){
          this.banners=banners.list;
      }
    })
  
  },
}

2.6-axios.create()方法

  • 作用: 创建一个axios实例对象

    import axios from 'axios';
    const http=axios.create({
        // 配置基础域名
        baseURL:'http://localhost:3000/api',
        // 请求头: 系统, 自定义
        headers:{
            token:'123456789'
        }
    });
    
    // 请求拦截器
    // req: 系统自动注入, 包含了和请求相关的一些数据对象
    http.interceptors.request.use(function(req){
        // console.log(req,'interceptors.request');
        // console.log(req.headers);
        // 添加自定义请求头
        req.headers.token='12345678';
        // 一定要有返回值
        return req;    
    });
    
    //  响应拦截器
    // response: 系统自动注入的参数, 包含和响应相关的数据对象
    http.interceptors.response.use(function(response){
        // console.log(response,'interceptors.response');
        // response.data是服务端返回的真实数据
        return response.data;
    });
    export default http; 
    

3-测试数据接口服务器的搭建

  1. 下载数据接口源代码shop-api-数据接口服务器.zip

  2. 解压

  3. 安装依赖: 进入数据接口项目根目录, 执行如下命令行

    npm i 
    
  4. 导入数据库备份文件

  5. 修改项目配置文件(主要修改数据库配置信息), 打开/config/global.js, 做如下修改

    exports.dbConfig = {
        host: 'localhost', //数据库地址
        user: 'root',//数据库用户名
        password: 'root',//数据库用户密码
        port: 3306,
        database: 'shop_db' // 数据库名字
    }
    
  6. 启动数据接口服务器

    npm run start
    // 或者(如果没有安装nodemon工具,使用如下命令启动)
    node ./bin/www
    
  7. 通过浏览器访问http://localhost:3000, 如果能正常响应, 说明数据接口服务器启动成功

axios案例模板所需依赖项

  • bootstrap: 第三方的css演示库, 主要提供了一些css类选择器, 可以快速对页面进行美化
  • swiper: 一个第三方的轮播图插件
npm i swiper@3.4.2 bootstrap@3.3.7 -S

4-token

  • token: 服务端返回的一个随机字符串, 包含了一些登录用户的信息, 后端程序可对其进行解密操作
  • 作用: 登录凭证, 请求需要登录认证的数据接口的时候, 需要将其发送给数据接口进行登录认证

5-参考文档

posted @ 2020-11-24 20:51  穷人绅士  阅读(207)  评论(0编辑  收藏  举报
/* 鼠标点击求赞文字特效 */ /*鼠标跟随效果*/