Vue2.0 和 Vue3.0 插槽slot设置

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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值