AI写作智能体 自主规划任务,支持联网查询和网页读取,多模态高效创作各类分析报告、商业计划、营销方案、教学内容等。 广告
最近项目是用iView组件库进行开发,里面的Upload上传组件用的频繁,所以我稍微进行了一下封装并配合表单以及v-model使用,简化代码方便使用。下面捋一捋过程和思路。 <br> **一、引入Upload组件:** 官网:https://www.iviewui.com/components/upload ![](https://img.kancloud.cn/c6/2f/c62f60823776be17ce0e47a24af40798_1313x655.png) 把这段代码连同样式先复制到自己的代码里。 <br> **二、在props里面写好父组件要使用的数据和类型:** ``` props: { // 上传路径 action: { type: String, default: "/yhsboot/upload/file" }, // 请求头(可以用于鉴权) headers: { type: Object, }, // 默认列表 defaultList: { type: Array }, // 格式 format: { type: Array, default: function () { return ['jpg','jpeg','png'] } }, // 大小 size: { type: Number, default: 2 }, // 数量 limit: { type: Number, default: 5 }, width: { type: String, default: '60px' }, height: { type: String, default: '60px' }, } ``` 若还有什么要更改的数据可以自行设置,props改了,Upload也要改 ``` <Upload ref="upload" :show-upload-list="false" :default-file-list="defaultList" :on-success="handleSuccess" :format="format" :max-size="size*1024" :on-format-error="handleFormatError" :on-exceeded-size="handleMaxSize" :before-upload="handleBeforeUpload" multiple :headers="headers" :action="action" type="drag" style="display: inline-block;"> ... </Upload> ``` 数据变了,记得把methods和data里面的数据也相应改一下,避免报错。 使用一下就是这样,image-upload就是自己定义的名字: ``` <image-upload :defaultList = "defaultList" :headers="upHeaders" :limit="3" > </image-upload> ``` 这个时候使用组件看到的效果是这样的: ![](https://img.kancloud.cn/ab/2d/ab2d8dd1f66874d27a103a9d0b30d789_225x76.png) <br> **三、关于图片尺寸的设置:** 可以看到我前面props里面设了width和height的值,要设置它们的值,那么样式不要写死,然后在需要设置宽高的地方,更改代码如下: ``` :style="{width: width, height: height, lineHeight: height}" ``` 至此基础部分已经完成。 <br> **四、与v-model绑定:** 上传组件95%的情况都是搭配表单使用,所以如果不能轻松配合表单,那么我们自定义封装的组件就没有意义了。首先在自定义组件里面加上代码: ``` model: [{ // 注意event的名字就叫input prop: 'uploadList', event: 'input' }] ``` 这里的uploadList就是图片数据,也是你v-model绑定后拿到的数据。 然后写一个初始化方法: ``` // 初始化 init() { this.$emit('input',this.hanldeList(this.uploadList)) } ``` hanldeList方法就是处理图片的数据格式,可以返回数组,可以返回对象,可以返回字符串,可以根据情况灵活设定。由于平时用的最多的是数组,所以我的写法如下: ``` hanldeList(arr) { // 当限制图片数量为单张时默认传字符串,为多张时传数组 if(this.limit === 1){ return arr[0].url }else{ let new_arr = []; arr.map((val,ind)=>{ new_arr.push(val.url) }) return new_arr } } ``` 注意我这里当图片限制为一张时(比如头像上传),返回字符串,其余情况返回数组。 最后一步不要忘记,在mounted生命周期里调用init方法,不然默认列表在v-model里面拿不到数据。 ``` mounted () { this.uploadList = this.$refs.upload.fileList; this.init(); } ``` 接下来使用看看。 <br> **五、搭配Form表单使用:** ``` <Form :model="formCustom"> <FormItem label="图片:" prop="uoloadList"> <image-upload :defaultList = "defaultList" :headers="upHeaders" v-model="formCustom.uoloadList"> </image-upload> </FormItem> <FormItem> <Button type="primary" @click="handleSubmit('formCustom')">提交</Button> </FormItem> </Form> ``` ``` handleSubmit (name) { console.log("表单数据111",this.formCustom) }, ``` ![](https://img.kancloud.cn/b5/58/b55863226488632c89b58136cedbce65_278x146.png) <br> 控制台打印如下: <br> ![](https://img.kancloud.cn/b2/c3/b2c371b7020e35ce9192fc759a529151_716x192.png) 可以看到已经达成我们要的效果了。 <br> **六、自定义插槽:** 然而我还觉得不够,毕竟设计图中上传图标可不一定长这个样,所以如果要更改图标,那么就要利用起插槽了。然后我在Upload里面加入一段代码: ``` <slot name="upload"> <div :style="{width: width, height: height, lineHeight: height}"> <slot name="icon"> <Icon type="ios-camera" size="20"></Icon> </slot> </div> </slot> ``` 经过我思考,我觉得改的最多的就两个地方,一个是图标,插槽名叫icon,使用如下: ``` <image-upload :defaultList = "defaultList" :headers="upHeaders" > <template slot="icon"> <Icon type="md-cloud-upload" size="24" color="#57a3f3" /> </template> </image-upload> ``` ![](https://img.kancloud.cn/ae/f4/aef4a047e628f765e6ce0559730ead28_297x156.png) 甚至还可以更改整个上传框的样式,插槽名为upload: ``` <image-upload :headers="upHeaders" > <template slot="upload"> <div style="width: 200px; height: 90px; lineHeight: 90px"> <p> <Icon type="md-cloud-upload" size="24" color="#57a3f3" /> 请上传清晰的照片 </p> </div> </template> </image-upload> ``` ![](https://img.kancloud.cn/7b/2d/7b2d45728bd195be2977ff4ccfba4cf5_322x185.png) 至此算是大功告成。 <br> **七、总结:** 这次自定义组件算是磕磕碰碰完成了,自己抽时间一点点的测试,完成了也特别有成就感。个人认为自定义组件封装能综合考察对vue.js的掌握,难怪不少公司面试时也喜欢问有没有自己封装过组件。也希望自己不断学习,不断进步,特写此博客与君共勉。