美文网首页
Vue3 获取 ref 元素的几种方式

Vue3 获取 ref 元素的几种方式

作者: Cherry丶小丸子 | 来源:发表于2023-03-15 11:15 被阅读0次
    静态绑定

    获取单个 dom 元素

    <template>
        <button ref="domRef">dom</button>
    </template>
    <script setup>
        import { ref, onMounted } from 'vue';
    
        // 声明一个跟 ref 同名的变量即可,来保存元素
        const domRef = ref(null);
    
        onMounted(() => {
            domRef.value.style.background = "red";
        })
    </script>
    

    v-for 中使用

    <template>
        <ul>
            <li v-for="item in list" ref="domRef">
                {{ item }}
            </li>
        </ul>
    </template>
    <script setup>
        import { ref, onMounted } from 'vue';
        const list = ref([
            /* ... */
        ])
    
        const domRef = ref([]);
        onMounted(() => {
            console.log(domRef.value)
        })
    </script>
    
    但需要注意的是,itemRefs 元素数组并不保证与 list 数组为相同的顺序
    

    需要注意的是,访问的时候,要确保 ref 引用值已经成功绑定上元素,我们可以使用以下几种方式确保获取

    // onMounted
    onMounted(() => {
      domRef.value.style.background = "red";
    })
    
    // nextTick
    nextTick(() => {
        domRef.value.style.background = "red";
    })
    
    // watchEffect
    watchEffect(() => {
        if (domRef.value) {
            domRef.value.style.background = "red";
        }
    })
    
    // watch
    watch(domRef, val => {
        domRef.value.style.background = "red";
    })
    
    动态绑定

    动态绑定中,分为两种方式,一种是通过将 ref 设置为函数,第二种则是通过 getCurrentInstance 方法访问当前组件实例上的 $refs

    ref 设置函数,获取单个 dom 元素

    <template>
        <button :ref="handleRef">动态 Ref</button>
    </template>
    <script setup>
        import { ref } from 'vue'
        
        const btnRef = ref(null);
        // 赋值动态ref到变量
        const handleRef = el => {
            if (el) {
                btnRef.value = el;
            }
        }
    </script>
    
    ref 的函数回调中,我们能够接受到元素返回值,再动态设置到响应式变量即可
    

    ref 设置函数,v-for 中使用

    <template>
        <ul>
            <li v-for="item in list" :key="item.id" :ref="el => handleRef(el, item)">
                <button>{{ item.id }}</button>
            </li>
        </ul>
    </template>
    
    <script setup>
        import { ref } from "vue";
    
        const list = ref([{ id: "111" }, { id: "222" }, { id: "333" }]);
    
        let handleRefs = ref([]);
        const handleRef = (el, item) => {
            console.log(el, item);
            handleRefs.value.push(el);
        }
    </script>
    

    通过 getCurrentInstance 方法

    <template>
        <ul>
            <li v-for="item in list" :key="item.id" :ref="item.id">
                <button>{{ item.id }}</button>
            </li>
        </ul>
    </template>
    <script setup>
        import { getCurrentInstance, onMounted, ref } from "vue";
    
        const { proxy } = getCurrentInstance();
    
        const list = ref([{ id: "111" }, { id: "222" }, { id: "333" }]);
        onMounted(() => {
            console.log(proxy.$refs["111"]);
        })
    </script>
    

    这种方式,与 vue2 的 this.$refs 一般无二,只是我们用了 getCurrentInstance 函数在 setup 中获取了当前组件实例以替代 this

    获取 vue 实例

    需要注意的是,无论通过以上哪种方式获取元素,如果元素为 vue 组件,则需要在子组件中使用 defineExpose 进行暴露。

    在父组件中,我们静态绑定 childRef

    <template>
        <Test ref="childRef"></Test>
    </template>
    
    <script setup lang="ts">
        import Test from "./components/test.vue";
        import { onMounted, ref } from "vue";
    
        const childRef = ref(null);
        onMounted(() => {
            console.log(childRef.value.btnRef)
        })
    </script>
    

    在子组件中,我们需要通过defineExpose函数,手动暴露出来ref引用值,该值指向了button元素

    <template>
        <button ref="btnRef">子组件</button>
    </template>
    
    <script setup>
        import { ref } from "vue";
    
        const btnRef = ref(null)
        defineExpose({
            btnRef
        })
    </script>
    

    相关文章

      网友评论

          本文标题:Vue3 获取 ref 元素的几种方式

          本文链接:https://www.haomeiwen.com/subject/wejlrdtx.html