You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3选项式API:如何从父组件访问子组件中的元素

从父组件操作子组件元素的解决方案

你的问题核心是父组件无法直接访问子组件内部的DOM元素ref,因为子组件的ref属于其内部作用域。下面给你两种可行的实现方式:

方式一:通过子组件的ref访问内部元素

修改父组件

给循环的子组件绑定统一的ref(循环后会生成数组),再通过子组件实例的$refs获取内部input:

import InputText from "./InputText.js";

export default {
    components: { InputText },
    template: `
        {{ things }}<br><br>
        <!-- 给子组件加ref="inputTexts",循环后生成组件实例数组 -->
        <input-text v-for="thing in things" :key="thing.id" :thing="thing" ref="inputTexts" />
        <br><br>
        <button @click="focusBox()">TEST</button>
    `,
    data() {
        return {
            things: [{
                "id": 1,
                "name": ""
            }, {
                "id": 2,
                "name": ""
            }, {
                "id": 3,
                "name": ""
            }]
        }
    },
    methods: {
        focusBox() {
            // 筛选出id为2的子组件实例
            const targetComponent = this.$refs.inputTexts.find(item => item.thing.id === 2);
            // 通过子组件内部的refs获取input并执行聚焦
            targetComponent.$refs[`thing_${targetComponent.thing.id}`].focus();
        }
    }
}

子组件保持不变

你原来的动态ref写法是正确的,无需修改:

export default {
    template: `
        <input type="text" v-model="thing.name" :ref="'thing_' + thing.id">
        <br>
    `,
    props: {
        thing: Object
    }
}

方式二:子组件暴露方法给父组件调用(更推荐,符合组件封装原则)

这种方式不需要父组件直接操作子组件DOM,而是由子组件提供方法,父组件调用即可,更符合Vue的组件通信规范。

修改子组件

添加一个focusInput方法,负责聚焦内部的input元素:

export default {
    template: `
        <input type="text" v-model="thing.name" :ref="'thing_' + thing.id">
        <br>
    `,
    props: {
        thing: Object
    },
    methods: {
        focusInput() {
            this.$refs[`thing_${this.thing.id}`].focus();
        }
    }
}

修改父组件

同样给子组件绑定ref数组,找到目标组件后直接调用其暴露的方法:

import InputText from "./InputText.js";

export default {
    components: { InputText },
    template: `
        {{ things }}<br><br>
        <input-text v-for="thing in things" :key="thing.id" :thing="thing" ref="inputTexts" />
        <br><br>
        <button @click="focusBox()">TEST</button>
    `,
    data() {
        return {
            things: [{
                "id": 1,
                "name": ""
            }, {
                "id": 2,
                "name": ""
            }, {
                "id": 3,
                "name": ""
            }]
        }
    },
    methods: {
        focusBox() {
            const targetComponent = this.$refs.inputTexts.find(item => item.thing.id === 2);
            targetComponent.focusInput();
        }
    }
}

你之前写法失败的原因

你尝试的this.$refs.thing_2.focus()无效,是因为thing_2是子组件内部定义的ref,父组件的$refs只会包含自己模板里声明的ref,无法直接获取子组件内部的DOM引用。

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 09:55:09