1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > ant design vue 中Upload组件如何自定义文件列表的样式

ant design vue 中Upload组件如何自定义文件列表的样式

时间:2021-10-19 12:07:03

相关推荐

ant design vue 中Upload组件如何自定义文件列表的样式

ant design vue 中Upload组件如何自定义文件列表的样式

问题历程UploadList 组件源码h() 方法实现注

问题

技术:vueant design vue在开发项目的时候呢,遇到这样一个需求:就是在展示文件列表的时候,需要使用小图标标明该文件的类型实现类似下图的效果:

历程

首先当前还是仔细去研究官方文档啦不幸的是,官方文档并未给出相应的案例有点麻爪,然后向领导反映:“能不能用文字代替呀”,领导人给我一张图:

经过对官方文档仔细的阅读,依旧咩有发现领导给的案例,想想可能是真滴没有,因为领导之前是用reactant designreact的支持是相当成熟的,而ant design vue才发布没多长时间呢,这个案例的写法呢,也是典型的JSX语法继续研究官方文档,Upload组件其实是有一个showUploadList的属性的,从命名可以看出,应该是控制文件列表是否展示的,再看看官方文档的解释:

没错了,所以现在就有一个简单的思路,不使用默认的文件列表展示,我们重新自定义,简单来说,就是设置showUploadList = "flase"。之前使用element-ui的时候,对默认的文件列表样式做过重构,主要就是在beforeUpload的时候进行初始化,监听on-progress事件,获取文件上传的进度,然后将这些数据按照UI在页面上展示出来就可以了。需要注意的是,修改和删除vue实例data里面的Object属性,需要使用this.$setthis.$delete哦 在ant design vueUpload组件里呢,我们就需要监听组件的change事件,file里面的percent属性,就是上传文件的进度啦

仔细的捋了捋之后,发现这种实现其实是有点丢了西瓜捡了芝麻的,因为自定义的话。 这里的文件列表展示除了每一项有小图标,其他样式其实跟默认样式是一毛一样的,所以自定义样式基本跟UploadList有90%保持一致呢。无论是照猫画虎,还是复制粘贴,都是显得很是冗余而且,上传文件的进度条,加载动效等可能都要复刻进去花费这么大功夫只搞这么一个小功能,想想真滴是有些得不偿失呢 接下来,我又到Github上看有没有人提过相关的issue,结果还是一无所获哎,只能去看看源码了

UploadList 组件源码

源码链接这里着重看看UploadList中有关file.name的部分。因为含有file.name字段的就是有关文件名的展示。

const preview = file.url? [<atarget="_blank"rel="noopener noreferrer"class={listItemNameClass}title={file.name}{...linkProps}href={file.url}onClick={e => this.handlePreview(file, e)}>{file.name}</a>,downloadOrDelete,]: [<spankey="view"class={`${prefixCls}-list-item-name`}onClick={e => this.handlePreview(file, e)}title={file.name}>{file.name}</span>,downloadOrDelete,];

官方UploadList的实现使用的是JSX用法,所以,根据JSX语法的特性,某种意义上说,{ file.name }应该是可以作为一个组件出现的上面我们知道file.name可以是一个组件。但是在我这个项目要实现的话,可能也需要对原有的代码进行JSX语法的重构,这个任务也是相对比较重的有没有更简单的方法呢?其实在项目中我们引用第三方包或者插件的时候,它都是以javascriptES5) 的形式出现的所以可以再看看node_moudles目录下该组件的源码

var preview = file.url ? [h('a',(0, _babelHelperVueJsxMergeProps2['default'])([{attrs: {target: '_blank',rel: 'noopener noreferrer',title: file.name},'class': listItemNameClass }, linkProps, {attrs: {href: file.url},on: {'click': function click(e) {return _this2.handlePreview(file, e);}}}]),[file.name]), downloadOrDelete] : [h('span',{key: 'view','class': prefixCls + '-list-item-name',on: {'click': function click(e) {return _this2.handlePreview(file, e);}},attrs: {title: file.name}},[file.name]), downloadOrDelete];

不难看出,这里的file.name是作为h()方法的第三个参数的首元素出现的h() 方法又是个什么玩意呢?从代码本身看,它是render()方法的第一个参数

h() 方法

上节说过,h()render()方法的第一个参数了解过vue同学应该都知道,render()其实就是vue实例的渲染函数,它比模板更接近编译器,简单来说,它可以通过javascript来创建你的HTML。渲染函数官方文档链接h()方法还有另一种我们熟悉的写法createElement()

createElement亦即h参数

// @returns {VNode}createElement(// {String | Object | Function}// 一个 HTML 标签名、组件选项对象,或者// resolve 了上述任何一种的一个 async 函数。必填项。'div',// {Object}// 一个与模板中 attribute 对应的数据对象。可选。{// (详情见下一节)},// {String | Array}// 子级虚拟节点 (VNodes),由 `createElement()` 构建而成,// 也可以使用字符串来生成“文本虚拟节点”。可选。['先写一些文字',createElement('h1', '一则头条'),createElement(MyComponent, {props: {someProp: 'foobar'}})])

上节提到,file.name是作为h()方法的第三个参数的首元素出现的仔细观察,h方法的第三个参数,它支持的类型有两种String | Array,而在UploadList的源码,它正式作为Array类型出现的

Array即数组中数组元素的类型可以是:VNodes | 文本虚拟节点

综上所述,我们不难得出结论:file.name的值可以是一个 VNode类型的虚拟节点

实现

有了思路实现就简单了,在需要自定义的地方使用 createElement方法创建相应的 VNode 即可代码如下:

export default {created () {console.log(this.$route.params.enterpriseId)// 获取当前 vue 实例的渲染函数const h = this.$createElementfilesData.financial_statements = filesData.financial_statements.map(item => ({...item,name: h('span', null, [item.name,h('img', {attrs: {src: require('@/assets/sheet_types/audit_sheet.png') },class: {'sheet-type-img': true }})])}))this.enterprise = {...this.enterprise, ...filesData }this.enterprise.id = this.$route.params.enterpriseId}}

.sheet-type-img {width: 20px;height: 20px;margin: 0px 10px;}

这样修改之后呢,浏览器控制台会有下图的情况:

看了看是warn的程度,不影响程序正常运行哦最终效果

转载请注明出处!!!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。