【VUE3】如何封装一个公共组件(示例:基于element+封装一个时刻选择器TimeSelect)

2,928 阅读2分钟

业务需求: 电力市场运行日会分为96个交易出清时间,每15分钟一段,时刻选择器需要从00:15到24:00

遇到问题: element+中时刻选择器不包含24:00点,所以需要自己用下拉框组件封装一个时刻选择器。

封装公共组件的思路:

image.png

一,新建组件

1,在component文件夹中新建新组建文件夹TimeSelect,并新建index.vue文件

在此单文件组件中,完成所需组件的主要功能。

2,vue单文件分为以下三个模块:

<template>
//书写html结构相关的代码
    <div class="time-select">
        <el-select v-model="value" v-bind="$attrs"  @change="updateHandle">
            <template  #prefix>
                <span style="height: 100%; display: flex; justify-content: center; align-items: center;">
                    <el-icon><Clock /></el-icon>
                </span>
            </template>
            <el-option
                v-for="item in options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
                :disabled="item.value < minTime || item.value >maxTime"
            />
        </el-select>
    </div>
</template>

<script setup lang="ts">
//js代码,进行逻辑和数据处理(部分代码)
const options = ref([
    {
        value: '',
        label: '',
    },
]);
//getTimePoint函数组装options中值(略)
</script>

<style lang="scss" scoped>
//css,添加scoped是防止样式污染
.time-select{
    display: inline-block;
}
</style>

二,父子组件间传值

vue3的setup语法中,父子组件间传值通过defineProps,defineEmits

使用方法:

//显式声明所接受的 props
const props = defineProps({
    /**当前双向数据绑定的值 */
    value: {
        type: [String, Number],
        default: '',
    },
    /**最早时间点,早于该时间的时间段将被禁掉 */
    minTime: {
        type: [String, Number],
        default: '00:00',
    },
    /**最晚时间点,晚于该时间的时间段将被禁掉 */
    maxTime: {
        type: [String, Number],
        default: '24:00',
    }
});

// 触发与监听事件
const emit = defineEmits(['update:value']);

function updateHandle(value) {
    emit('update:value', value);
}

还有属性透传,“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 classstyle 和 id

另,可以通过defineExpose暴露子组件中的属性(setup语法的组件是默认关闭的,即实例中不会暴露属性)

三,全局注册组件

main.ts

// 引入时刻选择组件
import TimeSelect from '@/components/TimeSelect/index.vue';

// 全局组件挂载
app.component('TimeSelect', TimeSelect);

组件全局注册后,使用时,不用再单独引入,直接使用对应标签即可。

四,页面中使用示例

//父组件中引用,标签<time-select />
<span class="demonstration">时刻选择:</span>
 <time-select
      v-model="startTime"
      :max-time="endTime"     //这是自己显式声明接受的的props
      placeholder="开始时刻"   //这就是透传的属性
      style="width: 140px"
      @update:value="dataFormat"  //这是emit
/>
<time-select
     v-model="endTime"
     :min-time="startTime"
     placeholder="结束时刻"
     style="width: 140px"
     @update:value="dataFormat"
/>

示例:

image.png

总结

整体思路是对应实际工作中的流程做了简单的记录,如果错误,欢迎指正,感谢大佬们的阅读!!

祝大家兔年大吉~~

新的一年要健健康康哦~