• 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之前一直处于等待中。

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

    1. // 全局守卫,前置守卫 在路由跳转之前进行判断
    2. router.beforeEach(async (to, from, next) => {
    3. //to:可以获取到你要跳转到哪个路由信息
    4. // from::可以获取到你从哪个路由来的信息
    5. // next : 放行函数 可以放行到指定的路由
    6. let token = store.state.user.token
    7. let name = store.state.user.userinfo.name;
    8. if (token) {
    9. //用户已经登录了,去login(不让去,停留在首页)
    10. if (to.path == '/login') {
    11. next('/')
    12. } else {
    13. // 登录去的不是login,
    14. if (name) {
    15. next()
    16. } else {
    17. // 没有用户信息。派发action ,让仓库存储用户信息 进行跳转
    18. try {
    19. await store.dispatch('asyncUserInfo')
    20. next()
    21. } catch (e) {
    22. // token 失效,获取不到用户信息,清除token 重新登录,
    23. await store.dispatch('asyncUserOut')
    24. }
    25. }
    26. }
    27. } else {
    28. // 未登录不能去 支付 个人中心 去登录页
    29. let toPath = to.path
    30. console.log(toPath);
    31. if (toPath.indexOf('/myOrder') != -1 || toPath.indexOf('/ShopCart') != -1 || toPath.indexOf('/Center') != -1) {
    32. console.log('未登录');
    33. //未登录的时候想去而没有去成的信息,存储于地址栏中【路由】
    34. next('/login?redirect=' + toPath)
    35. } else {
    36. console.log('放行');
    37. next()
    38. }
    39. }
    40. })

    3.路由独享守卫(beforeEnter)

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

    1. {
    2. path: '/Trade',
    3. component: Trade,
    4. meta: { show: true },
    5. beforeEnter: (to, from, next) => {
    6. //去交易页必须从购物车来
    7. if (from.path == '/ShopCart') {
    8. next()
    9. } else {
    10. //停留在当前页
    11. next(false)
    12. }
    13. }
    14. },

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

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

    (1)beforeRouteEnter


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

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

    (2)beforeRouteUpdate

    1. beforeRouteLeave(to,from,next){
    2. const answer = window.confirm("你确定要离开吗")
    3. if(answer){
    4. next()
    5. }else {
    6. next(false)
    7. }
    8. }

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


    (3)beforeRouteLeave

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

    1. beforeRouteLeave(to,from,next){
    2. const answer = window.confirm("你确定要离开吗")
    3. if(answer){
    4. next()
    5. }else {
    6. next(false)
    7. }
    8. }

    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 构造器,第二个参数是一个可选的选项对象:

    1. MyPlugin.install = function (Vue, options) {
    2. // 1. 添加全局资源
    3. Vue.directive('my-directive', {
    4. bind (el, binding, vnode, oldVnode) {
    5. // 逻辑...
    6. }
    7. ...
    8. })
    9. // 2. 注入组件选项
    10. Vue.mixin({
    11. created: function () {
    12. // 逻辑...
    13. }
    14. ...
    15. })
    16. // 3. 添加实例方法
    17. Vue.prototype.$myMethod = function (methodOptions) {
    18. // 逻辑...
    19. }
    20. }

    注意:如果插件是一个对象,必须提供 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(‘第一个参数是指令的名称’,{第二个参数是一个对象,这个对象上有钩子函数})

    下边举例说明:

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

    局部自定义指令

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

    下边举例说明:

    1. directives: {
    2. // 指令名称
    3. dir1: {
    4. inserted(el) {
    5. // 指令中第一个参数是当前使用指令的DOM
    6. console.log(el);
    7. console.log(arguments);
    8. // 对DOM进行操作
    9. el.style.width = '200px';
    10. el.style.height = '200px';
    11. el.style.background = '#000';
    12. }
    13. },
    14. color: { // 为元素设置指定的字体颜色
    15. bind(el, binding) {
    16. el.style.color = binding.value;
    17. }
    18. }
    19. }

    自定义组件的钩子函数


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

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

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

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


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

    1.防抖

    2.图片懒加载

    3.一键 Copy的功能

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


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

    1、 输入框自动聚焦

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


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

    1. Vue.directive('clickoutside', {
    2. bind(el, binding) {
    3. function documentHandler(e) {
    4. if (el.contains(e.target)) {
    5. return false
    6. }
    7. if (binding.expression) {
    8. binding.value(e)
    9. }
    10. }
    11. el.__vueMenuHandler__ = documentHandler
    12. document.addEventListener('click', el.__vueMenuHandler__)
    13. },
    14. unbind(el) {
    15. document.removeEventListener('click', el.__vueMenuHandler__)
    16. delete el.__vueMenuHandler__
    17. }
    18. })
    19. new Vue({
    20. el: '#app',
    21. data: {
    22. show: false
    23. },
    24. methods: {
    25. handleHide() {
    26. this.show = false
    27. }
    28. }
    29. })
    30. <div class="main" v-menu="handleHide">
    31. <button @click="show = !show">点击显示下拉菜单</button>
    32. <div class="dropdown" v-show="show">
    33. <div class="item"><a href="#">选项 1</a></div>
    34. <div class="item"><a href="#">选项 2</a></div>
    35. <div class="item"><a href="#">选项 3</a></div>
    36. </div>
    37. </div>
    1. <span v-relativeTime="time"></span>
    2. new Vue({
    3. el: '#app',
    4. data: {
    5. time: 1565753400000
    6. }
    7. })
    8. Vue.directive('relativeTime', {
    9. bind(el, binding) {
    10. // Time.getFormatTime() 方法,自行补充
    11. el.innerHTML = Time.getFormatTime(binding.value)
    12. el.__timeout__ = setInterval(() => {
    13. el.innerHTML = Time.getFormatTime(binding.value)
    14. }, 6000)
    15. },
    16. unbind(el) {
    17. clearInterval(el.innerHTML)
    18. delete el.__timeout__
    19. }
    20. })

  • 相关阅读:
    广义最小残量法
    微软Azure配置中心 App Configuration (三):配置的动态更新
    FastAPI 学习之路(十四)响应模型
    你的编程能力从什么时候开始突飞猛进? 我的回答:2013年,我开始喜欢编程了。
    IntelliJ IDEA - Maven 在控制台Maven编译正常,但是在IDEA中不正常,表现不一致
    华为设备ACL配置命令
    JAVA大学生过程培养信息系统计算机毕业设计Mybatis+系统+数据库+调试部署
    数据结构与算法_AVL平衡二叉树_四种旋转,插入和删除
    Java继承分析
    计数排序和排序的稳定性
  • 原文地址:https://blog.csdn.net/qq_63358859/article/details/125618402