博客
关于我
Vue3+elementplus实现图片上传下载(最强实践)
阅读量:795 次
发布时间:2023-02-16

本文共 3883 字,大约阅读时间需要 12 分钟。

图片上传子组件实现

作为开发者,你需要实现一个照片上传、预览以及将图片地址转换为逗号隔开的字符串的组件。这个组件需要实时监听并发送最新数据到父组件。以下是实现步骤和代码:

  • 引入必要的Vue功能
  • 实现自定义上传函数
  • 处理图片校验规则
  • 提供图片删除功能
  • 使用Element Plus组件库
  • 代码示例:

    import { computed, ref, watch } from 'vue';
    import { upload } from '@/api/file';
    import { ElMessage } from 'element-plus';
    import emitter from '@/utils/emitter';
    export default defineComponent(() => {
    const imageUrls = ref
    ([]);
    // 计算属性,用于生成逗号隔开的图片地址字符串
    const commaSeparatedUrls = computed(() => imageUrls.value.join(','));
    // 监听图片地址变化,即时发送最新数据给父组件
    watch(imageUrls, () => {
    console.log('发送图片地址', commaSeparatedUrls.value);
    emitter.emit('send-imageUrls', commaSeparatedUrls.value);
    }, { deep: true });
    // 图片校验规则
    const beforeUpload = (file: File) => {
    const isJPGOrPNG = file.type === 'image/jpeg' || file.type === 'image/png';
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isJPGOrPNG) {
    ElMessage.error('picture must be jpg/png format!');
    return false;
    }
    if (!isLt2M) {
    ElMessage.error('picture size can not exceed 2MB!');
    return false;
    }
    return true;
    };
    // 删除图片
    const deleteImage = (imgUrl: string) => {
    imageUrls.value.splice(imgUrl, 1);
    };
    // 自定义上传
    const customUpload = (file: File) => {
    const formData = new FormData();
    formData.append('file', file);
    upload(formData).then((response: any) => {
    const imgUrl = response.data;
    imageUrls.value.push(imgUrl);
    });
    };
    return {
    imageUrls,
    commaSeparatedUrls,
    beforeUpload,
    deleteImage,
    customUpload
    };
    });

    表单父组件实现

    在父组件中引入图片上传子组件,并接受消息。确保组件在卸载后解绑事件,避免内存泄漏。以下是实现步骤和代码:

  • 引入必要的Vue功能
  • 组件引用
  • 表单验证
  • 数据双向绑定
  • 事件处理
  • 代码示例:

    import { reactive, ref, onUnmounted } from 'vue';
    import type { ComponentSize, FormInstance, FormRules } from 'element-plus';
    import { type HouseInter } from '@/types/model';
    import emitter from '@/utils/emitter';
    import ImageUploader from '@/components/ImageUploader.vue';
    export default defineComponent(() => {
    const formSize = ref
    ('default');
    const ruleFormRef = ref
    ();
    const ruleForm = reactive
    ({});
    const rules = reactive
    >({
    type: [{ required: true, message: '请选择房源类型', trigger: 'change' }],
    tittle: [{ required: true, message: '请填写标题', trigger: 'change' }]
    });
    // 接收图片上传子组件的最新消息
    emitter.on('send-imageUrls', (value: string) => {
    ruleForm.housePhoto = value;
    console.log('接收图片地址', ruleForm.housePhoto);
    });
    onUnmounted(() => {
    emitter.off('send-imageUrls');
    });
    const submitForm = async (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    await formEl.validate((valid, fields) => {
    if (valid) {
    console.log('提交成功!');
    } else {
    console.log('验证失败!', fields.error);
    }
    });
    };
    const resetForm = (formEl: FormInstance | undefined) => {
    if (!formEl) return;
    formEl.resetFields();
    };
    return {
    formSize,
    ruleFormRef,
    ruleForm,
    rules,
    submitForm,
    resetForm
    };
    });

    消息工具类实现

    使用mitt库实现事件发布和订阅功能。以下是实现代码:

    import mitt from 'mitt';
    import { ref } from 'vue';
    export default {
    install() {
    const emitter = mitt();
    const num = ref(0);
    // 绑定事件
    emitter.on('add', () => {
    console.log('add被调用了', num.value);
    });
    // 解绑事件
    setTimeout(() => {
    emitter.off('add');
    }, 5000);
    return {
    emit: (type: string, data: any) => {
    emitter.emit(type, data);
    }
    };
    }
    };

    以上代码实现了一个高效的图片上传子组件和对应的父组件管理,确保数据实时同步并避免内存泄漏。

    转载地址:http://mijfk.baihongyu.com/

    你可能感兴趣的文章