VUE动态组件,插槽和自定义指令

news2024/11/16 5:51:31

文章目录

  • 动态组件
    • 1.component组件的使用
      • -keep-alive的使用
        • keep-alive生命周期
        • 学习keep-alive组件的include和exclude属性
          • include(指定keep-alive的哪些组件可以被缓存,不指定的话默认所有都会被缓存)
        • exclude(排除项,与include刚好相反,二者不能同时使用)
  • 插槽
      • v-slot指令
        • v-slot的简写形式
        • 当插槽没有被指定具体内容时,指定一个默认内容
      • 具名插槽的定义和使用
      • 作用域插槽的基本用法
      • 作用域插槽的解构赋值
  • 自定义指令
      • 私有自定义指令的声明
        • 效果图
        • 使用binding.value获取指令绑定的值
        • update函数
        • 自定义指令的简写形式
      • 全局自定义指令的声明

动态组件

1.component组件的使用

1.什么是动态组件?动态组件就是指的是动态切换组件的显示和隐藏

在这里插入图片描述
可以把component理解为一个占位符,专门为组件占位,需要展示哪个组件,就给component指定组件的名称即可
如下:
在这里插入图片描述
在这里插入图片描述
但此时会发现上面的值是写死的,下面代码案例就可以实现动态绑定了

在这里插入图片描述

<template>
  <div class="app-container">
    <h1>App 根组件</h1>
    <hr />
    <button @click="comName='left'">展示Left</button>
    <button @click="comName='right'">展示Right</button>
    <div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <!-- <left></left>
      <right></right> -->
      <keep-alive>
        <component :is='comName'></component>
      </keep-alive>
    </div>
  </div>
</template>

<script>
import left from '@/components/Left.vue'
import right from '@/components/Right.vue'
export default {
  data(){
    return{
      comName:'right'
    }
  },
  components:{
    left,
    right
  }
}
</script>

<style lang="less">
.app-container {
  padding: 1px 20px 20px;
  background-color: #efefef;
}
.box {
  display: flex;
}
</style>

-keep-alive的使用

当在left组件定义个按钮,让其值自增1,初始值为0,当加到某一值时,切换right组件,再切换回来,就会发现left值又回到了初始值,如下:

初始值为0,加到了18
在这里插入图片描述
点击切换到right组件
在这里插入图片描述
再点回来left组件
在这里插入图片描述
可以发现left组件切换后回到了初始值,保存不了数据(即每次切换组件都是组件重新渲染了,就是组件创建–销毁—创建–销毁的过程)
可以通过-keep-alive解决这个问题(就是保持组件的状态)

<div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <!-- <left></left>
      <right></right> -->
      <keep-alive>
        <component :is='comName'></component>
      </keep-alive>
    </div>

keep-alive可以把内部的组件进行缓存,而不是销毁组件
使用-keep-alive包裹要保持状态的组件即可(用vue调试工具可以查看left组件每次切换没有被销毁重新创建,而是变灰了,等重新切换回来就正常了(组件被缓存到内存了),同理right组件也是灰了,然后二者就不会重复销毁—创建—销毁—创建了)
在这里插入图片描述
然后刷新网页,问题成功解决

keep-alive生命周期

当组件被缓存时,会自动触发组件的deactivated生命周期函数。
当组件被激活时,会自动触发组件的activated生命周期函数。

<script>
export default {
  activated(){
    console.log("组件被激活了,activated");
  },
  destroyed(){
    console.log("组件被销毁了");
  },
  deactivated(){
    console.log("组件被缓存了");
  },
  data(){
    return {
      count:0
    }
  }
}
</script>

每次切换left组件控制台的打印
在这里插入图片描述

学习keep-alive组件的include和exclude属性

include(指定keep-alive的哪些组件可以被缓存,不指定的话默认所有都会被缓存)

下面演示left组件会被缓存,right组件不用被缓存的示例

	  <keep-alive include="left">//指定left组件被缓存
        <component :is='comName'></component>
      </keep-alive>

在这里插入图片描述
在这里插入图片描述
left组件被缓存了,right组件创建—销毁—创建—销毁状态

下面演示多个组件需要被缓存,因为我这就left和right,没有更多的,因此就指定这两个

	  <keep-alive include="left,right">//指定组件名称,多个组件用逗号分割
        <component :is='comName'></component>
      </keep-alive>

exclude(排除项,与include刚好相反,二者不能同时使用)

下面演示left组件会被缓存,right组件不用被缓存的示例

	  <keep-alive exclude="right">//指定right组件不被缓存
        <component :is='comName'></component>
      </keep-alive>

当组件向外导出提供了name值如下
在这里插入图片描述
那上面的排除和包含项的具体名字不再使用注册提供的名称了,要以组件自己提供的name值为准,注册名还是以标签形式展现到页面使用

插槽

插槽(Slot)是vue为组件的封装者提供的能力。允许开发者在封装组件时,把不确定的、希望由用户指定的部分定义为插槽。可以把插槽认为是组件封装期间,为用户预留的内容的占位符。

在这里插入图片描述
在left组件定义个插槽
在这里插入图片描述
在App父组件使用插槽显示内容
在这里插入图片描述
显示效果
在这里插入图片描述
简单来说,插槽就是相当于子组件给父组件定义的注册名标签内的内容占位置

v-slot指令

vue官方规定:每个插槽都有一个name属性,来指定当前插槽的名称,默认不写的话相当于name=“default”
默认情况下,使用组件的时候,提供的内容都会放到名字为default的插槽之中,例如上面的p标签默认放到default插槽内

<slot name="default"></slot>

v-slot只能加给组件或者template标签,其他不可用(不能直接用在元素上),因此使用方式如下

<div class="box">
      <!-- 渲染 Left 组件和 Right 组件 -->
      <left>
      //使用template标签接收v-slot指令
      //如果要把内容填充到指定名称的插槽中,需要使用v-slot:这个指令
      //':'后面的为引用的组件的slot标签的name属性值,默认为default
      //这里的template标签只起到包裹的作用,不会被渲染成真实的html元素,可以浏览器控制台查看标签源代码,可以发现并没有template
        <template v-slot:default>
          <p>left组件的内容区域</p>
        </template>
      </left>
    </div>

v-slot的简写形式

简写: 例如插槽name属性为default,那么简写为 #default

当插槽没有被指定具体内容时,指定一个默认内容

在这里插入图片描述
直接在插槽内直接写就可以
效果图:
在这里插入图片描述

具名插槽的定义和使用

如果在封装组件时需要预留多个插槽节点,则需要为每个插槽指定具体的name 名称。这种带有具体名称的插槽叫做“具名插槽”。示例代码如下:
注意:没有指定name名称的插槽,会有隐含的名称叫做’'default"。
新建个active.vue文件,内容如下:(在这段代码定义了三个插槽,分别为标题,内容,作者)

<template>
    <div class="active-container">
        <!-- 文章标题 -->
        <div class="header-box">
            <slot name="title"></slot>
        </div>
        <!-- 文章内容 -->
        <div class="content-box">
            <slot name="body"></slot>
        </div>
        <!-- 文章作者 -->
        <div class="footer-box">
            <slot name="zuozhe"></slot>
        </div>
    </div>
</template>

<script>
export default {
    name: 'Active'
}
</script>

<style lang="less" scoped>
    .active-container{
        >div{
            min-height: 150px;
        }
        .header-box{
            background-color: pink;
        }
        .content-box{
            background-color: lightblue;
        }
        .footer-box{
            background-color: lightsalmon;
        }
    }
</style>

下面代码为App.vue使用部分

<active>
      <template #title>
        <h1>我是标题部分</h1>
      </template>
      <template #body>
        <h1>我是内容部分</h1>
      </template>
      <template #zuozhe>
        <h1>我是作者部分</h1>
      </template>
    </active>

最终效果:
在这里插入图片描述

作用域插槽的基本用法

在插槽定义时同时可以传递一些数据
在子组件中,定义插槽,同时携带数据,如下:(在上个代码作者里面改动的)

<!-- 文章作者 -->
        <div class="footer-box">
            <slot name="zuozhe" msg="xiaoji 牛逼"></slot>//msg为携带的数据(这个属性是随便定义的,也可以定义别的或多个)
        </div>

在父组件中接收展示

	<template #zuozhe="obj">//obj为形参,随便填写,为了接收子组件插槽的msg的数据
        <h1>我是作者部分</h1>
        {{ obj }}//可以通过打点访问里面的属性
      </template>

效果图:
在这里插入图片描述
在封装组件时,为预留的提供属性对应的值,简单来说就是带数据的插槽,这种用法就叫做’作用域插槽’

作用域插槽的解构赋值

还是参照上面的代码将obj解构赋值
在父组件中接收展示

	<template #zuozhe="{msg}">//obj为形参,随便填写,为了接收子组件插槽的msg的数据,接收多个数据的结构赋值用逗号分割
        <h1>我是作者部分</h1>
        {{ msg}}//可以通过打点访问里面的属性
      </template>

效果图:
在这里插入图片描述

自定义指令

vue中的自定义指令分为两类,分别是:
私有自定义指令
全局自定义指令

私有自定义指令的声明

在每个vue 组件中,可以在directives节点下声明私有自定义指令。
需求:定义v-color指令,当元素绑定到此指令时,元素内的颜色会变成红色
代码如下:

export default {
  components: { 
    left,
    active
  },
  // 私有自定义指令的节点
  directives:{
    //定义v-color指令,为绑定到的HTML元素设置红色的文字
    //定义名为color的指令,指向一个配置对象(空对象时,到这里v-color就可以用了(不会报错了),只是没做操作)
    color:{
      //业务逻辑
      //当这个v-color指令第一次被绑定元素身上时就会立即触发bind函数
      bind(el){
        // 形参中的el 是绑定了此指令的、原生的 DOM对象
        console.log(el,1);
        el.style.color='red'
      }
    }
  }
}

在这里插入图片描述

效果图

在这里插入图片描述

使用binding.value获取指令绑定的值

//定义数据节点和自定义指令节点
 data(){
    return {
      color:'blue'
    }
  },
  // 私有自定义指令的节点
  directives:{
    //定义v-color指令,为绑定到的HTML元素设置红色的文字
    //定义名为color的指令,指向一个配置对象(空对象时,到这里v-color就可以用了(不会报错了),只是没做操作)
    color:{
      //业务逻辑
      //当这个v-color指令第一次被绑定元素身上时就会立即触发bind函数
      bind(el,binding){
        // 形参中的el 是绑定了此指令的、原生的 DOM对象
        console.log(el,1);
        console.log(binding)
        el.style.color=binding.value
      }
    }
  },

给v-color绑定数据节点的颜色数据

<h1 v-color="color">App 根组件</h1>

先定义一个数据节点存放颜色,然后为元素绑定数据触发bind方法,打印bind方法的第二个形参,结果如下,可以发现数据的键为value,通过此参数动态改变颜色数据
在这里插入图片描述
效果图:
在这里插入图片描述
也可以不声明data数据节点,可以直接声明数据,通过以下代码可以动态去设置自己想要的值,切记一定要用单引号,不然会当成data数据去data去找了,代码如下:
这种方式是自己赋值,不是通过data数据获取的

<h1 v-color="'yellow'">App 根组件</h1>
<h1 v-color="'orange'">App 根组件</h1>
<h1 v-color="'pink'">App 根组件</h1>

这是再打印bind的第二个参数,会发现里面有个数据expression 之前的值为color,通过我们自己传值变成了我们自己传的值,而不是color了
expression 这个值为我们v-color=" ",为这个双引号的里面的值,我们真正的值在value里面存放,expression 代表我们自己传的值

update函数

bind指令只在第一次绑定时才出发,例如定一个按钮,点击按钮改变颜色数据,此时不会触发bind函数,这时候就需要update函数了

在这里插入图片描述

自定义指令的简写形式

如果bind和update函数中的逻辑完全相同,则对象格式的自定义指令可以简写成函数格式:

 directives:{
    color(el,binding){
        // 在bind和update时,会触发相同的业务逻辑
        console.log(el,1);
        console.log(binding)
        el.style.color=binding.value
      }
  },

全局自定义指令的声明

全局共享的自定义指令需要在main.js通过“Vue.directive()”进行声明,示例代码如下:

//全写
Vue.directive('color',{
	bind(el,binding){
		el.style.color=binding.value
	},
	update(el,binding){
		el.style.color=binding.value
	}
})

//简写
//参数一:字符串,表示全局自定义指令的名字
//参数二:对象,用来接收指令的参数值
Vue.directive('color',function(el,binding){
	el.style.color=binding.value
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/134360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NodeJS - Express使用

文章目录1. 参数1.1 获取URL中的动态参数2. 静态资源2.1 挂载路径前缀3. nodemon4.1路由4.1 路由的匹配过程4.2 模块化路由4.3 为路由模块添加前缀5. 中间件5.1 全局生效的中间件5.2 全局生效中间件的简化形式5.3 中间件的作用5.4 局部生效的中间件5.5 定义多个局部中间件5.6 使…

计算机xxxxxxx

文章目录1.互联网的两大组成部分&#xff08;边缘部分与核心部分&#xff09;的特点是什么&#xff1f;它们的工作方式各有什么特点&#xff1f;2.简述分组交换的要点。3.试从多个方面比较电路交换、报文交换和分组交换的主要优缺点。4.网络协议的三个要素是什么&#xff1f;各…

十二、生产者和消费者问题、队列、线程池

内容 理解消费者、生产者的案例执行过程&#xff0c; 理解用队列方式做消费者、生产者的案例 会使用线程池运行任务, 理解ThreadPoolExecutor7个参数的含义&#xff08;会根据需要 通过参数控制线程池的总数量&#xff09; 匿名内部类里的异常处理 Thread 使用匿名内部类…

VScode中不同目录间python库函数的调用

问题描述 vscode中跨目录的模块调用远不如pycharm中的来的简单&#xff0c;在pycharm中即使是不同库文件夹中子函数也可以进行互相调用。而在VScode中则需要我们手动向其中添加依赖路径。如下相同的文件结构&#xff0c;在pycharm中可以简单的在model_arc_pesudo中导入model中的…

HTTP传输过程

简介 HTTPS是在HTTP的基础上和ssl/tls证书结合起来的一种协议,保证了传输过程中的安全性,减少了被恶意劫持的可能.很好的解决了解决了http的三个缺点&#xff08;被监听、被篡改、被伪装&#xff09; 对称加密和非对称加密 对称加密 即加密的密钥和解密的密钥相同, 非对称加…

1801. 积压订单中的订单总数

插&#xff1a; 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 坚持不懈&#xff0c;越努力越幸运&#xff0c;大家一起学习鸭~~~ 题目&#xff1a; 给你一个二维整数数组 orders &…

【HTMLCSS】运维、后端你该会的前端基本内容

文章目录前言一、HTML5基础1.1、前端开发的核心技术1.2、Web组成标准1.3、HTML 实例1.3.1、第一个网页1.4、 文本标签1.5、转义字符1.6、图片1.7、超链接1.8、列表1.8.1、无序列表1.8.2、有序列表1.8.3、自定义列表1.9、表格1.9.1、合并单元格1.10、表单二、CSS基础2.1、入门2.…

【论文导读】Stable Learning via Sparse Variable Independence

准备follow一下稳定学习的系列论文&#xff0c;从这篇开始吧。 AAAI2023上的&#xff0c;主要是根据前几年稳定学习组提出的SV特征分类、关注稳定的S特征的样本重加权的优化 针对问题和措施&#xff1a; 稳定学习算法采用的样本重加权有弊端&#xff1a; 1&#xff0c;在有限…

ESP8266 SDK开发之AiThinkerIDE_V1.5.2安装、配置以及编写一个程序

【本文发布于https://blog.csdn.net/Stack_/article/details/128509864&#xff0c;未经允许不得转载&#xff0c;转载须注明出处】 前言 乐鑫官方不搞IDE&#xff0c;安信可搞了IDE&#xff0c;但是各版本之间安装配置有差异&#xff0c;还没有文档说明。官方安装配置教程不完…

IEEE论文投稿流程

转载文章 这是篇节省你翻论坛、查资料的文章。 我将把每一步尽量写的清楚&#xff0c;能够让新手按照这篇文章进行完整的投稿。 即使你从未投过稿&#xff0c;完全不了解IEEE的投稿流程&#xff0c;希望按照这篇文章&#xff0c;能够帮助你流畅无误的投稿 这是针对本科生和低年…

springboot整合springcloud之nacos配置中心

整合配置中心nacos 应用场景&#xff0c;每次改配置要重新启动才能生效&#xff0c;而把配置放到nacos上&#xff0c;如有修改&#xff0c;那么发布后项目自动就生效了。 场景2&#xff1a;不同微服务单独设置一个命名空间。 一、项目操作 1.引入依赖 <!--使用spring-cloud…

JDBC---Maven之jdbc连接数据库

Maven之jdbc连接数据库 这里需提前将maven环境配置好 链接: Maven环境配置 文章目录Maven之jdbc连接数据库JDBC创建Maven工程JDBC访问数据库步骤1.Class.forName()加载驱动2.DriverManager获取Connection连接3.创建Statement执行SQL语句4.返回ResultSet查询结果()5.释放资源JD…

vsmoon靶场实战笔记

vsmoon靶场实战笔记 web打点 信息收集 nmap扫描端口 扫描结果 └─$ nmap -sV -A 192.168.1.106 -Pn Starting Nmap 7.92 ( https://nmap.org ) at 2023-01-01 12:51 CST Nmap scan report for 192.168.1.106 Host is up (0.00014s latency). Not shown: 986 closed tcp p…

YOLOv5更换骨干网络之 GhostNet

论文地址&#xff1a;https://arxiv.org/abs/1911.11907 代码地址&#xff1a;https://github.com/huawei-noah/ghostnet 由于内存和计算资源有限&#xff0c;在嵌入式设备上部署卷积神经网络&#xff08;CNN&#xff09;很困难。特征图中的冗余是那些成功的神经网络的重要特征…

年度征文 | 回顾2022,展望2023(我难忘的2022,我憧憬的2023)

个人简介 &#x1f440;个人主页&#xff1a; 前端杂货铺 &#x1f64b;‍♂️学习方向&#xff1a; 主攻前端方向&#xff0c;也会涉及到服务端 &#x1f4c3;个人状态&#xff1a; 在校大学生一枚&#xff0c;已拿多个前端 offer&#xff08;秋招&#xff09; &#x1f680;未…

用javascript分类刷leetcode7.双指针(图文视频讲解)

双指针 普通指针&#xff1a;两指针同一方向或不同方向对撞指针&#xff1a;两指针互相靠拢快慢指针&#xff1a;一快一慢 141. 环形链表 (easy) 给你一个链表的头节点 head &#xff0c;判断链表中是否有环。 如果链表中有某个节点&#xff0c;可以通过连续跟踪 next 指针再…

LeetCode字符串经典题目(四)

1. LeetCode344. 反转字符串 2. LeetCode541. 反转字符串 II 3. LeetCode剑指 Offer 05. 替换空格 4. LeetCode151. 反转字符串中的单词 5. LeetCode剑指 Offer 58 - II. 左旋转字符串 6. LeetCode28. 找出字符串中第一个匹配项的下标​ 7. LeetCode459. 重复的子字符串​…

Mac内存空间不足如何释放储存空间?深度清理Mac磁盘空间的方法教程

今日coco玛奇朵将分享一些能够释放大量Mac内存空间的方法&#xff0c;以便大家能够优化Mac的运行速度外还能规避由于Mac空间不足而导致安装Ventura时出现的一系列问题。 大家都知道更新Macos都需要预备非常大的内存空间才能进行&#xff0c;当更新完Macos之后都会留下大量的备…

台大应用深度学习笔记

deep learning end-to-end training 1. 神经元 1.1 为什么需要bias&#xff1f; 为了给对应位置一个prior&#xff0c;给它一个初始值&#xff0c;b越大&#xff0c;σ(z)11e−z\sigma(z) \frac{1}{1e^{-z}}σ(z)1e−z1​越大&#xff0c;越趋向于1. 多层神经网络&#xff…

安装Windows和Ubuntu双系统

制作Ubuntu安装盘在Windows上查看磁盘格式 不同的磁盘格式&#xff0c;需要跟BIOS里面不同的引导模式配合来启动操作系统&#xff0c;如下图&#xff1a; 我的电脑是GPT格式&#xff1a; 准备好给Ubuntu的磁盘空间 在Windows系统中&#xff0c;在一个200G的清空数据的磁盘上…