Vue 3中如何获取插槽元素的src属性?
Vue 3中获取插槽元素src属性的正确方式
Vue 3对插槽实现做了重构,this.$slots的结构和Vue 2差异很大,这是导致原有代码失效的核心原因:
- Vue 2中
this.$slots.default直接是VNode数组 - Vue 3中
this.$slots.default是返回VNode数组的函数,必须调用才能拿到插槽内容;同时VNode的属性不再存于attrs,而是移到了props中(标准HTML属性会被解析到props)
修正后的选项式API代码
修改你的getPhotoBackgroundSrc方法如下:
getPhotoBackgroundSrc() { let image_url = ''; // 调用default函数获取插槽VNode数组,处理插槽为空的情况 const defaultSlots = this.$slots.default?.() || []; // 过滤掉文本节点(比如插槽里的空格、换行),找到第一个img元素的VNode const imgVNode = defaultSlots.find(vnode => vnode.type === 'img'); if (imgVNode) { // Vue3中img的src属性存储在props中 image_url = imgVNode.props?.src || ''; } let css = ''; if (this.position === 'center') { css += 'background-position-y: center;'; } // 确保有图片地址再添加背景图样式 if (this.type === 'cover' && image_url) { css += ` background-image: url("${image_url}");`; } return css; }
关键注意点
- 必须调用插槽函数:Vue 3的插槽都是函数,通过
this.$slots.default()才能获取实际的VNode列表,直接访问this.$slots.default只会得到函数本身,这也是你之前看到undefined的原因。 - 属性位置变化:标准HTML元素的属性(比如img的src)在Vue 3中会被解析到VNode的
props对象下,而非Vue 2的attrs。 - 过滤无效节点:插槽内容可能包含文本节点(比如换行、空格),需要通过
vnode.type === 'img'过滤出目标元素,避免误取到无效节点。
组合式API写法(可选)
如果组件改用组合式API,可以使用useSlots钩子获取插槽:
import { useSlots } from 'vue'; export default { setup() { const slots = useSlots(); const getPhotoBackgroundSrc = () => { let image_url = ''; const defaultSlots = slots.default?.() || []; const imgVNode = defaultSlots.find(vnode => vnode.type === 'img'); if (imgVNode) { image_url = imgVNode.props?.src || ''; } let css = ''; // 后续逻辑和选项式API一致 if (this.position === 'center') { css += 'background-position-y: center;'; } if (this.type === 'cover' && image_url) { css += ` background-image: url("${image_url}");`; } return css; }; return { getPhotoBackgroundSrc }; } }
内容的提问来源于stack exchange,提问作者Floris
相关产品推荐
相关产品推荐

