vue 一个组件的开发,引出组件开发流程和知识点

发布于:2025-03-26 ⋅ 阅读:(20) ⋅ 点赞:(0)

Vue开发一个导入数据的组件,以下具体说明整个流程和相关知识点

需求是开发一个数据导入组件,此组件是一个公共组件,而且是个常用组件,在很多功能页面上都会用到。

1.导入文件组件 开发

<template>
    <div class="content">
        <div class="item">
            <span style="color: red">*</span><span style="padding-right: 10px">选择文件</span>
            <input ref="excel-upload-input" class="excel-upload-input" type="file" accept=".xlsx, .xls"
                @change="handleClick" />
            <el-button icon="el-icon-upload2" @click="uploadFile">上传</el-button>
            <div style="padding: 10px 10px 0 60px">
                <span v-if="rawFile" style="padding-left: 10px; color: #1890ff" @click="openFile">{{ rawFile.name }}</span>
                <span v-if="rawFile" style="padding-left: 5px; cursor: pointer" @click="cancelFile"><i
                        class="el-icon-delete"></i></span>
            </div>
        </div>
        <div class="item download">
            <span style="cursor: pointer" @click="downloadMdule">EXCEL模板下载</span>
        </div>
        <div class="item">
            <p>注意</p>
            <p>1、数据应该严格按照模板样式填写</p>
            <p>2、导入模板中带*号字段均要填写</p>
        </div>
        <div style=" display: flex; justify-content: flex-end; padding-top: 10px;width: 100%;  ">
            <el-button @click="close">取 消</el-button>
            <el-button type="primary" @click="submit" :loading="loading">确 定</el-button>
        </div>
    </div>
</template>

<script>
export default {
    name: 'importWork',
    data() {
        return {
            rawFile: null,
            loading: false
        };
    },
    props: {
        tempUrl: "",
    },
    methods: {
        downloadMdule() {
            window.open(this.tempUrl, "_blank");
        },
        uploadFile() {
            this.$refs["excel-upload-input"].click();
        },
        // 上传的文件
        handleClick(e) {
            console.log(e);
            const files = e.target.files;
            const rawFile = files[0]; // only use files[0]
            const isSizeValid = rawFile.size / 1024 <= 100; // Maximum size: 500k
            if (!isSizeValid) {
                this.errorTip("文件过大,不能超过100k");
                return;
            }
            if (!rawFile) return;
            this.upload(rawFile);
        },
        upload(file) {
            this.rawFile = file;
            console.log(file);
        },
        async submit() {
            if (!this.rawFile) {
                this.errorTip("请上传文件");
                return;
            }

            const formData = new FormData();
            formData.append("file", this.rawFile);
            this.loading = true;
            this.$emit("handle", formData, (res) => {
                this.loading = false;

                this.successTip(res.message);
                this.$emit("reload");
                this.rawFile = null;
                this.$refs["excel-upload-input"].value = "";
            });
        },
        close() {
            this.$emit("close");
        },
        cancelFile() {
            this.rawFile = null;
            this.$refs["excel-upload-input"].value = "";
        },
    }
}
</script>
<style lang="scss" scoped>
.content {
    padding: 0 20px;

    .excel-upload-input {
        display: none;
        z-index: -9999;
    }

    .item {
        padding: 10px 0;
    }

    .download {
        color: #1890ff;
        display: flex;
        justify-content: space-between;
    }
}
</style>

代码分析:

  • template 和 style 部分略过,这就是普通的上传文件Html的结构,如果这一块不会,那就去补习HTML

  • script 里面涉及到几个知识点:

    • props父组件向子组件传递数据的一种机制
      • 通过 props,父组件可以将数据传递给子组件,子组件则可以接收并使用这些数据。
      • 此处我接收的是一个 导入模版的字段,导入模版是啥,不解释
    • this.$refs["excel-upload-input"].click()
      • this.$refs 是一个用于直接访问 DOM 元素或子组件实例的对象。
      • 使用 this.$refs["excel-upload-input"].click() 时,通过 ref 属性获取 隐藏的上传文件输入框 元素,并手动触发它的 click 事件。
    • handleClick 方法 是文件框有变化时触发的,我这里是检测文件大小,实际上可以检测文件格式等等。
      • 方法内,最后将上传文件的对象,赋值给 rawFile 属性,方便后面调用
    • this.$emit("handle", formData, (res) => {...} 很重要, 很重要, 很重要
      • this.$emit子组件向父组件传递事件和数据的一种方式。
      • 通过 $emit,子组件可以触发一个自定义事件,并传递数据给父组件,父组件则可以监听这个事件并做出相应的处理。
        • 由于导入数据的功能肯定是每个父组件独立的功能,很少情况下,所有上传数据会请求到同一接口,但不排除这种情况,此处不做计较
        • 此次导入数据的逻辑就是,上传组件只负责上传,处理数据是父组件自己处理,然后将结果给上传组件,上传组件根据结果,来显示成功和失败。
      • handle 是父组件的定义的事件,后续会说明。
      • formData 是传递的数据
      • (res) => {} 是回调函数,父组件在处理完事件后调用该回调函数并传递结果。父组件使用,会在下面展示。

其他的相关代码,不做解释,都是常规操作

2.调用方,即父组件 调用

  <el-dialog title="批量导入" :visible.sync="importDataDialog.dialogVisible" width="1000px" :close-on-click-modal="false">
      <importData v-if="importDataDialog.tempUrl" @close="closeImportData" @handle="handleImportData"
           @reload="reloadImportData" ref="importDataRef" :tempUrl="importDataDialog.tempUrl">
       </importData>
   </el-dialog>

<script>
    //处理批量导入
    async handleImportData(formData, callback) {
         console.log(formData)
         let res = await importOrderData(formData);
         callback(res);
     },
</script>

父组件调用就很简单了

  • importDataDialog.tempUrl 是模版url,我用if 判断,如果没值,上传组件不加载,因为需求是必须让用户先下载模版
  • :tempUrl="importDataDialog.tempUrl" 即父组件给子组件传递数据,子组件用props 获取
  • @handle 父组件监听事件,等待子组件的调用
  • handleImportData 是父组件监听后,处理上传数据的方法
    • Vue.js 中,async 和 await 是 JavaScript 中用于处理异步操作的语法糖。可以使用 async 和 await 来处理异步操作,比如 API 请求、定时器等。
    • 上传数据处理完成后,返回结果res 通过 回调函数 callback 传统数据
    • callback 接收到数据,进行相应的判断,提示等等逻辑

上述一个最简单的公用上传组件开发完成,接下来就是调试。然后根据用户需求,继续完善优化组件。


网站公告

今日签到

点亮在社区的每一天
去签到