闲叙

嗯又在加班,处理一个小问题,但是呢我的Vue学的确实不是很好所以费了一番功夫在这里记录一下中间遇到的问题和学到的知识。

问题介绍

首先审批记录这个样字的,其实我觉得也还行,是因为需求的问题,电脑端是可以评论文件的,手机端则没有这个需求,所以在做组件的时候统一使用的图片,当你使用电脑端评论文件的时候,在手机端就会看到这个东西,其实我觉得之前的还是挺好的。
然后呢需要实现这个功能,我们的电脑端是使用Vue的Element,但是手机端使用的vant,所以就很尴尬,没有办法直接使用,还好我们的前段做了一个附件的功能,里面可以合理的处理文件和图片的关系,所以我的难点就变成了如何在组件里面使用组件

组件

historyData.vue审批记录组件

<template><div class="Eleme"><div class="nohistory" v-show="false"><div class="nohistory_img"></div><p>暂无审批记录</p></div><!-- 有审批记录 --><div class="history flow"><ul><li class="LiBefore" v-for="(site,index) in historydata" :key="index"><img class="flow_img" :src=site.url /><div class="flow_name">{{site.name}}<span class="post">{{site.post}}</span><span>{{site.agree}}</span><span class="flow_time">{{site.date}}</span><div><p>{{site.content}}</p></div><div v-for="(si,index2) in site.commenturl" :key="index2"><img  class="flow_img" :src="si.url" /></div></div></li></ul></div></div>
</template>

首先我们可以通过看前段代码看到问题原因,就是因为你把img标签里面放了文件的访问地址,所以出现的问题,但是基于最小程度修改代码的想法,我们把每一个图片直接换成每一个附件组件,其实也可以将每一条评论穿进去但是修改的太多了就不做修改了。
然后让我们来看一下附件的前段vue
imgShowField.vue显示附件组件

<template><div style="text-align:left;background-color:white"><div v-for="(item,index) in imageFileList" style="text-align:left;margin:25px;width:100;display:inline-block" :key="index+'image'" @click="expandImage(item,index)"><van-image width="50" height="50" :src="item.filePath"></van-image><br/><span style="font-size:12px;display:inline-block">{{item.fileName}}</span></div><div v-for="(item,index) in documentFileList" style="text-align:left;margin:25px;width:100;display:inline-block" :key="index+'document'" @click="expandDocument(item,index)"><van-image width="50" height="50" :src="item.filePath"></van-image><br/><span style="font-size:12px;display:inline-block">{{item.fileName}}</span></div><van-image-preview v-model="showPicture" :images="imageList" @change="onChange" :start-position="pictureIndex"><template v-slot:index>{{imageFileList[pictureIndex].fileName}}</template></van-image-preview><van-popup v-model="showFile" position="bottom" :style="{ height: '100%' }" get-container="body"><check-provel ref="fileShow" @backToprovel="backToprovel"></check-provel></van-popup></div>
</template>

这里面需要实现的一个问题就是实现将img标签替换为imgShowField这个组件,但是又因为这个组件的ref名称不能够相同,所以我们需要使用动态的方式实现一个ref的命名和ref命名之后的初始化,所以我们使用了动态的格式。
上代码
组件的引入,components中定义组件就不写了

<template><div class="Eleme"><div class="nohistory" v-show="false"><div class="nohistory_img"></div><p>暂无审批记录</p></div><!-- 有审批记录 --><div class="history flow"><ul><li class="LiBefore" v-for="(site,index) in historydata" :key="index"><img class="flow_img" :src=site.url /><div class="flow_name">{{site.name}}<span class="post">{{site.post}}</span><span>{{site.agree}}</span><span class="flow_time">{{site.date}}</span><div><p>{{site.content}}</p></div><img-show-field :ref="'imgShowField'+index"></img-show-field></div></li></ul></div></div>
</template>

我们直接将img标签修改为附件的组件,然后开始处理这个组价的初始化,因为有v-for所以我们可以拿到v-for中的index,这样我们初始化组件的就是imgShowField'+index,其实这个编译之后也就是imgShowField0,imgShowField1,imgShowField2这种的名称,然后现在在初始化的时候我们使用

init: function () {const self = this // 将this对象传递进来 (必须)return api.getHistoryByProinstid(this.proInsId).then(function (res) {if (res.taskList) {res.taskList.forEach(element => {let resultData = {}if (element.nextUsers.length !== 0) {resultData.name = element.nextUsers[0].realNameresultData.url = element.nextUsers[0].headUrl} else {resultData.name = ''resultData.url = ''}resultData.post = element.nextNodeNameresultData.content = '等待审批'self.historydata.push(resultData)})}if (res.cycles) {res.cycles.forEach((element, index) => {let resultData = {}resultData.name = element.auditorNameresultData.agree = element.auditStatusNameif (element.auditType === 'repeal') {resultData.post = ' 该单据已撤销 '} else if (element.auditType === 'rejected') {resultData.post = element.nodeName + ' 该单据已拒绝 '} else if (element.processStatus === 'done' && element.nodeId === 'handling' && element.auditType !== 'transfer') {resultData.post = element.nodeName + ' 该单据已办理完成 '} else {resultData.post = element.nodeName}resultData.date = element.auditTimeresultData.content = element.auditContentif (element.auditTypeDesc === '转交') {resultData.content = '转办'}if (element.sysAttachmentDTOList) {element.sysAttachmentDTOList.forEach(site => {api.shareFile(site.fileId).then(res => {console.log(res)site.url = res})})resultData.commenturl = element.sysAttachmentDTOList}self.$nextTick(() => {self.$refs[`imgShowField${index + 1}`][0].init(element.sysAttachmentDTOList)})resultData.url = element.auditorImgUrlself.historydata.push(resultData)})}let resultData = {}resultData.name = res.submitUser.submitPerNameresultData.post = '发起人'resultData.date = res.submitUser.submitDateresultData.url = res.submitUser.submitHeadUrlself.historydata.push(resultData)// console.log('审批记录', JSON.stringify(self.historydata))})},

使用

self.$refs[`imgShowField${index + 1}`][0].init(element.sysAttachmentDTOList)

方式使用找打,至于这个为什么要加1,是因为我们的这个审批记录数据需要分为两种第一种是发起者,谁谁谁发起什么审批流程,第二种才是我们意义上面的审批记录,例如说到了谁谁谁审批,谁谁评论,我们在展示的时候需要将这两种数据拼接在一起,因为发起者的时间肯定更早而且不会有评论的图片所以我们在展示图片的时候需要将后移一位,然后呢一般的初始化组件也会失败因为需要使用self.$nextTick(() => {的形式进行初始化,这样我们就完成了我们的第一部,现在可以显示图片还有文件了并且文件的显示是一个文件的图标,因为需求设置不要能够预览文件,所以第一期的任务完成了,在一个组件里面初始化多个组件

但是问题结束了吗

没有还远远没有,感谢测试他们在努力的测试下发现了原来已经完成的单据再次评论是会出现问题的,具体问题就是评论成功之后不显示评论的内容,然后我们就开始分析,为什么不显示呢

这一种他的结构是正常的我们可以正常显示

这一种是不显示,因为这个我已经改完了所以它显示的,就是因为,我们的在展示逻辑的时候有一个是会在最后一个节点审批通过之后添加一个该审批单据已完成,因为他已经完成的单据中的一个属性taskids这个就会消失(这是我们公司使用的工作流的一个东西以后我会说一下的),因为某些原因的报错所以引发了一些问题。
其实我在上面的写的代码有一个很严重的问题,就是附件这个组件在初始化的时候需要初始化几个这个东西是不确定是,是需要通过下面的拼装的数据的historydata来确定的,所以在这里肯定会遇到一个加载的问题,如果让下面加载完之后不要初始化这个组件呢,因为这个原因我改正了这个组件的命名方式,先来看代码

<template><div class="Eleme"><div class="nohistory" v-show="false"><div class="nohistory_img"></div><p>暂无审批记录</p></div><!-- 有审批记录 --><div class="history flow"><ul><li class="LiBefore" v-for="(site,index) in historydata" :key="index"><img class="flow_img" :src=site.url /><div class="flow_name">{{site.name}}<span class="post">{{site.post}}</span><span>{{site.agree}}</span><span class="flow_time">{{site.date}}</span><div><p>{{site.content}}</p></div>
<!--                      <div v-for="(si,index2) in site.commenturl" :key="index2">-->
<!--                          <img  class="flow_img" :src="si.url" @click="readPicOrFile(site.commenturl,index2)"/>-->
<!--                      </div>-->
<!--                      <img-show-field ref="imgShowField"></img-show-field>--><img-show-field ref="imgShowField" :key="index"></img-show-field></div></li></ul></div></div>
</template>
init: function () {const self = this // 将this对象传递进来 (必须)let list = []api.getHistoryByProinstid(this.proInsId).then(function (res) {list = res// console.log('审批记录', JSON.stringify(self.historydata))}).then(res => {if (list.taskList) {list.taskList.forEach(element => {let resultData = {}if (element.nextUsers.length !== 0) {resultData.name = element.nextUsers[0].realNameresultData.url = element.nextUsers[0].headUrl} else {resultData.name = ''resultData.url = ''}resultData.post = element.nextNodeNameresultData.content = '等待审批'self.historydata.push(resultData)})}if (list.cycles) {list.cycles.forEach((element, index) => {let resultData = {}resultData.name = element.auditorNameresultData.agree = element.auditStatusNameif (element.auditType === 'repeal') {resultData.post = ' 该单据已撤销 '} else if (element.auditType === 'rejected') {resultData.post = element.nodeName + ' 该单据已拒绝 '} else if (element.processStatus === 'done' && element.nodeId === 'handling' && element.auditType !== 'transfer') {resultData.post = element.nodeName + ' 该单据已办理完成 '} else {resultData.post = element.nodeName}resultData.date = element.auditTimeresultData.content = element.auditContentif (element.auditTypeDesc === '转交') {resultData.content = '转办'}if (element.sysAttachmentDTOList) {element.sysAttachmentDTOList.forEach(site => {api.shareFile(site.fileId).then(res => {console.log(res)site.url = res})})resultData.commenturl = element.sysAttachmentDTOList}resultData.url = element.auditorImgUrlself.historydata.push(resultData)})}let resultData = {}resultData.name = list.submitUser.submitPerNameresultData.post = '发起人'resultData.date = list.submitUser.submitDateresultData.url = list.submitUser.submitHeadUrlself.historydata.push(resultData)}).then(res => {self.$nextTick(() => {self.historydata.forEach((element, index) => {// this.$refs[`generate${index}`][0].getData().then(data => {//   alert(JSON.stringify(data))// }).catch(e => {// })// this.$refs[`imgShowField${index}`][0]if (element.commenturl !== null && self.$refs.imgShowField[index] !== undefined) {self.$refs.imgShowField[index].init(element.commenturl)}// for (var i; i < self.$refs.imgShowField.length; i++) {//   self.$refs.imgShowField[i].init(element.sysAttachmentDTOList)// }})})})},

上面的两个代码分别是组件的位置和存放的方式我们在这里讲解一下
我们使用了<img-show-field ref="imgShowField" :key="index"></img-show-field>这种方式来对于组件进行一个定义,虽然说ref的名称不不能够重复但是我们这里是使用的一个组的概念,就是都是这个名称但是这个是一个数组我们使用一个数组的概念,为了解决我们的组件初始化没有完成但是组件已经出现的问题,其实我们先将v-for的元素给取出,然后再去遍历这样既可以拿到所有的元素了应该是没得问题了。
还有就是在职做组件的时候需要考虑到一个问题就是初始化组件的时候的传值,这个附件组件初始化的传值需要考虑到可能为null,undefined,不要直接就用传过来对象的属性,因为会报异常的。

Vue组件里初始化组件,一对多相关推荐

  1. [vue] vue组件里的定时器要怎么销毁?

    [vue] vue组件里的定时器要怎么销毁? const timer = setInterval(() =>{ // 某些定时器操作 }, 500); // 通过$once来监听定时器,在bef ...

  2. [vue] vue组件里写的原生addEventListeners监听事件,要手动去销毁吗?为什么?

    [vue] vue组件里写的原生addEventListeners监听事件,要手动去销毁吗?为什么? 需要,原生DOM事件必须要手动销毁,否则会造成内存泄漏 个人简介 我是歌谣,欢迎和大家一起交流前后 ...

  3. [vue] 为什么我们写组件的时候可以写在.vue里呢?可以是别的文件名后缀吗?

    [vue] 为什么我们写组件的时候可以写在.vue里呢?可以是别的文件名后缀吗? 也可以写为js,jsx,ts,tsx这种 个人简介 我是歌谣,欢迎和大家一起交流前后端知识.放弃很容易, 但坚持一定很 ...

  4. vue ref是在组件里唯一吗_父组件伸手子组件的方式总结

    1. 前言 这篇文章就是总结react,vue父组件如何伸手获取子组件的数据以及调用子组件方法的. 2. react 以下的代码都是基于16.8版本. 2.1 类组件 react在hook出来前,只要 ...

  5. cli vue 外部js 引入 文件_javascript - vue cli构建的项目中,vue组件里怎么引入外部js文件里的方法...

    问 题 我想在content组件里调用外部js(test.js)里的diyfun方法,怎么实现呢? 我的content组件代码: Click export default { data () { re ...

  6. 面试官:你封装过组件吗?说一下你是在vue项目里如何封装组件的?

    你封装过组件吗?? 说一下组件封装???? 你在项目中是如何封装组件的????? 以上问题是面试官,最常问到的问题?那么你应该如何回答呢? 答: 我用vue开发的所有项目,都是采用组件化的思想开发的. ...

  7. vue中在当前组件中定义的全局变量怎么在methods中使用_Vue原理解析(十):搞懂事件API原理及在组件库中的妙用...

    在vue内部初始化时会为每个组件实例挂载一个this._events私有的空对象属性: vm._events = Object.create(null) // 没有__proto__属性 这个里面存放 ...

  8. Vue生命周期及组件

    目录 Vue 生命周期钩子 钩子函数的由来 生命周期钩子函数 生命周期图示 钩子函数测试 添加组件展示: 组件数据更新: 没建任务, 没有任务销毁, 看不到实际的效果. 创建定时任务销毁定时任务 Vu ...

  9. 实例化vue对象 绑定子组件_Vue-双向数据绑定

    实例 Vue.js应用的创建很简单,通过构造函数 Vue 就可以创建一个 Vue 的根实例,并启动 Vue: var app = new Vue({//选项 }); 变量 app 就代表了这个 Vue ...

最新文章

  1. 从 AlphaGo 到具有人类智慧的 AI 究竟有多远?François Chollet 有了一些新想法
  2. 伏威谈淘宝网的高并发处理与压力测试(转)
  3. python画出心形图-python如何绘制心形
  4. python 去掉文件头部几行_批量重命名文件的python代码
  5. spring调用存储过程
  6. 【NLP】如何系统性的学习NLP,有三AI-NLP知识星球等你来
  7. 还在为多集群管理烦恼吗?RedHat 和蚂蚁、阿里云给开源社区带来了OCM
  8. 天池 在线编程 订单分配(回溯)
  9. js 计时器无法清除是为什么
  10. bzoj 3930: [CQOI2015]选数
  11. 14寸笔记本电脑推荐_2020笔记本电脑推荐(小米篇)
  12. IOS上路_04-简单示例-图片浏览器
  13. springboot干什么的_SpringBoot是什么?干嘛用的?新手入门看这一篇就够了
  14. Learning Deep Features for Discriminative Localization
  15. 切图教程,app切图命名总结
  16. js获取当前时间的年月日时分秒以及时间的格式化
  17. WebSocket 结合 Nginx 实现域名及 WSS 协议访问
  18. 这几行 C++ 代码,真的骚!
  19. 基于C#的音乐播放器
  20. idea git 拉取代码特别慢解决方案

热门文章

  1. 蚂蚁区块链正式升级为蚂蚁链,究竟在下怎样的一盘大棋?
  2. 诺贝尔奖今起揭晓 4位华裔科学家成热门
  3. 特来电、星星充、国家电网三足鼎立的充电桩遭巨头偷袭
  4. iOS保持App真后台运行
  5. pygame.USEREVENT创建多个用户事件
  6. (接上篇)浮动静态路由主备路径故障倒换实验NQA技术
  7. 抄币不要盲目看价值,不然会被牵着走
  8. 盘点和反思在微信的阴影下艰难求生的移动端IM应用
  9. 中国阀门喷射式喷墨打印机市场深度研究分析报告
  10. 中电十所提前批面经(通信算法岗)