Vue2.0 代码
父组件
<el-marker
:mark="item.mark"
v-for="(item, key) in markList"
:key="key"
>
<!--
@slot 自定义标记的内容,参数为 { mark }, 即marks属性中数值key对应的数据
-->
<slot v-if="$scopedSlots.mark" name="mark" :mark="item.mark"> </slot>
</el-marker>
子组件 是一个js文件写法
export default {
name: 'ElMarker',
props: {
mark: {
type: [String, Object],
},
},
render() {
let label = typeof this.mark === 'string' ? this.mark : this.mark.label
return (
<div class="el-slider__marks-text" >
{this.$slots.default ? this.$slots.default : label}
</div>
)
}
}
数据
markList = [
{ mark: '10岁' },
{ mark: '20岁' },
{
mark: {
label: 11,
type: 'warning',
desc: '预警'
}
}
]
上面的例子更适合调用父组件 然后使用插槽
<el-father :markList="markList">
<template #mark="{ mark }">
<span class="slider-mark">
{{ mark.label || mark }}
<el-tag v-if="mark.desc" :type="mark.type" class="slider-mark--tag">{{ mark.desc }}</el-tag>
</span>
</template>
</el-father>
Vue3.0写法
父组件
<slider-marker
v-for="(item, key) in markList"
:key="key"
:mark="item.mark">
<!--
@slot 自定义标记的内容,参数为 { mark }, 即marks属性中数值key对应的数据。
-->
<slot v-if="$slots.mark" name="mark" :mark="item.mark"> </slot>
</slider-marker>
子组件 是一个 ts 文件写法
import { computed, defineComponent, h } from 'vue'
import { buildProps, definePropType, isString } from 'element-plus/es/utils/index'
import { useNamespace } from 'element-plus/es/hooks/index'
import type { CSSProperties, ExtractPropTypes } from 'vue'
export const sliderMarkerProps = buildProps({
mark: {
type: definePropType<
| string
| {
style: CSSProperties
label: any
}
>([String, Object]),
default: undefined,
},
} as const)
export type SliderMarkerProps = ExtractPropTypes<typeof sliderMarkerProps>
export default defineComponent({
name: 'ElSliderMarker',
props: sliderMarkerProps,
setup(props, { slots }) {
const ns = useNamespace('slider')
const label = computed(() => {
return isString(props.mark) ? props.mark : props.mark!.label
})
return () =>
h(
'div',
{
class: ns.e('marks-text'),
style: style.value,
},
slots.default ? slots.default() : label.value
)
},
})
注意几个关键点:
1、setup 函数接受两个参数:props 和 context。context 是一个对象,它包含了 attrs、slots、emit 和 expose 等属性。
2、在这个例子中,我们使用了 slots.default 来访问默认插槽的内容。如果默认插槽有内容,我们就渲染它(注意 slots.default() 是一个函数,需要被调用以获取 VNodes)。如果没有内容,我们就渲染 label.value。
3、我们使用了 h 函数来创建虚拟 DOM 节点(VNodes),这是 Vue 3 中创建元素的标准方式,特别是在 render 函数或 setup 函数的返回函数中。
4、useNamespace 是一个假设的函数,它可能是一个自定义的组合函数,用于处理类名命名空间的逻辑。这不是 Vue 的核心 API 的一部分,但你可以根据自己的需要实现它。
5、vue2.0 中 $scopedSlots 改写为了 $slots。
887

被折叠的 条评论
为什么被折叠?



