vue组件($refs对象,动态组件,插槽,自定义指令)
一、ref
1.ref引用
每个vue组件实例上,都包含一个$refs对象,里面存储着对应dom元素或组件的引用。默认情况下,组件的$refs指向一个空对象。
2.使用ref获取dom元素的引用
<template><h3 ref="myh3">ref组件</h3><button @click="getRef">getRef</button>
</template>
<script>
export default{methods:{getRef(){console.log('this',this.$refs);this.$refs.myh3.style.color='red'}}
}
</script>
3.使用ref引用组件实例
<template><MyIndex ref="myIndexRef"></MyIndex><button @click="getRef">getRef</button>
</template>
<script>
import MyIndex from './index copy.vue';
export default{components:{MyIndex},methods:{getRef(){console.log('this',this.$refs);this.$refs.myIndexRef.reset()}}
}
</script><template><div>{{count}}<button @click="this.count+=1">按钮</button></div>
</template>
<script>
export default{data(){return{count:1}},methods:{reset(){this.count=0}}
}
</script>
4.控制文本框和按钮的按需切换
<template><input type="text" v-if="inputVisible" ref="ipt"><button v-else @click="showInput">getRef</button>
</template>
<script>
export default{data(){return{inputVisible:false}},methods:{showInput(){this.inputVisible=true;//获取文本框的引用对象,访问的ipt是undefind,dom更新是异步的,拿不到最新domthis.$nextTick(()=>{this.$refs.ipt.focus();})}}
}
</script>
5.组件是异步执行dom更新的
6.this.$nextTick(cb)
组件的$nextTick(cb)方法,会把cb回调推迟到下一个dom更新周期之后执行。简单理解:等组件的dom异步地重新渲染完成后,再执行cb回调函数。从而能保证cb回调函数可以操作到最新的dom元素。
二、动态组件
1.什么是动态组件
动态组件时动态切换组建的显示与隐藏。vue提供了一个<component>组件,专门用来实现组件的动态渲染。
a.<component>是组件的占位符
b.通过is属性动态指定要渲染的组件名称
c.<component is="要渲染的组件名称"></component>
2.如何实现动态组件渲染
<template><button @click="comName='Home'">首页</button><button @click="comName='Movie'">电影</button><hr><component :is='comName'></component>
</template>
<script>
import Home from './home.vue'
import Movie from './movie.vue'
export default{components:{Home,Movie},data(){return{comName:'Home'}}
}
</script>
3.使用keep-alive保持组件的状态
默认情况下,动态切换组件时无法保持组件的状态。可以使用vue内置的<keep-alive>组件保持动态组件的状态。
<template><button @click="comName='Home'">首页</button><button @click="comName='Movie'">电影</button><hr><keep-alive><component :is='comName'></component></keep-alive>
</template>
<script>
import Home from './home.vue'
import Movie from './movie.vue'
export default{components:{Home,Movie},data(){return{comName:'Home'}}
}
</script><template><div>Home组件{{ count }}<button @click="count+=1">+1</button></div>
</template>
<script>
export default{data(){return{count:1}},created(){console.log('created');},unmounted(){console.log('unmounted');},
}
</script>
三、插槽
1.什么是插槽
插槽是vue组件为组件的封装者提供的能力。允许开发者在封装组件时,把不确定、希望由用户指定的部分定义为插槽。
可以把插槽认为是组件封装期间,为用户预留的内容占位符。
没有预留插槽的内容会被丢弃
<template><Home><p>-------------</p></Home>
</template>
<script>
import Home from './home.vue'
export default{components:{Home},
}
</script><template><div>Home组件<p>p1p1p1p1p1p1p1p1p1p1p1p1p1</p><slot></slot><p>p2p2p2p2p2p2p2p2p2p2p2p2p2</p></div>
</template>
2.后备内容(默认内容)
封装组件时,可以为预留的<slot>插槽提供后备内容(默认内容)。如果组件的使用者没有为插槽提供任何内容,则后备内容会生效。
<template><Home><!-- <p>-------------</p> --></Home>
</template>
<script>
import Home from './home.vue'
export default{components:{Home},
}
</script><template><div>Home组件<p>p1p1p1p1p1p1p1p1p1p1p1p1p1</p><slot>默认xxxxxxxx</slot><p>p2p2p2p2p2p2p2p2p2p2p2p2p2</p></div>
</template>
3.具名插槽
如果在封装组件时需要预留多个插槽节点,则需要为每个<slot>插槽指定具体的name名称。这种带有具体名称的插槽叫做“具名插槽”。
v-slot:可以简写为字符#
<template><Home><!-- v-slot:可简写为# --><template v-slot:header>头部</template><p>-------------</p><template #footer>底部</template></Home>
</template>
<script>
import Home from './home.vue'
export default{components:{Home},
}
</script><template><div>Home组件<slot name="header"></slot><slot>默认xxxxxxxx</slot><slot name="footer"></slot></div>
</template>
4.作用域插槽
在封装组件的过程中,可以为预留的<slot>插槽绑定props数据,这种带有props数据的<slot>插槽叫做作用域插槽。
<template><Home><template v-slot:default="scope">{{ scope }}{{ scope.info.name }}</template></Home>
</template>
<script>
import Home from './home.vue'
export default{components:{Home},
}
</script><template><div>Home组件<slot :info="infomation" :msg="msg"></slot></div>
</template>
<script>
export default{data(){return{infomation:{name:'zs',age:18},msg:'123'}}
}
</script>
解构作用域插槽
<template><Home><template #default="{info,msg}">{{ info.name }}{{ info.age }}{{ msg }}</template></Home>
</template>
<script>
import Home from './home.vue'
export default{components:{Home},
}
</script>
作用域插槽的使用场景
<template><Home><template #default="{user}"><td>{{user.name}}</td><td>{{ user.age }}</td><td><input type="checkbox" :checked="user.state"></td></template></Home>
</template>
<script>
import Home from './home.vue'
export default{components:{Home},
}
</script><template><div>Home组件<table><tr><td>名字</td><td>年龄</td><td>状态</td></tr><tr v-for="item in list" :key="item"><slot :user="item"></slot></tr></table></div>
</template>
<script>
export default{data(){return{list:[{name:'zs1',age:18,state:true},{name:'zs2',age:17,state:false},{name:'zs3',age:15,state:true}],}}
}
</script>
四、自定义指令
vue 中自定义指令分为两类:私有自定义指令,全局自定义指令。
在每个vue组件中,可以在directives节点下声明私有自定义指令。
1.私有自定义指令
<template><input type="text" v-focus>
</template>
<script>
export default{directives:{focus:{//当被绑定的元素插入到dom中时,会自定触发mounted函数mounted(el){el.focus()//让被绑定的元素自动获取焦点}}}
}
</script>
2.全局自定义指令
在main.js文件中声明自定义指令
const app = createApp(App)
app.directive('focus',{mounted(el){el.focus()}
})
3.updated函数
mounted函数只在元素第一次插入dom时被调用,当dom更新时mounted函数不会被触发。updated函数会在每次dom更新后被调用。
<template><input type="text" v-focus>{{ count }}<button @click="count+=1">+1</button>
</template>
<script>
export default{data(){return{count:1}}
}
</script>//main.jsmain.js
const app = createApp(App)
app.directive('focus',{mounted(el){el.focus()},updated(el){el.focus()}
})
在vue2的项目中使用自定义指令时,mounted->bind,updated->update
如果mounted,updated函数中的逻辑完全相同,可以简写
const app = createApp(App)
app.directive('focus',(el)=>{el.focus()
})
4.指令的参数值
在绑定指令时,可以通过等号的形式为指令绑定具体的参数值。binding.value
<template><input type="text" v-model.number="count" v-focus v-color="'red'"><p v-color="'green'">{{ count }}</p><button @click="count+=1">+1</button>
</template>
<script>
import Home from './home.vue'
export default{components:{Home},data(){return{count:1}}
}
</script>//main.js
const app = createApp(App)
app.directive('focus',(el)=>{el.focus()
})
app.directive('color',(el,binding)=>{el.style.color=binding.value
})
五、Table案例
1.搭建项目基本结构
npm create vite
cd vite-project
npm install
2.请求商品列表数据
npm i axios
//main.js
import axios from 'axios'
//配置请求的根路径
axios.defaults.baseURL='http://localhost:3000'
//将axios挂载为全局的$http自定义属性
app.config.globalProperties.$http=axios
3.封装MyTable组件
a.通过props属性,为MyTable.vue组件指定数据源
b.在MyTable.vue组件中,预留header的具名插槽
c.在MyTable.vue组件中,预留body的作用域插槽
<template><table><thead><slot name="header"></slot></thead><tbody><tr v-for="(item,index) in data" :key="item"><slot name="body" :row="item" :index="index"></slot></tr></tbody></table>
</template>
<script>
export default{props:{data:{type:Array,default:[],require:true}}
}
</script>
4.实现删除功能
5.实现添加标签的功能
a.实现input和button的按需展示(v-if,v-else)
b.让input自动获取焦点(自定义指令)
c.文本框失去焦点自动隐藏
d.文本框的enter,esc按键事件
把用户在文本框中输入的值,预先转存到常量val中,清空文本的值,v-if='false'隐藏文本框
判断val的值是否为空,如果为空,则不进行添加,
判断val的值是否已经存在于数组中,如果存在,则不进行添加,return
将用户输入的内容,作为新标签push到当前tag数组中
<template><MyTable :data="goodsList"><template #header><td>#</td><td>商品名称</td><td>价格</td><td>标签</td><td>操作</td></template> <template #body="{row,index}"><td>{{index+1}}</td><td>{{ row.title }}</td><td>¥{{ row.price }}</td><td><inputv-if="row.inputVisible"ref="InputRef"v-model.trim="row.inputValue"class="ml-1 w-20"@keyup.enter="handleInputConfirm(row)"@blur="handleInputConfirm(row)"@keyup.esc="row.inputValue=''"v-focus/><el-button v-else class="button-new-tag ml-1" size="small" @click="row.inputVisible = true">+Tag</el-button><el-tag class="ml-2" type="success" v-for="item in row.tag" :key="item">{{ item }}</el-tag></td><td><el-button type="danger" @click="deleteFn(row.id)">删除</el-button></td></template></MyTable>
</template>
<script>
import MyTable from './MyTable.vue'
export default{components:{MyTable},data(){return{goodsList:[]}},methods:{async getGoodsList(){const {data:res}=await this.$http.get('/goodsList')console.log('res',res);this.goodsList = res.map(item=>{return{...item,inputVisible:false,inputValue:''}})},deleteFn(id){this.goodsList = this.goodsList.filter(item=>item.id!==id)},handleInputConfirm(row){const val = row.inputValue;row.inputValue = '';row.inputVisible = false;if(!val||row.tag.indexOf(val) !==-1)returnrow.tag.push(val)},},created(){this.getGoodsList()},directives:{focus(el){el.focus()}}
}
</script>
相关文章:

vue组件($refs对象,动态组件,插槽,自定义指令)
一、ref 1.ref引用 每个vue组件实例上,都包含一个$refs对象,里面存储着对应dom元素或组件的引用。默认情况下,组件的$refs指向一个空对象。 2.使用ref获取dom元素的引用 <template><h3 ref"myh3">ref组件</h3&g…...

构建高可用和高防御力的云服务架构第五部分:PolarDB(5/5)
引言 云计算与数据库服务 云计算作为一种革命性的技术,已经深刻改变了信息技术行业的面貌。它通过提供按需分配的计算资源,使得数据存储、处理和分析变得更加灵活和高效。在云计算的众多服务中,数据库服务扮演着核心角色。数据库服务不仅负…...

QT窗口无法激活弹出问题排查记录
问题背景 问题环境 操作系统: 银河麒麟V10SP1qt版本 : 5.12.12 碰见了一个问题应用最小化,然后激活程序窗口无法弹出 这里描述一下代码的逻辑,使用QLocalServer实现一个单例进程,具体的功能就是在已存在一个程序A进程时,再启动这个程序A,新的程序A进程会被杀死,然后激活已存…...
node.js 版本管理
在Node.js开发中,版本管理是一个非常重要的环节,特别是当你需要同时维护多个项目,而这些项目又依赖于不同版本的Node.js时。以下是一些常用的Node.js版本管理工具和方法: 1. NVM (Node Version Manager) NVM是Node.js版本管理的…...
使用Python实现图形学曲线和曲面的NURBS算法
目录 使用Python实现图形学曲线和曲面的NURBS算法引言NURBS曲线的数学原理1. NURBS曲线定义2. 权重的作用 NURBS曲线的Python实现1. 类结构设计2. 代码实现3. 代码详解使用示例 NURBS曲面的扩展NURBS曲面类实现 总结 使用Python实现图形学曲线和曲面的NURBS算法 引言 NURBS&a…...
SpringBoot3
文章目录 一、为什么要学习SpringBoot二、SpringBoot介绍2.1 约定优于配置2.2 SpringBoot中的约定三、SpringBoot快速入门3.1 快速构建SpringBoot3.1.1 选择构建项目的类型3.1.2 项目的描述3.1.3 指定SpringBoot版本和需要的依赖3.1.4 导入依赖3.1.5 编写了Controller3.1.6 测试…...
【Text2SQL】领域优质论文分享
解读论文:Enhancing Few-shot Text-to-SQL Capabilities of Large Language Models: A Study on Prompt Design Strategies 1. 重要贡献 这篇论文的主要贡献在于提出了一种新的方法来增强大型语言模型(LLMs)在少量样本(Few-shot…...

2024全国研究生数学建模竞赛(数学建模研赛)ABCDEF题深度建模+全解全析+完整文章
全国研究生数学建模竞赛(数学建模研赛)于9月21日8时正式开赛,赛程4天半,咱这边会在开赛后第一时间给出对今年的6道赛题的评价、分析和解答。包括ABCDEF题深度建模全解全析完整文章,详情可以点击底部的卡片来获取哦。 …...
Java项目中异常处理的最佳实践
1. 异常分类 首先,理解异常的不同类型是合理处理异常的基础。Java中的异常大致可以分为两大类: 受检异常(Checked Exceptions):这些异常必须被捕获或声明抛出,例如IOException。非受检异常(Un…...
CSS基本概念以及CSS的多种引入方式
CSS基本概念 CSS是层叠样式表,又叫级联样式表,简称样式表。CSS的文件后缀为.css,CSS用于HTML文档中元素样式的定义。 CSS的基本语法 CSS的规则由2个主要的部分构成:选择器以及一条或者多条声明。 选测器通常是你血药改变样式的…...
TiDB 简单集群部署拓扑文件
TiDB集群部署 服务器环境部署拓扑 都2024了还在为分库分表烦恼吗😘,用分布式数据库TiDB、OceanBase、华为 GaussDB,你就使劲往里存数据。 早下班、少脱发、脱单! 🙏🏻🙏🏻Ƕ…...

十三 系统架构设计(考点篇)
1 软件架构的概念 一个程序和计算系统软件体系结构是指系统的一个或者多个结构。结构中包括软件的构件,构件 的外部可见属性以及它们之间的相互关系。 体系结构并非可运行软件。确切地说,它是一种表达,使软件工程师能够: (1)分…...

Java-数据结构-二叉树-习题(三)  ̄へ ̄
文本目录: ❄️一、习题一(前序遍历非递归): ▶ 思路: ▶ 代码: ❄️二、习题二(中序遍历非递归): ▶ 思路: ▶ 代码: ❄️三、习题三(后序遍历非递归): ▶ 思路: …...

SpringBoot+Aop+注解方式 实现多数据源动态切换
整体思路: 引入基本依赖SpringBootAopMySqlMyBatislombok在配置文件中配置多个数据源创建数据源配置类用于读取配置编写用于标识切换数据源的注解创建数据源切换工具类DataSourceContextHolder编写切面类用于在注解生效处切换数据源编写配置类,加载数据…...

企业如何高效应对多类型知识产权事务的复杂挑战?
随着企业的发展和创新活动的不断推进,越来越多的企业拥有了大量的专利、商标和软著等知识产权,这些不仅关乎企业的技术创新成果,更直接影响到企业的品牌价值和市场竞争力。然而,当企业拥有多件知识产权时,复杂的申请、…...

openeuler22.03 LTS 源码编译安装nginx1.22.1
openeuler22.03 LTS 源码编译安装nginx1.22.1 下载安装包 #官网下载nginx1.22.1 wget http://nginx.org/download/nginx-1.22.1.tar.gz安装依赖包 #安装依赖包,NGINX是C语言写的,pcre-devel支持正则表达式,openssl 开启加密 [rootproxy ~]…...

图片压缩工具免费怎么找?归纳了这几个压缩工具
有哪些图片压缩工具免费?在数字化时代,图像已成为我们生活中不可或缺的一部分。无论是网站设计、社交媒体分享还是文件传输,高质量的图片都扮演着重要的角色。但高质量往往意味着大文件体积,这可能会导致加载速度变慢或存储空间不…...

【Kubernetes知识点】解读HPA的 thrashing(抖动)问题
【Kubernetes知识点】解读HPA的 thrashing(抖动)问题 目录 1 概念 1.1 什么是 Thrashing 现象?1.2 HPA 中 Thrashing 产生的原因1.3 解决 Thrashing 的优化措施 1.3.1 设置合适的阈值1.3.2 使用自定义指标和基于负载的自动扩缩1.3.3 增加扩…...

Unity 设计模式 之 结构型模式 -【装饰者模式】【外观模式】【享元模式】【代理模式】
Unity 设计模式 之 结构型模式 -【装饰者模式】【外观模式】【享元模式】【代理模式】 目录 Unity 设计模式 之 结构型模式 -【装饰者模式】【外观模式】【享元模式】【代理模式】 一、简单介绍 二、装饰者模式(Decorator Pattern) 1、什么时候使用装…...

Linux上Qt安装相关的内容及在QtCreator使用QChart模块需要的配置
引言 下面是Ubuntu上Qt安装相关的内容及在QtCreator使用QChart模块需要的配置。 关于Qt安装及环境 Qt的模块 查看已经安装的模块 sudo apt search qt5-安装新的模块 sudo apt install qt5-svg # 安装Qt SVG模块3.查看qt已经安装了哪些模块 dpkg -l | grep libqt安装qt,…...

视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...

k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...

让回归模型不再被异常值“带跑偏“,MSE和Cauchy损失函数在噪声数据环境下的实战对比
在机器学习的回归分析中,损失函数的选择对模型性能具有决定性影响。均方误差(MSE)作为经典的损失函数,在处理干净数据时表现优异,但在面对包含异常值的噪声数据时,其对大误差的二次惩罚机制往往导致模型参数…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机
这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...
SpringAI实战:ChatModel智能对话全解
一、引言:Spring AI 与 Chat Model 的核心价值 🚀 在 Java 生态中集成大模型能力,Spring AI 提供了高效的解决方案 🤖。其中 Chat Model 作为核心交互组件,通过标准化接口简化了与大语言模型(LLM࿰…...

消防一体化安全管控平台:构建消防“一张图”和APP统一管理
在城市的某个角落,一场突如其来的火灾打破了平静。熊熊烈火迅速蔓延,滚滚浓烟弥漫开来,周围群众的生命财产安全受到严重威胁。就在这千钧一发之际,消防救援队伍迅速行动,而豪越科技消防一体化安全管控平台构建的消防“…...
Android屏幕刷新率与FPS(Frames Per Second) 120hz
Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数,单位是赫兹(Hz)。 60Hz 屏幕:每秒刷新 60 次,每次刷新间隔约 16.67ms 90Hz 屏幕:每秒刷新 90 次,…...
Yii2项目自动向GitLab上报Bug
Yii2 项目自动上报Bug 原理 yii2在程序报错时, 会执行指定action, 通过重写ErrorAction, 实现Bug自动提交至GitLab的issue 步骤 配置SiteController中的actions方法 public function actions(){return [error > [class > app\helpers\web\ErrorAction,],];}重写Error…...
AWS vs 阿里云:功能、服务与性能对比指南
在云计算领域,Amazon Web Services (AWS) 和阿里云 (Alibaba Cloud) 是全球领先的提供商,各自在功能范围、服务生态系统、性能表现和适用场景上具有独特优势。基于提供的引用[1]-[5],我将从功能、服务和性能三个方面进行结构化对比分析&#…...
在Spring Boot中集成RabbitMQ的完整指南
前言 在现代微服务架构中,消息队列(Message Queue)是实现异步通信、解耦系统组件的重要工具。RabbitMQ 是一个流行的消息中间件,支持多种消息协议,具有高可靠性和可扩展性。 本博客将详细介绍如何在 Spring Boot 项目…...