闲叙

嗯又在加班,处理一个小问题,但是呢我的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. 深度优先算法回溯实例
  2. Eclipse中的常用快捷键
  3. 能用钱解决的,绝不要花时间 过来人的11条人生经验
  4. android 粘性service,Android服务1 Service
  5. lol战绩查询接口_大聪明,3000元配置一台能畅玩LOL、CF、DNF的腾讯全家桶电脑,该怎么办?——12.10更新...
  6. Mysql 的表级锁和行级锁
  7. android ble status,Android BLE peripheral disconnects with status code BLE_HCI_INSTANT_PASSED(0x28)
  8. 程序员面试金典 - 面试题 10.05. 稀疏数组搜索(二分查找)
  9. PowerShell-将CSV导入SQL Server
  10. Linux curl命令
  11. luogu P1503 鬼子进村
  12. 惠普m154a状态页_惠普新品NS—1005w无线智能应用与驱动安装篇
  13. 更新数据时出错——所有记录中均未找到搜索关键字
  14. AMD将于年内推出高端Polaris图形处理器
  15. 微型计算机远程编程微软,用微软的云计算来远程管理自己的电脑
  16. 如何在电脑手机间互传文件?
  17. 跨时钟域问题(三)异步FIFO的Verilog实现(格雷码)
  18. Java分布式开发中的RPC
  19. VC++LNK2005错误:already defined in *.obj
  20. 编码,隐匿在计算机软硬件背后的语言读书笔记(6/7/8)

热门文章

  1. 动态规划问题——招聘会
  2. 小技巧——如何为foxmail中的文字编辑超链接
  3. Particle for alexa smart home skill (3)
  4. mongodb数据库的下载、安装、配置与使用
  5. 【差分约束+spfa优化】P3084 [USACO13OPEN]Photo G
  6. 自媒体领域选择大全,自媒体新手参考资料
  7. “新四大发明”走出去:“小鲜肉之国”孟加拉也有“支付宝”啦
  8. 从2.3.3到4.1.1:最全的android系统源码下载大集合
  9. case when 用法
  10. 具有手摇柴油机带动的油泵和空压机带动的柴油喷嘴的涡轮喷气式飞机