feat: JsonEditor
This commit is contained in:
parent
2c99cd20f0
commit
c0f4517b87
|
@ -179,6 +179,14 @@ const adminList = [
|
|||
meta: {
|
||||
title: 'router.richText'
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'json-editor',
|
||||
component: 'views/Components/Editor/JsonEditor',
|
||||
name: 'JsonEditor',
|
||||
meta: {
|
||||
title: 'router.jsonEditor'
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
@ -588,6 +596,7 @@ const testList: string[] = [
|
|||
'/components/table/ref-table',
|
||||
'/components/editor-demo',
|
||||
'/components/editor-demo/editor',
|
||||
'/components/editor-demo/json-editor',
|
||||
'/components/search',
|
||||
'/components/descriptions',
|
||||
'/components/image-viewer',
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
"url": "^0.11.1",
|
||||
"vue": "3.3.4",
|
||||
"vue-i18n": "9.2.2",
|
||||
"vue-json-pretty": "^2.2.4",
|
||||
"vue-router": "^4.2.4",
|
||||
"vue-types": "^5.1.1"
|
||||
},
|
||||
|
|
|
@ -22,6 +22,7 @@ import {
|
|||
} from 'element-plus'
|
||||
import { InputPassword } from '@/components/InputPassword'
|
||||
import { Editor } from '@/components/Editor'
|
||||
import { JsonEditor } from '@/components/JsonEditor'
|
||||
import { ComponentName } from '../types'
|
||||
|
||||
const componentMap: Recordable<Component, ComponentName> = {
|
||||
|
@ -47,7 +48,8 @@ const componentMap: Recordable<Component, ComponentName> = {
|
|||
InputPassword: InputPassword,
|
||||
Editor: Editor,
|
||||
TreeSelect: ElTreeSelect,
|
||||
Upload: ElUpload
|
||||
Upload: ElUpload,
|
||||
JsonEditor: JsonEditor
|
||||
}
|
||||
|
||||
export { componentMap }
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
UploadProps
|
||||
} from 'element-plus'
|
||||
import { IEditorConfig } from '@wangeditor/editor'
|
||||
import { JsonEditorProps } from '@/components/JsonEditor'
|
||||
import { CSSProperties } from 'vue'
|
||||
|
||||
export interface PlaceholderModel {
|
||||
|
@ -53,7 +54,8 @@ export enum ComponentNameEnum {
|
|||
INPUT_PASSWORD = 'InputPassword',
|
||||
EDITOR = 'Editor',
|
||||
TREE_SELECT = 'TreeSelect',
|
||||
UPLOAD = 'Upload'
|
||||
UPLOAD = 'Upload',
|
||||
JSON_EDITOR = 'JsonEditor'
|
||||
}
|
||||
|
||||
type CamelCaseComponentName = keyof typeof ComponentNameEnum extends infer K
|
||||
|
@ -620,6 +622,7 @@ export interface FormSchema {
|
|||
| InputPasswordComponentProps
|
||||
| TreeSelectComponentProps
|
||||
| UploadComponentProps
|
||||
| JsonEditorProps
|
||||
| any
|
||||
|
||||
/**
|
||||
|
|
|
@ -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(1),
|
||||
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'
|
||||
}
|
|
@ -147,6 +147,7 @@ export default {
|
|||
defaultTable: 'Basic example',
|
||||
editor: 'Editor',
|
||||
richText: 'Rich text',
|
||||
jsonEditor: 'JSON Editor',
|
||||
dialog: 'Dialog',
|
||||
imageViewer: 'Image viewer',
|
||||
descriptions: 'Descriptions',
|
||||
|
@ -300,6 +301,7 @@ export default {
|
|||
verifyReset: 'Verify reset',
|
||||
// 富文本编辑器
|
||||
richText: 'Rich text',
|
||||
jsonEditor: 'JSON Editor',
|
||||
form: 'Form',
|
||||
// 远程加载
|
||||
remoteLoading: 'Remote loading',
|
||||
|
@ -448,7 +450,9 @@ export default {
|
|||
},
|
||||
richText: {
|
||||
richText: 'Rich text',
|
||||
richTextDes: 'Secondary packaging based on wangeditor'
|
||||
richTextDes: 'Secondary packaging based on wangeditor',
|
||||
jsonEditor: 'JSON Editor',
|
||||
jsonEditorDes: 'Secondary packaging based on vue-json-pretty'
|
||||
},
|
||||
dialogDemo: {
|
||||
dialog: 'Dialog',
|
||||
|
|
|
@ -147,6 +147,7 @@ export default {
|
|||
defaultTable: '基础示例',
|
||||
editor: '编辑器',
|
||||
richText: '富文本',
|
||||
jsonEditor: 'JSON编辑器',
|
||||
dialog: '弹窗',
|
||||
imageViewer: '图片预览',
|
||||
descriptions: '描述',
|
||||
|
@ -298,6 +299,8 @@ export default {
|
|||
verifyReset: '验证重置',
|
||||
// 富文本编辑器
|
||||
richText: '富文本编辑器',
|
||||
// JSON编辑器
|
||||
jsonEditor: 'JSON编辑器',
|
||||
form: '表单',
|
||||
// 远程加载
|
||||
remoteLoading: '远程加载',
|
||||
|
@ -441,7 +444,9 @@ export default {
|
|||
},
|
||||
richText: {
|
||||
richText: '富文本',
|
||||
richTextDes: '基于 wangeditor 二次封装'
|
||||
richTextDes: '基于 wangeditor 二次封装',
|
||||
jsonEditor: 'JSON编辑器',
|
||||
jsonEditorDes: '基于 vue-json-pretty 二次封装'
|
||||
},
|
||||
dialogDemo: {
|
||||
dialog: '弹窗',
|
||||
|
|
|
@ -220,6 +220,14 @@ export const asyncRouterMap: AppRouteRecordRaw[] = [
|
|||
meta: {
|
||||
title: t('router.richText')
|
||||
}
|
||||
},
|
||||
{
|
||||
path: 'json-editor',
|
||||
component: () => import('@/views/Components/Editor/JsonEditor.vue'),
|
||||
name: 'JsonEditor',
|
||||
meta: {
|
||||
title: t('router.jsonEditor')
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
|
|
@ -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>
|
|
@ -1760,6 +1760,20 @@ const schema = reactive<FormSchema[]>([
|
|||
)
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
field: 'field85',
|
||||
component: 'Divider',
|
||||
label: t('formDemo.jsonEditor')
|
||||
},
|
||||
{
|
||||
field: 'field86',
|
||||
component: 'JsonEditor',
|
||||
label: t('formDemo.default'),
|
||||
value: {
|
||||
a: 1,
|
||||
b: 2
|
||||
}
|
||||
}
|
||||
])
|
||||
</script>
|
||||
|
|
|
@ -31,7 +31,12 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||
return {
|
||||
base: env.VITE_BASE_PATH,
|
||||
plugins: [
|
||||
Vue(),
|
||||
Vue({
|
||||
script: {
|
||||
// 开启defineModel
|
||||
defineModel: true
|
||||
}
|
||||
}),
|
||||
VueJsx(),
|
||||
// WindiCSS(),
|
||||
progress(),
|
||||
|
@ -145,7 +150,8 @@ export default ({ command, mode }: ConfigEnv): UserConfig => {
|
|||
'intro.js',
|
||||
'qrcode',
|
||||
'@wangeditor/editor',
|
||||
'@wangeditor/editor-for-vue'
|
||||
'@wangeditor/editor-for-vue',
|
||||
'vue-json-pretty'
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue