关于消息通知部分的原型设计
开始:
- 最开始接到做消息通知这部分的内容的时候就想到要做一个类似csdn这种样子的界面,一张一张小卡片的形式显示每条消息的标题内容时间,最开始对前端部分的循环基本没什么了解,不知道该如何写出类似于这种效果的界面,想着能从elementUI里找到类似的也失败了,只能自己硬写了。
探索:
- 在了解到v-for的使用的时候,发现这部分出奇的简单,但是考虑到checkbox单选多选的绑定,批量删除批量已读功能的实现又退缩了,有点无法想象其中实现的原理。不过编程的东西,总得上手实践,实践起来总会发现问题并没有想象的那么复杂。
- 为了先和后端对接好,测试接口数据问题,先用列表实现了一下大致思路,也就是如下图这样的一个页面。
- 这和原型的设计差距有点大,这可能就是买家秀与卖家秀的区别吧。
- 做成这样实在是交不了差,于是多方查找询问之后,打算用v-for来实现一个“买家秀”。
实践:
当需要将一个数组遍历或枚举一个对象循环显示时候,常用的就是列表渲染指令v-for. 它需要结合着in或者of来使用
- 为了显示很多个类似这种小卡片的形式进行循环,所以首先要写好一个card所包含的元素,包括其对应的样式。
<div class="space-right-bottom">
<div class="card-system-item" v-for="message in list" :key="message.messageId">
<div class="top">
<span class="sub-title">{{message.messageTitle}}</span>
<span class="time">{{message.messageSendTime}}</span>
</div>
<div class="bottom">
<span class="text">{{message.messageContent}}</span>
</div>
- 这里就是用v-for循环渲染每一张card,list为后端所返回的数据列表,message为每一个对象,每一个对象又包含其对应的标题时间内容。
- 为了实现批量选择,需要在每个标题前面加一个checkbox,首先需要写一个checkbox到这个卡片内部,其次需要写一个checkbox到组件外面为了实现全选。
// 这个checkbox置于组件外,用于全选
<input type="checkbox" v-model="checkedAll" id="all" @click="selectAll()">
//这个checkbox置于组件内,用于单选
<input type="checkbox" :value="message.messageId" :id="message.messageId" @click="checkedOne(message.messageId)" v-model="checked" />
下面是实现全选与单选的js代码,因为后端需要接收所删除的messageId所拼接成的字符串,这里我就直接“+”起来了拼接字符串,实现了对应的功能。
checkedOne (messageId){
this.messageId = messageId
console.log(this.messageId)
},
selectAll:function(){
if(this.checkedAll){
this.checked = [];
}else{
this.checked = [];
this.list.forEach((message)=>{
this.checked.push(message.messageId);
if (this.messageId === ''){
this.messageId = message.messageId
} else {
this.messageId = this.messageId + ',' + message.messageId
}
})
}
}
实现checkbox全选,思路参考的这篇博客。
- 实现了全选就可以进行已读删除的更改,已读删除的原理后端所写的逻辑是相同的,因为删除是逻辑删除,所以都是用一个状态数据项的0/1来表示删除或者未删除,已读或者未读。前端代码如下:
<div class="space-right-center" >
<input type="checkbox" v-model="checkedAll" id="all" @click="selectAll()">
<el-button type="primary" icon="el-icon-success" @click.native="batchRead">已读</el-button>
<el-button type="primary" icon="el-icon-delete-solid" @click.native="batchDelete">删除</el-button>
</div>
batchDelete() {
const _this = this
this.userId = window.sessionStorage.getItem('ID')
this.messageInfor.userId = this.userId
this.$confirm(this.$t('tips.confirmDelete'), this.$t('common.tips'),{
confirmButtonText: this.$t('common.confirm'),
cancelButtonText: this.$t('common.cancel'),
type: 'warning'
}).then(() => {
this.messageInfor.messageIds = this.messageId
this.$post('******/******/batchDelete', this.messageInfor).then(() => {
this.$message({
message: this.$t('tips.deleteSuccess'),
type: 'success'
})
this.search()
})
})
},
batchRead() {
const _this = this
this.userId = window.sessionStorage.getItem('ID')
this.messageInfor.userId = this.userId
this.messageInfor.messageIds = this.messageId
console.log(this.messageInfor)
this.$post('*******/*******/batchHaveRead', this.messageInfor).then(() => {
this.$message({
message: "已读处理完成",
type: 'success'
})
this.search()
})
}
- 到这一步就实现了删除、已读,但是页面上还没有已读未读的区分,于是我灵机一动加了个图标,想着已读的消息就是个打开的信封,未读的消息则是一个封闭的信封,于是找了个免费图标网站下了两张图https://thenounproject.com/search/?q=email
- 将图片放到每个消息标题之前,这里要用v-if来判断当前消息是什么状态
v-if使用一般有两个场景:
1- 多个元素 通过条件判断展示或者隐藏某个元素、多个元素
2- 进行两个视图之间的切换
https://blog.youkuaiyun.com/qq_24147051/article/details/79776519
<img src="../assets/toread.png" v-if="message.messageStatus == 0" class="toread" alt="未读">
<img src="../assets/alread.png" v-else-if="message.messageStatus == 1" class="read" alt="已读">
结束:
经过上面的种种,总算有了现在的最终版本:
不过测试出了两个bug。。。只能单选或者全选,选两个三个或者多个会只删除已读一个,这个等下要改改,等改好了再补充。另外标记为已读之后会让消息置顶,这个设定不是很合理,也要改改,目前就记录这些,希望得到大佬的指点。