vform3跨页面存储,使用indexdb
1. indexdb封装
- indexDb.js
js
/**
* 封装的方法以及用法
* 打开数据库
*/
export const openDB = (dbName, storeName, version = 1) => {
return new Promise((resolve, reject) => {
let indexedDB = window.indexedDB
let db
const request = indexedDB.open(dbName, version)
request.onsuccess = function (event) {
db = event.target.result // 数据库对象
console.log("开启数据库")
resolve(db)
}
request.onerror = function (event) {
reject(event)
}
request.onupgradeneeded = function (event) {
// 数据库创建或升级的时候会触发
console.log('onupgradeneeded')
db = event.target.result // 数据库对象
let objectStore
if (!db.objectStoreNames.contains(storeName)) {
objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表
// objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段
}
}
})
}
/**
* 新增数据
*/
export const addData = (db, storeName, data) => {
return new Promise((resolve, reject) => {
let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写")
.objectStore(storeName) // 仓库对象
.add(data)
request.onsuccess = function (event) {
resolve(event)
}
request.onerror = function (event) {
throw new Error(event.target.error)
reject(event)
}
})
}
/**
* 通过主键读取数据
*/
export const getDataByKey = (db, storeName, key) => {
return new Promise((resolve, reject) => {
let transaction = db.transaction([storeName]) // 事务
let objectStore = transaction.objectStore(storeName) // 仓库对象
let request = objectStore.get(key)
request.onerror = function (event) {
reject(event)
}
request.onsuccess = function (event) {
resolve(request.result)
}
})
}
/**
* 通过游标读取数据
*/
export const cursorGetData = (db, storeName) => {
let list = []
let store = db.transaction(storeName, 'readwrite') // 事务
.objectStore(storeName) // 仓库对象
let request = store.openCursor() // 指针对象
return new Promise((resolve, reject) => {
request.onsuccess = function (e) {
let cursor = e.target.result
if (cursor) {
// 必须要检查
list.push(cursor.value)
cursor.continue() // 遍历了存储对象中的所有内容
} else {
resolve(list)
}
}
request.onerror = function (e) {
reject(e)
}
})
}
/**
* 通过索引读取数据
*/
export const getDataByIndex = (db, storeName, indexName, indexValue) => {
let store = db.transaction(storeName, 'readwrite').objectStore(storeName)
let request = store.index(indexName).get(indexValue)
return new Promise((resolve, reject) => {
request.onerror = function (e) {
reject(e)
}
request.onsuccess = function (e) {
resolve(e.target.result)
}
})
}
/**
* 通过索引和游标查询记录
*/
export const cursorGetDataByIndex = (db, storeName, indexName, indexValue) => {
let list = []
let store = db.transaction(storeName, 'readwrite').objectStore(storeName) // 仓库对象
let request = store.index(indexName) // 索引对象
.openCursor(IDBKeyRange.only(indexValue)) // 指针对象
return new Promise((resolve, reject) => {
request.onsuccess = function (e) {
let cursor = e.target.result
if (cursor) {
list.push(cursor.value)
cursor.continue() // 遍历了存储对象中的所有内容
} else {
resolve(list)
}
}
request.onerror = function (ev) {
reject(ev)
}
})
}
/**
* 更新数据
*/
export const updateDB = (db, storeName, data) => {
let request = db.transaction([storeName], 'readwrite') // 事务对象
.objectStore(storeName) // 仓库对象
.put(data)
return new Promise((resolve, reject) => {
request.onsuccess = function (ev) {
resolve(ev)
}
request.onerror = function (ev) {
resolve(ev)
}
})
}
/**
* 删除数据
*/
export const deleteDB = (db, storeName, id) => {
let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)
return new Promise((resolve, reject) => {
request.onsuccess = function (ev) {
resolve(ev)
}
request.onerror = function (ev) {
resolve(ev)
}
})
}
/**
* 删除数据库
*/
export const deleteDBAll = dbName => {
// console.log(dbName)
let deleteRequest = window.indexedDB.deleteDatabase(dbName)
return new Promise((resolve, reject) => {
deleteRequest.onerror = function (event) {
console.log('删除失败')
}
deleteRequest.onsuccess = function (event) {
console.log('删除成功')
}
})
}
/**
* 关闭数据库
*/
export const closeDB = db => {
db.close()
console.log('数据库已关闭')
}
/**
* 封装的方法以及用法
* 打开数据库
*/
export const openDB = (dbName, storeName, version = 1) => {
return new Promise((resolve, reject) => {
let indexedDB = window.indexedDB
let db
const request = indexedDB.open(dbName, version)
request.onsuccess = function (event) {
db = event.target.result // 数据库对象
console.log("开启数据库")
resolve(db)
}
request.onerror = function (event) {
reject(event)
}
request.onupgradeneeded = function (event) {
// 数据库创建或升级的时候会触发
console.log('onupgradeneeded')
db = event.target.result // 数据库对象
let objectStore
if (!db.objectStoreNames.contains(storeName)) {
objectStore = db.createObjectStore(storeName, { keyPath: 'id' }) // 创建表
// objectStore.createIndex('name', 'name', { unique: true }) // 创建索引 可以让你搜索任意字段
}
}
})
}
/**
* 新增数据
*/
export const addData = (db, storeName, data) => {
return new Promise((resolve, reject) => {
let request = db.transaction([storeName], 'readwrite') // 事务对象 指定表格名称和操作模式("只读"或"读写")
.objectStore(storeName) // 仓库对象
.add(data)
request.onsuccess = function (event) {
resolve(event)
}
request.onerror = function (event) {
throw new Error(event.target.error)
reject(event)
}
})
}
/**
* 通过主键读取数据
*/
export const getDataByKey = (db, storeName, key) => {
return new Promise((resolve, reject) => {
let transaction = db.transaction([storeName]) // 事务
let objectStore = transaction.objectStore(storeName) // 仓库对象
let request = objectStore.get(key)
request.onerror = function (event) {
reject(event)
}
request.onsuccess = function (event) {
resolve(request.result)
}
})
}
/**
* 通过游标读取数据
*/
export const cursorGetData = (db, storeName) => {
let list = []
let store = db.transaction(storeName, 'readwrite') // 事务
.objectStore(storeName) // 仓库对象
let request = store.openCursor() // 指针对象
return new Promise((resolve, reject) => {
request.onsuccess = function (e) {
let cursor = e.target.result
if (cursor) {
// 必须要检查
list.push(cursor.value)
cursor.continue() // 遍历了存储对象中的所有内容
} else {
resolve(list)
}
}
request.onerror = function (e) {
reject(e)
}
})
}
/**
* 通过索引读取数据
*/
export const getDataByIndex = (db, storeName, indexName, indexValue) => {
let store = db.transaction(storeName, 'readwrite').objectStore(storeName)
let request = store.index(indexName).get(indexValue)
return new Promise((resolve, reject) => {
request.onerror = function (e) {
reject(e)
}
request.onsuccess = function (e) {
resolve(e.target.result)
}
})
}
/**
* 通过索引和游标查询记录
*/
export const cursorGetDataByIndex = (db, storeName, indexName, indexValue) => {
let list = []
let store = db.transaction(storeName, 'readwrite').objectStore(storeName) // 仓库对象
let request = store.index(indexName) // 索引对象
.openCursor(IDBKeyRange.only(indexValue)) // 指针对象
return new Promise((resolve, reject) => {
request.onsuccess = function (e) {
let cursor = e.target.result
if (cursor) {
list.push(cursor.value)
cursor.continue() // 遍历了存储对象中的所有内容
} else {
resolve(list)
}
}
request.onerror = function (ev) {
reject(ev)
}
})
}
/**
* 更新数据
*/
export const updateDB = (db, storeName, data) => {
let request = db.transaction([storeName], 'readwrite') // 事务对象
.objectStore(storeName) // 仓库对象
.put(data)
return new Promise((resolve, reject) => {
request.onsuccess = function (ev) {
resolve(ev)
}
request.onerror = function (ev) {
resolve(ev)
}
})
}
/**
* 删除数据
*/
export const deleteDB = (db, storeName, id) => {
let request = db.transaction([storeName], 'readwrite').objectStore(storeName).delete(id)
return new Promise((resolve, reject) => {
request.onsuccess = function (ev) {
resolve(ev)
}
request.onerror = function (ev) {
resolve(ev)
}
})
}
/**
* 删除数据库
*/
export const deleteDBAll = dbName => {
// console.log(dbName)
let deleteRequest = window.indexedDB.deleteDatabase(dbName)
return new Promise((resolve, reject) => {
deleteRequest.onerror = function (event) {
console.log('删除失败')
}
deleteRequest.onsuccess = function (event) {
console.log('删除成功')
}
})
}
/**
* 关闭数据库
*/
export const closeDB = db => {
db.close()
console.log('数据库已关闭')
}
存储
- vform.vue
vue
<template>
<v-form-designer class="vform_designer_wrap" ref="VFormDesignerRef" :banned-widgets="bannedWidgets"
:designer-config="designerConfig" :form-templates="formTemplates"
@generatePage="generatePage"></v-form-designer>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from "vue-router";
import { ElMessage } from 'element-plus';
import * as indexDb from '@/utils/indexDb.js'
const router = useRouter();
const VFormDesignerRef = ref(null)
// 禁止显示的表单组件
const bannedWidgets = [
// 'tab',
/* 'tab',
'time-range',
'date-range',
'table',
'rate',
'html-text',
'color',
'slider',
'picture-upload',
'file-upload',
'rich-editor',
'cascader' */
]
// 显示的内容
const designerConfig = {
/* //是否显示语言切换菜单
languageMenu: false,
//是否显示GitHub、文档等外部链接
externalLink: false,
//是否显示表单模板
formTemplates: true,
//是否禁止修改唯一名称
widgetNameReadonly: false,
//是否显示组件事件属性折叠面板
eventCollapse: true,
//是否显示清空设计器按钮
clearDesignerButton: true,
//是否显示预览表单按钮
previewFormButton: true,
//是否显示导入JSON按钮
importJsonButton: true,
//是否显示导出JSON器按钮
exportJsonButton: true,
//是否显示导出代码按钮
exportCodeButton: false,
//是否显示生成SFC按钮
generateSFCButton: false,
//是否显示生成页面按钮
generatePageButton: false,
toolbarMaxWidth: 300,
toolbarMinWidth: 300,
//表单设计器预设CSS代码
presetCssCode: '' */
}
// 模板
const formTemplates = [
{
title: '一个简单的人员信息登记表',
imgUrl: '/vform-template/image/test1.png',
jsonUrl: '/vform-template/json/test1.json',
// description: '表单模板详细说明...'
},
{
title: 'test2',
imgUrl: '/vform-template/image/drone.jpg',
jsonUrl: '/vform-template/json/drone.json',
// description: '表单模板详细说明...'
},
{
title: 'test3',
imgUrl: '/vform-template/image/highway.jpg',
jsonUrl: '/vform-template/json/highway.json',
// description: '表单模板详细说明...'
}
]
const initIndexDb = async (obj) => {
const dbName = 'myVFormDB', storeName = 'myVFormStore'
const db = await indexDb.openDB(dbName, storeName, 1)
const serchData = async () => {
return await indexDb.getDataByKey(db, storeName, 'myVFormId_1')
}
/**
* 先查询
* 如果数据库为空,创建
* 如果数据库不为空,更新
*/
serchData().then(async (res) => {
if (!res) {
await indexDb.addData(db, storeName, {
id: "myVFormId_1", // 必须且值唯一
config: JSON.stringify(obj)
})
} else {
// console.log('已有数据', res)
await indexDb.updateDB(db, storeName, { id: "myVFormId_1", config: JSON.stringify(obj) })
}
await indexDb.closeDB(db)
ElMessage.success('保存成功')
})
}
const generatePage = formJson => {
// console.log('generatePage', formJson)
initIndexDb(formJson)
router.push("/complain/vformRender")
}
</script>
<style lang="scss" scoped>
.vform_designer_wrap {
margin: 0 !important;
padding: 0 !important;
overflow: hidden;
:deep .main-content {
aside.el-aside {
height: 90vh !important;
overflow-y: auto;
}
section.el-container {
main.el-main {
height: 84vh !important;
overflow-y: auto;
}
}
}
:deep .float-right.external-link {
display: none;
}
:deep .el-header.main-header {
display: none;
}
:deep .el-container.full-height {
overflow-y: auto;
}
}
</style>
<template>
<v-form-designer class="vform_designer_wrap" ref="VFormDesignerRef" :banned-widgets="bannedWidgets"
:designer-config="designerConfig" :form-templates="formTemplates"
@generatePage="generatePage"></v-form-designer>
</template>
<script setup>
import { ref } from 'vue'
import { useRouter } from "vue-router";
import { ElMessage } from 'element-plus';
import * as indexDb from '@/utils/indexDb.js'
const router = useRouter();
const VFormDesignerRef = ref(null)
// 禁止显示的表单组件
const bannedWidgets = [
// 'tab',
/* 'tab',
'time-range',
'date-range',
'table',
'rate',
'html-text',
'color',
'slider',
'picture-upload',
'file-upload',
'rich-editor',
'cascader' */
]
// 显示的内容
const designerConfig = {
/* //是否显示语言切换菜单
languageMenu: false,
//是否显示GitHub、文档等外部链接
externalLink: false,
//是否显示表单模板
formTemplates: true,
//是否禁止修改唯一名称
widgetNameReadonly: false,
//是否显示组件事件属性折叠面板
eventCollapse: true,
//是否显示清空设计器按钮
clearDesignerButton: true,
//是否显示预览表单按钮
previewFormButton: true,
//是否显示导入JSON按钮
importJsonButton: true,
//是否显示导出JSON器按钮
exportJsonButton: true,
//是否显示导出代码按钮
exportCodeButton: false,
//是否显示生成SFC按钮
generateSFCButton: false,
//是否显示生成页面按钮
generatePageButton: false,
toolbarMaxWidth: 300,
toolbarMinWidth: 300,
//表单设计器预设CSS代码
presetCssCode: '' */
}
// 模板
const formTemplates = [
{
title: '一个简单的人员信息登记表',
imgUrl: '/vform-template/image/test1.png',
jsonUrl: '/vform-template/json/test1.json',
// description: '表单模板详细说明...'
},
{
title: 'test2',
imgUrl: '/vform-template/image/drone.jpg',
jsonUrl: '/vform-template/json/drone.json',
// description: '表单模板详细说明...'
},
{
title: 'test3',
imgUrl: '/vform-template/image/highway.jpg',
jsonUrl: '/vform-template/json/highway.json',
// description: '表单模板详细说明...'
}
]
const initIndexDb = async (obj) => {
const dbName = 'myVFormDB', storeName = 'myVFormStore'
const db = await indexDb.openDB(dbName, storeName, 1)
const serchData = async () => {
return await indexDb.getDataByKey(db, storeName, 'myVFormId_1')
}
/**
* 先查询
* 如果数据库为空,创建
* 如果数据库不为空,更新
*/
serchData().then(async (res) => {
if (!res) {
await indexDb.addData(db, storeName, {
id: "myVFormId_1", // 必须且值唯一
config: JSON.stringify(obj)
})
} else {
// console.log('已有数据', res)
await indexDb.updateDB(db, storeName, { id: "myVFormId_1", config: JSON.stringify(obj) })
}
await indexDb.closeDB(db)
ElMessage.success('保存成功')
})
}
const generatePage = formJson => {
// console.log('generatePage', formJson)
initIndexDb(formJson)
router.push("/complain/vformRender")
}
</script>
<style lang="scss" scoped>
.vform_designer_wrap {
margin: 0 !important;
padding: 0 !important;
overflow: hidden;
:deep .main-content {
aside.el-aside {
height: 90vh !important;
overflow-y: auto;
}
section.el-container {
main.el-main {
height: 84vh !important;
overflow-y: auto;
}
}
}
:deep .float-right.external-link {
display: none;
}
:deep .el-header.main-header {
display: none;
}
:deep .el-container.full-height {
overflow-y: auto;
}
}
</style>
读取
- vformRender.vue
vue
<template>
<section class="vformRender">
<el-button @click="renderFrom">重新生成表单</el-button>
<el-button @click="back">返回</el-button>
<div class="render_wrap" v-loading="!renderFlag">
<v-form-render v-if="renderFlag" :form-json="formJson" :form-data="formData" ref="vFormRenderRef" />
</div>
</section>
</template>
<script setup>
import { ref, reactive, onUnmounted } from 'vue'
import { useRouter } from "vue-router";
import * as indexDb from '@/utils/indexDb.js'
const router = useRouter();
const vFormRenderRef = ref(null)
let renderFlag = ref(true)
let renderLoading = ref(false)
let formJson = reactive({})
const formData = reactive({})
const dbName = 'myVFormDB', storeName = 'myVFormStore'
let db = null
const renderFrom = async () => {
renderFlag.value = false
db = await indexDb.openDB(dbName, storeName, 1)
let data = await indexDb.getDataByKey(db, storeName, 'myVFormId_1')
formJson = JSON.parse(data.config)
// console.log(formJson)
renderFlag.value = true
}
const back = async () => {
router.push('/complain/vform')
await indexDb.deleteDBAll('myVFormDB')
}
renderFrom()
onUnmounted(async () => {
await indexDb.closeDB(db)
})
</script>
<style lang="scss" scoped>
.render_wrap {
width: 95%;
height: 80vh;
margin: 20px auto 0;
margin-top: 20px;
overflow-y: auto
}
</style>
<template>
<section class="vformRender">
<el-button @click="renderFrom">重新生成表单</el-button>
<el-button @click="back">返回</el-button>
<div class="render_wrap" v-loading="!renderFlag">
<v-form-render v-if="renderFlag" :form-json="formJson" :form-data="formData" ref="vFormRenderRef" />
</div>
</section>
</template>
<script setup>
import { ref, reactive, onUnmounted } from 'vue'
import { useRouter } from "vue-router";
import * as indexDb from '@/utils/indexDb.js'
const router = useRouter();
const vFormRenderRef = ref(null)
let renderFlag = ref(true)
let renderLoading = ref(false)
let formJson = reactive({})
const formData = reactive({})
const dbName = 'myVFormDB', storeName = 'myVFormStore'
let db = null
const renderFrom = async () => {
renderFlag.value = false
db = await indexDb.openDB(dbName, storeName, 1)
let data = await indexDb.getDataByKey(db, storeName, 'myVFormId_1')
formJson = JSON.parse(data.config)
// console.log(formJson)
renderFlag.value = true
}
const back = async () => {
router.push('/complain/vform')
await indexDb.deleteDBAll('myVFormDB')
}
renderFrom()
onUnmounted(async () => {
await indexDb.closeDB(db)
})
</script>
<style lang="scss" scoped>
.render_wrap {
width: 95%;
height: 80vh;
margin: 20px auto 0;
margin-top: 20px;
overflow-y: auto
}
</style>