专栏介绍:
凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章,应粉丝要求开始更新 Vue3 的相关技术文章,Vue 框架目前的地位大家应该都晓得,所谓三大框架使用人数最多,公司选型最多的框架,凉哥之前在文章中也提到过就是 Vue 框架之所以火起来的原因,和 Vue 框架相比其他框架的巨大优势,有兴趣的伙伴可以看一下 Vue框架背后的故事、尤大大对前端生态是这样看的,随着 Vue 框架不断的被认可,现如今的 Vue 框架已经是前端工程师必备的技能了,记得尤大大开发 Vue 的初衷,为了让自己的开发工作更加便捷,也希望这个框架能让更多人的开发工作变得轻松;现如今 Vue 框架做到了,尤大大做到了,当然在 20 年的 9 月 18 日,Vue 又向前端同僚们报告了一次大的突破 Vue3.0 版本正式发布!如今已经过去了两年多的时间,更多的公司选择了Vue3技术,所以凉哥也在这个时候为大家出这份专栏,本专栏将帮助大家掌握Vue3+TS技术,提升自己竞争力!点击链接订阅本专栏吧——Vue3通透教程【从零到一】
温故知新:
上篇文章中我们带领大家学习了Vue3 组合式API的生命周期钩子函数,你进行尝试了么?不知道大家是否理解我们的Vue框架的初衷哈,其实在我们的框架设计中,对于 声明式和命令式上做了很好的权衡,Vue就采用了声明式,就是为了减少对Dom的操作,但是我们仍有一些特殊的需求需要获取到我们的操作,如果我们再去使用原生的方式进行活动未免有点不搭,在Vue2中我们提供了 ref 来获取DOM和组件,那Vue3中我们又将如何使用呢?下面让我们 let’s coding!
不知道同学们是否熟悉我们Vue2中ref获取Dom的写法;很简单就是我们需要在模板中需要获取的Dom结构上加上ref属性,设置一个自定义值,然后我们可以在javaScript中通过 this.$refs['自定义的ref值']
这样我们就能够获取到我们的Dom元素了;好了让我们来尝试一下吧!
由于我们前面所有文章中的实例工程都是基于Vite构建的Vue3的工程,相信大家也是跟着我来做的,我们在前面讲过Vue3工程中可以使用Vue2的选项API,所以我们可以在Vue3工程中进行尝试!
<template>
<div>
你好:
<p ref="jhxl">几何心凉</p>
</div>
</template>
<script>
export default{
data(){
return{
}
},
mounted(){
console.log(this.$refs['jhxl'])
}
}
</script>
这样我们通过mounted函数中就可以通过ref拿到我们的p标签的dom结构,其实我们获取Dom的需求还是有不少的,除了我们对单独的Dom进行操作,其实我们还可以对组件进行操作,比如说我们需要对一些ui库的某个组建进行更新,比如我们的表单校验的触发;我们获取到Dom执行更新方法,比如我们通过获取一些特殊Dom的属性;
在Vue3通透教程【五】这篇文章中,为大家介绍了我们组合式API的响应式数据的转化,为大家介绍了两个 reactive 和 ref 那上面我们又介绍到了,其实Vue2中我们就是通过ref来获取DOM,那Vue3中的ref是用来定义响应式数据的,是否可以获取DOM呢?其实是可以的只不过我们在写法上可能有一点小小的差距,使用如下:
1)首先还是一样通过ref函数来创建一个响应式数据;
2)然后找到我们想要获取的DOM元素如Vue2一样通过ref绑定自定义值;
3)第一步的ref声明的变量要跟模板中的DOM绑定的ref值保持一致;
4)最后我们就可以在我们的 onMounted 函数中打印我们的变量了得到的就是我们的DOM。
<template>
<p>您好,<i ref="nodeDom"> 几何心凉</i></p>
</template>
<script setup>
import { ref, onMounted } from 'vue';
let nodeDom = ref(null)
onMounted(() => {
console.log(nodeDom.value)
})
</script>
上面我们提及到了Vue2中ref除了可以获取DOM操作DOM之外呢,还可以对组件进行操作,比如我们一些UI组件的更新,UI组件树形结构的内容操作获取,还有表单组件的校验等等,ref在Vue3中可以实现操作DOM也可以获取组件实例但是需要defineExpose函数配合使用;下面通过案例来看一下吧!
1)使用 语法糖的组件是默认关闭的——即通过模板引用或者 $parent 链获取到的组件的公开实例,不会暴露任何在
中声明的绑定。(也就是说我们在父组件通过ref直接获取到子组件,但是我们拿不到 setup 中的变量及方法)
创建一个子组件:son.vue 并且实现一个点赞的小功能。
<template>
<div>
<p>几何心凉</p>
共 {{ num }} 个赞,<button @click="zan">赞</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
let num = ref(0)
const zan = () => {
num.value++
}
</script>
然后我们在app.vue组件中引用这个组件。
<template>
<p>您好,</p>
<son></son>
</template>
<script setup>
import son from "./son.vue";
</script>
组件的展示和事件都没有问题,下面我们来尝试一下获取到组件实例并且我们拿到里面的数据以及调用里面的方法是否可行?(获取组件的方法跟我们上面介绍的获取Dom的方法是一样的)
<template>
<p>您好,</p>
<son ref="sonDom"></son>
</template>
<script setup>
import { onMounted ,ref} from "vue";
import son from "./son.vue";
const sonDom=ref(null)
onMounted(()=>{
console.log(sonDom.value)
console.log(sonDom.value.num)
sonDom.value.zan()
})
</script>
果然报错了,我们可以获取到组件实例,但是缺拿不到组件里面setup中的数据和方法,这就是我们组合API中的如果想要获取可以通过 defineExpose 编译器宏来显式指定在 组件中要暴露出去的属性; (说白了就是我们在 son.vue 中如果用的是setip语法糖 如果需要在父组件用到数据或者方法我们就用defineExpose暴露出去!)我们来实现一下代码。
<template>
<div>
<p>几何心凉</p>
共 {{ num }} 个赞,<button @click="zan">赞</button>
</div>
</template>
<script setup>
import { ref } from 'vue';
let num = ref(0)
const zan = () => {
console.log('我被执行了!')
num.value++
}
defineExpose({
num,zan
})
</script>
按照我们在上面 app.vue 中的打印了 num 并且执行了 zan 函数,num应该会++并且打印我被执行了!
好了这样我们就实现了我们的需求,综合上面的案例我们来实现一下小小的功能吧,那就是我们要在父组件添加一个踩的功能,子组件的赞是添加赞数,父组件的踩是减少赞数,我们来实现一下吧!其实我们的son.vue组件的代码就是上面这样无需更换了,我们来改造一下 app.vue 组件中的代码就好了!
<template>
<p>您好,</p>
<son ref="sonDom"></son><button @click="cai">踩</button>
</template>
<script setup>
import { onMounted, ref } from "vue";
import son from "./son.vue";
const sonDom = ref(null)
const cai = () => {
sonDom.value.num--
}
</script>
总结一下本篇文章我们学习了Vue3如何获取操作DOM,其实还是通过我们的ref,只不过我们首先通过ref来声明响应式数据,然后在我们的Dom层通过ref来绑定刚刚声明的响应式变量,然后我们在需要的地方通过变量即可获取到DOM,组件的获取也是如此,只不过在组件中我们可以通过ref拿到组件的实例,但是并不能直接拿到setup中的数据或者函数,这需要我们通过defineExpose在子组件进行暴露,我们方可在父组件进行获取!大家要多多尝试哦;各位小伙伴让我们 let’s coding!
本期推荐!
✨ 原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下
点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!
⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!
✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!