Vue中四种操作dom方法保姆级讲解

目录
  • 前言
  • 一、通过ref拿到dom的引用
    • 适用场景
    • 示例代码
  • 二、通过父容器的ref遍历拿到dom引用
    • 适用场景
    • 示例代码
  • 三、通过子组件emit传递ref
    • 适用场景
    • 示例代码
  • 四、通过:ref将dom引用放到数组中
    • 适用场景
    • 示例代码

前言

最近主管提出了许多优化用户体验的要求,其中很多涉及 dom 操作。本文将 Vue3 中常见的 dom 操作总结了一下。

一、通过ref拿到dom的引用

<template>
    <div class="ref-container">
        <div ref="sectionRef" class="ref-section"></div>
    </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const sectionRef = ref()
</script>

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

适用场景

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

示例代码

<template>
    <div class="ref-container">
        <p>通过 ref 直接拿到 dom</p>
        <div ref="sectionRef" class="ref-section"></div>
        <button @click="action" class="btn">变高</button>
    </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const sectionRef = ref()
let height = 100;
const action= () => {
    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引用

通过对父元素添加 ref 属性,并声明一个与 ref 属性名称相同的变量 list,此时通过 list.value 会获得包含子元素的 dom 对象。此时可以通过 list.value.children[index] 的形式获取子元素 dom

<template>
    <div class="ref-container">
        <div ref="list" 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 lang="ts" setup>
import { ref, reactive } from 'vue'
const list = ref()

适用场景

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

示例代码

<template>
    <div class="ref-container">
        <p>通过父容器遍历拿到dom</p>
        <div ref="list" 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 lang="ts" setup>
import { ref, reactive } from 'vue'
const list = 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>

三、通过子组件emit传递ref

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

<template>
    <div ref="childRef" @click="cellAction" class="cell-item">
        <span>{{item}}</span>
    </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const props = defineProps({
    item: Number
})
const emit = defineEmits(['cellTap']);
const childRef = ref();
const cellAction = () => {
    emit('cellTap', childRef.value);
}
</script>

适用场景

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

示例代码

<template>
    <div ref="childRef" @click="cellAction" class="cell-item">
        <span>{{item}}</span>
    </div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
const props = defineProps({
    item: Number
})
const emit = defineEmits(['cellTap']);
const childRef = ref()
const cellAction = () => {
    emit('cellTap', childRef.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="ref-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 lang="ts" setup>
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>

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

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

<template>
    <div class="ref-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 lang="ts" setup>
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>

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

适用场景

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

示例代码

<template>
    <div class="ref-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 lang="ts" setup>
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>

到此这篇关于Vue中四种操作dom方法保姆级讲解的文章就介绍到这了,更多相关Vue操作dom内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • vue操作dom元素的3种方法示例

    1.原生js操作dom const dom = getElementById('box') 2.vue官方方法:ref vue中的ref是把当前dom元素 " 抽离出来 " ,只要通过 this.$refs就可以获取到 < div class="set" ref="up"> .set是我们要操作的dom对象,它的ref是 up @click="Alert" 给父元素一个点击事件, 接下来我们来编写这个方法 meth

  • vue不操作dom实现图片轮播的示例代码

    本文介绍了vue不操作dom实现图片轮播的示例代码,分享给大家,具体如下: 效果 宽度为1190px且水平居中的轮播盒子: 中间是当前显示的默认尺寸图片: 左右两边是预显示的小尺寸图片: 轮播从右至左,图片逐渐放大. 做普通平滑轮播也可以参照这个思路 html <ul> <li v-for="(demo,index) in demoList" :key="index" :class="{'demo-left':demoStyle(inde

  • VUE中操作dom元素的几种方法(最新推荐)

    目录 VUE中操作dom元素 方法一: 方法二: vue操作dom元素的三种方法介绍和分析 以下是常用的三种方法: 1.jQuery操作dom(推荐指数:★☆☆☆☆): 2.原生js操作dom(推荐指数:★★★★☆): 3.vue官方方法:ref(推荐指数:★★★★★): VUE中操作dom元素 方法一: 访问子组件实例或子元素尽管存在 prop 和事件,有的时候你仍可能需要在 JavaScript 里直接访问一个子组件.为了达到这个目的,你可以通过 ref 这个 attribute 为子组件赋

  • 解决vue页面渲染但dom没渲染的操作

    我就废话不多说了,大家还是直接看代码吧~ this.$nextTick(() => { $("select[name='ddlCostCenter']").select2({ language: "zh-CN" }); }); 补充知识:vue+Echarts动态数据已经赋值,但是无法渲染页面的问题 最近用vue+Echarts想做一个饼状统计图,但是数据明明已经绑定完毕,但是页面渲染一直没有效果,最终才发现问题所在,自己还是个新手,主要对vue还不是很熟悉.

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

    目录 前言 通过ref直接拿到dom引用 适用场景 示例代码 通过父容器的ref遍历拿到dom引用 适用场景 示例代码 通过:ref将dom引用放到数组中 适用场景 示例代码 通过子组件emit传递ref 适用场景 示例代码 写在最后 前言 最近产品经理提出了很多用户体验优化的需求,涉及到很多dom的操作. 小张:“老铁,本来开发Vue2项目操作dom挺简单的,现在开发vue3项目,突然感觉一头雾水!” 我:“没事,原理都差不多,查查资料应该没问题的!” 至此将Vue3中dom操作常见的几种方式

  • Vue中四种操作dom方法保姆级讲解

    目录 前言 一.通过ref拿到dom的引用 适用场景 示例代码 二.通过父容器的ref遍历拿到dom引用 适用场景 示例代码 三.通过子组件emit传递ref 适用场景 示例代码 四.通过:ref将dom引用放到数组中 适用场景 示例代码 前言 最近主管提出了许多优化用户体验的要求,其中很多涉及 dom 操作.本文将 Vue3 中常见的 dom 操作总结了一下. 一.通过ref拿到dom的引用 <template> <div class="ref-container"

  • java中四种操作xml方式的比较

    1)DOM(JAXP Crimson解析器) DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准.DOM是以层次结构组织的节点或信息片断的集合.这个层次结构允许开发人员在树中寻找特定信息.分析该结构通常需要加载整个文档和构造层次结构,然后才能做任何工作.由于它是基于信息层次的,因而DOM被认为是基于树或基于对象的.DOM以及广义的基于树的处理具有几个优点.首先,由于树在内存中是持久的,因此可以修改它以便应用程序能对数据和结构作出更改.它还可以在任何时候在树中上下导航,而不是像SAX那

  • Java中四种遍历List的方法总结(推荐)

    实例如下: package com.ietree.basic.collection.loop; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * List遍历 * * @author Dylan */ public class ListLoop { public static void main(String[] args) { // 初始化一个长度为10的ArrayList L

  • jsp中四种传递参数的方法

    今天老师讲了jsp中四种传递参数的方法,我觉得总结一下,挺好的,以备后用! 1.form表单 2.request.setAttribute();和request.getAttribute(); 3.超链接:<a herf="index.jsp"?a=a&b=b&c=c>name</a> 4.<jsp:param> 下面一一举例说明: 1.form表单 form.jsp: <%@page contentType="tex

  • JS中的四种数据类型判断方法

    目录 1.typeof 2.instanceof 3.constructor 4.toString() 本文总结了四种判断方法: 1.typeof typeof是一个运算符,其有两种使用方式:(1)typeof(表达式); (2)typeof 变量名;返回值是一个字符串,用来说明变量的数据类型;所以可以用此来判断number, string, object, boolean, function, undefined, symbol 这七种类型,每种情况返回的内容如下表所示: // 字符串 con

  • 详解将数据从Laravel传送到vue的四种方式

    在过去的两三年里,我一直在研究同时使用 Vue 和 Laravel 的项目,在每个项目开发的开始阶段,我必须问自己 "我将如何将数据从 Laravel 传递到 Vue ?".这适用于 Vue 前端组件与 Blade 模板紧密耦合的两个应用程序,以及运行完全独立于 Laravel 后端的单页应用程序. 这里有四种不同的方法从一个到另一个获取数据. 直接回显到数据对象或组件属性中 赞成: 简单明了 反对: 必须与嵌入到 Blade 模板中的 Vue 应用程序一起使用 可以说是将数据从 La

  • JAVA四种基本排序方法实例总结

    本文实例讲述了JAVA四种基本排序方法.分享给大家供大家参考.具体如下: JAVA四种基本排序,包括冒泡法,插入法,选择法,SHELL排序法.其中选择法是冒泡法的改进,SHELL排序法是 插入法的改进.所以从根本上来说可以归纳为两种不同的排序方法:即:插入法&冒泡法 一 插入法: 遍历排序集合,每到一个元素时,都要将这个元素与所有它之前的元素遍历比较一遍,让符合排序顺序的元素挨个移动到当前范围内它最应该出现的位置.交换是相邻遍历移动,双重循环控制实现.这种排序法属于地头蛇类型,在我的地牌上我要把

  • Android SharedPreferences四种操作模式使用详解

    Android  SharedPreferences详解 获取SharedPreferences的两种方式: 1 调用Context对象的getSharedPreferences()方法 2 调用Activity对象的getPreferences()方法 两种方式的区别: 调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享. 调用Activity对象的getPreferences()方法获得的Sh

  • 对django的User模型和四种扩展/重写方法小结

    User模型 User模型是这个框架的核心部分.他的完整的路径是在django.contrib.auth.models.User.以下对这个User对象做一个简单了解: 字段: 内置的User模型拥有以下的字段: username: 用户名.150个字符以内.可以包含数字和英文字符,以及_.@.+..和-字符.不能为空,且必须唯一! first_name:歪果仁的first_name,在30个字符以内.可以为空. last_name:歪果仁的last_name,在150个字符以内.可以为空. e

  • Android  SharedPreferences四种操作模式使用详解

    Android  SharedPreferences详解 获取SharedPreferences的两种方式: 1 调用Context对象的getSharedPreferences()方法 2 调用Activity对象的getPreferences()方法 两种方式的区别: 调用Context对象的getSharedPreferences()方法获得的SharedPreferences对象可以被同一应用程序下的其他组件共享. 调用Activity对象的getPreferences()方法获得的Sh

随机推荐