页面持久化大体功能实现

Former-commit-id: 6de284ac144ef2dc9add34aa16502109485a16d2 [formerly 6de284ac144ef2dc9add34aa16502109485a16d2 [formerly 6de284ac144ef2dc9add34aa16502109485a16d2 [formerly 6de284ac144ef2dc9add34aa16502109485a16d2 [formerly 99351410cdef9041c1acbcd105ab7f02e23c4db1 [formerly d70ea9b6ea91dec0463c7e925a8eaab9c1990a6d]]]]]
Former-commit-id: 88212ee98bd64a47532ce9dac84a572f55248a87
Former-commit-id: 017b329b1b91a670b85398e771d34504cc027f26
Former-commit-id: 9d4254f31c10c6e1cc65c65b42847d91e3645566 [formerly b0c0b3fa63225f698741d26af019cee2c9e9258c]
Former-commit-id: 4a4e25525dd02ec2f4a566716a04d5751dc836f8
Former-commit-id: 32994d19e44dd945d144c72134c4aec7b0bc5b13
Former-commit-id: 625b25670c37b0fd33826ddfa845802f1a8e5533
Former-commit-id: ac609aa4a8a3284e927f6b704ccda7786c7df8a6
Former-commit-id: 47d02c0e39e0a6fcba7dfdc98782045193e40c6b
This commit is contained in:
liyang
2018-08-18 17:36:52 +08:00
parent 4d16ed0a22
commit 58c383e05d
9 changed files with 599 additions and 25 deletions

View File

@@ -2,7 +2,7 @@ import low from 'lowdb'
import LocalStorage from 'lowdb/adapters/LocalStorage' import LocalStorage from 'lowdb/adapters/LocalStorage'
import setting from '@/setting.js' import setting from '@/setting.js'
const adapter = new LocalStorage(`d2admin-${setting.version}`) const adapter = new LocalStorage(`d2admin-${setting.releases.version}`)
const db = low(adapter) const db = low(adapter)
// 初始化数据库 // 初始化数据库

View File

@@ -43,7 +43,11 @@ export default {
children: [ children: [
{ path: `${pre}db/all`, title: '全部数据', icon: 'table' }, { path: `${pre}db/all`, title: '全部数据', icon: 'table' },
{ path: `${pre}db/user`, title: '用户数据', icon: 'user' }, { path: `${pre}db/user`, title: '用户数据', icon: 'user' },
{ path: `${pre}db/public`, title: '公用数据', icon: 'users' } { path: `${pre}db/public`, title: '公用数据', icon: 'users' },
{ path: `${pre}db/page-public`, title: '页面存储', icon: 'file-o' },
{ path: `${pre}db/page-user`, title: '页面存储 用户', icon: 'file-o' },
{ path: `${pre}db/page-snapshot-public`, title: '页面快照', icon: 'file' },
{ path: `${pre}db/page-snapshot-user`, title: '页面快照 用户', icon: 'file' }
] ]
}, },
{ {

View File

@@ -0,0 +1,127 @@
<template>
<d2-container>
<template slot="header">持久化存储数据此页面独享</template>
<el-row>
<el-col :span="12">
<p class="d2-mt-0">增加不重复字段</p>
<el-button @click="handleSetRandom">增加</el-button>
<p>增加自定义字段</p>
<el-input v-model="keyNameToSet" placeholder="字段名" class="d2-mr-5" style="width: 100px;"/>
<el-input v-model="valueToSet" placeholder="值" class="d2-mr-5" style="width: 100px;"/>
<el-button @click="handleSet">增加</el-button>
<p>删除字段</p>
<el-select
v-model="keyNameToDelete"
placeholder="请选择要删除的 key">
<el-option
v-for="item in keyNameList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<p>清空当前用户数据</p>
<el-button @click="handleClear">清空</el-button>
</el-col>
<el-col :span="12">
<d2-highlight :code="dataDisplay"/>
</el-col>
</el-row>
</d2-container>
</template>
<script>
import day from 'dayjs'
import { mapActions } from 'vuex'
export default {
data () {
return {
dataDisplay: '',
keyNameToSet: '',
valueToSet: '',
keyNameList: [],
keyNameToDelete: ''
}
},
watch: {
keyNameToDelete (value) {
if (value) {
this.handleDelete(value)
}
}
},
mounted () {
this.load()
},
methods: {
...mapActions('d2admin/db', [
'databasePage',
'databasePageClear'
]),
/**
* 加载本地数据
*/
async load () {
const db = await this.databasePage({
vm: this
})
this.dataDisplay = JSON.stringify(db.value(), null, 2)
this.keyNameList = Object.keys(db.value()).map(k => ({
value: k,
label: k
}))
},
/**
* 删除一个字段
*/
async handleDelete (name) {
const db = await this.databasePage({
vm: this
})
db
.unset(name)
.write()
this.load()
this.keyNameToDelete = ''
},
/**
* 清空当前用户的数据
*/
async handleClear () {
await this.databasePageClear({
vm: this
})
this.load()
},
/**
* 添加一个数据
*/
async handleSet () {
if (this.keyNameToSet === '') {
this.$message.error('字段名不能为空')
return
}
const db = await this.databasePage({
vm: this
})
db
.set(this.keyNameToSet, this.valueToSet)
.write()
this.load()
},
/**
* 添加一个随机数据
*/
async handleSetRandom () {
const id = day().valueOf()
const db = await this.databasePage({
vm: this
})
db
.set(id, Math.round(id * Math.random()))
.write()
this.load()
}
}
}
</script>

View File

@@ -0,0 +1,111 @@
<template>
<d2-container>
<el-alert
slot="header"
type="success"
:closable="false"
title="下面的表单来自 Element 的表单示例,
在 D2Admin 的本页示例中你可以随意填写这个表单,
表单内容会自动实时持久化,
无论是切换标签页、重新打开标签页、刷新浏览器、重开浏览器、重开浏览器标签页等,
该页面数据都会自动恢复到上次填写的状态,
这些都只需要你使用 D2Admin 提供的两个方法,
总共只需要多写十几行代码"/>
<el-form ref="form" :model="form" label-width="80px" style="max-width: 600px; margin: 0px auto;">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col :span="2" style="text-align: center;">-</el-col>
<el-col :span="11">
<el-time-picker type="fixed-time" placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下活动" name="type"></el-checkbox>
<el-checkbox label="品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
<el-button
slot="footer"
type="danger"
@click="handleClear">
<d2-icon name="trash-o"/>
删除当前页面快照
</el-button>
</d2-container>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data () {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
async created () {
const data = await this.pageLoad({ vm: this })
for (const key in data) {
if (data.hasOwnProperty(key)) this[key] = data[key]
}
},
watch: {
$data: {
handler () {
this.pageSet({ vm: this })
},
deep: true
}
},
methods: {
...mapActions('d2admin/db', [
'pageSet',
'pageLoad',
'pageClear'
]),
async handleClear () {
await this.pageClear({ vm: this })
this.$message.success('此页面快照已经删除,请重新进入该页面或者关闭选项卡重新打开')
}
}
}
</script>

View File

@@ -0,0 +1,111 @@
<template>
<d2-container>
<el-alert
slot="header"
type="success"
:closable="false"
title="下面的表单来自 Element 的表单示例,
在 D2Admin 的本页示例中你可以随意填写这个表单,
表单内容会自动实时持久化,
无论是切换标签页、重新打开标签页、刷新浏览器、重开浏览器、重开浏览器标签页等,
该页面数据都会自动恢复到上次填写的状态,
这些都只需要你使用 D2Admin 提供的两个方法,
总共只需要多写十几行代码"/>
<el-form ref="form" :model="form" label-width="80px" style="max-width: 600px; margin: 0px auto;">
<el-form-item label="活动名称">
<el-input v-model="form.name"></el-input>
</el-form-item>
<el-form-item label="活动区域">
<el-select v-model="form.region" placeholder="请选择活动区域">
<el-option label="区域一" value="shanghai"></el-option>
<el-option label="区域二" value="beijing"></el-option>
</el-select>
</el-form-item>
<el-form-item label="活动时间">
<el-col :span="11">
<el-date-picker type="date" placeholder="选择日期" v-model="form.date1" style="width: 100%;"></el-date-picker>
</el-col>
<el-col :span="2" style="text-align: center;">-</el-col>
<el-col :span="11">
<el-time-picker type="fixed-time" placeholder="选择时间" v-model="form.date2" style="width: 100%;"></el-time-picker>
</el-col>
</el-form-item>
<el-form-item label="即时配送">
<el-switch v-model="form.delivery"></el-switch>
</el-form-item>
<el-form-item label="活动性质">
<el-checkbox-group v-model="form.type">
<el-checkbox label="线上活动" name="type"></el-checkbox>
<el-checkbox label="地推活动" name="type"></el-checkbox>
<el-checkbox label="线下活动" name="type"></el-checkbox>
<el-checkbox label="品牌曝光" name="type"></el-checkbox>
</el-checkbox-group>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form.resource">
<el-radio label="线上品牌商赞助"></el-radio>
<el-radio label="线下场地免费"></el-radio>
</el-radio-group>
</el-form-item>
<el-form-item label="活动形式">
<el-input type="textarea" v-model="form.desc"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary">立即创建</el-button>
<el-button>取消</el-button>
</el-form-item>
</el-form>
<el-button
slot="footer"
type="danger"
@click="handleClear">
<d2-icon name="trash-o"/>
删除当前页面快照
</el-button>
</d2-container>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data () {
return {
form: {
name: '',
region: '',
date1: '',
date2: '',
delivery: false,
type: [],
resource: '',
desc: ''
}
}
},
async created () {
const data = await this.pageLoad({ vm: this, user: true })
for (const key in data) {
if (data.hasOwnProperty(key)) this[key] = data[key]
}
},
watch: {
$data: {
handler () {
this.pageSet({ vm: this, user: true })
},
deep: true
}
},
methods: {
...mapActions('d2admin/db', [
'pageSet',
'pageLoad',
'pageClear'
]),
async handleClear () {
await this.pageClear({ vm: this, user: true })
this.$message.success('此页面快照已经删除,请重新进入该页面或者关闭选项卡重新打开')
}
}
}
</script>

View File

@@ -0,0 +1,132 @@
<template>
<d2-container>
<template slot="header">持久化存储数据此页面独享</template>
<el-row>
<el-col :span="12">
<p class="d2-mt-0">增加不重复字段</p>
<el-button @click="handleSetRandom">增加</el-button>
<p>增加自定义字段</p>
<el-input v-model="keyNameToSet" placeholder="字段名" class="d2-mr-5" style="width: 100px;"/>
<el-input v-model="valueToSet" placeholder="值" class="d2-mr-5" style="width: 100px;"/>
<el-button @click="handleSet">增加</el-button>
<p>删除字段</p>
<el-select
v-model="keyNameToDelete"
placeholder="请选择要删除的 key">
<el-option
v-for="item in keyNameList"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
<p>清空当前用户数据</p>
<el-button @click="handleClear">清空</el-button>
</el-col>
<el-col :span="12">
<d2-highlight :code="dataDisplay"/>
</el-col>
</el-row>
</d2-container>
</template>
<script>
import day from 'dayjs'
import { mapActions } from 'vuex'
export default {
data () {
return {
dataDisplay: '',
keyNameToSet: '',
valueToSet: '',
keyNameList: [],
keyNameToDelete: ''
}
},
watch: {
keyNameToDelete (value) {
if (value) {
this.handleDelete(value)
}
}
},
mounted () {
this.load()
},
methods: {
...mapActions('d2admin/db', [
'databasePage',
'databasePageClear'
]),
/**
* 加载本地数据
*/
async load () {
const db = await this.databasePage({
vm: this,
user: true
})
this.dataDisplay = JSON.stringify(db.value(), null, 2)
this.keyNameList = Object.keys(db.value()).map(k => ({
value: k,
label: k
}))
},
/**
* 删除一个字段
*/
async handleDelete (name) {
const db = await this.databasePage({
vm: this,
user: true
})
db
.unset(name)
.write()
this.load()
this.keyNameToDelete = ''
},
/**
* 清空当前用户的数据
*/
async handleClear () {
await this.databasePageClear({
vm: this,
user: true
})
this.load()
},
/**
* 添加一个数据
*/
async handleSet () {
if (this.keyNameToSet === '') {
this.$message.error('字段名不能为空')
return
}
const db = await this.databasePage({
vm: this,
user: true
})
db
.set(this.keyNameToSet, this.valueToSet)
.write()
this.load()
},
/**
* 添加一个随机数据
*/
async handleSetRandom () {
const id = day().valueOf()
const db = await this.databasePage({
vm: this,
user: true
})
db
.set(id, Math.round(id * Math.random()))
.write()
this.load()
}
}
}
</script>

View File

@@ -1,6 +1,6 @@
<template> <template>
<d2-container> <d2-container>
<template slot="header">持久化存储用数据用户区分存储</template> <template slot="header">持久化存储用数据当前用户</template>
<el-row> <el-row>
<el-col :span="12"> <el-col :span="12">
<p class="d2-mt-0">增加不重复字段</p> <p class="d2-mt-0">增加不重复字段</p>
@@ -55,14 +55,14 @@ export default {
}, },
methods: { methods: {
...mapActions('d2admin/db', [ ...mapActions('d2admin/db', [
'databaseByUser', 'database',
'databaseByUserClear' 'databaseClear'
]), ]),
/** /**
* 加载本地数据 * 加载本地数据
*/ */
async load () { async load () {
const db = await this.databaseByUser() const db = await this.database({ user: true })
this.dataDisplay = JSON.stringify(db.value(), null, 2) this.dataDisplay = JSON.stringify(db.value(), null, 2)
this.keyNameList = Object.keys(db.value()).map(k => ({ this.keyNameList = Object.keys(db.value()).map(k => ({
value: k, value: k,
@@ -73,7 +73,7 @@ export default {
* 删除一个字段 * 删除一个字段
*/ */
async handleDelete (name) { async handleDelete (name) {
const db = await this.databaseByUser() const db = await this.database({ user: true })
db db
.unset(name) .unset(name)
.write() .write()
@@ -84,7 +84,7 @@ export default {
* 清空当前用户的数据 * 清空当前用户的数据
*/ */
async handleClear () { async handleClear () {
await this.databaseByUserClear() await this.databaseClear({ user: true })
this.load() this.load()
}, },
/** /**
@@ -95,7 +95,7 @@ export default {
this.$message.error('字段名不能为空') this.$message.error('字段名不能为空')
return return
} }
const db = await this.databaseByUser() const db = await this.database({ user: true })
db db
.set(this.keyNameToSet, this.valueToSet) .set(this.keyNameToSet, this.valueToSet)
.write() .write()
@@ -106,7 +106,7 @@ export default {
*/ */
async handleSetRandom () { async handleSetRandom () {
const id = day().valueOf() const id = day().valueOf()
const db = await this.databaseByUser() const db = await this.database({ user: true })
db db
.set(id, Math.round(id * Math.random())) .set(id, Math.round(id * Math.random()))
.write() .write()

View File

@@ -1 +1 @@
3f797ef981679608bad178b6a1a748bfa08e6ade 7558a0da48296f987f92467e104ef3cd36eb2dde

View File

@@ -72,53 +72,142 @@ export default {
actions: { actions: {
/** /**
* @description 获取存储数据库对象 * @description 获取存储数据库对象
* @param {Object} context context
* @param {Object} param user {Boolean} 是否区分用户
*/ */
database () { database (context, {
user = false
} = {}) {
return new Promise(resolve => { return new Promise(resolve => {
resolve(db.get(pathInit({ resolve(db.get(pathInit({
dbName: 'database', dbName: 'database',
path: '', path: '',
user: false, user,
defaultValue: {} defaultValue: {}
}))) })))
}) })
}, },
/** /**
* @description 清空存储数据库对象 * @description 清空存储数据库对象
* @param {Object} context context
* @param {Object} param user {Boolean} 是否区分用户
*/ */
databaseClear () { databaseClear (context, {
user = false
} = {}) {
return new Promise(resolve => { return new Promise(resolve => {
resolve(db.get(pathInit({ resolve(db.get(pathInit({
dbName: 'database', dbName: 'database',
path: '', path: '',
user: false, user,
validator: () => false, validator: () => false,
defaultValue: {} defaultValue: {}
}))) })))
}) })
}, },
/** /**
* @description 获取存储数据库对象 [区分用户] * @description 获取存储数据库对象 [ 区分页面 ]
* @param {Object} context context
* @param {Object} param vm {Object} vue
* @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]
* @param {Object} param user {Boolean} 是否区分用户
*/ */
databaseByUser () { databasePage (context, {
vm,
basis = 'name',
user = false
} = {}) {
return new Promise(resolve => { return new Promise(resolve => {
resolve(db.get(pathInit({ resolve(db.get(pathInit({
dbName: 'database', dbName: 'database',
path: '', path: vm.$route[basis],
user: true, user,
defaultValue: {} defaultValue: {}
}))) })))
}) })
}, },
/** /**
* @description 清空存储数据库对象 [区分用户] * @description 清空存储数据库对象 [ 区分页面 ]
* @param {Object} context context
* @param {Object} param vm {Object} vue
* @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]
* @param {Object} param user {Boolean} 是否区分用户
*/ */
databaseByUserClear () { databasePageClear (context, {
vm,
basis = 'name',
user = false
} = {}) {
return new Promise(resolve => { return new Promise(resolve => {
resolve(db.get(pathInit({ resolve(db.get(pathInit({
dbName: 'database', dbName: 'database',
path: '', path: vm.$route[basis],
user: true, user,
validator: () => false,
defaultValue: {}
})))
})
},
/**
* @description 快速将页面当前的数据 ( $data ) 持久化
* @param {Object} context context
* @param {Object} param vm {Object} vue
* @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]
* @param {Object} param user {Boolean} 是否区分用户
*/
pageSet (context, {
vm,
basis = 'name',
user = false
}) {
return new Promise(resolve => {
resolve(db.get(pathInit({
dbName: 'database',
path: `${vm.$route[basis]}.$data`,
user,
validator: () => false,
defaultValue: vm.$data
})))
})
},
/**
* @description 快速获取页面快速持久化的数据
* @param {Object} context context
* @param {Object} param vm {Object} vue
* @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]
* @param {Object} param user {Boolean} 是否区分用户
*/
pageLoad (context, {
vm,
basis = 'name',
user = false
}) {
return new Promise(resolve => {
resolve(db.get(pathInit({
dbName: 'database',
path: `${vm.$route[basis]}.$data`,
user,
defaultValue: vm.$data
})).value())
})
},
/**
* @description 清空页面快照
* @param {Object} context context
* @param {Object} param vm {Object} vue
* @param {Object} param basis {String} 页面区分依据 [ name | path | fullPath ]
* @param {Object} param user {Boolean} 是否区分用户
*/
pageClear (context, {
vm,
basis = 'name',
user = false
}) {
return new Promise(resolve => {
resolve(db.get(pathInit({
dbName: 'database',
path: `${vm.$route[basis]}.$data`,
user,
validator: () => false, validator: () => false,
defaultValue: {} defaultValue: {}
}))) })))