Skip to content

二次封装组件

在平时的业务开发中,我们通常需要对第三方组件库进行二次封装来满足特殊的业务需求。

组件传参

useAttrs 可以获取到当前组件 非 defineProps 声明 的属性。

Vue
<template>
  <child v-model="textInput" :count="10" placeholder="请输入姓名" />
</template>
Vue
<template>
  <div class="my-component">
    <van-field v-bind="attrs" />
  </div>
</template>

<script setup>
import { useAttrs } from 'vue'
const props = defineProps(['count'])
const attrs = useAttrs() // => { modelValue, onUpdate:modelValue, placeholder }
</script>

组件插槽

useSlots 可以获取到父组件传入的全部插槽对象,再使用 v-for 遍历给子组件即可。

Vue
<template>
  <child v-model="textInput" :count="10" placeholder="请输入姓名">
    <template #label>
      <span>名称</span>
    </template>
    <template #left-icon>
      <span>icon</span>
    </template>
  </child>
</template>
Vue
<template>
  <div class="my-component">
    <van-field v-bind="attrs">
      <template v-for="(value, name) in slots" #[name]="slotData">
        <slot :name="name" v-bind="slotData || {}"></slot>
      </template>
    </van-field>
  </div>
</template>

<script setup>
import { useAttrs, useSlots } from 'vue'
const props = defineProps(['count'])
const attrs = useAttrs() // => { modelValue, onUpdate:modelValue, placeholder }

const slots = useSlots()
</script>

组件实例

在父组件中添加 ref 属性,但想拿到子组件中的实例时,可以使用 defineExpose 将子组件的实例导出给父组件。

Vue
<template>
  <child ref="childRef" v-model="textInput" :count="10" placeholder="请输入姓名">
    <template #label>
      <span>名称</span>
    </template>
    <template #left-icon>
      <span>icon</span>
    </template>
  </child>
</template>

<script setup>
import { ref } from 'vue'
const childRef = ref()
</script>
Vue
<template>
  <div class="my-component">
    <van-field ref="fieldRef" v-bind="attrs">
      <template v-for="(value, name) in slots" #[name]="slotData">
        <slot :name="name" v-bind="slotData || {}"></slot>
      </template>
    </van-field>
  </div>
</template>

<script setup>
import { useAttrs, useSlots, ref } from 'vue'
const props = defineProps(['count'])
const attrs = useAttrs() // => { modelValue, onUpdate:modelValue, placeholder }
const slots = useSlots()

const fieldRef = ref()
defineExpose({
  fieldRef
})
</script>

在 Vue2 环境下可以将 fieldRef 的属性在 mounted 生命周期中遍历赋值给 this 指向。