Vue进阶之旅:核心技术与实战(自定义指令、插槽与路由入门)

Vue进阶之旅:核心技术与实战


在Vue开发中,自定义指令、插槽与路由是非常重要的技术点,它们能够极大地提升我们开发的效率和灵活性。今天我们就一起来深入学习这些内容。

一、自定义指令

自定义指令允许我们封装一些DOM操作,扩展额外功能。

(一)注册方式

自己调用自己:

代码解释

  • 模板部分(<template>
<template>
  <div>
    <h1>自定义指令</h1>
    <input ref="inp" type="text">
  </div>
</template>

此部分定义了一个 Vue 组件的 HTML 结构,包含一个标题 <h1> 和一个文本输入框 <input>ref="inp" 为输入框添加了一个引用名称。

  • 脚本部分(<script>
export default {
   
   
  mounted () {
   
   
    this.$refs.inp.focus();
  }
}

此部分定义了一个 Vue 组件,在组件挂载完成(mounted 生命周期)时,通过 this.$refs.inp 找到 refinp 的输入框元素,并调用 focus() 方法让其获得焦点。

功能总结

该 Vue 组件的主要功能是在页面上展示一个包含标题和文本输入框的区域,并在组件挂载完成时使输入框自动获得焦点,方便用户直接输入,提升用户体验。

image-20250117114537476

接下来就是使用指令来获得焦点:

  1. 全局注册
    全局注册使用 Vue.directive 方法,语法如下:
Vue.directive('指令名', {
   
   
  inserted (el) {
   
   
    // 可以对el标签扩展额外功能,例如让元素获取焦点
    el.focus()
  }
})

在这里,inserted 钩子函数在被绑定元素插入父节点时调用 ,el 表示被绑定的DOM元素。举个例子:

全局注册解释

在 Vue 中,全局注册是将组件、指令或过滤器等添加到 Vue 实例的全局范围,以便在整个应用的任何组件中使用,无需在每个组件中单独导入或声明。

下述代码中的全局注册

Vue.directive('focus', {
   
   
  inserted (el) {
   
   
    el.focus();
  }
})
  • Vue.directive('focus', {...}) 用于全局注册自定义指令 focus
  • inserted(el) { el.focus() }focus 指令的一个钩子函数,当元素被插入页面时触发,使元素获得焦点。

使用场景

<input v-focus ref="inp" type="text">
  • 这里使用 v-focus 指令,因为它是全局注册的,无需额外导入或声明,元素插入页面时,会自动执行 inserted 函数使输入框聚焦。

总结
全局注册可在多个组件复用,避免重复代码,提高开发效率和可维护性,上述代码的 focus 指令就体现了这点。

  1. 局部注册
    在组件内部通过 directives 选项进行局部注册,示例代码如下:
export default {
   
   
  directives: {
   
   
    '指令名': {
   
   
      inserted (el) {
   
   
        el.focus()
      }
    }
  }
}

在标签中使用时,写法为 <input v-指令名 type="text">。通过自定义指令,我们可以避免在 mounted 钩子函数中使用 this.$refs.inp.focus() 这种较为繁琐的获取焦点方式,代码更加简洁。

局部注册解释

在 Vue 中,局部注册是指将自定义指令、组件或过滤器等仅在某个组件内部进行注册的操作,使其仅在该组件内可用,而不会影响到其他组件。

代码中的局部注册

export default {
   
   
  directives : {
   
   
    focus : {
   
   
      inserted (el) {
   
   
        el.focus();
      }
    }
  }
}
  • 在这个 Vue 组件的 script 部分,通过 directives 属性进行了自定义指令的注册。
  • focus : {...} 定义了一个名为 focus 的自定义指令。
  • inserted (el) {...} 是该指令的一个钩子函数,当使用 v-focus 指令的元素被插入页面时,会执行 el.focus() 操作,使元素获得焦点。

使用场景

<input v-focus ref="inp" type="text">
  • 这里使用 v-focus 指令,在上述代码中,focus 指令只在当前组件的输入框中使用,确保了其仅在该组件内发挥作用,不会影响其他组件,这就是典型的局部注册使用场景。

总结
上述代码中的 directives 属性的使用就是局部注册的体现,仅在当前组件内注册了 focus 指令,使其仅能在本组件内使用,与全局注册相比,其作用范围受限,但对于只在特定组件中使用的功能,局部注册能保持代码的简洁和独立性。

(二)指令的值

指令可以通过 “等号” 的形式绑定参数值,如 <div v-color="color">我是内容</div>。在指令的定义中,通过 binding.value 可以拿到指令值,指令值修改会触发 update 函数。示例代码如下:

directives: {
   
   
  color: {
   
   
    inserted (el, binding) {
   
   
      // 设置元素文字颜色为指令值
      el.style.color = binding.value
    },
    update (el, binding) {
   
   
      // 指令值更新时,更新元素文字颜色
      el.style.color = binding.value
    }
  }
}

这种方式可以应对更复杂的指令封装场景。

代码示例

<template>
  <div>
    <!-- 使用 v-color 指令,并将其绑定到 color1 数据 -->
    <h1 v-color="color1">自定义指令1</h1> 
    <!-- 使用 v-color 指令,并将其绑定到 color2 数据 -->
    <h1 v-color="color2">自定义指令2</h1> 
  </div>
</template>

<script>
export default {
     
     
  data () {
     
     
    return {
     
     
      // 定义 color1 的数据,初始值为红色
      color1 : 'red', 
      // 定义 color2 的数据,初始值为绿色
      color2 : 'green' 
    }
  },

  directives : {
     
     
    color : {
     
     
      inserted (el, binding) {
     
     
        // inserted 钩子函数:当指令所在元素插入页面时,将元素的颜色设置为指令绑定的值
        el.style.color = binding.value; 
      },

      update (el, binding) {
     
     
        // update 钩子函数:当指令绑定的值更新时,更新元素的颜色
        el.style.color = binding.value; 
      }
    }
  }
}
</script>

解释

  • template 部分,我们使用了 v-color 自定义指令,并将其绑定到组件中的 color1color2 数据。
  • script 部分:
    • 首先,通过 data 函数定义了 color1color2 的数据,分别初始化为 redgreen
    • 然后,在 directives 对象中定义了 color 自定义指令。
    • 对于 color 自定义指令:
      • inserted 钩子函数:当使用 v-color 指令的元素插入到页面时,会调用该函数。通过 binding.value 可以获取到指令绑定的值,将元素的颜色样式设置为该值。例如,对于 <h1 v-color="color1">自定义指令1</h1>,会将该 h1 元素的颜色设置为 red
      • update 钩子函数:当指令绑定的值发生更新时,会调用该函数。同样通过 binding.value 获取更新后的值,并更新元素的颜色。例如,如果 color1 的值从 red 变为 blue,元素的颜色会更新为 blue

使用场景和优势

  • 这种自定义指令的方式适用于对元素样式或其他 DOM 属性进行动态控制的场景。
  • 通过 binding.value 可以灵活地将不同的数据值绑定到指令上,实现元素样式或行为的动态调整。
  • 当数据发生变化时,update 钩子函数会自动更新元素的样式,无需手动操作 DOM,符合 Vue 的数据驱动视图的理念。

注意事项

  • 确保 binding.value 提供的值符合元素属性的要求,例如,在设置颜色时,需要提供有效的颜色值,如颜色名称、十六进制代码或 RGB 值等。
  • 合理使用 insertedupdate 钩子函数,根据不同的生命周期阶段实现相应的逻辑,避免冗余代码和性能问题。

通过这种方式,可以实现对元素样式的动态管理,在开发中可以根据不同的业务需求,扩展更多功能,如动态改变元素的大小、位置等,为开发更具交互性和动态性的 Vue 组件提供了很大的便利。

(三)v-loading指令封装

在实际开发中,数据请求时页面可能会空白,影响用户体验。我们可以封装 v-loading 指令来实现加载中的效果。

  1. 核心思路
    • 准备一个 loading 类,通过伪元素定位,设置宽高实现蒙层效果,让用户知晓数据正在加载。。
    • 利用 v-loading 指令,将其绑定到需要显示加载状态的元素上,并关联一个布尔变量。在数据请求开始时,将该变量置为 true,添加 loading 类,显示蒙层;数据请求结束后,将该变量置为 false,移除 loading 类,隐藏蒙层。
  2. 代码实现

CSS 部分

.loading:before {
   
   
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  width: 100%;
  height: 100%;
  background: #fff url('./loading.gif') no-repeat center;
}

.box {
   
   
  width: 800px;
  min-height: 500px;
  border: 3px solid orange;
  border-radius: 5px;
  position: relative;
}
.news {
   
   
  display: flex;
  height: 120px;
  width: 600px;
  margin: 0 auto;
  padding: 20px 0;
  cursor: pointer;
}
.news.left {
   
   
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding-right: 10px;
}
.news.left.title {
   
   
  font-size: 20px;
}
.news.left.info {
   
   
  color: #999999;
}
.news.left.info span {
   
   
  margin-right: 20px;
}
.news.right {
   
   
  width: 160px;
  height: 120px;
}
.news.right img {
   
   
  width: 100%;
  height: 100%;
  object-fit: cover;
}
  • .loading:before 样式:
    • content: '';:使用伪元素添加内容。
    • position: absolute;:设置绝对定位,使其覆盖父元素。
    • left: 0; top: 0; width: 100%; height: 100%;:确保覆盖整个父元素。
    • background: #fff url('./loading.gif') no-repeat center;:使用白色背景并在中心位置显示 loading.gif 图片,实现加载效果。

JavaScript 部分

<template>
  <div class="main">
    <div class="box" v-loading="isLoading">
      <ul>
        <li v-for="item in list" :key="item.id" class="news">
          <div class="left">
            <div class="title">{
  
  { item.title }}</div>
            <div class="info">
              <span>{
  
  { item.source }}</span>
              <span>{
  
  { item.time }}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yardon_Official

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值