项目正式开始,第一个功能模块的用户信息编辑就开始卡壳,特别是头像上传组件。
- 弹出框
a-mdal
的表单值怎么获取到的 ant-design-vue
上传组件的头像上传
使用 ant-design-vue
上传组件的头像上传。
在 Jeecg-boot 中头像上传是 antD 的上传组件 listType="picture-card"
,
在教程里是直接使用 upload
组件的 defaultFileList
API,
但他们 DEMO 是 listType="text"
,或 listType="picture-card"
但绑定的是 fileList
,
并不是 defaultFileList
,就和 ant-design-vue 的文档是一摸一样的照着读了一遍,
然后我直接复制的官方用户头像 DEMO,就出现了问题。
AntD 官方 DEMO
点击上传用户头像,并使用 beforeUpload 限制用户上传的图片格式和大小。beforeUpload 的返回值可以是一个 Promise 以支持异步处理,如服务端校验等
<template>
<a-upload
name="avatar"
listType="picture-card"
class="avatar-uploader"
:showUploadList="false"
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
:beforeUpload="beforeUpload"
@change="handleChange"
>
<img v-if="imageUrl" :src="imageUrl" alt="avatar" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
</template>
<script>
function getBase64(img, callback) {
const reader = new FileReader();
reader.addEventListener("load", () => callback(reader.result));
reader.readAsDataURL(img);
}
export default {
data() {
return {
loading: false,
imageUrl: ""
};
},
methods: {
handleChange(info) {
if (info.file.status === "uploading") {
this.loading = true;
return;
}
if (info.file.status === "done") {
// Get this url from response in real world.
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl;
this.loading = false;
});
}
},
beforeUpload(file) {
const isJPG = file.type === "image/jpeg";
if (!isJPG) {
this.$message.error("You can only upload JPG file!");
}
const isLt2M = file.size / 1024 / 1024 < 2;
if (!isLt2M) {
this.$message.error("Image must smaller than 2MB!");
}
return isJPG && isLt2M;
}
}
};
</script>
<style>
// css style...
</style>
第一天的时候,我直接复制的 用户头像 DEMO,然后直接使用了 defaultFileList
设置默认头像但是没效果,依然是空白。
找啊找啊找,发现 DEMO 上设置了 :showUploadList="false"
,删之…🙄 还是不行,继续查问题。
发现 defaultFileList
是不能异步设置的,要在组件初始化完成之前就设置好,或者使用 fileList
来设置默认头像 🙃,
emmm….怎么还有一个空白头像,原来还有一个 img
标签,删之。
现在的 upload
组件是这样的:
<a-upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
listType="picture-card"
:defaultFileList="fileList"
@change="handleChange"
>
<div v-if="fileList.length < 1">
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
好,现在基本显示没问题了,但是先要删除原先的头像再上传
等等..删除了头像怎么没出现上传头像按钮?handleChange 事件要修改成:
handleChange({ fileList }) {
this.fileList = fileList;
},
完事,基本完成。
但是…
需求:点击头像就能修改,而不是先要删除原先的头像再上传
所以结合两个官方 DEMO,最后修改如下:
<template>
// 上下文...
<a-upload
listType="picture-card"
class="avatar-uploader"
:showUploadList="false"
:action="uploadURL"
:beforeUpload="beforeUpload"
@change="handleChange"
>
<img v-if="imageUrl" :src="imageUrl" alt="avatar" style="width:100%;" />
<div v-else>
<a-icon :type="loading ? 'loading' : 'plus'" />
<div class="ant-upload-text">Upload</div>
</div>
</a-upload>
// 上下文...
</template>
<script>
export default {
data() {
return(){
url:{
upload: '/project/upload'
},
imageUrl: '',
loading: false
}
},
computed: {
uploadURL() {
return `${window._CONFIG['domianURL']}${this.url.upload}`
}
},
methods:{
handleChange(info) {
if (info.file.status === 'uploading') {
this.loading = true
return
}
if (info.file.status === 'done') {
getBase64(info.file.originFileObj, imageUrl => {
this.imageUrl = imageUrl
this.loading = false
})
// 这里可以放上传成功后台返回的图片url的表单赋值,使用 form.setFieldsValue 给表单赋值
}
},
beforeUpload(file) {
const isJPG = file.type === 'image/jpeg'
if (!isJPG) {
this.$message.error('You can only upload JPG file!')
}
const isLt2M = file.size / 1024 / 1024 < 2
if (!isLt2M) {
this.$message.error('Image must smaller than 2MB!')
}
return isJPG && isLt2M
}
// 初始图片赋值等方法
...
}
</script>
<style>
// css style...
</style>
弹出框的表单值是怎么设置的?
在 edit()
方法中传入了当前对象 record
。
AntD 封装了表单域 <Form.Item />
,需要使用 Form.create
来创建表单实例,
而且设置表单的值要用 form.setFieldsValue
(有些时候需要确保子组件完成渲染 $nextTick()
后才执行赋值操作)
且使用 pick()
[1] 函数从指定的对象中挑选出需要的任意 key
属性。
特殊控件(select,radio,checkbox)需要使用 v-decorator
来绑定数据 [2]
尾声
- 1,官方 DEMO 的代码差异比较大,特别是
handleChange
部分,需要细看。 - 2,对后台返回的数据有要求。
- 3,表单修改需要使用
setFieldsValue
来动态设置其他控件的值。
pick()
的坑待填,用的 lodash.pick 函数
v-decorator
挖坑,看后边什么时候填上