这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战
【千字长文,熬夜更新,原创不易,多多支持,感谢大家】
前言
Hello,小伙伴们大家好。我们继续来完善问卷调查功能。今天依然还是从问卷提交记录页面上做文章。前面的分享中我们已经实现了提交记录的列表展示功能,但仅仅一个列表展示还是不够的,因为列表中无法显示更多的信息(比如问卷详情)。下面我们就基于列表实现一个点击标题跳转到问卷详情页(结果页)和删除问卷的功能。
列表页改造
先来看看我们列表页要增加的功能:
- 点击标题跳转到详情页
- 点击某条记录实现删除问卷
基于以上两点我们就知道该从何下手了
- 首先将标题列修改为自定义列(具体可参考elementui官方示例),在自定义列中添加一个router-link标签,用于实现跳转
- 在列表的尾部新增一个自定义列,并在该列中添加一个删除按钮,当点击删除时先提示“是否确认操作”,用户确认后将记录删除
- 删除按钮我们依然使用elementui的el-button按钮,type为“danger”, circle为true,icon为“DeleteFilled”
- 删除前需要先确认是否删除,这里使用el-popconfirm确认框组件并绑定confirm确认事件,该组件需嵌套在el-button的外部
- 在JavaScript代码中导入ElButton,ElPopConfirm和ElMessage三个组件并注册
- 在setup方法中定义一个deleteHistory方法接收一个id作为参数,在该方法中调用api中deleteHistory方法实现删除操作
改造后的代码如下:
<template>
<el-table :data="data" stripe border style="width:100%">
<el-table-column prop="id" label="Id" width="50" />
<el-table-column prop="title" label="Title"><!--改为自定义列-->
<template #default="scope">
<router-link :to="'/result/'+scope.row.id">{{scope.row.title}}</router-link>
</template>
</el-table-column>
<el-table-column prop="user" label="User" width="150" />
<el-table-column prop="time" label="Time" width="200" />
<!--新增自定义列-->
<el-table-column prop="" label="Operation" width="100" >
<template #default="scope">
<el-popconfirm title="Are you sure???" @confirm="deleteHistory(scope.row.id)">
<template #reference>
<el-button type="danger" circle :icon="DeleteFilled"></el-button>
</template>
</el-popconfirm>
</template>
</el-table-column>
</el-table>
</template>
复制代码
import {ElTable, ElTableColumn, ElButton, ElPopConfirm, ElMessage} from 'element-plus';
import {ref} from 'vue';
import api from './api'
import { DeleteFilled } from "@element-plus/icons"
export default{
components:{ElTable, ElTableColumn, ElButton, ElPopConfirm},
setup(){
const data = ref([])
data.value = api.getList();
const deleteHistory = (id) => {
//删除后重新加载数据
data.value = api.deleteHistory(id);
ElMessage({
type:'sueccess',
message:'删除成功'
})
}
return {
data,
DeleteFilled,
deleteHistory
}
}
}
复制代码
路由改造
不知道有没有小伙伴发现:在上面新添加的router-link标签中,跳转的时候我们采用的是路由的路径传参(:to="'/result/'+scope.row.id"),因此我们需要对问卷结果页对应的路由进行改造。 原有的功能是在问卷提交成功后会将一大堆字符串作为参数通过地址栏传给结果页以展示,然而这样既不美观也不安全,因此我们将其改为路由路径传参,并且只需传一各问卷id即可。
// router/index.js
{
path:'/result/:id',//这里改为路径传参
name:"Result",
component: ()=>import(/*webpackChunkName: "Result" */ '../result.vue')
}
复制代码
路由修改后,提交按钮中涉及到的跳转及传参功能也需同步修改:
// Home.vue
const submit = () => {
// ...省略
router.push({
name:'Result',
params:{ // 注意这里有原来的query改为了params
id: newId
}
});
}
复制代码
结果页改造
在结果页中之前的做法是:将所有的问卷结果以字符串的形式传递过来,然后在从路由中解析出来暴露给模板展示。而在我们改造后只传了一个问卷id过来,因此我们还得在增加一步操作:
- 从路由参数中解析出问卷id值
- 根据id调用api中的获取问卷详情的方法:api.getHistory(id)
- 另外还需将原来的普通变量result改成响应式变量,这样才能保证页面数据的实时性
// ... 省略
setup(){
const id = JSON.parse(route.params.id);
let result = ref({});
result.value = JSON.parse(api.getHistory(id).question)
return {
result
}
}
复制代码
api
在api中新增两个方法:
- getHistory:接收一个id作为参数,用于根据id获取问卷详情
- 在该方法中调用原有getList方法,将localStorage中的所有问卷数据解析出来并暂存到histories变量中
- 遍历histories,找到histories中与传进了的id相同的问卷记录。这里我们借助数据的filter方法实现
- 返回找到的记录,需要注意的是:我们在保存提交记录时是按照正序排序,但是显示时应该按照倒序显示(即最新记录排在最前面),因此我们在拿到结果后还需做reverse处理一下。
- 最后需要注意一些容错处理
- deleteHistory:接收一个id作为参数,用于根据id删除问卷记录。这里的删除需要注意一下:正常情况如果我们是把记录保存在数据库中的,那么删除操作就是直接一条delete或者update语句就可以了。但是我们这个问卷系统中比较特殊:由于数据都是存在本地存储localStorage中的,因此删除时相对来说比较繁琐,概括的来说就是:先将所有数据取出来,然后再找到要删除的数据并把它从所有的数据中排除掉,最后再把排除后剩余的数据重新保存回localStorage中,具体步骤如下:
- 与getHistory方法一样,先调用getList方法,拿到所有的问卷记录数据并暂存到histories 中
- 遍历histories并根据参数id找到要删除的数据,将其从histories中移除掉(这里依然可以用数组的filter方法)
- 将移除后的新数据集重新存回到localStorage中。(需注意的是:通过getList方法拿到的数据是倒序排序的,而我们保存localStorage时应该按照正序保存,因此在保存前需要同样做reverse处理)
- 最后将新数据集返回给前端,用于数据的实时展示(注意还需再做一次reverse处理,因为reverse是直接改变的原数组)
// api/index.js
function getHistory(id){
const histories = getList();
const result = histories && histories.length && histories.filter(item => item.id === id);
return result.length > 0 && result[0];
}
function deleteHistory(id){
const histories = getList();
const result = histories && histories.length && histories.filter(item => item.id !== id);//过滤掉要删除的数据
result.reverse();//正序保存
localStorage.setItem(constants.History, JSON.stringify(result));
return result.reverse();//倒序展示
}
复制代码
效果展示
总结
本次分享中,我们给列表添加了查看详情及删除记录功能,同时对问卷结果页面及路由进行了合理化改造。截止目前距离我们问卷系统的成功也是越来越近了,期待小伙伴的的支持哦! 另外,本次分享在最初设计时本来想引进vuex的一些相关知识,即把数据从localStorage中解析出来后同时存到vuex中一份,然后后面所有关于数据的操作都基于vuex来实现,但是尝试下来发现用来vuex后有点多此一举(并且还有可能带来一些不必要的麻烦)于是在中间的时候就将其舍弃了。 本次分享就到这里了,喜欢的小伙伴欢迎点赞评论加关注哦!