【Vue3入门】自定义指令与插槽详解

🚀 欢迎来到我的CSDN博客:Optimistic _ chen

一名热爱技术与分享的全栈开发者,在这里记录成长,专注分享编程技术与实战经验,助力你的技术成长之路,与你共同进步!


🚀我的专栏推荐

专栏 内容特色 适合人群
🔥C语言从入门到精通 系统讲解基础语法、指针、内存管理、项目实战 零基础新手、考研党、复习
🔥Java基础语法 系统解释了基础语法、类与对象、继承 Java初学者
🔥Java核心技术 面向对象、集合框架、多线程、网络编程、新特性解析 有一定语法基础的开发者
🔥Java EE 进阶实战 Servlet、JSP、SpringBoot、MyBatis、项目案例拆解 想快速入门Java Web开发的同学
🔥Java数据结构与算法 图解数据结构、LeetCode刷题解析、大厂面试算法题 面试备战、算法爱好者、计算机专业学生
🔥Redis系列 从数据类型到核心特性解析 项目必备

🚀我的承诺:

✅ 文章配套代码:每篇技术文章都提供完整的可运行代码示例

✅ 持续更新:专栏内容定期更新,紧跟技术趋势

✅ 答疑交流:欢迎在文章评论区留言讨论,我会及时回复(支持互粉)


🚀 关注我,解锁更多技术干货!
⏳ 每天进步一点点,未来惊艳所有人!✍️ 持续更新中,记得⭐收藏关注⭐不迷路 ✨

📌 标签:#技术博客#编程学习#Java#C语言#算法#程序员

文章目录

自定义指令

【Vue入门】Vue指令超全总结:从入门到实战,看这一篇就够了这篇博客详细介绍了Vue常用的内置指令及其使用方法。然而在实际开发中,我们经常会遇到一些特殊需求,这时内置指令可能无法满足。为此,Vue提供了自定义指令功能,让开发者能够直接操作DOM元素,特别适合需要底层DOM操作的场景。

作用:封装一段公共的DOM操作 代码,方便复用。

基础语法:

javascript 复制代码
//全局注册
// main.js
Vue.directive('指令名', {
  // 指令定义
  //元素挂载后(成为DOM的一部分),自动执行
  mounted(el){
     //el:指令所在的DOM元素
  }
})

使用的方法基本和内置指令相同,< p v-指令名> </p>
自定义指令的主要作用是为DOM元素添加响应式行为 。与内置指令类似,自定义指令必须在*元素挂载完成后才能生效,因为其mounted生命周期钩子需要操作已存在于DOM树中的元素。

javascript 复制代码
// Vue 3
Vue.directive('focus', {
  mounted(el) {
    el.focus()  // 页面加载后输入框自动获取焦点
  }
})

// 使用
<input v-focus placeholder="自动获取焦点" />

函数式指令

现在实现一个color指令:传入不同的颜色,给标签设置文字颜色

在绑定指令时:可以通过"等号"的形式为指令绑定具体的参数

javascript 复制代码
//自定义指令:v-color动态绑定colorStr变量
<div v-color="colorStr">Some Text</div>

通过binding.value可以拿到指令值,指令值的修改会触发 updated钩子

javascript 复制代码
//语法
app.directive('color',{
     //挂载后自动触发
     mounted(el,binding){},
     //数据更新,每次都会执行
     updated(el,bingding){}
})

使用自定义指令

javascript 复制代码
app.directive('color', {
  // 元素挂载到DOM时执行
  mounted(el, binding) {
    el.style.color = binding.value  // 设置文字颜色
  },
  // 组件更新时执行
  updated(el, binding) {
    el.style.color = binding.value  // 更新文字颜色
  }
})

//简化:函数式指令,当mounted 和 updated 逻辑相同
app.direvtive('color',(el,binding)={
    //mounted和updated都会调用
    el.style.color=binding.value
})

插槽(重点)

定义:允许开发者对组件的结构⾃定义;本质就是⼀个占位,使⽤组件的时候传⼊指定的标签结构,从⽽做⼀个替换。

把一部分可复用的表情前结构抽离出去成为一个单独的JS文件,使用插槽对原生位置进行占位,让组件可以像 HTML 标签一样灵活地嵌套内容!

默认(匿名)插槽

作用:让组件的部分结构支持自定义(定制结构)

使用:

  1. 组件内需要定制的结构部分,使用slot标签占位(先占位)
  2. 使用组件时,把组件写成双标签,包裹需要展示的标签结构,从而替换掉slot(后传入)

本质上: 默认插槽是组件内某⼀部分结构不确定,需要自定义完成某些内容,每部分的内容各不相同,所以默认插槽可以自定义组件内的结构内容

父组件:多个礼物盒子,每个盒子内部的礼物都不同

javascript 复制代码
<script setup>

</script>

<!-- 父组件:给盒子里放不同的礼物 -->
<template>
  <div>
    <!-- 放一本书 -->
    <Child>
      <p>📖 《Vue入门到精通》</p>
    </Child>
    
    <!-- 放一个玩具 -->
    <Child>
      <p>🧸 毛绒熊</p>
    </Child>
    
    <!-- 什么都不放,盒子就是空的 -->
    <Child></Child>

  </div>
</template>

子组件:表示每个礼物的盒子

javascript 复制代码
<!-- 子组件:Child - 礼物盒子 -->
<template>
  <div class="gift-box">
    <h3>🎁 礼物盒子()</h3>
    <!-- 这个 slot 就是盒子的开口,放什么礼物由你决定 -->
    <slot></slot>
  </div>
</template>

当未向第三个Child标签传入内容时,系统默认会显示空白值。为了避免空白显示,建议预先在slot中定义默认内容。

javascript 复制代码
<!-- 子组件:GiftBox.vue - 礼物盒子 -->
<template>
  <div class="gift-box">
    <h3>🎁 礼物盒子()</h3>
    <!-- 这个 slot 就是盒子的开口,放什么礼物由你决定 -->
    <slot>这个礼物是空的</slot>
  </div>
</template>

具名插槽

作用:⼀个组件内有多处结构,需要外部传⼊标签,进⾏⾃定义

使用:

  1. 多个slot,使用name属性区分
    <slot name=" 名字 "> 默认内容 </slot>
  2. template+#插槽名,来分发相应的标签结构
    <template #名字> 要展⽰的内容</template>
javascript 复制代码
<template>
  <div>
    <h1>具名插槽</h1>
    <Child>
      <!-- 放左边口袋 -->
    <template #left>
      📱 手机
    </template>
    
    <!-- 放右边口袋 -->
    <template #right>
      🔑 钥匙
    </template>

    <!-- 放中间口袋(默认插槽) -->
    💳 公交卡
    </Child>
  </div>
</template>

<script setup>
import Child from './Child.vue';
</script>
javascript 复制代码
<template>
  <div class="child-container">
    <!-- 左边口袋 -->
    <div class="left-pocket">
      <slot name="left"></slot>
    </div>
    
    <!-- 右边口袋 -->
    <div class="right-pocket">
      <slot name="right"></slot>
    </div>
    
    <!-- 默认口袋(如果没指定放哪,就放这) -->
    <div class="center-pocket">
      <slot></slot>
    </div>
  </div>
</template>

作用域插槽

作用:带数据的插槽, 可以让组件功能更强⼤、更灵活、复⽤性更⾼。⽤slot占位的同时,还可以给slot 绑定数据,将来使⽤组件时,不仅可以传内容,还能使⽤slot带来的数据

使用:

  1. 在 template 中,通过#插槽名="变量"接收,如果没有给slot取名,默认是default
  2. 给相应的slot标签添加自定义属性

父组件:自己点菜(使用数据)

javascript 复制代码
<template>
  <div>
    <!-- 客人1:爱吃鱼 -->
    <Child>
      <template #default="{ fish, meat, vegetable }">
        <p>我要吃:{{ fish }}刺身,{{ meat }}烤着吃,{{ vegetable }}炒着吃</p>
      </template>
    </Child>
    
    <!-- 客人2:素食主义者 -->
    <Child>
      <template #default="{ vegetable }">
        <p>我只要:清炒{{ vegetable }}</p>
      </template>
    </Child>
    
    <!-- 客人3:随便,就用默认做法 -->
    <Child/>
  </div>
</template>

<script setup>
import Child from './Child.vue';
</script>

子组件:提供材料(数据)

javascript 复制代码
<!-- 子组件:Restaurant.vue -->
<template>
  <div class="restaurant">
    <h3>🍽️ 今日推荐</h3>
    
    <!-- ✅ 正确:把数据通过 slot 传递出去 -->
    <slot :fish="fish" :meat="meat" :vegetable="vegetable">
      <!-- 默认内容 -->
      <p>炒{{ fish }}、{{ meat }}、{{ vegetable }}</p>
    </slot>
  </div>
</template>

<script setup>
import { ref } from 'vue'

// 厨房准备的食材
const fish = ref('三文鱼')
const meat = ref('牛肉')
const vegetable = ref('西兰花')
</script>

作用域插槽的关键是子组件要通过 slot 的 attribute 传递数据父组件要通过 #default 接收数据。

完结撒花!🎉

如果这篇博客对你有帮助,不妨点个赞支持一下吧!👍
你的鼓励是我创作的最大动力~

想获取更多干货? 欢迎关注我的专栏 → optimistic_chen

📌 收藏本文,下次需要时不迷路!

我们下期再见!💫 持续更新中......


悄悄说:点击主页有更多精彩内容哦~ 😊

相关推荐
Dxy12393102162 小时前
JS如何把数据添加到列表中
前端·javascript·vue.js
牛奶咖啡132 小时前
基于Cobbler的系统自动化安装部署——Cobbler的安装部署实践
linux·运维·服务器·cobbler·cobbler的安装配置·cobbler环境检查问题解决·cobbler中导入系统镜像
m0_502724952 小时前
Arco design vue 阻止弹窗关闭
javascript·vue.js·arco design
mounter6252 小时前
深度解析 RDMA 技术的里程碑:基于 DMA-BUF 的 P2P 直接访问(GPU Direct RDMA 新姿势)
linux·运维·服务器·网络·p2p·kernel
旭久2 小时前
web前端开发好物推荐-(code-inspector-plugin/react-dev-inspector)页面快捷定位代码位置
前端·react.js·前端框架
南山十一少2 小时前
docker的安装及使用
运维·docker·容器
Willliam_william2 小时前
CentOS 7系统中进行时间/时区设置
linux·运维·centos
李白的天不白2 小时前
linux安装MongoDB
linux·运维·服务器
嘉琪0012 小时前
Day8 完整学习包(Vue 基础 & 响应式)——2026 0320
前端·vue.js·学习