Vue如何操作dom?下面本篇文章給大家介紹一下Vue3中操作dom的四種方式,希望給大家有所幫助!
前端(vue)入門到精通課程:進(jìn)入學(xué)習(xí)
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點(diǎn)擊使用
最近產(chǎn)品經(jīng)理提出了很多用戶體驗(yàn)優(yōu)化的需求,涉及到很多dom的操作。
小張:“老鐵,本來(lái)開(kāi)發(fā)Vue2項(xiàng)目操作dom挺簡(jiǎn)單的,現(xiàn)在開(kāi)發(fā)vue3項(xiàng)目,突然感覺(jué)一頭霧水!”
我:“沒(méi)事,原理都差不多,查查資料應(yīng)該沒(méi)問(wèn)題的!”
至此將Vue3中dom操作常見(jiàn)的幾種方式總結(jié)一下?。▽W(xué)習(xí)視頻分享:vue視頻教程)
通過(guò)ref直接拿到dom引用
<template> <div> <div ref="sectionRef"></div> </div> </template> <script setup> import {ref} from 'vue' const sectionRef = ref() </script>
通過(guò)對(duì)div元素添加了ref屬性,為了獲取到這個(gè)元素,我們聲明了一個(gè)與ref屬性名稱相同的變量sectionRef,然后我們通過(guò) sectionRef.value 的形式即可獲取該div元素。
適用場(chǎng)景
單一dom元素或者個(gè)數(shù)較少的場(chǎng)景
示例代碼
<template> <div> <p>通過(guò)ref直接拿到dom</p> <div ref="sectionRef"></div> <button @click="higherAction">變高</button> </div> </template> <script setup> import {ref} from 'vue' const sectionRef = ref() let height = 100; const higherAction = () => { height += 50; sectionRef.value.style = `height: ${height}px`; } </script> <style 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>
通過(guò)父容器的ref遍歷拿到dom引用
<template> <div> <div ref="listRef"> <div @click="higherAction(index)" v-for="(item, index) in state.list" :key="index"> <span>{{item}}</span> </div> </div> </div> </template> <script setup> import { ref, reactive } from 'vue' const listRef = ref()
通過(guò)對(duì)父元素添加了ref屬性,并聲明了一個(gè)與ref屬性名稱相同的變量listRef,此時(shí)通過(guò)listRef.value會(huì)獲得包含子元素的dom對(duì)象
此時(shí)可以通過(guò)listRef.value.children[index]的形式獲取子元素dom
適用場(chǎng)景
通過(guò)v-for循環(huán)生成的固定數(shù)量元素的場(chǎng)景
示例代碼
<template> <div> <p>通過(guò)父容器遍歷拿到dom</p> <div ref="listRef"> <div @click="higherAction(index)" v-for="(item, index) in state.list" :key="index"> <span>{{item}}</span> </div> </div> </div> </template> <script setup> 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 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>
通過(guò):ref將dom引用放到數(shù)組中
<template> <div> <div> <div :ref="setRefAction" @click="higherAction(index)" v-for="(item, index) in state.list" :key="index"> <span>{{item}}</span> </div> </div> </div> </template> <script 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>
通過(guò):ref循環(huán)調(diào)用setRefAction方法,該方法會(huì)默認(rèn)接收一個(gè)el參數(shù),這個(gè)參數(shù)就是我們需要獲取的div元素
此時(shí)可以通過(guò)state.refList[index]的形式獲取子元素dom
適用場(chǎng)景
通過(guò)v-for循環(huán)生成的不固定數(shù)量或者多種元素的場(chǎng)景
示例代碼
<template> <div> <p>通過(guò):ref將dom引用放到數(shù)組中</p> <div> <div :ref="setRefAction" @click="higherAction(index)" v-for="(item, index) in state.list" :key="index"> <span>{{item}}</span> </div> </div> </div> </template> <script 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 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>
通過(guò)子組件emit傳遞ref
<template> <div ref="cellRef" @click="cellAction"> <span>{{item}}</span> </div> </template> <script setup> import {ref} from 'vue'; const props = defineProps({ item: Number }) const emit = defineEmits(['cellTap']); const cellRef = ref(); const cellAction = () => { emit('cellTap', cellRef.value); } </script>
通過(guò)對(duì)子組件添加了ref屬性,并聲明了一個(gè)與ref屬性名稱相同的變量cellRef,此時(shí)可以通過(guò)emit將cellRef.value作為一個(gè)dom引用傳遞出去
適用場(chǎng)景
多個(gè)頁(yè)面都可能有操作組件dom的場(chǎng)景
示例代碼
<template> <div ref="cellRef" @click="cellAction"> <span>{{item}}</span> </div> </template> <script setup> import {ref} from 'vue'; const props = defineProps({ item: Number }) const emit = defineEmits(['cellTap']); const cellRef = ref(); const cellAction = () => { emit('cellTap', cellRef.value); } </script> <style 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> <p>通過(guò)子組件emit傳遞ref</p> <div> <Cell :item="item" @cellTap="cellTapHandler" v-for="(item, index) in state.list" :key="index"> </Cell> </div> </div> </template> <script 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 scoped> .demo2-container { width: 100%; height: 100%; .list-section { width: 200px; } } </style>
【相關(guān)視頻教程推薦:vuejs入門教程、web前端入門】