在 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