Vue高级5-router-反向代理-路径别名

Vue 进阶

  1. 动态路由 + 路由传参 + 路由接参

    • 案例: 移动端常见的: 分类 -》 列表 -》 详情 -》 购物车
  2. 引入组件库

    • 组件库就是可以快速帮助我们实现样式布局和基本逻辑

    • 组件库 vs ui库

      • 组件库指的是有组件构成的类库
      • ui库更多偏向的的是样式: sui
    • 类型

      说明:Vue的组件库很多,我这边列举的是比较流行的

      • pc端 【 后台管理系统 】

        • element-ui 饿了吗前端开发团队完成

        • iview

      • 移动端

        • Mint-ui

        • Vant

    • 组件库安装

      • 安装方式

        1. 全局引入: 将组件库中所有组件都引入项目,这样会增大项目体积

          1. yarn add element-ui -D

          2. 在main.js中引入: import ElmentUI from ‘element-ui’

          3. 在main.js中使用Vue.use注册插件

            • Vue.use( ElementUI )
        2. 按需引入: 只将我们需要的组件引入进来

          1. yarn add element-ui
          2. yarn add babel-plugin-component -D 帮助我们做按需引入的第三方模块

注意: 项目配置文件修改了,我们必须重启项目
测试组件库是否引入成功
多试几个组件库,多用几个

  1. Vue项目配置反向代理,实现跨域

    • Vue cli3 webpack配置放在node_modules 中,也就是说我们不能直接更改,Vue提供了一个叫做vue.config.js的文件,没来作为webpack的覆盖配置文件,也可以说是vue项目的配置文件

    • vue.config.js 文件是放在项目 根目录 中

    • vue.config.js 文件是webpack配置文件,webpack底层就是node.js

      • 使用的是common.js规范
      module.exports = {
          devServer: {
              proxy: {
                  // 一个键值就是一个反向代理的配置
                  '/index.php': {
                      target: 'http://www.qinqin.net',//目标源指的就是你要跨域的目标
                      changeOrigin: true, // 修改目标源为我们当前源
                  }
              }
          }
      }
      
    • 修改配置文件,项目要重启 【 特别注意 】

  2. 案例演示

  3. 动态路由

    • 在vue项目中,使用vue-router如果进行不传递参数的路由模式,则称为静态路由;如果能够传递参数,对应的路由数量是不确定的,此时的路由称为动态路由。动态路由,是以冒号为开头的(😃

    • 举例:

      • localhost:3000/detail/001?a=1&b=2
      • localhost:3000/detail/002?a=2&b=3
      • detail
          {
              path: '/list/:id', //用于url携带id  和  查找字符串
              component: List,
              name: 'list'
          },
      
  4. 路由传参

    1. 在router-link组件的to属性上进行–声明式

          <router-link
              :to = "{
                  name: 'list',
                  params: {
                      id: ele.api_cid
                  },
                  query: {
                      cid: ele.api_cid
                  }
              }"
          >
              <img :src = " ele.img " alt="">
              <span> {{ ele.name }} </span>
          </router-link>
      
    2. 通过编程式导航来完成

      1. push
        • this.$router.push(’/home’)
        • this.$router.push({name,params,query})
        • push可以将我们的操作存放到浏览器的历史记录
      // 字符串
      router.push('home')
      
      // 对象
      router.push({ path: 'home' })
      
      // 命名的路由
      router.push({ name: 'user', params: { userId: '123' }})
      
      // 带查询参数,变成 /register?plan=private
      router.push({ path: 'register', query: { plan: 'private' }})
      

      注意:如果提供了 path,params 会被忽略,上述例子中的 query 并不属于这种情况。取而代之的是下面例子的做法,你需要提供路由的 name 或手写完整的带有参数的 path:

      const userId = '123'
      router.push({ name: 'user', params: { userId }}) // -> /user/123
      router.push({ path: `/user/${userId}` }) // -> /user/123
      // 这里的 params 不生效
      router.push({ path: '/user', params: { userId }}) // -> /user
      
      1. replace

        • this.$router.replace(’/home’)
        • this.$router.replace({name,params,query})
        • replace没有将我们的操作存放到浏览器的历史记录, 效果为返回了二级
      2. push/replace的参数就是to属性的参数

      3. router(n)

        • 这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似
        methods: {
            goBack () {
                this.$router.go( -1 )
            }
        },
        
        // 在浏览器记录中前进一步,等同于 history.forward()
        router.go(1)
        
        // 后退一步记录,等同于 history.back()
        router.go(-1)
        
        // 前进 3 步记录
        router.go(3)
        
        // 如果 history 记录不够用,那就默默地失败呗
        router.go(-100)
        router.go(100)
        
  5. 路由接参

    • 通过 this.$route就可以将路由路径中的数据接收到,这个就是路由接参

    • 一般用来请求数据时候的参数 类似于 购物车的 sid。。。。。。。

            params: {
      
                   r: 'class/cyajaxsub',
      
                   page: 1,
      	
                   cid: this.$route.query.cid,    //通过this.$route
      
                   px: 't',
      
                   cac_id: ''
      
            }
      
  6. 动态路由组件

    • 当url发生改变时,对应的组件是不变的,也就是共用了同一个组件,那么这就是动态路由组件
  7. 编程式导航

    • push

    • replace

    • push vs replace

      • replace 不会将我们的页面跳转放入历史记录,效果是返回2层
      • push 会将我们的页面跳转放入历史记录,效果返回一层
  8. 如果我们给组件身上添加原生事件,那么我们需要加一个修饰符 native

       <el-button type="primary" @click.native = "goLogin"> 登录 </el-button>
    

路由的导航守卫

阿里p7要求: 路由导航守卫 、 路由鉴权

  1. 共有三个类型

    • 全局导航守卫

      • beforeEach 全局导航守卫 - 前置守卫 - 管理的是路由的进入
      const router = new VueRouter({ ... })
      
      router.beforeEach((to, from, next) => {
        // ...
      })
      
    1. to表示目标路径 - 我想进哪里

      1. from表示当前路径 - 我现在所处的路径

      2. next 表示 from 到 to的连接 ,它可以控制是否允许进入

        • next() 表示允许通过 默认实参为true
        • next () == next(true)
        • next (true) 表示可以进入
        • next (false) 表示不允许进入
        • 如果 不写next 表示不允许进入
      3. 业务:当我们登陆了之后,我们前端要将后端给的token值存储起来,然后我们通过判断token是否存在,来进入项目

        	router.beforeEach(( to,from,next ) => {
            
           		const token = localStorage.getItem( 'token' )
             // 如果token不存在,那么我们自动跳转登录页面,然后让用户登录,来获得token值 
                if ( to.path == '/home') {
                    next()
                }
                if ( to.path == '/category' ) {
                    next()
                }
                if ( !token ) {
                    // next( 路由路径 )  可以跳转某一个路由 
                    /* 以下这么些会出现一个问题就是死循环 */
                        // console.log( 1 )
                        // next('/mine/login')
                        // next()
                    /*  
                        所以要想不出现死循环,我们要加判断条件 
                        思考: 需要打破这个死循环的条件 
        
                        这样,用户进入哪一个页面可以由我们来控制 
                    */
                    switch ( to.path ) {
                        case '/home':
                            next('/mine/login')
                            next()
                            break;
                        case '/category':
                            next('/mine/login')
                            next()
                            break;
                        case '/shopcar':
                            next('/mine/login')
                            next()
                            break;
                        default:
                            break;
                    }
        		}
            }
        
      • afterEach 后置守卫 - 表示的离开
        router.afterEach(( to,from ) => {
            //没有next参数,那就没有拦截作用,它可以提示作用
            if ( to.path == '/home' ) {
                 alert( '您是否要今天入首页?' )
            }
        })
        
    • 路由独享守卫

      • 你可以在路由配置上直接定义 beforeEnter 守卫:
      • 针对的是一个路由的配置

      • 案例: 权限验证

        • 数据库: 用户组
          • 普通用户
          • 管理员
          • 超级管理员
        • 我们登录后,后台会返回给我们info信息,通过信息来判断它是哪个类型用户
        {
            path: '/recommend',
            component: Recommend,
            beforeEnter ( to,from,next ) {
                //可以做拦截
                console.log('beforeEnter')
                next()
                // 超级管理员
            }
        },
        
    • 组件内守卫

      const Foo = {
        template: `...`,
        beforeRouteEnter (to, from, next) {
          // 在渲染该组件的对应路由被 confirm 前调用
          // 不!能!获取组件实例 `this`
          // 因为当守卫执行前,组件实例还没被创建
        },
        beforeRouteUpdate (to, from, next) {
          // 在当前路由改变,但是该组件被复用时调用
          // 举例来说,对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,
          // 由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。
          // 可以访问组件实例 `this`
        },
        beforeRouteLeave (to, from, next) {
          // 导航离开该组件的对应路由时调用
          // 可以访问组件实例 `this`
        }
      }
      
      • beforeRouteEnter 前置守卫
        • 拦截 表示进入组件之前
        • 数据预载 【 给组件提前获得数据】
        • 问题:我们想把获得的数据提前给到组件,但是我们在这个钩子中无法获得组件,this也没有
        • 示例如下:
        data () {
            return {
                category: { //注意这里写两层
                    data: null
                }
            }
        },
        beforeRouteEnter ( to,from,next ) { // 表示进入组件前
            console.log( this ) // 没有this
            axios.get('/mock/shopcar.json')
                .then( res => {
                    console.log( 'res',res )
                    // 问题:我们想把获得的数据提前给到组件,但是我们在这个钩子中无法获得组件,this也没有
                    // 解决
                    next( vm => {
                        // vm就是当前组件
                        console.log( 'vm',vm )
                        // vm.name = "yyb" 这么加的话是无法成功的
                        // 因为vue中响应式数据要求在data选项中定义
                        vm.$set( vm.category, 'data', res.data )//这样加我们的数据合并到data选项中
                        // vm.$set / Vue.$set底层是Object.assign  也就是对象合并
                        next()
                    })
                })
                .catch( err => console.log( err ))
        },
            
        
        
      • beforRouteUpdate更新守卫
        1. 路由改变 但是组件复用的 情况下就会调用这个钩子
        2. 例如:
          • 对于一个带有动态参数的路径 /foo/:id,在 /foo/1 和 /foo/2 之间跳转的时候,由于会渲染同样的 Foo 组件,因此组件实例会被复用。而这个钩子就会在这个情况下被调用。可以访问组件实例 this
      • beforRouteLeave后置守卫
        1. 也是拦截
        2. 在用户离开路由前触发
        3. 这个离开守卫通常用来禁止用户在还未保存修改前突然离开。该导航可以通过 next(false) 来取消。
        beforeRouteLeave ( to,from,next ) {
            // 也是拦截
            // this可以拿到 
            if ( this.username || this.password || this.email || this.phone ) {
                if ( confirm( '您确定要离开吗' ) ) {
                    next()
                } else {
                    next( false )
                }
            } else {
                next()
            }
        },
        
  2. 如何处理路由拦截,也就是我们被卡在登录页面或是其他页面

    • 想办法得到token
      • 后台接口文档中找登录的接口,然后自己写个ajax发送一次请求,然后将token保存在cookie
    • 如果token拿不到,我们就先 注释 掉人家的拦截【 导航守卫 】,然后完成自己的任务
  3. 数据请求拿不到怎么办?

    • 根据接口文档,对应的返回值的字段 mock 数据 , 进行数据请求,然后数据渲染

完整的导航解析流程

  1. 导航被触发。
  2. 在失活的组件里调用离开守卫。
  3. 调用全局的 beforeEach 守卫。
  4. 在重用的组件里调用 beforeRouteUpdate 守卫 (2.2+)。
  5. 在路由配置里调用 beforeEnter
  6. 解析异步路由组件。
  7. 在被激活的组件里调用 beforeRouteEnter
  8. 调用全局的 beforeResolve 守卫 (2.5+)。
  9. 导航被确认。
  10. 调用全局的 afterEach 钩子。
  11. 触发 DOM 更新。
  12. 用创建好的实例调用 beforeRouteEnter 守卫中传给 next 的回调函数。

路由懒加载

默认分块

  1. 结合 Vue 的异步组件和 Webpack 的代码分割功能,轻松实现路由组件的懒加载。

    • 结合这两者,这就是如何定义一个能够被 Webpack 自动代码分割的异步组件。
    const Foo = () => import('./Foo.vue')
    

把组件按组分块

有时候我们想把某个路由下的所有组件都打包在同个异步块 (chunk) 中。只需要使用 命名 chunk,一个特殊的注释语法来提供 chunk name (需要 Webpack > 2.4)。

const Foo = () => import(/* webpackChunkName: "group-foo" */ './Foo.vue')
const Bar = () => import(/* webpackChunkName: "group-foo" */ './Bar.vue')
const Baz = () => import(/* webpackChunkName: "group-foo" */ './Baz.vue')

过渡动效

  1. <router-view> 是基本的动态组件,所以我们可以用 <transition> 组件给它添加一些过渡效果:

    <transition>
      <router-view></router-view>
    </transition>
    
    <transition
      mode="in-out"   //先进后出 
      mode="out-in"	  //先出后进
      enter-active-class="animated lightSpeedIn"   //开始的动画
      leave-active-class="animated lightSpeedOut"  //离开的动画
    >
      <router-view></router-view>
    </transition>
    
  2. 也可以给单个路由设置过度动画效果

    • 上面的用法会给所有路由设置一样的过渡效果,如果你想让每个路由组件有各自的过渡效果,可以在各路由组件内使用 <transition> 并设置不同的 name。
    const Foo = {
      template: `
        <transition name="slide">
          <div class="foo">...</div>
        </transition>
      `
    }
    
    const Bar = {
      template: `
        <transition name="fade">
          <div class="bar">...</div>
        </transition>
      `
    }
    
  3. 普通标签也可以使用过度动画效果

    <div id="example-1">
      <button @click="show = !show">
        Toggle render
      </button>
      <transition name="slide-fade">
        <p v-if="show">hello</p>
      </transition>
    </div>
    
  4. 普通标签也可以使用过度动画效果

    <div id="example-1">
      <button @click="show = !show">
        Toggle render
      </button>
      <transition name="slide-fade">
        <p v-if="show">hello</p>
      </transition>
    </div>
    

Vue 路径别名

module.exports = {
    chainWebpack: config => {
        config.resolve.alias
            // 需要重启 IDE
            .set('assets', resolve('src/assets'))
            .set('components', resolve('src/components'))
        // 这里只写了两个个,你可以自己再加,按这种格式.set('', resolve(''))
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值