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,…...

lettuce引起的Redis command timeout异常
项目使用Lettuce,在自己的环境下跑是没有问题的。在给客户做售前压测时,因为客户端环境比较恶劣,service服务和中间件服务不在同一机房。服务启动后不一会就会出现Redis command timeout异常。 经过差不多两周的追查,最后没办法把…...

【Hadoop】一、Hadoop入门:基础配置、集群配置、常用脚本
基础设置 网络设置 创建好一个 centos 虚拟机,修改网络配置文件: /etc/sysconfig/network-scripts/ifcfg-ens33修改 BOOTPROTO 为 static 以及添加 IPADDR、GATEWAY、DNS1 TYPE"Ethernet" PROXY_METHOD"none" BROWSER_ONLY&quo…...

Ollama:本地运行大模型【含UI界面】
文章目录 Ollama 简介安装 ollamaWindows 安装Docker 安装其它平台安装支持的模型模型清单模型参数与运行内存快速启动 llama 模型llama 模型介绍运行 llama3.1 模型通过 HTTP API 访问ollama 命令语法常用示例特别示例自定义模型创建 Modelfile创建模型并运行集成 Web 页面Ope…...

【论文阅读】Grounding Language with Visual Affordances over Unstructured Data
Abstract 最近的研究表明,大型语言模型(llms)可以应用于将自然语言应用于各种各样的机器人技能。然而,在实践中,学习多任务、语言条件机器人技能通常需要大规模的数据收集和频繁的人为干预来重置环境或帮助纠正当前的…...

目标检测:滑块验证
最近在做一些爬虫相关的任务,有时候在登录时候需要去做滑块验证,刚好自己是做AI这一块得,就想着使用目标检测去做检测,然后绕过滑块。...

Unreal Engine 5 C++: 编辑器工具编写入门01(中文解释)
目录 准备工作 1.创建插件 2.修改插件设置 快速资产操作(quick asset action) 自定义编辑器功能 0.创建编辑器button,测试debug message功能 大致流程 详细步骤 1.ctrlF5 launch editor 2.创建新的cpp class,derived from AssetAction…...

力扣上刷题之C语言实现-Day2
一. 简介 本文记录一下,力扣C语言逻辑题。主要涉及 数组方面的知识。 二. 涉及数组的 C语言逻辑题 1. 两数之和 给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target…...

Visual Studio 2022 - QT 环境中文字符乱码问题
Visual Studio 2022 - QT 环境中文字符乱码问题 一、Visual Studio 2022 - Qt 环境 在 QT 中使用中文字符串常会出现乱码现象,如下:以下提供了几个解决方法,仅供参考 QString str "百香果真是一直可爱的小猫咪"; qDebug() <…...

获得ASPICE认证需要满足哪些条件?
要获得ASPICE认证,需要满足以下条件: ( 要明确的是:在ASPICE行业中专业来说,ASPICE项目是没有认证,而只有评估。不过,为了方便沟通,人们常将这一评估过程称为认证。) 一、基础条件…...

鸿蒙_异步详解
参考详细链接: 鸿蒙HarmonyOS异步并发开发指南...