vue3 二次封装 ant-design-vue 组件的 4 种方式

1,278 阅读1分钟

1. 传统封装

直接使用 ant 的组件, 声明需要的属性和方法, 父子组件传参, 这里还运用了vue3.3新特性 defineOptions 和 defineModel

/src/components/SegmentedTabs.vue

<template>
  <a-segmented :class="$style.segmented_tab" v-model:value="value" :options="tabs" @change="change" />
</template>

<script lang="ts" setup>
defineOptions({ name: 'SegmentedTabs', inheritAttrs: false }) // inheritAttrs 是否透传属性
const value = defineModel<string | number>('value', { default: '' });
const props = defineProps<{ tabs }>();
const emits = defineEmits(['change'])
/**
 * tab的change回调
 */
const change = (value) => {
  emits('change', value)
}
</script>
<style lang="less" module>
.segmented_tab {
  :global {
    .@{antNamespace}-segmented-item {
      border-radius: 30px !important;
    }
  }
}
</style>

2. template + tsx

利用 $attrs 透传属性和方法

<template>
  <a-segmented :class="$style.segmented_tab" v-bind="$attrs" :options="tabs"/>
</template>

<script lang="ts" setup>
defineOptions({ name: 'SegmentedTabs2' })
const props = defineProps<{tabs}>();

</script>

3. script tsx

在script里面写tsx, 合并 ant 组件的props 和自定义props

<script lang="tsx">
import { defineComponent } from 'vue';
import { Segmented } from 'ant-design-vue';
import type { SegmentedProps } from 'ant-design-vue';

interface SegmentedTabsProps extends SegmentedProps {
  tabs: [{ name: string, value: string | number }]
}
export default defineComponent({
  name: 'SegmentedTabs3',
  components: { Segmented },
  props: {
    ...RadioGroup.props,
    tabs: {
      type: Array,
      default: () => [],
    }
  },
  setup(props: SegmentedTabsProps, { emit, slots }) {
    return () => (
        <Segmented  {...props} :options="tabs" />
    )
  }
})
</script>

4. 纯tsx

import { Segmented } from 'ant-design-vue';
import type { SegmentedProps } from 'ant-design-vue';
interface SegmentedTabsProps extends SegmentedProps {
  tabs: [{ name: string, value: string | number }]
}

export const SegmentedTabs4 = ({ tabs, ...props }: SegmentedTabsProps) => {
  return (
    <Segmented  {...props} :options="tabs" />
  )
}

使用组件

<!-- tab -->
<SegmentedTabs v-model:value="tabValue" v-model:tabs="tabs" @change="tabChange"/>
        

const tabs = ref([
  { name: '影响线路', value: 1 },
  { name: '现场情况', value: 2 },
])
const tabValue = ref(tabs[0].value)

/**
 * tab切换
 */
const tabChange= (value) => {
  debugger
}