【Vue3.0实战逐步深入系列】保存问卷记录到localStorage并基于elementui的table组件实现历史记录的展示功能

1,115 阅读5分钟

这是我参与11月更文挑战的第26天,活动详情查看:2021最后一次更文挑战

【千字长文,熬夜更新,原创不易,多多支持,感谢大家】

前言

小伙伴们大家好。今天我们继续来完善我们的问卷调查功能。昨天我们已经为问卷添加了数据有效性校验功能。从问卷主题配置到问卷数据有效性校验再到问卷的保存和提交,整个问卷系统已经初具雏形逐步完善了,但仍然还欠缺许多功能比如按角色登录,后台管理,提交记录展示等等。别急,既然是逐步深入系列我们就一步步慢慢来。今天就将实现问卷提交记录保存及展示功能。

保存提交记录

为了操作方便我们就不借助后台数据库了,依然使用本地存储localStorage进行历史记录的保存,拢共分为三大步:

  • 首先来分析一下我们要保存的信息:
    • 提交记录的唯一标识字段id,提交记录的标题title,填写问卷的用户user,提交时间time,以及问卷的具体信息question
    • 其中id作为唯一标识,为了方便我们就把它做成自增类型,并且将每次自增后的最大值也保存到localStorage中
    • 最后将所有字段封装成一个对象保存在localStorage中
  • 这里已经多次用到了localStorage,那么必然就会涉及到多个不同的key值,为了方便维护,我们把这些key单独存到一个文件constants.js中
    • Question:值为“QUESTION”,用于保存每次填写问卷的临时记录
    • MaxId: 值为“MAXID”,用于保存自增后的最大ID值
    • History:值为“HISTORY”,用于保存每次提交的记录
  • 在submit方法中添加保存提交记录的逻辑
    • 首先根据maxid在localStorage中拿到当前的最大id值,拿到id后先进行自增操作,然后再重新存回到localStorage中
    • 组装提交记录对象,如:{ id: newId, title:QUESTION:第${newId}次提交记录, user:'Yannis', time: new Date().toLocaleString(), question: JSON.stringify(result) },(注意在保存问卷结果时需要进行JSON转换一下)
    • 根据key History从localStorage中拿到已经保存的提交记录histories。这里从localStorage中拿到的保存结果进行JSON转换后应该是一个数组类型。
    • 将上面组装好的提交记录对象push到数组histories中
    • 将数组histories进行JSON转换后重新存回到localStorage中
//constants.js
export default{
	MaxId:"MAXID",
	Question:"QUESTION",
	History:"HISTORY"
}
const submit = () => {
	// ...省略
	let maxId = localStorage.getItem(constants.MaxId);
	let newId = maxId ? ++maxId: 1;
	localStorage.setItem(constants.MaxId, newId);
	const records ={
		id: newId,
		title:`QUESTION:第${newId}次提交记录`,
		user:'Yannis',
		time: new Date().toLocaleString(),
		question: JSON.stringify(result)
	}
	
	const histories = localStorage.getItem(constants.History) ? JSON.parse(localStorage.getItem(constants.History)) : [];
	histories.push(records);
	localStorage.setItem(constants.History, JSON.stringify(histories)) 
	// ...省略
}

提交记录展示

既然已经保存了提交记录,那么接下来的操作就是将提交记录以列表的形式再展示出来,这里我们借助elementui的Table组件来展示记录

  • 新建HistoryList.vue组件
  • 导入elementui的ElTableElTableColumn两个组件
  • 导入vue中的ref方法用于定义响应式变量
  • 导入constants用于根据key从localStorage中获取已保存的历史记录列表
  • 在setup函数中中定义一个响应式变量data
  • 从localStorage中根据对应的key值拿到已保存的历史记录数据
  • 将数据进行JSON转换后赋值给响应式变量data
  • 将data通过return的方式暴露给模板使用
  • 在模板中使用el-table和el-table-column实现列表展示

HistoryList.vue组件完整代码如下:

<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" />
		<el-table-column prop="user" label="User" width="150" />
		<el-table-column prop="time" label="Time" width="200" />
	</el-table>
</template>
import {ElTable, ElTableColumn} from 'element-plus';
import {ref} from 'vue';
import constants from './constants'
export default{
	components:{ElTable, ElTableColumn}, 
	setup(){
		const data = ref([])
		const histories = localStorage.getItem(constants.History);
		data.value = histories ? JSON.parse(histories) : [];
		return {
			data
		}
	}
}

为列表页配置路由

新增列表页面后为了能够实现页面的切换,我们还需要为列表页面配置路由规则,修改router下的index.js文件,添加如下代码:

//...省略
{
	path:'/list',
	name:"List",
	component:()=>import(/*webpackChunkName: "List"*/ '../HistoryList.vue')
}

修改App.vue添加提交记录超链接

在路由配置好后,我们还应该为提交记录列表页面添加一个入口:在App.vue中添加一个router-link用于跳转:

<!--...省略-->
<router-link to="/list">提交记录</router-link>
<!--...省略-->

数据分离

到此,其实一个列表展示功能基本上已经完成了,但是我们发现localStorage中保存的数据会在不同的页面中频繁使用(比如在Home页面的保存数据,在List页面的查询数据),随着以后功能和页面的越来越多,那么对localStorage中数据操作也就会越来越频繁,为了方便以后的管理和维护,我们把数据操作相关的部分单独提取到一个api文件中进行统一管理:

  • 在api目录下新增一个index.js文件
  • 在该文件中定义一个内部函数getMaxId,用于获取或生成自增ID
  • 定义一个saveHistory方法接收一个对象类型参数:record,用于保存提交记录
  • 将Home.vue的submit方法中的保存逻辑拆分到以上两个方法中
  • 在定义一个getList方法用于从localStorage中获取列表数据
  • 最后需要将对外的方法通过export的形式暴露出去
// api/index.js
import constants from '../constants'
function getMaxId(){
	let maxId = localStorage.getItem(constants.MaxId);
	let newId = maxId ? ++maxId : 1;
	localStorage.setItem(constants.MaxId, newId);
	return newId;
}

function getList(){
	const histories = localStorage.getItem(constants.History) ? JSON.parse(localStorage.getItem(constants.History)) : [];
	return histories.reverse();//默认最近一次提交排在最前面
}

function saveHistory(record){
	record.id = getMaxId();
	record.title = `QUESTION:第【${record.id}】次问卷提交记录`
	const histories = getList();
	histories.push(record);
	localStorage.setItem(constants.History, JSON.stringify(histories))
	return record.id;
}

export default {
	getList,
	saveHistory
}

数据抽离后还需将原来Home.vue中的保存逻辑和HistoryList.vue中的获取逻辑改成直接从API中调用方法获取

// Home.vue
import api from './api'

const submit = () => {
	// ...省略
	const record ={	
		user:'Yannis',
		time: new Date().toLocaleString(),
		question: JSON.stringify(result)
	}
	const newId = api.saveHistory(record)
	// ...省略
}


// HistoryList.vue
import api from './api'
	setup(){
		const data = ref([])
		data.value = api.getList();
		return {
			data
		}
	}

总结

好了,到此问卷提交记录的列表展示及优化功能就完成了,本次分享利用本地存储localStorage实现了每次提交记录的保存,同时借助elementui的Table组件实例了提交记录的列表展示,最后还实现了数据与业务的剥离最终完成了我们的保存及展示功能。 本次分享就到这里了,喜欢的小伙伴欢迎点赞评论加关注哦!