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

Vue 3中nextTick()结合焦点Ref使用问题:textarea自动聚焦报错

问题分析与解决方案

你遇到的错误核心原因是元素ref与数据ref命名冲突,加上错误地覆盖了ref引用,导致content.value不是DOM元素而是字符串,自然无法调用focus()方法。具体问题和修复步骤如下:

1. 解决ref命名冲突

你同时把textarea的ref设为content,又用const content = ref('')作为v-model的绑定变量,这会导致两者混淆。Vue3中,元素ref指向的是DOM元素对象,而数据ref是响应式字符串,重名后会相互覆盖,最终content指向的是数据变量而非DOM元素。

修复:给元素ref和数据变量起不同的名字,比如把元素ref改为contentRef,数据变量保留content。

2. 修正ref引用的赋值方式

在openingHTMLEmbedder事件回调里,你直接用content = data.content,这会把原本的响应式ref对象替换成普通字符串,彻底丢失DOM元素的引用。正确的做法是修改ref的.value属性。

同样,existingBlot = data.existingBlot也是错误的,应该改为existingBlot.value = data.existingBlot。

3. 确保在DOM渲染完成后调用focus

要先执行modalShown.value = true让textarea渲染到DOM中,再借助nextTick等待DOM更新完成后调用focus。


修改后的完整代码:

<textarea 
ref="contentRef" 
cols="30" 
rows="10" 
class="input" 
placeholder="Paste your HTML here"
v-model="content">
</textarea>

<script setup>
import { nextTick, onMounted, ref } from 'vue';

const modalShown = ref(false);
const existingBlot = ref(null);
const content = ref('');
const contentRef = ref(null);

const applyHTML = () => {
    emit('adding', {
        content: content.value,
        existingBlot: existingBlot.value,
    });

    close();
}

const close = () => {
    modalShown.value = false;
    content.value = '';
    existingBlot.value = null;
}

onMounted(() => {
    emitter.on('openingHTMLEmbedder', async (data) => {
        if (data) {
            content.value = data.content;
            existingBlot.value = data.existingBlot;
        }
        modalShown.value = true;
        await nextTick();
        contentRef.value?.focus();
    });
});
</script>

额外注意点:

  • 传递数据给父组件时,要传content.value而非content(ref对象),否则父组件拿到的是响应式对象而非实际值。
  • 使用contentRef.value?.focus()的可选链操作符,可以避免模态框未渲染时contentRef.value为null的报错。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 01:50:29