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

Vue.js 3中textarea组件内slot失效的最简替代方案

Vue.js 3 自定义textarea组件内容传递解决方案

原生<textarea>标签内部不支持Vue的<slot/>机制,直接在textarea里写slot无法生效。下面是两种简洁的替代方案:

方案一:使用defineModel(Vue 3.3+ 推荐)

利用Vue 3.3新增的defineModel语法糖,结合组件挂载时提取插槽文本作为初始值,代码最简洁:

组件代码:

<template>
  <textarea v-model="modelValue"></textarea>
</template>

<script setup>
import { onMounted } from 'vue'

const modelValue = defineModel({ default: '' })

// 挂载时自动把插槽文本设为初始内容(如果没传v-model的话)
onMounted(() => {
  if (!modelValue.value && $slots.default) {
    // 提取插槽里的纯文本内容
    modelValue.value = $slots.default()[0].children.join('').trim()
  }
})
</script>

使用方式:

<c-textarea>hello world</c-textarea>

方案二:基于Props和自定义事件(兼容Vue 3.x全版本)

如果项目还没升级到Vue 3.3,可以用传统的props+emit方式:

组件代码:

<template>
  <textarea 
    :value="displayContent" 
    @input="$emit('update:content', $event.target.value)"
  ></textarea>
</template>

<script setup>
import { computed } from 'vue'

const props = defineProps({
  content: {
    type: String,
    default: ''
  }
})

const emit = defineEmits(['update:content'])

// 优先用props传的内容,没有的话取插槽文本
const displayContent = computed(() => {
  if (props.content) return props.content
  return $slots.default ? $slots.default()[0].children.join('').trim() : ''
})
</script>

使用方式:

<!-- 直接传初始文本 -->
<c-textarea>hello world</c-textarea>

<!-- 也支持双向绑定 -->
<c-textarea v-model:content="myText"></c-textarea>

注意事项

  • 以上方案默认插槽里是纯文本,如果插槽包含HTML标签,需要额外处理(比如过滤标签只保留文本)
  • 插槽文本会作为初始值,后续修改textarea内容不会影响插槽本身(符合表单组件的预期)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 23:16:11