• 技术文章 >web前端 >Vue.js

    Vue3如何操作dom?四种方式介绍

    青灯夜游青灯夜游2022-10-28 19:29:51转载718
    Vue如何操作dom?下面本篇文章给大家介绍一下Vue3中操作dom的四种方式,希望给大家有所帮助!

    大前端成长进阶课程:进入学习

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

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

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

    至此将Vue3中dom操作常见的几种方式总结一下!(学习视频分享:vue视频教程

    通过ref直接拿到dom引用

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

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

    适用场景

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

    1.gif

    示例代码

    <template>
        <div>
            <p>通过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>

    通过父容器的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()

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

    2.gif

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

    适用场景

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

    3.gif

    示例代码

    <template>
        <div>
            <p>通过父容器遍历拿到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>

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

    <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>

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

    4.gif

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

    适用场景

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

    5.gif

    示例代码

    <template>
        <div>
            <p>通过:ref将dom引用放到数组中</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>

    通过子组件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>

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

    6.gif

    适用场景

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

    7.gif

    示例代码

    <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>通过子组件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>

    【相关视频教程推荐:vuejs入门教程web前端入门

    以上就是Vue3如何操作dom?四种方式介绍的详细内容,更多请关注php中文网其它相关文章!

    声明:本文转载于:掘金社区,如有侵犯,请联系admin@php.cn删除

    前端(VUE)零基础到就业课程:点击学习

    清晰的学习路线+老师随时辅导答疑

    自己动手写 PHP MVC 框架:点击学习

    快速了解MVC架构、了解框架底层运行原理

    专题推荐:vue3 vue.js Vue
    上一篇:聊聊Vue中的计算属性computed 下一篇:自己动手写 PHP MVC 框架(40节精讲/巨细/新人进阶必看)

    相关文章推荐

    • ❤️‍🔥共22门课程,总价3725元,会员免费学• ❤️‍🔥接口自动化测试不想写代码?• 10个提高开发效率的Vue3常用插件(快来收藏)• 6个实用的Vue3相关生态(总结分享)• 详解Vue3状态管理库Pinia的使用方法• Laravel与Vue Nginx配置的2个常见问题解决方法• 详解Vue中的Mustache插值语法、v-bind指令
    1/1

    PHP中文网