vue pc商城---最终篇

目录

路由导航守卫

简介

2.全局守卫

3.路由独享守卫(beforeEnter)

4.组件内的守卫(3个)

(1)beforeRouteEnter

(2)beforeRouteUpdate

(3)beforeRouteLeave

Vue - 自定义插件

一、使用插件

二、开发插件

三、开发实例

 vue自定义指令使用

全局自定义指令

局部自定义指令

自定义组件的钩子函数

三、自定义组件的应用场景

二、 vue自定义指令的应用场景


路由导航守卫

简介

vue-router提供的导航守卫主要用来通过跳转或取消的方式守卫导航。
每个守卫接受三个参数:
(1)to:即将要进入的目标路由对象
(2)from:当前导航正要离开的路由
(3) next:一定要调用该方法来resolve这个钩子。执行效果依赖next方法的调用参数。如果next函数没有执行或是传入了false等值,这个跳转就会被终止掉。

2.全局守卫


只要触发了路由就会触发路由前置和后置守卫
(1)全局前置守卫
当一个导航触发时,全局前置守卫按照创建顺序调用。守卫是异步解析执行,此时导航在所有守卫resolve完之前一直处于等待中。只有等所有守卫resolve之前一直处于等待中。

用途:可以用来判断进入的路由是否想让一开始就进入的,如果不是可以让它跳转过去。
 

// 全局守卫,前置守卫 在路由跳转之前进行判断
router.beforeEach(async (to, from, next) => {
  //to:可以获取到你要跳转到哪个路由信息
  // from::可以获取到你从哪个路由来的信息
  // next : 放行函数 可以放行到指定的路由
  let token = store.state.user.token
  let name = store.state.user.userinfo.name;
  if (token) {
    //用户已经登录了,去login(不让去,停留在首页)
    if (to.path == '/login') {
      next('/')
    } else {
      // 登录去的不是login,
      if (name) {
        next()
      } else {
        // 没有用户信息。派发action ,让仓库存储用户信息 进行跳转
        try {
          await store.dispatch('asyncUserInfo')
          next()
        } catch (e) {
          // token 失效,获取不到用户信息,清除token 重新登录,
          await store.dispatch('asyncUserOut')
        }
      }

    }
  } else {

    // 未登录不能去 支付 个人中心 去登录页
    let toPath = to.path
    console.log(toPath);
    if (toPath.indexOf('/myOrder') != -1 || toPath.indexOf('/ShopCart') != -1 || toPath.indexOf('/Center') != -1) {
      console.log('未登录');
      //未登录的时候想去而没有去成的信息,存储于地址栏中【路由】
      next('/login?redirect=' + toPath)
    } else {
      console.log('放行');
      next()
    }

  }
})

3.路由独享守卫(beforeEnter)

写在routes中的,每个路由独有的,只在当前路由中生效。

 {
        path: '/Trade',
        component: Trade,
        meta: { show: true },
        beforeEnter: (to, from, next) => {
            //去交易页必须从购物车来
            if (from.path == '/ShopCart') {
                next()
            } else {
                //停留在当前页
                next(false)
            }

        }
    },

4.组件内的守卫(3个)

直接写在对应组件页面中。
beforeRouterEnter:进入该组件的对应路由后触发
beforeRouterUpdate:当同一个组件,path参数不同时,进行切换的时候触发。比如这种:path:/music/:id
beforeRouterLeave:要离开该组件的对应路由时触发。

(1)beforeRouteEnter


在这里不能使用this,这时实例还没有被创建
如果要使用this。用下面这种办法:在next中通过vm来代替this

  //组件内守卫 组件实例还没有被创建
  beforeRouteEnter(to, from, next) {
    if (from.path == "/Pay") {
      next();
    } else {
      next(false);
    }
  },

(2)beforeRouteUpdate

beforeRouteLeave(to,from,next){
	const answer = window.confirm("你确定要离开吗")
	if(answer){
		next()
    }else {
		next(false)
	}
}

在当前路由改变,但是只有在该组件被复用时调用。
举例来说:对于一个带有动态参数的路径/foo/:id 在/foo/1与/foo/2之间进行切换跳转的时候会复用foo组件,所以才会触发这个钩子。


(3)beforeRouteLeave

案例:当所在组件的路由要离开时,给个弹窗,是否退出,是就退出,next中值为false则不退出。

beforeRouteLeave(to,from,next){
	const answer = window.confirm("你确定要离开吗")
	if(answer){
		next()
    }else {
		next(false)
	}
}

Vue - 自定义插件

插件通常用来为 Vue 添加全局功能,例如数据字典插件等。

1

2

3

a)插件通常会为 Vue 添加全局功能,一般是添加全局方法/全局指令/过滤器等

b)Vue 插件有一个公开方法 install ,通过 install 方法给 Vue 添加全局功能

c)通过全局方法 Vue.use() 使用插件,它需要在你调用 new Vue() 启动应用之前完成

一、使用插件

通过全局方法 Vue.use() 使用插件。它需要在你调用 new Vue() 启动应用之前完成:

1

2

3

4

5

6

// 调用 `MyPlugin.install(Vue)`

Vue.use(MyPlugin)

new Vue({

  // ...组件选项

})

也可以传入一个可选的选项对象:

1

Vue.use(MyPlugin, { someOption: true })

Vue.use 会自动阻止多次注册相同插件,届时即使多次调用也只会注册一次该插件,在像 CommonJS 这样的模块环境中,你应该始终显式地调用 Vue.use()。

当 install 方法被同一个插件多次调用,插件将只会被安装一次。

二、开发插件

Vue.js 的插件应该暴露一个 install 方法。这个方法的第一个参数是 Vue 构造器,第二个参数是一个可选的选项对象:

MyPlugin.install = function (Vue, options) {
  // 1. 添加全局资源
  Vue.directive('my-directive', {
    bind (el, binding, vnode, oldVnode) {
      // 逻辑...
    }
    ...
  })
 
  // 2. 注入组件选项
  Vue.mixin({
    created: function () {
      // 逻辑...
    }
    ...
  })
 
  // 3. 添加实例方法
  Vue.prototype.$myMethod = function (methodOptions) {
    // 逻辑...
  }
}

注意:如果插件是一个对象,必须提供 install 方法。如果插件是一个函数,它会被作为 install 方法。install 方法调用时,会将 Vue 作为参数传入。

三、开发实例

实例:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

//所谓vue的插件,就是一个js对象

let myplugin = {}

myplugin.install = function(Vue,Options){

    // 添加属性与方法

    //这里我写的$testProp等加了$符号的,表示他为vue全局的,但实际上不加也可以的,访问时也不加就行了

    Vue.prototype.$myoption='我是来自插件的属性',

    Vue.prototype.$myfn=function(){

        console.log('我是来自插件的方法')

    }

    // 添加全局混入

    Vue.mixin({

        mounted() {

            console.log('组件创建成功')

        },

    })

    // 添加全局指令

    Vue.directive('dir',{

        inserted:function(ele){

            ele.style.border='2px solid green'

        }

    })

}

export default myplugin

main.js里面安装插件:

1

2

import myplugin from './plugin/myplugin'

Vue.use(myplugin)

插件使用:

1

2

3

4

5

6

7

8

9

10

11

12

13

<template>

    <div>

        <h1 v-dir>123</h1>

    </div>

</template>

<script>

export default {

    mounted() {

        console.log(this.$myoption)

        this.$myfn()

    },

}

</script>

 

注意:插件与组件的区别:

组件 (Component) 是用来构成你的 App 的业务模块,它的目标是 App.vue

插件 (Plugin) 是用来增强你的技术栈的功能模块,它的目标是 Vue 本身。

 vue自定义指令使用

vue中除了核心功能内置的指令外,也允许注册自定义指令。有的情况下,对普通DOM元素进行底层操作,这时候就会用到自定义指令。

全局自定义指令

是通过Vue.directive(‘第一个参数是指令的名称’,{第二个参数是一个对象,这个对象上有钩子函数})

下边举例说明:

 Vue.directive('focus', {
		// el:指令所绑定的元素,可以用来直接操作 DOM。
		//binding:一个对象,包含以下 property:
      inserted: function (el) { // inserted 表示被绑定元素插入父节点时调用
        el.focus();
      }
    });

局部自定义指令

局部注册通过在组件options选项中设置directive属性
是定义在组件内部的,只能在当前组件中使用

下边举例说明:

directives: {
        // 指令名称
        dir1: {
            inserted(el) {
                // 指令中第一个参数是当前使用指令的DOM
                console.log(el);
                console.log(arguments);
                // 对DOM进行操作
                el.style.width = '200px';
                el.style.height = '200px';
                el.style.background = '#000';
            }
        },
        color: { // 为元素设置指定的字体颜色
          bind(el, binding) {
            el.style.color = binding.value;
          }
        }
	}

自定义组件的钩子函数


自定义指令也像组件那样存在钩子函数:

一个指令定义对象可以提供如下几个钩子函数 (均为可选):

inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
项目中:拖拽

三、自定义组件的应用场景


使用自定义组件组件可以满足我们日常一些场景,这里给出几个自定义组件的案例:

1.防抖

2.图片懒加载

3.一键 Copy的功能

二、 vue自定义指令的应用场景


使用自定义指令背景
代码复用和抽象的主要形式是组件。
当需要对普通 DOM 元素进行底层操作,此时就会用到自定义指令
但是,对于大幅度的 DOM 变动,还是应该使用组件
常用案例

1、 输入框自动聚焦

// 注册一个全局自定义指令 `v-focus`
Vue.directive('focus', {
  // 当被绑定的元素插入到 DOM 中时
  inserted: function (el) {
    // 聚焦元素
    el.focus()
  }
})
<input v-focus>


2 下拉菜单
点击下拉菜单本身不会隐藏菜单
点击下拉菜单以外的区域隐藏菜单

Vue.directive('clickoutside', {
  bind(el, binding) {
    function documentHandler(e) {
      if (el.contains(e.target)) {
       return false 
      }
      
      if (binding.expression) {
        binding.value(e)
      }
    }
    
    el.__vueMenuHandler__ = documentHandler
    document.addEventListener('click', el.__vueMenuHandler__)
  },
  unbind(el) {
    document.removeEventListener('click', el.__vueMenuHandler__)
    delete el.__vueMenuHandler__
  }
})

new Vue({
  el: '#app',
  data: {
    show: false
  },
  methods: {
    handleHide() {
      this.show = false
    }
  }
})
<div class="main" v-menu="handleHide">
  <button @click="show = !show">点击显示下拉菜单</button>
  <div class="dropdown" v-show="show">
    <div class="item"><a href="#">选项 1</a></div>
    <div class="item"><a href="#">选项 2</a></div>
    <div class="item"><a href="#">选项 3</a></div>
  </div>
</div>
<span v-relativeTime="time"></span>
new Vue({
  el: '#app',
  data: {
    time: 1565753400000
  }
})

Vue.directive('relativeTime', {
  bind(el, binding) {
    // Time.getFormatTime() 方法,自行补充
    el.innerHTML = Time.getFormatTime(binding.value)
    el.__timeout__ = setInterval(() => {
      el.innerHTML = Time.getFormatTime(binding.value)
    }, 6000)
  },
  unbind(el) {
    clearInterval(el.innerHTML)
    delete el.__timeout__
  }
})

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值