Merge branch 'master' into release
commit
fa1735fbdb
@ -0,0 +1,4 @@
|
||||
import JsonEditor from './src/JsonEditor.vue'
|
||||
export type { JsonEditorProps } from './src/types'
|
||||
|
||||
export { JsonEditor }
|
||||
@ -0,0 +1,98 @@
|
||||
<script setup lang="ts">
|
||||
import VueJsonPretty from 'vue-json-pretty'
|
||||
import 'vue-json-pretty/lib/styles.css'
|
||||
import { propTypes } from '@/utils/propTypes'
|
||||
import { computed } from 'vue'
|
||||
|
||||
const emits = defineEmits([
|
||||
'update:modelValue',
|
||||
'node-click',
|
||||
'brackets-click',
|
||||
'icon-click',
|
||||
'selected-value'
|
||||
])
|
||||
|
||||
const props = defineProps({
|
||||
modelValue: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
},
|
||||
deep: propTypes.number.def(5),
|
||||
showLength: propTypes.bool.def(true),
|
||||
showLineNumbers: propTypes.bool.def(true),
|
||||
showLineNumber: propTypes.bool.def(true),
|
||||
showIcon: propTypes.bool.def(true),
|
||||
showDoubleQuotes: propTypes.bool.def(true),
|
||||
virtual: propTypes.bool.def(false),
|
||||
height: propTypes.number.def(400),
|
||||
itemHeight: propTypes.number.def(20),
|
||||
rootPath: propTypes.string.def('root'),
|
||||
nodeSelectable: propTypes.func.def(),
|
||||
selectableType: propTypes.oneOf<'multiple' | 'single'>(['multiple', 'single']).def(),
|
||||
showSelectController: propTypes.bool.def(false),
|
||||
selectOnClickNode: propTypes.bool.def(true),
|
||||
highlightSelectedNode: propTypes.bool.def(true),
|
||||
collapsedOnClickBrackets: propTypes.bool.def(true),
|
||||
renderNodeKey: propTypes.func.def(),
|
||||
renderNodeValue: propTypes.func.def(),
|
||||
editable: propTypes.bool.def(true),
|
||||
editableTrigger: propTypes.oneOf<'click' | 'dblclick'>(['click', 'dblclick']).def('click')
|
||||
})
|
||||
|
||||
const data = computed(() => props.modelValue)
|
||||
|
||||
const localModelValue = computed({
|
||||
get: () => data.value,
|
||||
set: (val) => {
|
||||
console.log(val)
|
||||
emits('update:modelValue', val)
|
||||
}
|
||||
})
|
||||
|
||||
const nodeClick = (node: any) => {
|
||||
emits('node-click', node)
|
||||
}
|
||||
|
||||
const bracketsClick = (collapsed: boolean) => {
|
||||
emits('brackets-click', collapsed)
|
||||
}
|
||||
|
||||
const iconClick = (collapsed: boolean) => {
|
||||
emits('icon-click', collapsed)
|
||||
}
|
||||
|
||||
const selectedChange = (newVal: any, oldVal: any) => {
|
||||
console.log(newVal, oldVal)
|
||||
emits('selected-value', newVal, oldVal)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<VueJsonPretty
|
||||
v-model:data="localModelValue"
|
||||
:deep="deep"
|
||||
:show-length="showLength"
|
||||
:show-line-numbers="showLineNumbers"
|
||||
:show-line-number="showLineNumber"
|
||||
:show-icon="showIcon"
|
||||
:show-double-quotes="showDoubleQuotes"
|
||||
:virtual="virtual"
|
||||
:height="height"
|
||||
:item-height="itemHeight"
|
||||
:root-path="rootPath"
|
||||
:node-selectable="nodeSelectable"
|
||||
:selectable-type="selectableType"
|
||||
:show-select-controller="showSelectController"
|
||||
:select-on-click-node="selectOnClickNode"
|
||||
:highlight-selected-node="highlightSelectedNode"
|
||||
:collapsed-on-click-brackets="collapsedOnClickBrackets"
|
||||
:render-node-key="renderNodeKey"
|
||||
:render-node-value="renderNodeValue"
|
||||
:editable="editable"
|
||||
:editable-trigger="editableTrigger"
|
||||
@node-click="nodeClick"
|
||||
@brackets-click="bracketsClick"
|
||||
@icon-click="iconClick"
|
||||
@selected-change="selectedChange"
|
||||
/>
|
||||
</template>
|
||||
@ -0,0 +1,23 @@
|
||||
export interface JsonEditorProps {
|
||||
value: any
|
||||
deep?: number
|
||||
showLength?: boolean
|
||||
showLineNumbers?: boolean
|
||||
showLineNumber?: boolean
|
||||
showIcon?: boolean
|
||||
showDoubleQuotes?: boolean
|
||||
virtual?: boolean
|
||||
height?: number
|
||||
itemHeight?: number
|
||||
rootPath?: string
|
||||
nodeSelectable?: (...args: any[]) => boolean
|
||||
selectableType?: 'multiple' | 'single'
|
||||
showSelectController?: boolean
|
||||
selectOnClickNode?: boolean
|
||||
highlightSelectedNode?: boolean
|
||||
collapsedOnClickBrackets?: boolean
|
||||
renderNodeKey?: (...args: any[]) => any
|
||||
renderNodeValue?: (...args: any[]) => any
|
||||
editable?: boolean
|
||||
editableTrigger?: 'click' | 'dblclick'
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
import { Config, driver } from 'driver.js'
|
||||
import 'driver.js/dist/driver.css'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const { variables } = useDesign()
|
||||
|
||||
export const useGuide = (options?: Config) => {
|
||||
const driverObj = driver(
|
||||
options || {
|
||||
showProgress: true,
|
||||
nextBtnText: t('common.nextLabel'),
|
||||
prevBtnText: t('common.prevLabel'),
|
||||
doneBtnText: t('common.doneLabel'),
|
||||
steps: [
|
||||
{
|
||||
element: `#${variables.namespace}-menu`,
|
||||
popover: {
|
||||
title: t('common.menu'),
|
||||
description: t('common.menuDes'),
|
||||
side: 'right'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: `#${variables.namespace}-tool-header`,
|
||||
popover: {
|
||||
title: t('common.tool'),
|
||||
description: t('common.toolDes'),
|
||||
side: 'left'
|
||||
}
|
||||
},
|
||||
{
|
||||
element: `#${variables.namespace}-tags-view`,
|
||||
popover: {
|
||||
title: t('common.tagsView'),
|
||||
description: t('common.tagsViewDes'),
|
||||
side: 'bottom'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
...driverObj
|
||||
}
|
||||
}
|
||||
@ -1,47 +0,0 @@
|
||||
import introJs from 'intro.js'
|
||||
import { IntroJs, Step, Options } from 'intro.js'
|
||||
import 'intro.js/introjs.css'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { useDesign } from '@/hooks/web/useDesign'
|
||||
|
||||
export const useIntro = (setps?: Step[], options?: Options) => {
|
||||
const { t } = useI18n()
|
||||
|
||||
const { variables } = useDesign()
|
||||
|
||||
const defaultSetps: Step[] = setps || [
|
||||
{
|
||||
element: `#${variables.namespace}-menu`,
|
||||
title: t('common.menu'),
|
||||
intro: t('common.menuDes'),
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
element: `#${variables.namespace}-tool-header`,
|
||||
title: t('common.tool'),
|
||||
intro: t('common.toolDes'),
|
||||
position: 'left'
|
||||
},
|
||||
{
|
||||
element: `#${variables.namespace}-tags-view`,
|
||||
title: t('common.tagsView'),
|
||||
intro: t('common.tagsViewDes'),
|
||||
position: 'bottom'
|
||||
}
|
||||
]
|
||||
|
||||
const defaultOptions: Options = options || {
|
||||
prevLabel: t('common.prevLabel'),
|
||||
nextLabel: t('common.nextLabel'),
|
||||
skipLabel: t('common.skipLabel'),
|
||||
doneLabel: t('common.doneLabel')
|
||||
}
|
||||
|
||||
const introRef: IntroJs = introJs()
|
||||
|
||||
introRef.addSteps(defaultSetps).setOptions(defaultOptions)
|
||||
|
||||
return {
|
||||
introRef
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,63 @@
|
||||
import { useTagsViewStoreWithOut } from '@/store/modules/tagsView'
|
||||
import { RouteLocationNormalizedLoaded, useRouter } from 'vue-router'
|
||||
import { computed, nextTick, unref } from 'vue'
|
||||
|
||||
export const useTagsView = () => {
|
||||
const tagsViewStore = useTagsViewStoreWithOut()
|
||||
|
||||
const { replace, currentRoute } = useRouter()
|
||||
|
||||
const selectedTag = computed(() => tagsViewStore.getSelectedTag)
|
||||
|
||||
const closeAll = (callback?: Fn) => {
|
||||
tagsViewStore.delAllViews()
|
||||
callback?.()
|
||||
}
|
||||
|
||||
const closeLeft = (callback?: Fn) => {
|
||||
tagsViewStore.delLeftViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
||||
callback?.()
|
||||
}
|
||||
|
||||
const closeRight = (callback?: Fn) => {
|
||||
tagsViewStore.delRightViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
||||
callback?.()
|
||||
}
|
||||
|
||||
const closeOther = (callback?: Fn) => {
|
||||
tagsViewStore.delOthersViews(unref(selectedTag) as RouteLocationNormalizedLoaded)
|
||||
callback?.()
|
||||
}
|
||||
|
||||
const closeCurrent = (view?: RouteLocationNormalizedLoaded, callback?: Fn) => {
|
||||
if (view?.meta?.affix) return
|
||||
tagsViewStore.delView(view || unref(currentRoute))
|
||||
|
||||
callback?.()
|
||||
}
|
||||
|
||||
const refreshPage = async (view?: RouteLocationNormalizedLoaded, callback?: Fn) => {
|
||||
tagsViewStore.delCachedView()
|
||||
const { path, query } = view || unref(currentRoute)
|
||||
await nextTick()
|
||||
replace({
|
||||
path: '/redirect' + path,
|
||||
query: query
|
||||
})
|
||||
callback?.()
|
||||
}
|
||||
|
||||
const setTitle = (title: string, path?: string) => {
|
||||
tagsViewStore.setTitle(title, path)
|
||||
}
|
||||
|
||||
return {
|
||||
closeAll,
|
||||
closeLeft,
|
||||
closeRight,
|
||||
closeOther,
|
||||
closeCurrent,
|
||||
refreshPage,
|
||||
setTitle
|
||||
}
|
||||
}
|
||||
@ -1,34 +0,0 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import { store } from '../index'
|
||||
|
||||
export interface DictState {
|
||||
isSetDict: boolean
|
||||
dictObj: Recordable
|
||||
}
|
||||
|
||||
export const useDictStore = defineStore('dict', {
|
||||
state: (): DictState => ({
|
||||
isSetDict: false,
|
||||
dictObj: {}
|
||||
}),
|
||||
getters: {
|
||||
getDictObj(): Recordable {
|
||||
return this.dictObj
|
||||
},
|
||||
getIsSetDict(): boolean {
|
||||
return this.isSetDict
|
||||
}
|
||||
},
|
||||
actions: {
|
||||
setDictObj(dictObj: Recordable) {
|
||||
this.dictObj = dictObj
|
||||
},
|
||||
setIsSetDict(isSetDict: boolean) {
|
||||
this.isSetDict = isSetDict
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export const useDictStoreWithOut = () => {
|
||||
return useDictStore(store)
|
||||
}
|
||||
@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { JsonEditor } from '@/components/JsonEditor'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const defaultData = ref({
|
||||
title: '标题',
|
||||
content: '内容'
|
||||
})
|
||||
|
||||
watch(
|
||||
() => defaultData.value,
|
||||
(val) => {
|
||||
console.log(val)
|
||||
},
|
||||
{
|
||||
deep: true
|
||||
}
|
||||
)
|
||||
|
||||
setTimeout(() => {
|
||||
defaultData.value = {
|
||||
title: '异步标题',
|
||||
content: '异步内容'
|
||||
}
|
||||
}, 4000)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContentWrap :title="t('richText.jsonEditor')" :message="t('richText.jsonEditorDes')">
|
||||
<JsonEditor v-model="defaultData" />
|
||||
</ContentWrap>
|
||||
</template>
|
||||
@ -1,223 +1,186 @@
|
||||
<script setup lang="ts">
|
||||
// import { ContentWrap } from '@/components/ContentWrap'
|
||||
// import { Search } from '@/components/Search'
|
||||
// import { useI18n } from '@/hooks/web/useI18n'
|
||||
// import { ElButton, ElTag } from 'element-plus'
|
||||
// import { Table } from '@/components/Table'
|
||||
// import { getTableListApi, delTableListApi } from '@/api/table'
|
||||
// import { useTable } from '@/hooks/web/useTable'
|
||||
// import { TableData } from '@/api/table/types'
|
||||
// import { h, ref, reactive } from 'vue'
|
||||
// import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
|
||||
// import { useDictStore } from '@/store/modules/dict'
|
||||
// import { getDictOneApi } from '@/api/common'
|
||||
// import { TableColumn } from '@/types/table'
|
||||
import { CrudSchema, useCrudSchemas } from '@/hooks/web/useCrudSchemas'
|
||||
import { useI18n } from '@/hooks/web/useI18n'
|
||||
import { reactive } from 'vue'
|
||||
import { JsonEditor } from '@/components/JsonEditor'
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { ElRow, ElCol } from 'element-plus'
|
||||
|
||||
// const dictStore = useDictStore()
|
||||
const { t } = useI18n()
|
||||
|
||||
// const { register, tableObject, methods } = useTable<TableData>({
|
||||
// getListApi: getTableListApi,
|
||||
// delListApi: delTableListApi,
|
||||
// response: {
|
||||
// list: 'list',
|
||||
// total: 'total'
|
||||
// }
|
||||
// })
|
||||
const crudSchemas = reactive<CrudSchema[]>([
|
||||
{
|
||||
field: 'selection',
|
||||
search: {
|
||||
hidden: true
|
||||
},
|
||||
form: {
|
||||
hidden: true
|
||||
},
|
||||
detail: {
|
||||
hidden: true
|
||||
},
|
||||
table: {
|
||||
type: 'selection'
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'index',
|
||||
label: t('tableDemo.index'),
|
||||
type: 'index',
|
||||
search: {
|
||||
hidden: true
|
||||
},
|
||||
form: {
|
||||
hidden: true
|
||||
},
|
||||
detail: {
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'title',
|
||||
label: t('tableDemo.title'),
|
||||
search: {
|
||||
component: 'Input'
|
||||
},
|
||||
form: {
|
||||
component: 'Input',
|
||||
colProps: {
|
||||
span: 24
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
span: 24
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'author',
|
||||
label: t('tableDemo.author'),
|
||||
search: {
|
||||
hidden: true
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'display_time',
|
||||
label: t('tableDemo.displayTime'),
|
||||
search: {
|
||||
hidden: true
|
||||
},
|
||||
form: {
|
||||
component: 'DatePicker',
|
||||
componentProps: {
|
||||
type: 'datetime',
|
||||
valueFormat: 'YYYY-MM-DD HH:mm:ss'
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'importance',
|
||||
label: t('tableDemo.importance'),
|
||||
search: {
|
||||
hidden: true
|
||||
},
|
||||
form: {
|
||||
component: 'Select',
|
||||
componentProps: {
|
||||
style: {
|
||||
width: '100%'
|
||||
},
|
||||
options: [
|
||||
{
|
||||
label: '重要',
|
||||
value: 3
|
||||
},
|
||||
{
|
||||
label: '良好',
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
label: '一般',
|
||||
value: 1
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'pageviews',
|
||||
label: t('tableDemo.pageviews'),
|
||||
search: {
|
||||
hidden: true
|
||||
},
|
||||
form: {
|
||||
component: 'InputNumber',
|
||||
value: 0
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'content',
|
||||
label: t('exampleDemo.content'),
|
||||
search: {
|
||||
hidden: true
|
||||
},
|
||||
table: {
|
||||
show: false
|
||||
},
|
||||
form: {
|
||||
component: 'Editor',
|
||||
colProps: {
|
||||
span: 24
|
||||
}
|
||||
},
|
||||
detail: {
|
||||
span: 24
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'action',
|
||||
width: '260px',
|
||||
label: t('tableDemo.action'),
|
||||
search: {
|
||||
hidden: true
|
||||
},
|
||||
form: {
|
||||
hidden: true
|
||||
},
|
||||
detail: {
|
||||
hidden: true
|
||||
}
|
||||
}
|
||||
])
|
||||
|
||||
// const { getList, setSearchParams } = methods
|
||||
|
||||
// getList()
|
||||
|
||||
// const { t } = useI18n()
|
||||
|
||||
// const crudSchemas = reactive<CrudSchema[]>([
|
||||
// {
|
||||
// field: 'index',
|
||||
// label: t('tableDemo.index'),
|
||||
// type: 'index',
|
||||
// form: {
|
||||
// show: false
|
||||
// },
|
||||
// detail: {
|
||||
// show: false
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'title',
|
||||
// label: t('tableDemo.title'),
|
||||
// search: {
|
||||
// show: true
|
||||
// },
|
||||
// form: {
|
||||
// colProps: {
|
||||
// span: 24
|
||||
// }
|
||||
// },
|
||||
// detail: {
|
||||
// span: 24
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'author',
|
||||
// label: t('tableDemo.author')
|
||||
// },
|
||||
// {
|
||||
// field: 'display_time',
|
||||
// label: t('tableDemo.displayTime'),
|
||||
// form: {
|
||||
// component: 'DatePicker',
|
||||
// componentProps: {
|
||||
// type: 'datetime',
|
||||
// valueFormat: 'YYYY-MM-DD HH:mm:ss'
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'importance',
|
||||
// label: t('tableDemo.importance'),
|
||||
// formatter: (_: Recordable, __: TableColumn, cellValue: number) => {
|
||||
// return h(
|
||||
// ElTag,
|
||||
// {
|
||||
// type: cellValue === 1 ? 'success' : cellValue === 2 ? 'warning' : 'danger'
|
||||
// },
|
||||
// () =>
|
||||
// cellValue === 1
|
||||
// ? t('tableDemo.important')
|
||||
// : cellValue === 2
|
||||
// ? t('tableDemo.good')
|
||||
// : t('tableDemo.commonly')
|
||||
// )
|
||||
// },
|
||||
// search: {
|
||||
// show: true,
|
||||
// component: 'Select',
|
||||
// componentProps: {
|
||||
// options: dictStore.getDictObj.importance
|
||||
// }
|
||||
// },
|
||||
// form: {
|
||||
// component: 'Select',
|
||||
// componentProps: {
|
||||
// options: [
|
||||
// {
|
||||
// label: '重要',
|
||||
// value: 3
|
||||
// },
|
||||
// {
|
||||
// label: '良好',
|
||||
// value: 2
|
||||
// },
|
||||
// {
|
||||
// label: '一般',
|
||||
// value: 1
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'importance2',
|
||||
// label: `${t('tableDemo.importance')}2`,
|
||||
// search: {
|
||||
// show: true,
|
||||
// component: 'Select',
|
||||
// dictName: 'importance'
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'importance3',
|
||||
// label: `${t('tableDemo.importance')}3`,
|
||||
// search: {
|
||||
// show: true,
|
||||
// component: 'Select',
|
||||
// api: async () => {
|
||||
// const res = await getDictOneApi()
|
||||
// return res.data
|
||||
// }
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'pageviews',
|
||||
// label: t('tableDemo.pageviews'),
|
||||
// form: {
|
||||
// component: 'InputNumber',
|
||||
// value: 0
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'content',
|
||||
// label: t('exampleDemo.content'),
|
||||
// table: {
|
||||
// show: false
|
||||
// },
|
||||
// form: {
|
||||
// component: 'Editor',
|
||||
// colProps: {
|
||||
// span: 24
|
||||
// }
|
||||
// },
|
||||
// detail: {
|
||||
// span: 24
|
||||
// }
|
||||
// },
|
||||
// {
|
||||
// field: 'action',
|
||||
// width: '260px',
|
||||
// label: t('tableDemo.action'),
|
||||
// form: {
|
||||
// show: false
|
||||
// },
|
||||
// detail: {
|
||||
// show: false
|
||||
// }
|
||||
// }
|
||||
// ])
|
||||
|
||||
// const { allSchemas } = useCrudSchemas(crudSchemas)
|
||||
|
||||
// const delLoading = ref(false)
|
||||
|
||||
// const delData = async (row: TableData | null, multiple: boolean) => {
|
||||
// tableObject.currentRow = row
|
||||
// const { delList, getSelections } = methods
|
||||
// const selections = await getSelections()
|
||||
// delLoading.value = true
|
||||
// await delList(
|
||||
// multiple ? selections.map((v) => v.id) : [tableObject.currentRow?.id as string],
|
||||
// multiple
|
||||
// ).finally(() => {
|
||||
// delLoading.value = false
|
||||
// })
|
||||
// }
|
||||
const { allSchemas } = useCrudSchemas(crudSchemas)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<!-- <Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams" />
|
||||
|
||||
<div class="mb-10px">
|
||||
<ElButton :loading="delLoading" type="danger" @click="delData(null, true)">
|
||||
{{ t('exampleDemo.del') }}
|
||||
</ElButton>
|
||||
</div>
|
||||
|
||||
<Table
|
||||
v-model:pageSize="tableObject.pageSize"
|
||||
v-model:currentPage="tableObject.currentPage"
|
||||
:columns="allSchemas.tableColumns"
|
||||
:data="tableObject.tableList"
|
||||
:loading="tableObject.loading"
|
||||
:pagination="{
|
||||
total: tableObject.total
|
||||
}"
|
||||
@register="register"
|
||||
>
|
||||
<template #action="{ row }">
|
||||
<ElButton type="danger" @click="delData(row, false)">
|
||||
{{ t('exampleDemo.del') }}
|
||||
</ElButton>
|
||||
</template>
|
||||
</Table> -->
|
||||
<ContentWrap title="useCrudSchemas">
|
||||
<ElRow :gutter="20">
|
||||
<ElCol :span="24">
|
||||
<ContentWrap title="原始数据数据" class="mt-20px">
|
||||
<JsonEditor v-model="crudSchemas" />
|
||||
</ContentWrap>
|
||||
</ElCol>
|
||||
<ElCol :span="24">
|
||||
<ContentWrap title="查询组件数据结构" class="mt-20px">
|
||||
<JsonEditor v-model="allSchemas.searchSchema" />
|
||||
</ContentWrap>
|
||||
</ElCol>
|
||||
<ElCol :span="24">
|
||||
<ContentWrap title="表单组件数据结构" class="mt-20px">
|
||||
<JsonEditor v-model="allSchemas.formSchema" />
|
||||
</ContentWrap>
|
||||
</ElCol>
|
||||
<ElCol :span="24">
|
||||
<ContentWrap title="表格组件数据结构" class="mt-20px">
|
||||
<JsonEditor v-model="allSchemas.tableColumns" />
|
||||
</ContentWrap>
|
||||
</ElCol>
|
||||
<ElCol :span="24">
|
||||
<ContentWrap title="表格组件数据结构" class="mt-20px">
|
||||
<JsonEditor v-model="allSchemas.detailSchema" />
|
||||
</ContentWrap>
|
||||
</ElCol>
|
||||
</ElRow>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
|
||||
@ -0,0 +1,60 @@
|
||||
<script setup lang="ts">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { ElButton } from 'element-plus'
|
||||
import { useTagsView } from '@/hooks/web/useTagsView'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
const { push } = useRouter()
|
||||
|
||||
const { closeAll, closeLeft, closeRight, closeOther, closeCurrent, refreshPage, setTitle } =
|
||||
useTagsView()
|
||||
|
||||
const closeAllTabs = () => {
|
||||
closeAll(() => {
|
||||
push('/dashboard/analysis')
|
||||
})
|
||||
}
|
||||
|
||||
const closeLeftTabs = () => {
|
||||
closeLeft()
|
||||
}
|
||||
|
||||
const closeRightTabs = () => {
|
||||
closeRight()
|
||||
}
|
||||
|
||||
const closeOtherTabs = () => {
|
||||
closeOther()
|
||||
}
|
||||
|
||||
const refresh = () => {
|
||||
refreshPage()
|
||||
}
|
||||
|
||||
const closeCurrentTab = () => {
|
||||
closeCurrent(undefined, () => {
|
||||
push('/dashboard/analysis')
|
||||
})
|
||||
}
|
||||
|
||||
const setTabTitle = () => {
|
||||
setTitle(new Date().getTime().toString())
|
||||
}
|
||||
|
||||
const setAnalysisTitle = () => {
|
||||
setTitle(`分析页-${new Date().getTime().toString()}`, '/dashboard/analysis')
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContentWrap title="useTagsView">
|
||||
<ElButton type="primary" @click="closeAllTabs"> 关闭所有标签页 </ElButton>
|
||||
<ElButton type="primary" @click="closeLeftTabs"> 关闭左侧标签页 </ElButton>
|
||||
<ElButton type="primary" @click="closeRightTabs"> 关闭右侧标签页 </ElButton>
|
||||
<ElButton type="primary" @click="closeOtherTabs"> 关闭其他标签页 </ElButton>
|
||||
<ElButton type="primary" @click="closeCurrentTab"> 关闭当前标签页 </ElButton>
|
||||
<ElButton type="primary" @click="refresh"> 刷新当前标签页 </ElButton>
|
||||
<ElButton type="primary" @click="setTabTitle"> 修改当前标题 </ElButton>
|
||||
<ElButton type="primary" @click="setAnalysisTitle"> 修改分析页标题 </ElButton>
|
||||
</ContentWrap>
|
||||
</template>
|
||||
@ -0,0 +1,80 @@
|
||||
<script setup lang="ts">
|
||||
import { ContentWrap } from '@/components/ContentWrap'
|
||||
import { Form, FormSchema } from '@/components/Form'
|
||||
import { useValidator } from '@/hooks/web/useValidator'
|
||||
import { useForm } from '@/hooks/web/useForm'
|
||||
import { reactive } from 'vue'
|
||||
import { FormItemRule } from 'element-plus'
|
||||
|
||||
const { formRegister, formMethods } = useForm()
|
||||
|
||||
const { getFormData } = formMethods
|
||||
|
||||
const { required, lengthRange, notSpace, notSpecialCharacters } = useValidator()
|
||||
|
||||
const formSchema = reactive<FormSchema[]>([
|
||||
{
|
||||
field: 'field1',
|
||||
label: '必填',
|
||||
component: 'Input'
|
||||
},
|
||||
{
|
||||
field: 'field2',
|
||||
label: '长度范围',
|
||||
component: 'Input'
|
||||
},
|
||||
{
|
||||
field: 'field3',
|
||||
label: '不能有空格',
|
||||
component: 'Input'
|
||||
},
|
||||
{
|
||||
field: 'field4',
|
||||
label: '不能有特殊字符',
|
||||
component: 'Input'
|
||||
},
|
||||
{
|
||||
field: 'field5',
|
||||
label: '是否相等-值1',
|
||||
component: 'Input'
|
||||
},
|
||||
{
|
||||
field: 'field6',
|
||||
label: '是否相等-值2',
|
||||
component: 'Input'
|
||||
}
|
||||
])
|
||||
|
||||
const rules = reactive<{
|
||||
[key: string]: FormItemRule[]
|
||||
}>({
|
||||
field1: [required()],
|
||||
field2: [
|
||||
lengthRange({
|
||||
min: 2,
|
||||
max: 5
|
||||
})
|
||||
],
|
||||
field3: [notSpace()],
|
||||
field4: [notSpecialCharacters()],
|
||||
field5: [
|
||||
{
|
||||
asyncValidator: async (_, val, callback) => {
|
||||
const formData = await getFormData()
|
||||
const { field6 } = formData
|
||||
if (val !== field6) {
|
||||
callback(new Error('两个值不相等'))
|
||||
} else {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<ContentWrap title="useValidator">
|
||||
<Form :schema="formSchema" :rules="rules" @register="formRegister" />
|
||||
</ContentWrap>
|
||||
</template>
|
||||
Loading…
Reference in New Issue