在 Vue 3 中,<script setup> 提供了一种简洁的方式来定义组件。结合 Element Plus 库,我们可以轻松地二次封装组件,提升代码的复用性和可维护性。本文将演示如何使用 <script setup> 语法封装一个自定义的 Element Plus Input 组件。1. 前提条件
确保你的项目已经安装了 Vue 3 和 Element Plus。
已有基本的 Vue 3 和 Element Plus 的使用经验。
2. 创建自定义的 Input 组件
我们将基于 Arco Design 的 select 组件进行二次封装。下面是完整的代码示例:

<template>
  <a-select
    v-model="valueComp"
    v-bind="$attrs"
    :loading="loading"
    allow-search
    value-key="id"
    :filter-option="false"
    placeholder="请选择"
    @change="handleChange"
    @search="handleSearch"
    @input-value-change="handleInputChange"
    @popup-visible-change="handleVisibleChange"
  >
    <a-option v-for="item in options" :key="item.code" :value="item.id">
      <a-tooltip :content="`${item.code} / ${item.name}`">
        <span>{{ `${item.name}` }}</span>
      </a-tooltip>
    </a-option>
  </a-select>
</template>

<script setup lang="ts">
  import { apiGetPage } from '@/api/capacityManagement/driver';
  import useLoading from '@/hooks/loading';
  import { PropType, ref, watchEffect, watch } from 'vue';

  const props = defineProps({
    value: {
      type: [String, Array] as PropType<any>,
    },
    id: {
      type: String,
      default: '',
    },
    carrierId: {
      type: String,
    },
    carrierAttribute: {
      type: [String] as PropType<any>,
    },
    queryParam: {
      type: Object as PropType<any>,
      default() {
        return {};
      },
    },
    autoSearch: {
      type: Boolean,
      default: true,
    },
  });
  const emits = defineEmits([
    'update:value',
    'update:mobile',
    'update:name',
    'update:coldFlag',
    'update:id',
    'onChange',
  ]);
  const { loading, setLoading } = useLoading();
  const valueComp = ref('');
  watchEffect(() => {
    // 数据库默认为0,接口返回'0'
    valueComp.value = ['0', 0].includes(props.value) ? undefined : props.value;
  });
  interface vehicleType {
    id: string;
    code: string;
    name: string;
    mobile: string;
    status: number;
    coldFlag: number;
  }
  const options = ref<vehicleType[]>([]);
  async function fetchOptions(keywords: string) {
    const { carrierId } = props;
    setLoading(true);
    try {
      const req = {
        current: 1,
        size: 99,
        keywords,
        carrierId,
        ...props.queryParam,
      };
      const { data } = await apiGetPage(req);
      options.value = data.records;
    } catch (error) {
      /* empty */
    } finally {
      setLoading(false);
    }
  }
  if (props.autoSearch) {
    fetchOptions(props.value);
  }
  function handleSearch(value: string) {
    fetchOptions(value);
  }
  function handleChange(value: any) {
    const target = options.value?.find((i: { id: string }) => i.id === value);
    emits('update:value', target?.name || value);
    emits('update:mobile', target?.mobile);
    emits('update:id', target?.id);
    emits('update:coldFlag', target?.coldFlag);
    emits('onChange', target);
  }
  function handleInputChange(value: any) {
    if (value) {
      handleChange(value);
    }
  }
  function handleVisibleChange(visible: boolean) {
    if (visible) {
      fetchOptions('');
    }
  }
  watch(
    // 根据其他条件联动查询
    () => props.carrierId,
    () => {
      fetchOptions('');
    }
  );
</script>

3. 在父组件中使用自定义的组件

我们可以在父组件中使用这个自定义的组件:

<template>
<autoDriverList
 v-model:value="editItem.driverName"
 v-model:id="editItem.driverId"
 v-model:mobile="editItem.driverMobile"
 :carrier-attribute="CARRIER_ATTRIBUTE.THIRD_PARTY"
 :carrier-id="editItem.carrierId"
 allow-clear
 />
</template>
 
<script setup>
import { ref } from 'vue';
import autoDriverListfrom './autoDriverList.vue';
 
const editItem= ref({driverName:'',driverId:'',driverMobile:'',carrierId:''});
</script>

4. 总结
使用 Vue 3 的 <script setup> 语法,我们可以更简洁地封装组件,提高代码的复用性和可维护性。通过这个自定义的 Element Plus Input 组件的示例,你可以学习到如何高效地封装和管理组件逻辑。希望这篇文章对你理解和使用 Vue 3 的 <script setup> 语法封装组件有所帮助!如果有任何问题,欢迎随时提问。
以下是关于vue3二次封装elment-ui组件的文章,也可以使用类似方法进行封装 https://blog.csdn.net/weixin_65644264/article/details/139801203

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐