Vue3中操作dom的方式有哪些

其他教程   发布日期:2025年04月20日   浏览次数:175

这篇文章主要介绍“Vue3中操作dom的方式有哪些”,在日常操作中,相信很多人在Vue3中操作dom的方式有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue3中操作dom的方式有哪些”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    一、通过 ref 拿到 dom 的引用

    1. <template>
    2. <div class="ref-container">
    3. <div ref="sectionRef" class="ref-section"></div>
    4. </div>
    5. </template>
    6. <script lang="ts" setup>
    7. import { ref } from 'vue'
    8. const sectionRef = ref()
    9. </script>

    通过对

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

    适用场景

    • 单一

      1. dom
      元素或者个数较少的场景

    示例代码

    1. <template>
    2. <div class="ref-container">
    3. <p>通过 ref 直接拿到 dom</p>
    4. <div ref="sectionRef" class="ref-section"></div>
    5. <button @click="action" class="btn">变高</button>
    6. </div>
    7. </template>
    8. <script lang="ts" setup>
    9. import { ref } from 'vue'
    10. const sectionRef = ref()
    11. let height = 100;
    12. const action= () => {
    13. height += 50;
    14. sectionRef.value.style = `height: ${height}px`;
    15. }
    16. </script>
    17. <style lang="scss" scoped>
    18. .demo1-container {
    19. width: 100%;
    20. height: 100%;
    21. .ref-section {
    22. width: 200px;
    23. height: 100px;
    24. background-color: pink;
    25. transition: all .5s ease-in-out;
    26. }
    27. .btn {
    28. width: 200px;
    29. height: 50px;
    30. background-color: gray;
    31. color: #fff;
    32. margin-top: 100px;
    33. }
    34. }
    35. </style>

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

    通过对父元素添加

    1. ref
    属性,并声明一个与
    1. ref
    属性名称相同的变量
    1. list
    ,此时通过
    1. list.value
    会获得包含子元素的
    1. dom
    对象。此时可以通过
    1. list.value.children[index]
    的形式获取子元素
    1. dom
    1. <template>
    2. <div class="ref-container">
    3. <div ref="list" class="list-section">
    4. <div @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
    5. <span>{{item}}</span>
    6. </div>
    7. </div>
    8. </div>
    9. </template>
    10. <script lang="ts" setup>
    11. import { ref, reactive } from 'vue'
    12. const list = ref()

    适用场景

    • 通过

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

    示例代码

    1. <template>
    2. <div class="ref-container">
    3. <p>通过父容器遍历拿到dom</p>
    4. <div ref="list" class="list-section">
    5. <div @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
    6. <span>{{item}}</span>
    7. </div>
    8. </div>
    9. </div>
    10. </template>
    11. <script lang="ts" setup>
    12. import { ref, reactive } from 'vue'
    13. const list = ref()
    14. const state = reactive({
    15. list: [1, 2, 3, 4, 5, 6, 7, 8]
    16. })
    17. const higherAction = (index: number) => {
    18. let height = listRef.value.children[index].style.height ? listRef.value.children[index].style.height : '20px';
    19. height = Number(height.replace('px', ''));
    20. listRef.value.children[index].style = `height: ${height + 20}px`;
    21. }
    22. </script>
    23. <style lang="scss" scoped>
    24. .demo2-container {
    25. width: 100%;
    26. height: 100%;
    27. .list-section {
    28. width: 200px;
    29. .list-item {
    30. width: 200px;
    31. height: 20px;
    32. background-color: pink;
    33. color: #333;
    34. transition: all .5s ease-in-out;
    35. display: flex;
    36. justify-content: center;
    37. align-items: center;
    38. }
    39. }
    40. }
    41. </style>

    三、通过子组件 emit 传递 ref

    通过对子组件添加

    1. ref
    属性,并声明一个与
    1. ref
    属性名称相同的变量
    1. childRef
    ,此时通过
    1. emit
    1. childRef.value
    作为一个
    1. dom
    引用传递出去。
    1. <template>
    2. <div ref="childRef" @click="cellAction" class="cell-item">
    3. <span>{{item}}</span>
    4. </div>
    5. </template>
    6. <script lang="ts" setup>
    7. import { ref } from 'vue'
    8. const props = defineProps({
    9. item: Number
    10. })
    11. const emit = defineEmits(['cellTap']);
    12. const childRef = ref();
    13. const cellAction = () => {
    14. emit('cellTap', childRef.value);
    15. }
    16. </script>

    适用场景

    • 多个页面都可能有操作组件

      1. dom
      的场景

    示例代码

    1. <template>
    2. <div ref="childRef" @click="cellAction" class="cell-item">
    3. <span>{{item}}</span>
    4. </div>
    5. </template>
    6. <script lang="ts" setup>
    7. import { ref } from 'vue'
    8. const props = defineProps({
    9. item: Number
    10. })
    11. const emit = defineEmits(['cellTap']);
    12. const childRef = ref()
    13. const cellAction = () => {
    14. emit('cellTap', childRef.value);
    15. }
    16. </script>
    17. <style lang="scss" scoped>
    18. .cell-item {
    19. width: 200px;
    20. height: 20px;
    21. background-color: pink;
    22. color: #333;
    23. transition: all .5s ease-in-out;
    24. display: flex;
    25. justify-content: center;
    26. align-items: center;
    27. }
    28. </style>
    1. <template>
    2. <div class="ref-container">
    3. <p>通过子组件emit传递ref</p>
    4. <div class="list-section">
    5. <Cell :item="item" @cellTap="cellTapHandler" v-for="(item, index) in state.list" :key="index">
    6. </Cell>
    7. </div>
    8. </div>
    9. </template>
    10. <script lang="ts" setup>
    11. import { reactive } from 'vue'
    12. import Cell from '@/components/Cell.vue'
    13. const state = reactive({
    14. list: [1, 2, 3, 4, 5, 6, 7],
    15. refList: [] as Array<any>
    16. })
    17. const cellTapHandler = (el: any) => {
    18. let height = el.style.height ? el.style.height : '20px';
    19. height = Number(height.replace('px', ''));
    20. el.style = `height: ${height + 20}px`;
    21. }
    22. </script>
    23. <style lang="scss" scoped>
    24. .demo2-container {
    25. width: 100%;
    26. height: 100%;
    27. .list-section {
    28. width: 200px;
    29. }
    30. }
    31. </style>

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

    通过

    1. :ref
    循环调用
    1. setRefAction
    方法,该方法会默认接收一个
    1. el
    参数,这个参数就是我们需要获取的
    1. div
    元素。
    1. <template>
    2. <div class="ref-container">
    3. <div class="list-section">
    4. <div :ref="setRefAction" @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
    5. <span>{{item}}</span>
    6. </div>
    7. </div>
    8. </div>
    9. </template>
    10. <script lang="ts" setup>
    11. import { reactive } from 'vue'
    12. const state = reactive({
    13. list: [1, 2, 3, 4, 5, 6, 7],
    14. refList: [] as Array<any>
    15. })
    16. const setRefAction = (el: any) => {
    17. state.refList.push(el);
    18. }
    19. </script>

    此时可以通过

    1. state.refList[index]
    的形式获取子元素
    1. dom

    适用场景

    • 通过

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

    示例代码

    1. <template>
    2. <div class="ref-container">
    3. <p>通过:ref将dom引用放到数组中</p>
    4. <div class="list-section">
    5. <div :ref="setRefAction" @click="higherAction(index)" class="list-item" v-for="(item, index) in state.list" :key="index">
    6. <span>{{item}}</span>
    7. </div>
    8. </div>
    9. </div>
    10. </template>
    11. <script lang="ts" setup>
    12. import { reactive } from 'vue'
    13. const state = reactive({
    14. list: [1, 2, 3, 4, 5, 6, 7],
    15. refList: [] as Array<any>
    16. })
    17. const higherAction = (index: number) => {
    18. let height = state.refList[index].style.height ? state.refList[index].style.height : '20px';
    19. height = Number(height.replace('px', ''));
    20. state.refList[index].style = `height: ${height + 20}px`;
    21. console.log(state.refList[index]);
    22. }
    23. const setRefAction = (el: any) => {
    24. state.refList.push(el);
    25. }
    26. </script>
    27. <style lang="scss" scoped>
    28. .demo2-container {
    29. width: 100%;
    30. height: 100%;
    31. .list-section {
    32. width: 200px;
    33. .list-item {
    34. width: 200px;
    35. height: 20px;
    36. background-color: pink;
    37. color: #333;
    38. transition: all .5s ease-in-out;
    39. display: flex;
    40. justify-content: center;
    41. align-items: center;
    42. }
    43. }
    44. }
    45. </style>

    附:在vue3中获取dom,有几点需要注意

    1,获取dom的ref元素名称,要对应暴露的名称,不然会出现无效的dom报错,也就是拿到的是null

    2,在setup中,使用ref(null)获取dom

    3,不能直接在setup里面拿到dom的值,因为setup对应的生命周期是created,所以必须在后续的生命周期钩子里面拿到,比如onMounted

    以上就是Vue3中操作dom的方式有哪些的详细内容,更多关于Vue3中操作dom的方式有哪些的资料请关注九品源码其它相关文章!