Vue3中操作dom的四种方式总结(建议收藏!)

 更新时间:2022年12月29日 10:49:49   作者:潇潇夜雨丶  
VUE是通过传递一些配置给Vue对象和页面中引用插值表达式来操作DOM的,下面这篇文章主要给大家介绍了关于Vue3中操作dom的四种方式总结,文中通过实例代码介绍的非常详细,需要的朋友可以参考下

前言

最近产品经理提出了很多用户体验优化的需求,涉及到很多dom的操作。

小张:“老铁,本来开发Vue2项目操作dom挺简单的,现在开发vue3项目,突然感觉一头雾水!”

我:“没事,原理都差不多,查查资料应该没问题的!”

至此将Vue3中dom操作常见的几种方式总结一下!

通过ref直接拿到dom引用

<template>
    <div class="demo1-container">
        <div ref="sectionRef" class="ref-section"></div>
    </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
const sectionRef = ref()
</script>

通过对div元素添加了ref属性,为了获取到这个元素,我们声明了一个与ref属性名称相同的变量sectionRef,然后我们通过 sectionRef.value 的形式即可获取该div元素。

适用场景

单一dom元素或者个数较少的场景

示例代码

<template>
    <div class="demo1-container">
        <p>通过ref直接拿到dom</p>
        <div ref="sectionRef" class="ref-section"></div>
        <button @click="higherAction" class="btn">变高</button>
    </div>
</template>

<script setup lang="ts">
import {ref} from 'vue'
const sectionRef = ref()
let height = 100;

const higherAction = () => {
    height += 50;
    sectionRef.value.style = `height: ${height}px`;
}
</script>

<style lang="scss" scoped>
.demo1-container {
    width: 100%;
    height: 100%;

    .ref-section {
        width: 200px;
        height: 100px;
        background-color: pink;
        transition: all .5s ease-in-out;
    }

    .btn {
        width: 200px;
        height: 50px;
        background-color: gray;
        color: #fff;
        margin-top: 100px;
    }
}
</style>

通过父容器的ref遍历拿到dom引用

<template>
    <div class="demo2-container">
        <div ref="listRef" class="list-section">
            <div @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
                <span>{{item}}</span>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
const listRef = ref()

通过对父元素添加了ref属性,并声明了一个与ref属性名称相同的变量listRef,此时通过listRef.value会获得包含子元素的dom对象

此时可以通过listRef.value.children[index]的形式获取子元素dom

适用场景

通过v-for循环生成的固定数量元素的场景

示例代码

<template>
    <div class="demo2-container">
        <p>通过父容器遍历拿到dom</p>
        <div ref="listRef" class="list-section">
            <div @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
                <span>{{item}}</span>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
const listRef = ref()
const state = reactive({
    list: [1, 2, 3, 4, 5, 6, 7, 8]
})

const higherAction = (index: number) => {
    let height = listRef.value.children[index].style.height ? listRef.value.children[index].style.height : '20px';
    height = Number(height.replace('px', ''));
    listRef.value.children[index].style = `height: ${height + 20}px`;
}
</script>

<style lang="scss" scoped>
.demo2-container {
    width: 100%;
    height: 100%;

    .list-section {
        width: 200px;
        .list-item {
            width: 200px;
            height: 20px;
            background-color: pink;
            color: #333;
            transition: all .5s ease-in-out;
            display: flex;
            justify-content: center;
            align-items: center;
        }
    }
}
</style>

通过:ref将dom引用放到数组中

<template>
    <div class="demo2-container">
        <div class="list-section">
            <div :ref="setRefAction" @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
                <span>{{item}}</span>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue'

const state = reactive({
    list: [1, 2, 3, 4, 5, 6, 7],
    refList: [] as Array<any>
})

const setRefAction = (el: any) => {
    state.refList.push(el);
}
</script>

通过:ref循环调用setRefAction方法,该方法会默认接收一个el参数,这个参数就是我们需要获取的div元素

此时可以通过state.refList[index]的形式获取子元素dom

适用场景

通过v-for循环生成的不固定数量或者多种元素的场景

示例代码

<template>
    <div class="demo2-container">
        <p>通过:ref将dom引用放到数组中</p>
        <div class="list-section">
            <div :ref="setRefAction" @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
                <span>{{item}}</span>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue'

const state = reactive({
    list: [1, 2, 3, 4, 5, 6, 7],
    refList: [] as Array<any>
})

const higherAction = (index: number) => {
    let height = state.refList[index].style.height ? state.refList[index].style.height : '20px';
    height = Number(height.replace('px', ''));
    state.refList[index].style = `height: ${height + 20}px`;
    console.log(state.refList[index]);
}

const setRefAction = (el: any) => {
    state.refList.push(el);
}
</script>

<style lang="scss" scoped>
.demo2-container {
    width: 100%;
    height: 100%;

    .list-section {
        width: 200px;
        .list-item {
            width: 200px;
            height: 20px;
            background-color: pink;
            color: #333;
            transition: all .5s ease-in-out;
            display: flex;
            justify-content: center;
            align-items: center;
        }
    }
}
</style>

通过子组件emit传递ref

<template>
    <div ref="cellRef" @click="cellAction" class="cell-item">
        <span>{{item}}</span>
    </div>
</template>

<script setup lang="ts">
import {ref} from 'vue';

const props = defineProps({
    item: Number
})
const emit = defineEmits(['cellTap']);
const cellRef = ref();
const cellAction = () => {
    emit('cellTap', cellRef.value);
}
</script>

通过对子组件添加了ref属性,并声明了一个与ref属性名称相同的变量cellRef,此时可以通过emit将cellRef.value作为一个dom引用传递出去

适用场景

多个页面都可能有操作组件dom的场景

示例代码

<template>
    <div ref="cellRef" @click="cellAction" class="cell-item">
        <span>{{item}}</span>
    </div>
</template>

<script setup lang="ts">
import {ref} from 'vue';

const props = defineProps({
    item: Number
})
const emit = defineEmits(['cellTap']);
const cellRef = ref();
const cellAction = () => {
    emit('cellTap', cellRef.value);
}
</script>

<style lang="scss" scoped>
.cell-item {
    width: 200px;
    height: 20px;
    background-color: pink;
    color: #333;
    transition: all .5s ease-in-out;
    display: flex;
    justify-content: center;
    align-items: center;
}
</style>
<template>
    <div class="demo2-container">
        <p>通过子组件emit传递ref</p>
        <div class="list-section">
            <Cell :item="item" @cellTap="cellTapHandler" v-for="(item, index) in state.list" :key="index">
            </Cell>
        </div>
    </div>
</template>

<script setup lang="ts">
import { reactive } from 'vue'
import Cell from '@/components/Cell.vue'
const state = reactive({
    list: [1, 2, 3, 4, 5, 6, 7],
    refList: [] as Array<any>
})

const cellTapHandler = (el: any) => {
    let height = el.style.height ? el.style.height : '20px';
    height = Number(height.replace('px', ''));
    el.style = `height: ${height + 20}px`;
}
</script>

<style lang="scss" scoped>
.demo2-container {
    width: 100%;
    height: 100%;

    .list-section {
        width: 200px;
    }
}
</style>

写在最后

到此这篇关于Vue3中操作dom的四种方式总结的文章就介绍到这了,更多相关Vue3操作dom方式内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue实现父子组件双向绑定的方法总结

    vue实现父子组件双向绑定的方法总结

    Vue.js 是一种流行的 JavaScript 框架,它提供了一种简单且高效的方式来构建用户界面,在 Vue 中,父子组件之间的双向绑定是一种常见的需求,下面我们就来学习一下vue中父子组件双向绑定的常用方法吧
    2023-10-10
  • Vue.js的复用组件开发流程完整记录

    Vue.js的复用组件开发流程完整记录

    这篇文章主要给大家介绍了关于Vue.js的复用组件开发流程的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-11-11
  • Vue动态设置el-table操作列的宽度自适应

    Vue动态设置el-table操作列的宽度自适应

    这篇文章主要给大家介绍了关于Vue如何动态设置el-table操作列的宽度自适应,很多页面都需要用到表格组件el-table,如果没有给el-table-column指定宽度,默认情况下会平均分配给剩余的列,需要的朋友可以参考下
    2023-07-07
  • Vue 2 如何添加 register-service-worker 实现缓存请求的问题

    Vue 2 如何添加 register-service-worker 实现缓存请求的问题

    这篇文章主要介绍了Vue 2 如何添加 register-service-worker 以实现缓存请求的目的,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-11-11
  • vue项目element-ui级联选择器el-cascader回显的问题及解决

    vue项目element-ui级联选择器el-cascader回显的问题及解决

    这篇文章主要介绍了vue项目element-ui级联选择器el-cascader回显的问题及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-07-07
  • ElementUI中利用table表格自定义表头Tooltip文字提示

    ElementUI中利用table表格自定义表头Tooltip文字提示

    这篇文章主要介绍了ElementUI中利用table表格自定义表头Tooltip文字提示,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • vue3+ts import引入第三方js文件报错的2种解决方法

    vue3+ts import引入第三方js文件报错的2种解决方法

    这篇文章主要给大家介绍了关于vue3+ts import引入第三方js文件报错的2种解决方法,在Vue中通常我们引入一个js插件都是使用npm方式下载然后import使用的,需要的朋友可以参考下
    2023-08-08
  • Vue中使用sass实现换肤功能

    Vue中使用sass实现换肤功能

    这篇文章主要介绍了Vue中使用sass实现换肤功能,实现此功能用到了三个主要文件(base.scss、mixin.scss、varibale.scss),需要的朋友可以参考下
    2018-09-09
  • vue iview封装模态框的方法

    vue iview封装模态框的方法

    这篇文章主要为大家详细介绍了vue iview封装模态框的方法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-07-07
  • 详解Vue3中侦听器watch的使用教程

    详解Vue3中侦听器watch的使用教程

    学过 vue2 的小伙伴们肯定学习过侦听器,主要是用来监听页面数据或者是路由的变化,来执行相应的操作,在 vue3里面呢,也有侦听器的用法,功能基本一样,本文就来为大家详细讲讲
    2022-07-07

最新评论