大良网站建设市场互联网公司排名保定
web/
2025/9/28 0:38:33/
文章来源:
大良网站建设市场,互联网公司排名保定,做海岛旅游预定网站的,株洲企业关键词优化最新报价最近需要写一个评论区功能#xff0c;所以打算仿照抖音做一个评论功能#xff0c;支持展开和收起#xff0c; 首先我们需要对功能做一个拆解#xff0c;评论区功能#xff0c;两个模块#xff0c;一个是发表评论模块#xff0c;一个是评论展示区。接下来对这两个模块进行… 最近需要写一个评论区功能所以打算仿照抖音做一个评论功能支持展开和收起 首先我们需要对功能做一个拆解评论区功能两个模块一个是发表评论模块一个是评论展示区。接下来对这两个模块进行详细描述。 使用到的技术 uniapp uview2.0 文章最后我会贴上全部源码 一、发表评论模块
这个模块使用uview的两个组件来完成分别是u-popup弹出层和u-input输入框
下面是代码和展示图
u-popup :showtalkShow modebottom :customStyle{width:100%,border-radius:8rpx} closepopclosed openkeyboardtrue :safeAreaInsetBottomtrueview classflex justify-between align-center stylepadding: 32rpx;div classcirbOX padding-left padding-right-smu--form labelPositionleft :modeltalkData :rulesRules refForm :borderBottomfalseu-form-item label proptxt :borderBottomfalse refitem1 labelWidth0u--input :focuskeyboard v-modeltalkData.txt cursorSpacing30 maxlength100 :placeholderpinglunHolder bordernone clearable/u--input/u-form-item/u--form/divdiv classsubmitpinglun clicksubmit发布/div/view/u-popup 这部分需要注意两点
1.input组件的focus属性的设置
在弹出层弹出的时候 在open事件中对input的focus属性布尔值设置为trueclose时候设置focus为false。这样做的目的是在弹出输入评论的弹窗时会拉起小键盘这个交互方式是模仿的微信朋友圈发布评论的形式。
2.input的cursorSpacing属性输入框聚焦时底部与键盘的距离设置
当键盘拉起时候整个输入框因为设置了cursorSpacing30故整体页面会被小键盘托起。 当收起小键盘时候输入框有回归到手机底部因为我们popup设置的是底部的弹出层。这样是和微信朋友圈发布评论是对标的。 二、展示评论区的功能
这一部分我封装成了组件因为需求的要求需要下拉加载评论故在组件外部循环一级评论组件内部展示一级评论和二级评论其中二级评论是在组件内部去循环,
循环一级评论的时候需要注意因为后续要获取pinglun组件的实例所以在ref的设置上面起初我按照for循环提供的index来拼的字符串这也导致后续bug的出现埋下伏笔所以我后续调整了选择了id这个唯一值作为组件实例的ref名字这个很关键
div v-for(item,index) in onePagePinglunList :keyitem.id classmargin-bottompinglun :refpinglun-${item.levelOneCommentVo.id} :caseIdDatacaseId :dataitem :indexxxindex commentgoComment noLoginsonNoLogin/pinglun/div
组件代码
templatediv!-- 一级评论 --div classflex justify-start align-start margin-bottom-smdiv classmargin-right-xsd-image :dSrconePageList.levelOneCommentVo.userAvatar dModeaspectFit dWidth72rpx dHeight72rpx/d-image/divdiv classflex-subdiv classflex justify-start align-centerdiv classname margin-right-sm{{onePageList.levelOneCommentVo.userName}}/divdiv classzuozhe flex justify-center align-center v-ifonePageList.levelOneCommentVo.belongAuthor1作者/div/divdiv classflex justify-between align-center clickgoPinglun(1,onePageList.levelOneCommentVo.id,onePageList.levelOneCommentVo.userName,onePageList.levelOneCommentVo.id)div classcontent flex-sub{{onePageList.levelOneCommentVo.content}}/divdiv classflex flex-direction align-center stylewidth: 68rpx; click.stoplikepinglun(1,,onePageList.levelOneCommentVo.id)div classmargin-bottom-xsdiv v-showonePageList.levelOneCommentVo.isCurrentUserLike0u-icon nameheart color#667286 size34rpx/u-icon/divdiv v-showonePageList.levelOneCommentVo.isCurrentUserLike1u-icon nameheart-fill colorred size34rpx/u-icon/div/divdiv classlikeNum{{onePageList.levelOneCommentVo.likeCount}}/div/div/divdiv classtime{{ $u.timeFrom(new Date(onePageList.levelOneCommentVo.createTime).getTime())}}/div/div/div!-- 二级评论 --div classerpinglunBox :style{height:${pingjiaBoxMaxHeight}px,opacity:pinglunOpcity,}div classpinglunDomdiv v-for(item,index) in onePageList.twoLevelpinglun :keyitem.id classmargin-bottom-smdiv classflex justify-start align-startdiv classmargin-right-xsd-image :dSrcitem.userAvatar dModeaspectFit dWidth72rpx dHeight72rpx/d-image/divdiv classflex-subdiv classflex justify-start align-centerdiv classname margin-right-sm{{item.userName}}/divdiv classzuozhe flex justify-center align-center margin-right-sm v-ifitem.belongAuthor1作者/divdiv classname v-ifitem.isReplayTwoComment1回复 {{item.replayLevelTwoCommentUser.userName}}/div/divdiv classflex justify-between align-center clickgoPinglun(2,item.id,item.userName,onePageList.levelOneCommentVo.id)div classcontent flex-sub{{item.content}}/divdiv classflex flex-direction align-center stylewidth: 68rpx; click.stoplikepinglun(2,index,item.id)div classmargin-bottom-xsdiv v-showitem.isCurrentUserLike0u-icon nameheart color#667286 size34rpx/u-icon/divdiv v-showitem.isCurrentUserLike1u-icon nameheart-fill colorred size34rpx/u-icon/div/divdiv classlikeNum{{item.likeCount}}/div/div/divdiv classtime{{ $u.timeFrom(new Date(item.createTime).getTime())}}/div/div/div/div/div/div!-- 展开和收起按钮 --div classflex justify-start align-center stylepadding-left: 84rpx;div classseeMore padding-top-sm padding-bottom flex align-center v-ifonePageList.levelTwoCommentCount 0params.current totalPage click$u.throttle(getTwoLevelPinglun, 1000,true)div classmargin-right-xs查看更多回复/divu-icon namearrow-down color#00875A size28rpx :boldtrue/u-icon/divdiv classseeMore retract padding-top-sm padding-bottom margin-left flex justify-center align-center v-ifparams.current 1 click$u.throttle(retract, 1000,true)div classmargin-right-xs收起/divu-icon namearrow-up color#00875A size28rpx :boldtrue/u-icon/div/div/div
/template
感觉唯一的难点在于因为展开收缩使用的过渡动画大家应该都知道想使用这个过渡必须设置有效值也就是说比如我给高度写过渡动画从一个高度到一个高度都需要是具体的值atuo这种被内容撑开的高度是不作数的。
这里拿高度需要注意的是需要等待渲染完毕再去获取高度不然拿到的值就是不准确的。
下面是我写的获取高度的函数。如果一个nexttick也获取不到准确高度那么就再加个延时器就差不多可以获取到准确高度了。 updatHeight() {let that thisthis.$nextTick(() {// this.timer setTimeout(() {this.createSelectorQuery().select(.pinglunDom).boundingClientRect(function(rect) {// console.log(rect);that.pingjiaBoxMaxHeight rect.heightthat.pinglunOpcity 1}).exec();// }, 0)})},
还有一个需要注意的点就是在一级评论发布之后需要拿到所有pinglu组件的实例去调用这个方法重置所有二级评论的高度。调用这个方法的前提也必须是一级评论的渲染完毕不然还是不起作用
以下是代码
this.$forceUpdate();this.$nextTick(() {for (let i 0; i this.onePagePinglunList.length; i) {this.$refs[pinglun-${this.onePagePinglunList[i].levelOneCommentVo.id}][0].updatHeight() if (this.onePagePinglunList[i].twoLevelpinglun.length 0) {this.$refs[pinglun-${this.onePagePinglunList[i].levelOneCommentVo.id}][0].params.current 1}}})
至此应该就没什么需要注意的地方了
可能也是第一次写这个功能还有很多可以优化的地方。希望对各位有所帮助接下来我把评论功能所有源码贴在下面。
因为我的评论功能是在案例详情里面的所以有两个文件一个是案例详情一个就是封装的评论组件
案例详情
templatediv :style{padding-bottom:${(safeAreaBottom*2)144}rpx}div stylepadding: 32rpx 32rpx 50rpx;div classmargin-bottom-sm txt-1成功蜕变历程/divdiv classtoplicheng flex justify-center align-center margin-bottom-smdiv classflex flex-direction align-centerdiv classflex align-centerd-image dSrchttps://tj-data.oss-cn-hangzhou.aliyuncs.com/uploadFiles/wx/mzkHomeland/caseDetailIcON2.png dModeaspectFit dWidth32rpx dHeight32rpx/d-imagediv classtoptxt1 margin-left-xs体重/div/divdiv classtoptxt2 margin-top-xs{{topweightcha||0}}kg/div/divdiv classmidBox flex flex-direction align-centerdiv classxmonth flex justify-center align-center margin-bottom-xs逆糖3个月/divdiv classtopshuxian/div/divdiv classflex flex-direction align-centerdiv classflex align-centerd-image dSrchttps://tj-data.oss-cn-hangzhou.aliyuncs.com/uploadFiles/wx/mzkHomeland/caseDetailIcON1.png dModeaspectFit dWidth32rpx dHeight32rpx/d-imagediv classtoptxt1 margin-left-xs空腹血糖/div/divdiv classtoptxt2 margin-top-xs{{topxuetangcha||0}}mmol/L/div/div/div!-- 案例信息 --div classcaseBoxdiv classcase-head-box flex justify-between align-centerdiv classhead-left-box flexdiv classavatarBoxu-avatar :srcdetailData.userInfoVo.userAvatar || https://tj-data.oss-cn-hangzhou.aliyuncs.com/uploadFiles/wx/mzkHomeland/healthy.png size72rpx modeaspectFill/u-avatar/divdivdiv classtxt-1 margin-bottom-xs{{detailData.userInfoVo.userName||暂无昵称}}/divdiv classtxt-2{{detailData.isExistServicePack?detailData.servicePackVo.servicePackName:暂无服务包}}/div/div/divdiv class flex justify-center align-center stylewidth: 80rpx;height: 80rpx;u-icon nameshare-square color size34rpx/u-icon/div/divdiv classcaseBoxContentBoxu-row justifyspace-startu-col span4view classtxt-4 margin-bottom项目/view/u-colu-col span4view classtxt-4 margin-bottom管理前/view/u-colu-col span4view classtxt-4 margin-bottom管理后/view/u-col/u-rowu-row justifyspace-startu-col span4viewdiv classtxt-3服务时间/div/view/u-colu-col span4viewdiv classstartTime{{detailData.managementInfoVo.managementStartTime||--}}/div/view/u-colu-col span4viewdiv classendTime{{detailData.managementInfoVo.managementEndTime||--}}/div/view/u-col/u-rowdiv classline/divu-row justifyspace-startu-col span4viewdiv classtxt-3体重/divdiv classtxt-7kg/div/view/u-colu-col span4viewdiv classyellow-box flex justify-center align-center styleposition: relative;{{detailData.managementInfoVo.beforeManagementWeight||--}}div classjiantou v-ifdetailData.managementInfoVo.beforeManagementFastingSugarBloodTrend3d-image dSrchttps://tj-data.oss-cn-hangzhou.aliyuncs.com/uploadFiles/wx/mzkHomeland/redUp.png dModeaspectFit dWidth24rpx dHeight24rpx/d-image/divdiv classjiantou v-else-ifdetailData.managementInfoVo.beforeManagementFastingSugarBloodTrend1d-image dSrchttps://tj-data.oss-cn-hangzhou.aliyuncs.com/uploadFiles/wx/mzkHomeland/greenDown.png dModeaspectFit dWidth24rpx dHeight24rpx/d-image/div/div/view/u-colu-col span4viewdiv classgreen-box flex justify-center align-center{{detailData.managementInfoVo.afterManagementWeight||--}}/div/view/u-col/u-rowdiv classline/divu-row justifyspace-startu-col span4viewdiv classtxt-3空腹血糖/divdiv classtxt-7mmol/L/div/view/u-colu-col span4viewdiv classyellow-box flex justify-center align-center styleposition: relative;{{detailData.managementInfoVo.beforeManagementFastingSugarBlood||--}}div classjiantouv-ifdetailData.managementInfoVo.beforeManagementWeightTrend3||detailData.managementInfoVo.beforeManagementWeightTrend4||detailData.managementInfoVo.beforeManagementWeightTrend5d-image dSrchttps://tj-data.oss-cn-hangzhou.aliyuncs.com/uploadFiles/wx/mzkHomeland/redUp.png dModeaspectFit dWidth24rpx dHeight24rpx/d-image/divdiv classjiantou v-else-ifdetailData.managementInfoVo.beforeManagementWeightTrend1d-image dSrchttps://tj-data.oss-cn-hangzhou.aliyuncs.com/uploadFiles/wx/mzkHomeland/greenDown.png dModeaspectFit dWidth24rpx dHeight24rpx/d-image/div/div/view/u-colu-col span4viewdiv classgreen-box flex justify-center align-center{{detailData.managementInfoVo.afterManagementFastingSugarBlood||--}}/div/view/u-col/u-rowdiv classline/divu-row justifyspace-startu-col span4viewdiv classtxt-3用药数量/div/view/u-colu-col span4viewdiv classyellow-box flex justify-center align-center{{detailData.managementInfoVo.beforeManagementMedicationCount||0}}/div/view/u-colu-col span4viewdiv classgreen-box flex justify-center align-center{{detailData.managementInfoVo.afterManagementMedicationCount||0}}/div/view/u-col/u-rowdiv classline/divu-row justifyspace-startu-col span4viewdiv classtxt-3对比照片/div/view/u-colu-col span4viewdiv classmargin-bottom-smdivdiv v-ifdetailData.managementInfoVo.beforeManagementImagePhoto classnoPicBox flex justify-center align-center暂无/divdiv v-elsed-image :dSrcdetailData.managementInfoVo.beforeManagementImagePhoto dModeaspectFit dWidth140rpx dHeight140rpx/d-image/div/div/div/view/u-colu-col span4viewdiv classmargin-bottom-smdivdiv v-ifdetailData.managementInfoVo.afterManagementImagePhoto classnoPicBox flex justify-center align-center暂无/divdiv v-elsed-image :dSrcdetailData.managementInfoVo.afterManagementImagePhoto dModeaspectFit dWidth140rpx dHeight140rpx/d-image/div/div/div/view/u-col/u-row/div/div!-- 评价 --div classevaluateBox margin-top-sm margin-bottom-smdiv classmargin-bottom-sm txt-1健康评价/divdiv classmargin-top-sm flex flex-wrap pingjiaBoxview classpingjiaDomdiv v-for(item,index) in defaultPingjia :keyitem.id classflex div classtag margin-right-sm flex align-center margin-bottom-sm :style{background:item.styleBg}div styleheight: 100%; classflex align-start margin-right-smd-image :dSrcitem.styleIcon dModeaspectFit dWidth26rpx dHeight26rpx/d-image/divtext :style{max-width: 544rpx,word-break: break-all,color:item.styleColor}{{item.content}}/text/div/div/view/div/div!-- echart --!-- div classmargin-bottom-sm styleposition: relative;overflow: hidden; v-for(item,index) in echartList :keyindexdetailChart :echarTypeitem/detailChart/div --/div!-- 评论 --div stylepadding: 0 32rpx 56rpx;background: #FFFFFF;div classflex justify-between align-centerdiv classpingluntitle{{detailData.interActionVo.commentCount||0}} 评论/divdiv/div/divdiv v-for(item,index) in onePagePinglunList :keyitem.id classmargin-bottompinglun :refpinglun-${item.levelOneCommentVo.id} :caseIdDatacaseId :dataitem :indexxxindex commentgoComment noLoginsonNoLogin shouqishouqiTwoPinglun/pinglun/div/divdiv classcontentB- 让每个人都能从知识中获得健康 -/div!-- 底部评价评论点赞收藏 --div classpingjialikeBox flex justify-between align-center :style{bottom:${(safeAreaBottom*2)}rpx}div classtalksomething flex justify-center align-center clickopenPinglun说点什么吧/divdiv classflex justify-around stylewidth: 428rpx;div classflex align-center btn click$u.throttle(clickLike, 500,true)div v-showdetailData.interActionVo.isCurrentUserLike0u-icon nameheart color size34rpx/u-icon/divdiv v-showdetailData.interActionVo.isCurrentUserLike1u-icon nameheart-fill colorred size34rpx/u-icon/divtext classmargin-left-xs{{detailData.interActionVo.likeCount||0}}/text/divdiv classflex align-center btn click$u.throttle(clickCollect, 500,true)div v-showdetailData.interActionVo.isCurrentUserCollection0u-icon namestar color size34rpx/u-icon/divdiv v-showdetailData.interActionVo.isCurrentUserCollection1u-icon namestar-fill color#ff991f size34rpx/u-icon/divtext classmargin-left-xs{{detailData.interActionVo.collectionCount||0}}/text/divdiv class flex align-center btnu-icon namechat color size34rpx/u-icontext classmargin-left-xs{{detailData.interActionVo.commentCount||0}}/text/div/div/divu-popup :showtalkShow modebottom :customStyle{width:100%,border-radius:8rpx} closepopclosed openkeyboardtrue :safeAreaInsetBottomtrueview classflex justify-between align-center stylepadding: 32rpx;div classcirbOX padding-left padding-right-smu--form labelPositionleft :modeltalkData :rulesRules refForm :borderBottomfalseu-form-item label proptxt :borderBottomfalse refitem1 labelWidth0u--input :focuskeyboard v-modeltalkData.txt cursorSpacing30 maxlength100 :placeholderpinglunHolder bordernone clearable/u--input/u-form-item/u--form/divdiv classsubmitpinglun clicksubmit发布/div/view/u-popupu-modal title确认登录 :showshow1 width608rpx content为了您的良好体验,建议您先确认登录 ~ :closeOnClickOverlaytrue closeshow1falseu-button slotconfirmButton text确定 shapecircle color#00875A open-typegetPhoneNumber getphonenumbergetPhoneNumber :customStyle{width:264rpx,height:68rpx}/u-button/u-modalu-toast refuToast/u-toast/div
/templatescriptimport { mapState } from vuex;import detailChart from ./detailEchart.vueimport pinglun from ./pinglun.vueimport { sub } from /utils/tool.jsimport { getDetail, getCurveModule, collection, like, savecomment, getLevelOnePage } from /api/case/case.jsexport default {data() {return {show1: false,keyboard: false,pinglunHolder: 说点什么吧,Rules: {txt: [{required: true,type: any,message: 评论不能为空,trigger: [blur, change]},{validator: (rule, value, callback) {return value.length 100;},message: 您评论的字数超过100,请调整您的字数~,trigger: [blur, change]}],},talkShow: false,talkData: { //弹框form值 评论txt: },caseId: null,echartList: [],detailData: {},defaultPingjia: [],topweightcha: null,topxuetangcha: null,pinglunForm: { //接口参数caseId: null,caseLevelOneCommentId: , //对一级评论进行回复时不可为空caseLevelTwoCommentId: , //对二级评论进行回复时不可为空content: null,userId: null,},params: {current: 1,limit: 5,likeSort: 2, //点赞数排序 1升序 2降序timeSort: 2, //创建时间排序 1升序 2降序},totalPage: 1,onePagePinglunList: [],pinglunType: null, //判断用户评论的类型是案例评论3还是一级评论1还是二级评论2erpinglunIndex: 0, //暂存二级评论发送给父级组件给的一级评论的index}},components: { detailChart, pinglun },computed: {...mapState([hasLogin, safeAreaBottom, userInfo, ])},// 发送给朋友onShareAppMessage(res) {return {title: 妙智健康案例,path: /pages-caseStory/caseDetail/index?caseId${this.caseId}title${this.detailData.userInfoVo.userName}}},//分享到朋友圈onShareTimeline(res) {return {title: 妙智健康案例,query: caseId${this.caseId}title${this.detailData.userInfoVo.userName},path: /pages-caseStory/caseDetail/index //自定义路径拼参数会导致接收参数会失败}},onReady() {},onLoad(option) {this.$refs.Form.setRules(this.Rules)this.caseId option?.caseIduni.setNavigationBarTitle({title: ${option.title||}案例});this.getdetailData()this.getLevelOnePageData()},onUnload() {// this.$store.commit(set_caseShareEchartPicList, [])},onShow() {},methods: {sub,async getPhoneNumber(e) {// console.log(获取手机号code, e) //获取手机号已经不需要先进行wx.login最新文档if (!e.detail.code) {uni.showToast({title: 登录需要获取您的手机号,icon: none,duration: 2500})return}let resss await this.$store.dispatch(loginFn, e) //能同步拿到vux中mutaion的resolve然后给fourDataNum赋值登录后数据更新console.log(resss);if (resss.state 1) { //登录成功this.show1 false}},async getdetailData() {uni.showLoading({title: 加载中...})try {let res await getDetail({caseId: this.caseId,userId: this.hasLogin ? this.userInfo?.userId : })let echarRes await getCurveModule({caseId: this.caseId,})if (res.state 1) {this.detailData res.contentthis.defaultPingjia res.content.personnelEvaluationVoListthis.topweightcha this.sub(this.detailData.managementInfoVo.afterManagementWeight, this.detailData.managementInfoVo.beforeManagementWeight)this.topxuetangcha this.sub(this.detailData.managementInfoVo.afterManagementFastingSugarBlood, this.detailData.managementInfoVo.beforeManagementFastingSugarBlood)}if (echarRes.state 1) {this.echartList echarRes.content.map(item {let obj {title: item.caseCurveType 1 ? 硅基 : (item.caseCurveType 2 ? 微策 : 体重),defaultTime: item.caseCurveType 1 ? item.curveStartDate : [item.curveStartDate, item.curveEndDate],userId: res.content.userInfoVo.userId}return obj})}uni.hideLoading();} catch (e) {uni.hideLoading();uni.$u.toast(e)}},async clickLike(item, index) {if (!this.hasLogin) {this.show1 truereturn}try {let res await like({userId: this.userInfo?.userId,caseId: this.caseId,})if (res.state 1) {if (this.detailData.interActionVo.isCurrentUserLike 1) {this.detailData.interActionVo.isCurrentUserLike 0this.detailData.interActionVo.likeCount--} else if (this.detailData.interActionVo.isCurrentUserLike 0) {this.detailData.interActionVo.isCurrentUserLike 1this.detailData.interActionVo.likeCount}}} catch (e) {uni.$u.toast(e)}},async clickCollect(item) {if (!this.hasLogin) {this.show1 truereturn}try {let res await collection({userId: this.userInfo?.userId,caseId: this.caseId,})if (res.state 1) {if (this.detailData.interActionVo.isCurrentUserCollection 1) {this.detailData.interActionVo.isCurrentUserCollection 0this.detailData.interActionVo.collectionCount--} else if (this.detailData.interActionVo.isCurrentUserCollection 0) {this.detailData.interActionVo.isCurrentUserCollection 1this.detailData.interActionVo.collectionCount}}} catch (e) {uni.$u.toast(e)}},popclosed() {this.talkData.txt this.keyboard falsethis.talkShow falseconsole.log(this.keyboard);},async getLevelOnePageData() {uni.showLoading({title: 加载中...})try {let res await getLevelOnePage({ userId: this.hasLogin ? this.userInfo?.userId : , caseId: Number(this.caseId), ...this.params })if (res.state 1) {for (let i 0; i res.content.records.length; i) {res.content.records[i].twoLevelpinglun []if (this.onePagePinglunList.some(item item.levelOneCommentVo.id res.content.records[i].levelOneCommentVo.id)) { //删除重复项res.content.records.splice(i, 1)}}this.onePagePinglunList [...this.onePagePinglunList, ...res.content.records]this.totalPage Math.ceil(res.content.total / this.params.limit) //总页数总数量/每页数量}uni.hideLoading();} catch (e) {uni.hideLoading();uni.$u.toast(e)}},openPinglun() {if (!this.hasLogin) {this.show1 truereturn}this.pinglunType 3 //案例评论this.pinglunHolder 说点什么吧this.pinglunForm.caseLevelOneCommentId //不回复一二级评论时候置空该字段this.pinglunForm.caseLevelTwoCommentId //不回复一二级评论时候置空该字段this.talkShow true// this.keyboard true},goComment(e) { //处理回复一级二级评论 案例的顶级评论在openPinglun()函数中console.log(e);this.pinglunType e.type //评论类型console.log(this.pinglunType, this.pinglunType);if (e.type 1) { //一级评论this.pinglunForm.caseLevelOneCommentId e.idthis.erpinglunIndex e.indexthis.pinglunHolder 回复 ${e.replyName}} else if (e.type 2) { //二级评论this.pinglunForm.caseLevelTwoCommentId e.idthis.erpinglunIndex e.indexthis.pinglunHolder 回复 ${e.replyName}}console.log(点击的item, this.$refs[pinglun-${this.erpinglunIndex}][0].onePageList);this.talkShow true// this.keyboard trueconsole.log(this.keyboard);},async submit() {this.pinglunForm.userId this.userInfo.userIdthis.pinglunForm.content this.talkData.txtthis.pinglunForm.caseId this.caseId// let form {// caseId: this.caseId,// caseLevelOneCommentId: , //对一级评论进行回复时不可为空// caseLevelTwoCommentId: , //对二级评论进行回复时不可为空// content: this.talkData.txt,// userId: this.userInfo.userId,// }try {let res await savecomment(this.pinglunForm)if (res.state 1) {if (this.pinglunType 3) { //案例评论this.onePagePinglunList.unshift({twoLevelpinglun: [],...res.content.caseCommentHomeVo})this.$forceUpdate();this.$nextTick(() {for (let i 0; i this.onePagePinglunList.length; i) {this.$refs[pinglun-${this.onePagePinglunList[i].levelOneCommentVo.id}][0].updatHeight() //重置子组件内部height 不管新增一级还是二级都需要全部重置高度不然会出现bugif (this.onePagePinglunList[i].twoLevelpinglun.length 0) {this.$refs[pinglun-${this.onePagePinglunList[i].levelOneCommentVo.id}][0].params.current 1}}console.log(this.$refs[pinglun-${127}][0].onePageList);})this.$forceUpdate();} else if (this.pinglunType 1 || this.pinglunType 2) { //回复一级评论或二级评论 push完需要注意的是在获取分页数据时候去重因为这个push操作是模拟更新数据后端并不知晓所以后端未做去重console.log(this.$refs[pinglun-${this.erpinglunIndex}][0].onePageList.twoLevelpinglun);this.$refs[pinglun-${this.erpinglunIndex}][0].onePageList.twoLevelpinglun.push({...res.content.caseLevelTwoCommentVo})console.log(this.$refs[pinglun-${this.erpinglunIndex}][0].onePageList.twoLevelpinglun);let indxx;for (let i 0; i this.onePagePinglunList.length; i) {if (this.onePagePinglunList[i].levelOneCommentVo.id this.erpinglunIndex) {indxx ibreak}}// 目的是防止发表一级评论之后父级向下重新注入数据会触发pinglun组件内部的watch导致会重置组件内部的twoLevelpinglun为[],this.onePagePinglunList[indxx].twoLevelpinglun this.$refs[pinglun-${this.erpinglunIndex}][0].onePageList.twoLevelpinglunthis.onePagePinglunList[indxx].levelTwoCommentCountthis.$refs[pinglun-${this.erpinglunIndex}][0].updatHeight() //重置子组件内部height}this.talkData.txt //重置评论this.keyboard false //自动聚焦设为falsethis.talkShow false //关闭弹窗this.updatePinglunNum() //更新评论数量console.log(this.keyboard);this.$refs.uToast.show({type: success,message: 已发送评论~,duration: 1200,})}} catch (e) {uni.$u.toast(e)}},sonNoLogin(e) {console.log(e);if (!this.hasLogin) {this.show1 truereturn}},async updatePinglunNum() {try {let res await getDetail({caseId: this.caseId,userId: this.hasLogin ? this.userInfo?.userId : })if (res.state 1) {this.detailData res.content}} catch (e) {uni.$u.toast(e)}},//因为每次发表二级评论都会往父级的twoLevelpinglun添加属性也就是submit函数里面的565行代码会导致一个bug 就是发布二级评论后// 因为同时给父级也赋值了故收起二级评论后再发表一级评论重置了了渲染会将父级被赋值的twoLevelpinglun同步到二级评论的twoLevelpinglun相当于之前收起操作白重置了twoLevelpinglunshouqiTwoPinglun(index) {let indxx;for (let i 0; i this.onePagePinglunList.length; i) {if (this.onePagePinglunList[i].levelOneCommentVo.id index) {indxx ibreak}}this.onePagePinglunList[indxx].twoLevelpinglun []},},// 上拉加载async onReachBottom() {if (this.params.current this.totalPage) {this.$refs.uToast.show({type: warning,message: 已经到底啦~,duration: 1200,})return}this.params.current 1await this.getLevelOnePageData()uni.stopPullDownRefresh() //停止上拉加载},// 下拉刷新触发async onPullDownRefresh() {this.params.current 1 //重置页码this.onePagePinglunList []await this.getLevelOnePageData()this.$refs.uToast.show({type: success,message: 刷新成功,duration: 1200,})uni.stopPullDownRefresh() //停止下拉刷新},}
/scriptstyle langscss scopedimport /pages-caseStory/style/caseCommon.scss;.pingluntitle {font-size: 28rpx;font-family: PingFangSC;color: #1F3253;height: 90rpx;line-height: 90rpx;}.contentB {margin: 42rpx 0;font-size: 24rpx;font-weight: 400;color: #667286;text-align: center;}.pingjialikeBox {padding: 32rpx;width: 100%;height: 144rpx;background: #FFFFFF;position: fixed;left: 0;.btn {height: 70rpx;width: 78rpx;}}.toplicheng {height: 160rpx;background: linear-gradient(47deg, rgba(23, 144, 109, 0.84) 0%, #5DC063 100%);border-radius: 12rpx;}.topshuxian {width: 1rpx;height: 80rpx;opacity: 0.5;border: 2rpx solid #FFFFFF;}.xmonth {width: 156rpx;height: 47rpx;background: #FFFFFF;border-radius: 0rpx 0rpx 14rpx 14rpx;opacity: 0.8;font-size: 24rpx;font-weight: 400;color: #00875A;}.toptxt1 {font-size: 28rpx;font-weight: 400;color: #FFFFFF;}.toptxt2 {font-size: 36rpx;font-weight: bold;color: #E2FFF5;}.midBox {width: 156rpx;height: 160rpx;margin-left: 70rpx;margin-right: 23rpx;}.noPicBox {width: 140rpx;height: 140rpx;background: #E7EFF6;}.jiantou {position: absolute;top: 0;right: 0;}.evaluateBox {background: #FFFFFF;border-radius: 12rpx;padding: 40rpx 32rpx 78rpx;.tag {background: #FFF6E9;border-radius: 30rpx;padding: 20rpx 30rpx 20rpx 20rpx;vertical-align: center;}}.talksomething {width: 248rpx;height: 80rpx;background: #F4F5F7;border-radius: 40rpx;font-size: 28rpx;font-weight: 400;color: #697588;}.cirbOX {width: 600rpx;height: 80rpx;background: #F4F5F7;border-radius: 40rpx;}.submitpinglun {height: 80rpx;width: 64rpx;font-size: 32rpx;font-weight: 500;color: #00875A;line-height: 80rpx;}
/style
pinglun组件
templatediv!-- 一级评论 --div classflex justify-start align-start margin-bottom-smdiv classmargin-right-xsd-image :dSrconePageList.levelOneCommentVo.userAvatar dModeaspectFit dWidth72rpx dHeight72rpx/d-image/divdiv classflex-subdiv classflex justify-start align-centerdiv classname margin-right-sm{{onePageList.levelOneCommentVo.userName}}/divdiv classzuozhe flex justify-center align-center v-ifonePageList.levelOneCommentVo.belongAuthor1作者/div/divdiv classflex justify-between align-center clickgoPinglun(1,onePageList.levelOneCommentVo.id,onePageList.levelOneCommentVo.userName,onePageList.levelOneCommentVo.id)div classcontent flex-sub{{onePageList.levelOneCommentVo.content}}/divdiv classflex flex-direction align-center stylewidth: 68rpx; click.stoplikepinglun(1,,onePageList.levelOneCommentVo.id)div classmargin-bottom-xsdiv v-showonePageList.levelOneCommentVo.isCurrentUserLike0u-icon nameheart color#667286 size34rpx/u-icon/divdiv v-showonePageList.levelOneCommentVo.isCurrentUserLike1u-icon nameheart-fill colorred size34rpx/u-icon/div/divdiv classlikeNum{{onePageList.levelOneCommentVo.likeCount}}/div/div/divdiv classtime{{ $u.timeFrom(new Date(onePageList.levelOneCommentVo.createTime).getTime())}}/div/div/div!-- 二级评论 --div classerpinglunBox :style{height:${pingjiaBoxMaxHeight}px,opacity:pinglunOpcity,}div classpinglunDomdiv v-for(item,index) in onePageList.twoLevelpinglun :keyitem.id classmargin-bottom-smdiv classflex justify-start align-startdiv classmargin-right-xsd-image :dSrcitem.userAvatar dModeaspectFit dWidth72rpx dHeight72rpx/d-image/divdiv classflex-subdiv classflex justify-start align-centerdiv classname margin-right-sm{{item.userName}}/divdiv classzuozhe flex justify-center align-center margin-right-sm v-ifitem.belongAuthor1作者/divdiv classname v-ifitem.isReplayTwoComment1回复 {{item.replayLevelTwoCommentUser.userName}}/div/divdiv classflex justify-between align-center clickgoPinglun(2,item.id,item.userName,onePageList.levelOneCommentVo.id)div classcontent flex-sub{{item.content}}/divdiv classflex flex-direction align-center stylewidth: 68rpx; click.stoplikepinglun(2,index,item.id)div classmargin-bottom-xsdiv v-showitem.isCurrentUserLike0u-icon nameheart color#667286 size34rpx/u-icon/divdiv v-showitem.isCurrentUserLike1u-icon nameheart-fill colorred size34rpx/u-icon/div/divdiv classlikeNum{{item.likeCount}}/div/div/divdiv classtime{{ $u.timeFrom(new Date(item.createTime).getTime())}}/div/div/div/div/div/div!-- 展开和收起按钮 --div classflex justify-start align-center stylepadding-left: 84rpx;div classseeMore padding-top-sm padding-bottom flex align-center v-ifonePageList.levelTwoCommentCount 0params.current totalPage click$u.throttle(getTwoLevelPinglun, 1000,true)div classmargin-right-xs查看更多回复/divu-icon namearrow-down color#00875A size28rpx :boldtrue/u-icon/divdiv classseeMore retract padding-top-sm padding-bottom margin-left flex justify-center align-center v-ifparams.current 1 click$u.throttle(retract, 1000,true)div classmargin-right-xs收起/divu-icon namearrow-up color#00875A size28rpx :boldtrue/u-icon/div/div/div
/templatescriptimport { mapState } from vuex;import { commentlike, getLevelOnePage, getLevelTwoPage } from /api/case/case.jsexport default {data() {return {caseId: null,indexxxx: null, //一级评论的indexparams: {current: 1,limit: 5,timeSort: 1, //创建时间排序 1升序 2降序},totalPage: 1,onePageList: {},pingjiaBoxMaxHeight: 0,pinglunOpcity: 0,timer: null,timer1: null,}},props: {caseIdData: {type: Number,// 定义是否必须传required: true,// 定义默认值default: 0},data: {type: Object,// 定义是否必须传required: true,// 定义默认值default: {}},indexxx: {type: Number,// 定义是否必须传required: true,// 定义默认值default: 0}},watch: {caseIdData: {immediate: true,handler(val) {this.caseId val;}},data: {immediate: true,handler(val) {this.onePageList val;}},indexxx: {immediate: true,handler(val) {this.indexxxx val;}}},components: {},computed: {...mapState([hasLogin, userInfo])},mounted() {},beforeDestroy() {clearTimeout(this.timer)clearTimeout(this.timer1)},methods: {async likepinglun(type, index, id) {if (!this.hasLogin) {this.$emit(noLogin, 一二级评论点赞未登录)return}let form {};if (type 1) {form.caseLevelOneCommentId id} else if (type 2) {form.caseLevelTwoCommentId id}try {let res await commentlike({ ...form, userId: this.userInfo?.userId })if (res.state 1) { //如果接口回调成功if (type 1) { //如果点击的是一级评论的点赞if (this.onePageList.levelOneCommentVo.isCurrentUserLike 0) { //判断点赞之前是0还是1 然后取反 并且对应点赞数量同步加减this.onePageList.levelOneCommentVo.isCurrentUserLike 1this.onePageList.levelOneCommentVo.likeCount} else if (this.onePageList.levelOneCommentVo.isCurrentUserLike 1) {this.onePageList.levelOneCommentVo.isCurrentUserLike 0this.onePageList.levelOneCommentVo.likeCount--}} else if (type 2) { //如果点击的是二级评论的点赞if (this.onePageList.twoLevelpinglun[index].isCurrentUserLike 0) {this.onePageList.twoLevelpinglun[index].isCurrentUserLike 1this.onePageList.twoLevelpinglun[index].likeCount} else if (this.onePageList.twoLevelpinglun[index].isCurrentUserLike 1) {this.onePageList.twoLevelpinglun[index].isCurrentUserLike 0this.onePageList.twoLevelpinglun[index].likeCount--}}}} catch (e) {uni.$u.toast(e)}},goPinglun(e, id, name, indexx) {if (e 1) { //一级评论this.$emit(comment, {type: e,id: id,// index: this.indexxxx,index: indexx,replyName: name, //点击的谁的评论进行回复用于在输入框的placeholder回显})} else if (e 2) { //二级评论this.$emit(comment, {type: e,id: id,// index: this.indexxxx,index: indexx,replyName: name, //点击的谁的评论进行回复用于在输入框的placeholder回显})}},async getTwoLevelPinglun() {try {let res await getLevelTwoPage({ userId: this.hasLogin ? this.userInfo?.userId : , caseLevelOneCommentId: this.onePageList.levelOneCommentVo.id, ...this.params })if (res.state 1) {for (let i 0; i res.content.records.length; i) {res.content.records[i].twoLevelpinglun []if (this.onePageList.twoLevelpinglun.some(item item.id res.content.records[i].id)) { //删除重复项res.content.records.splice(i, 1)console.log(发现重复项删除他);}}this.onePageList.twoLevelpinglun [...this.onePageList.twoLevelpinglun, ...res.content.records]this.totalPage Math.ceil(res.content.total / this.params.limit) //总页数总数量/每页数量this.params.current 1this.updatHeight()}} catch (e) {uni.$u.toast(e)}},retract() {this.pingjiaBoxMaxHeight 0this.pinglunOpcity 0this.params.current 1this.onePageList.twoLevelpinglun []this.timer1 setTimeout(() { //因为展开动画需要1s 故 在收起的时候延迟置空数组console.log(this.onePageList);this.$emit(shouqi, this.onePageList.levelOneCommentVo.id)}, 800)},updatHeight() {let that thisthis.$nextTick(() {// this.timer setTimeout(() {this.createSelectorQuery().select(.pinglunDom).boundingClientRect(function(rect) {// console.log(rect);that.pingjiaBoxMaxHeight rect.heightthat.pinglunOpcity 1}).exec();// }, 0)})},}}
/scriptstyle langscss scoped.name {font-size: 24rpx;font-weight: 400;color: #667286;}.content {font-size: 28rpx;font-weight: 400;color: #1F3253;}.time {font-size: 20rpx;font-weight: 400;color: #AFAFAF;}.likeNum {font-size: 20rpx;font-weight: 400;color: #667286;}.zuozhe {width: 60rpx;height: 28rpx;background: #FFFFFF;border-radius: 18rpx;border: 1rpx solid #00875A;font-size: 20rpx;font-weight: 400;color: #00875A;}.seeMore {font-size: 24rpx;font-weight: 400;color: #00875A;}.retract {width: 150rpx;text-align: center;}.erpinglunBox {padding-left: 84rpx;transition: height 1s, opacity 2s;overflow: hidden;}
/style
案例详情引入的scss文件 .font-20 {font-size: 20rpx;font-weight: 400;}.font-24 {font-size: 24rpx;font-weight: 400;}.txt-1 {font-size: 28rpx;font-weight: 500;color: #0F2C50;}.txt-2 {extend .font-20;color: #667286;}.txt-3 {extend .font-24;color: #667286;}.txt-4 {font-size: 24rpx;font-weight: 500;color: #667286;}.txt-5 {font-size: 36rpx;font-weight: bold;}.txt-6 {extend .font-24;color: #9CADC6;}.txt-7 {extend .font-20;color: #B7BCC3;}.txt-8 {extend .font-24;color: #fff;}.txt-9 {extend .font-24;color: #0F2C50;}.txt-10 {font-size: 28rpx;font-weight: 400;color: #667286;}.yell-green-base {width: 140rpx;height: 52rpx;border-radius: 2rpx;font-size: 36rpx;font-weight: bold;}.yellow-box {extend .yell-green-base;background-color: #FFF4CD;color: #FF991F;}.green-box {extend .yell-green-base;background: #E2FFEE;color: #00875A;}.timeFont{font-size: 32rpx;font-family: DINAlternate-Bold, DINAlternate;font-weight: bold;}.startTime{extend .timeFont;color: #FF991F;}.endTime{extend .timeFont;color: #00875A;}.line {height: 1rpx;border: 1rpx solid #E6E6E6;margin: 16rpx 0;}
.caseBox {background: #FFFFFF;border-radius: 12rpx;margin-top: 20rpx;padding: 0 32rpx;.case-head-box {height: 140rpx;}.avatarBox {width: 72rpx;height: 72rpx;margin-right: 16rpx;}.caseDetailBtn {width: 100rpx;height: 44rpx;background: #00875A;border-radius: 22rpx;}.rateBox {height: 80rpx;}.mar-80 {margin-right: 80rpx;}}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/83043.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!