19 changed files with 1159 additions and 41 deletions
@ -0,0 +1,8 @@ |
|||
import type { App } from 'vue'; |
|||
import codeEditor from './src/CodeEditor.vue'; |
|||
|
|||
export const CodeEditor = Object.assign(codeEditor, { |
|||
install(app: App) { |
|||
app.component(codeEditor.name, codeEditor); |
|||
}, |
|||
}); |
|||
@ -0,0 +1,51 @@ |
|||
<template> |
|||
<div class="h-full"> |
|||
<CodeMirrorEditor :value="getValue" @change="handleValueChange" :mode="mode" /> |
|||
</div> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, computed } from 'vue'; |
|||
import CodeMirrorEditor from './codemirror/CodeMirror.vue'; |
|||
import { isString } from '/@/utils/is'; |
|||
|
|||
const MODE = { |
|||
JSON: 'application/json', |
|||
html: 'htmlmixed', |
|||
js: 'javascript', |
|||
}; |
|||
export default defineComponent({ |
|||
name: 'CodeEditor', |
|||
components: { CodeMirrorEditor }, |
|||
props: { |
|||
value: { |
|||
type: [Object, String], |
|||
}, |
|||
mode: { |
|||
type: String, |
|||
default: MODE.JSON, |
|||
}, |
|||
}, |
|||
emits: ['change'], |
|||
setup(props, { emit }) { |
|||
const getValue = computed(() => { |
|||
const { value, mode } = props; |
|||
|
|||
if (mode === MODE.JSON) { |
|||
return isString(value) |
|||
? JSON.stringify(JSON.parse(value), null, 2) |
|||
: JSON.stringify(value, null, 2); |
|||
} |
|||
return value; |
|||
}); |
|||
|
|||
function handleValueChange(v) { |
|||
emit('change', v); |
|||
} |
|||
|
|||
return { |
|||
handleValueChange, |
|||
getValue, |
|||
}; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -0,0 +1,125 @@ |
|||
<template> |
|||
<div class="relative h-100 !h-full w-full overflow-hidden" ref="el"> </div> |
|||
</template> |
|||
|
|||
<script lang="ts"> |
|||
import { |
|||
ref, |
|||
onMounted, |
|||
onUnmounted, |
|||
watchEffect, |
|||
watch, |
|||
defineComponent, |
|||
unref, |
|||
nextTick, |
|||
} from 'vue'; |
|||
import { useDebounceFn } from '@vueuse/core'; |
|||
import { useAppStore } from '/@/store/modules/app'; |
|||
|
|||
import CodeMirror from 'codemirror'; |
|||
import './codemirror.css'; |
|||
import 'codemirror/theme/idea.css'; |
|||
import 'codemirror/theme/material-palenight.css'; |
|||
|
|||
// modes |
|||
import 'codemirror/mode/javascript/javascript'; |
|||
import 'codemirror/mode/css/css'; |
|||
import 'codemirror/mode/htmlmixed/htmlmixed'; |
|||
export default defineComponent({ |
|||
props: { |
|||
mode: { |
|||
type: String, |
|||
default: 'application/json', |
|||
}, |
|||
value: { |
|||
type: String, |
|||
default: '', |
|||
}, |
|||
readonly: { |
|||
type: Boolean, |
|||
default: false, |
|||
}, |
|||
}, |
|||
emits: ['change'], |
|||
setup(props, { emit }) { |
|||
const el = ref(); |
|||
let editor: Nullable<CodeMirror.Editor>; |
|||
|
|||
const debounceRefresh = useDebounceFn(refresh, 100); |
|||
const appStore = useAppStore(); |
|||
|
|||
watch( |
|||
() => props.value, |
|||
async (v) => { |
|||
await nextTick(); |
|||
const oldValue = editor?.getValue(); |
|||
v && v !== oldValue && editor?.setValue(v); |
|||
}, |
|||
{ flush: 'post' } |
|||
); |
|||
|
|||
watchEffect(() => { |
|||
editor?.setOption('mode', props.mode); |
|||
}); |
|||
|
|||
watch( |
|||
() => appStore.getDarkMode, |
|||
async () => { |
|||
setTheme(); |
|||
}, |
|||
{ |
|||
immediate: true, |
|||
} |
|||
); |
|||
|
|||
function setTheme() { |
|||
unref(editor)?.setOption( |
|||
'theme', |
|||
appStore.getDarkMode === 'light' ? 'idea' : 'material-palenight' |
|||
); |
|||
} |
|||
|
|||
function refresh() { |
|||
editor?.refresh(); |
|||
} |
|||
|
|||
async function init() { |
|||
const addonOptions = { |
|||
autoCloseBrackets: true, |
|||
autoCloseTags: true, |
|||
foldGutter: true, |
|||
gutters: ['CodeMirror-linenumbers'], |
|||
}; |
|||
|
|||
editor = CodeMirror(el.value!, { |
|||
value: '', |
|||
mode: props.mode, |
|||
readOnly: props.readonly, |
|||
tabSize: 2, |
|||
theme: 'material-palenight', |
|||
lineWrapping: true, |
|||
lineNumbers: true, |
|||
...addonOptions, |
|||
}); |
|||
editor?.setValue(props.value); |
|||
setTheme(); |
|||
editor?.on('change', () => { |
|||
emit('change', editor?.getValue()); |
|||
}); |
|||
} |
|||
|
|||
onMounted(async () => { |
|||
await nextTick(); |
|||
init(); |
|||
window.addEventListener('resize', debounceRefresh); |
|||
setTimeout(refresh, 50); |
|||
}); |
|||
|
|||
onUnmounted(() => { |
|||
window.removeEventListener('resize', debounceRefresh); |
|||
editor = null; |
|||
}); |
|||
return { el }; |
|||
}, |
|||
}); |
|||
</script> |
|||
@ -0,0 +1,21 @@ |
|||
import CodeMirror from 'codemirror'; |
|||
import './codemirror.css'; |
|||
import 'codemirror/theme/idea.css'; |
|||
import 'codemirror/theme/material-palenight.css'; |
|||
// import 'codemirror/addon/lint/lint.css';
|
|||
|
|||
// modes
|
|||
import 'codemirror/mode/javascript/javascript'; |
|||
import 'codemirror/mode/css/css'; |
|||
import 'codemirror/mode/htmlmixed/htmlmixed'; |
|||
// addons
|
|||
// import 'codemirror/addon/edit/closebrackets';
|
|||
// import 'codemirror/addon/edit/closetag';
|
|||
// import 'codemirror/addon/comment/comment';
|
|||
// import 'codemirror/addon/fold/foldcode';
|
|||
// import 'codemirror/addon/fold/foldgutter';
|
|||
// import 'codemirror/addon/fold/brace-fold';
|
|||
// import 'codemirror/addon/fold/indent-fold';
|
|||
// import 'codemirror/addon/lint/json-lint';
|
|||
// import 'codemirror/addon/fold/comment-fold';
|
|||
export { CodeMirror }; |
|||
@ -0,0 +1,571 @@ |
|||
/* BASICS */ |
|||
|
|||
.CodeMirror { |
|||
--base: #545281; |
|||
--comment: hsl(210, 25%, 60%); |
|||
--keyword: #af4ab1; |
|||
--variable: #0055d1; |
|||
--function: #c25205; |
|||
--string: #2ba46d; |
|||
--number: #c25205; |
|||
--tags: #d00; |
|||
--qualifier: #ff6032; |
|||
--important: var(--string); |
|||
|
|||
height: auto; |
|||
height: 100%; |
|||
font-family: var(--font-code); |
|||
direction: ltr; |
|||
} |
|||
|
|||
/* PADDING */ |
|||
|
|||
.CodeMirror-lines { |
|||
padding: 4px 0; /* Vertical padding around content */ |
|||
} |
|||
|
|||
.CodeMirror pre { |
|||
padding: 0 4px; /* Horizontal padding of content */ |
|||
} |
|||
|
|||
.CodeMirror-scrollbar-filler, |
|||
.CodeMirror-gutter-filler { |
|||
background-color: white; /* The little square between H and V scrollbars */ |
|||
} |
|||
|
|||
/* GUTTER */ |
|||
|
|||
.CodeMirror-gutters { |
|||
white-space: nowrap; |
|||
background-color: transparent; |
|||
border-right: 1px solid #ddd; |
|||
} |
|||
|
|||
.CodeMirror-linenumber { |
|||
min-width: 20px; |
|||
padding: 0 3px 0 5px; |
|||
color: var(--comment); |
|||
text-align: right; |
|||
white-space: nowrap; |
|||
opacity: 0.6; |
|||
} |
|||
|
|||
.CodeMirror-guttermarker { |
|||
color: black; |
|||
} |
|||
|
|||
.CodeMirror-guttermarker-subtle { |
|||
color: #999; |
|||
} |
|||
|
|||
/* FOLD GUTTER */ |
|||
|
|||
.CodeMirror-foldmarker { |
|||
font-family: arial; |
|||
line-height: 0.3; |
|||
color: #414141; |
|||
text-shadow: #f96 1px 1px 2px, #f96 -1px -1px 2px, #f96 1px -1px 2px, #f96 -1px 1px 2px; |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.CodeMirror-foldgutter { |
|||
width: 0.7em; |
|||
} |
|||
|
|||
.CodeMirror-foldgutter-open, |
|||
.CodeMirror-foldgutter-folded { |
|||
cursor: pointer; |
|||
} |
|||
|
|||
.CodeMirror-foldgutter-open::after, |
|||
.CodeMirror-foldgutter-folded::after { |
|||
position: relative; |
|||
top: -0.1em; |
|||
display: inline-block; |
|||
font-size: 0.8em; |
|||
content: '>'; |
|||
opacity: 0.8; |
|||
transform: rotate(90deg); |
|||
transition: transform 0.2s; |
|||
} |
|||
|
|||
.CodeMirror-foldgutter-folded::after { |
|||
transform: none; |
|||
} |
|||
|
|||
/* CURSOR */ |
|||
|
|||
.CodeMirror-cursor { |
|||
width: 0; |
|||
border-right: none; |
|||
border-left: 1px solid black; |
|||
} |
|||
|
|||
/* Shown when moving in bi-directional text */ |
|||
.CodeMirror div.CodeMirror-secondarycursor { |
|||
border-left: 1px solid silver; |
|||
} |
|||
|
|||
.cm-fat-cursor .CodeMirror-cursor { |
|||
width: auto; |
|||
background: #7e7; |
|||
border: 0 !important; |
|||
} |
|||
|
|||
.cm-fat-cursor div.CodeMirror-cursors { |
|||
z-index: 1; |
|||
} |
|||
|
|||
.cm-fat-cursor-mark { |
|||
background-color: rgba(20, 255, 20, 0.5); |
|||
-webkit-animation: blink 1.06s steps(1) infinite; |
|||
-moz-animation: blink 1.06s steps(1) infinite; |
|||
animation: blink 1.06s steps(1) infinite; |
|||
} |
|||
|
|||
.cm-animate-fat-cursor { |
|||
width: auto; |
|||
background-color: #7e7; |
|||
border: 0; |
|||
-webkit-animation: blink 1.06s steps(1) infinite; |
|||
-moz-animation: blink 1.06s steps(1) infinite; |
|||
animation: blink 1.06s steps(1) infinite; |
|||
} |
|||
@-moz-keyframes blink { |
|||
0% { |
|||
} |
|||
|
|||
50% { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
100% { |
|||
} |
|||
} |
|||
@-webkit-keyframes blink { |
|||
0% { |
|||
} |
|||
|
|||
50% { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
100% { |
|||
} |
|||
} |
|||
@keyframes blink { |
|||
0% { |
|||
} |
|||
|
|||
50% { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
100% { |
|||
} |
|||
} |
|||
|
|||
.cm-tab { |
|||
display: inline-block; |
|||
text-decoration: inherit; |
|||
} |
|||
|
|||
.CodeMirror-rulers { |
|||
position: absolute; |
|||
top: -50px; |
|||
right: 0; |
|||
bottom: -20px; |
|||
left: 0; |
|||
overflow: hidden; |
|||
} |
|||
|
|||
.CodeMirror-ruler { |
|||
position: absolute; |
|||
top: 0; |
|||
bottom: 0; |
|||
border-left: 1px solid #ccc; |
|||
} |
|||
|
|||
/* DEFAULT THEME */ |
|||
.cm-s-default.CodeMirror { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
.cm-s-default .cm-header { |
|||
color: blue; |
|||
} |
|||
|
|||
.cm-s-default .cm-quote { |
|||
color: #090; |
|||
} |
|||
|
|||
.cm-negative { |
|||
color: #d44; |
|||
} |
|||
|
|||
.cm-positive { |
|||
color: #292; |
|||
} |
|||
|
|||
.cm-header, |
|||
.cm-strong { |
|||
font-weight: bold; |
|||
} |
|||
|
|||
.cm-em { |
|||
font-style: italic; |
|||
} |
|||
|
|||
.cm-link { |
|||
text-decoration: underline; |
|||
} |
|||
|
|||
.cm-strikethrough { |
|||
text-decoration: line-through; |
|||
} |
|||
|
|||
.cm-s-default .cm-atom, |
|||
.cm-s-default .cm-def, |
|||
.cm-s-default .cm-property, |
|||
.cm-s-default .cm-variable-2, |
|||
.cm-s-default .cm-variable-3, |
|||
.cm-s-default .cm-punctuation { |
|||
color: var(--base); |
|||
} |
|||
|
|||
.cm-s-default .cm-hr, |
|||
.cm-s-default .cm-comment { |
|||
color: var(--comment); |
|||
} |
|||
|
|||
.cm-s-default .cm-attribute, |
|||
.cm-s-default .cm-keyword { |
|||
color: var(--keyword); |
|||
} |
|||
|
|||
.cm-s-default .cm-variable { |
|||
color: var(--variable); |
|||
} |
|||
|
|||
.cm-s-default .cm-bracket, |
|||
.cm-s-default .cm-tag { |
|||
color: var(--tags); |
|||
} |
|||
|
|||
.cm-s-default .cm-number { |
|||
color: var(--number); |
|||
} |
|||
|
|||
.cm-s-default .cm-string, |
|||
.cm-s-default .cm-string-2 { |
|||
color: var(--string); |
|||
} |
|||
|
|||
.cm-s-default .cm-type { |
|||
color: #085; |
|||
} |
|||
|
|||
.cm-s-default .cm-meta { |
|||
color: #555; |
|||
} |
|||
|
|||
.cm-s-default .cm-qualifier { |
|||
color: var(--qualifier); |
|||
} |
|||
|
|||
.cm-s-default .cm-builtin { |
|||
color: #7539ff; |
|||
} |
|||
|
|||
.cm-s-default .cm-link { |
|||
color: var(--flash); |
|||
} |
|||
|
|||
.cm-s-default .cm-error { |
|||
color: #ff008c; |
|||
} |
|||
|
|||
.cm-invalidchar { |
|||
color: #ff008c; |
|||
} |
|||
|
|||
.CodeMirror-composing { |
|||
border-bottom: 2px solid; |
|||
} |
|||
|
|||
/* Default styles for common addons */ |
|||
|
|||
div.CodeMirror span.CodeMirror-matchingbracket { |
|||
color: #0b0; |
|||
} |
|||
|
|||
div.CodeMirror span.CodeMirror-nonmatchingbracket { |
|||
color: #a22; |
|||
} |
|||
|
|||
.CodeMirror-matchingtag { |
|||
background: rgba(255, 150, 0, 0.3); |
|||
} |
|||
|
|||
.CodeMirror-activeline-background { |
|||
background: #e8f2ff; |
|||
} |
|||
|
|||
/* STOP */ |
|||
|
|||
/* The rest of this file contains styles related to the mechanics of |
|||
the editor. You probably shouldn't touch them. */ |
|||
|
|||
.CodeMirror { |
|||
position: relative; |
|||
overflow: hidden; |
|||
background: white; |
|||
} |
|||
|
|||
.CodeMirror-scroll { |
|||
position: relative; |
|||
height: 100%; |
|||
padding-bottom: 30px; |
|||
margin-right: -30px; |
|||
|
|||
/* 30px is the magic margin used to hide the element's real scrollbars */ |
|||
|
|||
/* See overflow: hidden in .CodeMirror */ |
|||
margin-bottom: -30px; |
|||
overflow: scroll !important; /* Things will break if this is overridden */ |
|||
outline: none; /* Prevent dragging from highlighting the element */ |
|||
} |
|||
|
|||
.CodeMirror-sizer { |
|||
position: relative; |
|||
border-right: 30px solid transparent; |
|||
} |
|||
|
|||
/* The fake, visible scrollbars. Used to force redraw during scrolling |
|||
before actual scrolling happens, thus preventing shaking and |
|||
flickering artifacts. */ |
|||
.CodeMirror-vscrollbar, |
|||
.CodeMirror-hscrollbar, |
|||
.CodeMirror-scrollbar-filler, |
|||
.CodeMirror-gutter-filler { |
|||
position: absolute; |
|||
z-index: 6; |
|||
display: none; |
|||
} |
|||
|
|||
.CodeMirror-vscrollbar { |
|||
top: 0; |
|||
right: 0; |
|||
overflow-x: hidden; |
|||
overflow-y: scroll; |
|||
} |
|||
|
|||
.CodeMirror-hscrollbar { |
|||
bottom: 0; |
|||
left: 0; |
|||
overflow-x: scroll; |
|||
overflow-y: hidden; |
|||
} |
|||
|
|||
.CodeMirror-scrollbar-filler { |
|||
right: 0; |
|||
bottom: 0; |
|||
} |
|||
|
|||
.CodeMirror-gutter-filler { |
|||
bottom: 0; |
|||
left: 0; |
|||
} |
|||
|
|||
.CodeMirror-gutters { |
|||
position: absolute; |
|||
top: 0; |
|||
left: 0; |
|||
z-index: 3; |
|||
min-height: 100%; |
|||
} |
|||
|
|||
.CodeMirror-gutter { |
|||
display: inline-block; |
|||
height: 100%; |
|||
margin-bottom: -30px; |
|||
white-space: normal; |
|||
vertical-align: top; |
|||
} |
|||
|
|||
.CodeMirror-gutter-wrapper { |
|||
position: absolute; |
|||
z-index: 4; |
|||
background: none !important; |
|||
border: none !important; |
|||
} |
|||
|
|||
.CodeMirror-gutter-background { |
|||
position: absolute; |
|||
top: 0; |
|||
bottom: 0; |
|||
z-index: 4; |
|||
} |
|||
|
|||
.CodeMirror-gutter-elt { |
|||
position: absolute; |
|||
z-index: 4; |
|||
cursor: default; |
|||
} |
|||
|
|||
.CodeMirror-gutter-wrapper ::selection { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
.CodeMirror-gutter-wrapper ::-moz-selection { |
|||
background-color: transparent; |
|||
} |
|||
|
|||
.CodeMirror-lines { |
|||
min-height: 1px; /* prevents collapsing before first draw */ |
|||
cursor: text; |
|||
} |
|||
|
|||
.CodeMirror pre { |
|||
position: relative; |
|||
z-index: 2; |
|||
margin: 0; |
|||
overflow: visible; |
|||
font-family: inherit; |
|||
font-size: inherit; |
|||
line-height: inherit; |
|||
color: inherit; |
|||
word-wrap: normal; |
|||
white-space: pre; |
|||
background: transparent; |
|||
border-width: 0; |
|||
|
|||
/* Reset some styles that the rest of the page might have set */ |
|||
-moz-border-radius: 0; |
|||
-webkit-border-radius: 0; |
|||
border-radius: 0; |
|||
-webkit-tap-highlight-color: transparent; |
|||
-webkit-font-variant-ligatures: contextual; |
|||
font-variant-ligatures: contextual; |
|||
} |
|||
|
|||
.CodeMirror-wrap pre { |
|||
word-break: normal; |
|||
word-wrap: break-word; |
|||
white-space: pre-wrap; |
|||
} |
|||
|
|||
.CodeMirror-linebackground { |
|||
position: absolute; |
|||
top: 0; |
|||
right: 0; |
|||
bottom: 0; |
|||
left: 0; |
|||
z-index: 0; |
|||
} |
|||
|
|||
.CodeMirror-linewidget { |
|||
position: relative; |
|||
z-index: 2; |
|||
padding: 0.1px; /* Force widget margins to stay inside of the container */ |
|||
} |
|||
|
|||
.CodeMirror-rtl pre { |
|||
direction: rtl; |
|||
} |
|||
|
|||
.CodeMirror-code { |
|||
outline: none; |
|||
} |
|||
|
|||
/* Force content-box sizing for the elements where we expect it */ |
|||
.CodeMirror-scroll, |
|||
.CodeMirror-sizer, |
|||
.CodeMirror-gutter, |
|||
.CodeMirror-gutters, |
|||
.CodeMirror-linenumber { |
|||
-moz-box-sizing: content-box; |
|||
box-sizing: content-box; |
|||
} |
|||
|
|||
.CodeMirror-measure { |
|||
position: absolute; |
|||
width: 100%; |
|||
height: 0; |
|||
overflow: hidden; |
|||
visibility: hidden; |
|||
} |
|||
|
|||
.CodeMirror-cursor { |
|||
position: absolute; |
|||
pointer-events: none; |
|||
} |
|||
|
|||
.CodeMirror-measure pre { |
|||
position: static; |
|||
} |
|||
|
|||
div.CodeMirror-cursors { |
|||
position: relative; |
|||
z-index: 3; |
|||
visibility: hidden; |
|||
} |
|||
|
|||
div.CodeMirror-dragcursors { |
|||
visibility: visible; |
|||
} |
|||
|
|||
.CodeMirror-focused div.CodeMirror-cursors { |
|||
visibility: visible; |
|||
} |
|||
|
|||
.CodeMirror-selected { |
|||
background: #d9d9d9; |
|||
} |
|||
|
|||
.CodeMirror-focused .CodeMirror-selected { |
|||
background: #d7d4f0; |
|||
} |
|||
|
|||
.CodeMirror-crosshair { |
|||
cursor: crosshair; |
|||
} |
|||
|
|||
.CodeMirror-line::selection, |
|||
.CodeMirror-line > span::selection, |
|||
.CodeMirror-line > span > span::selection { |
|||
background: #d7d4f0; |
|||
} |
|||
|
|||
.CodeMirror-line::-moz-selection, |
|||
.CodeMirror-line > span::-moz-selection, |
|||
.CodeMirror-line > span > span::-moz-selection { |
|||
background: #d7d4f0; |
|||
} |
|||
|
|||
.cm-searching { |
|||
background-color: #ffa; |
|||
background-color: rgba(255, 255, 0, 0.4); |
|||
} |
|||
|
|||
/* Used to force a border model for a node */ |
|||
.cm-force-border { |
|||
padding-right: 0.1px; |
|||
} |
|||
|
|||
@media print { |
|||
/* Hide the cursor when printing */ |
|||
.CodeMirror div.CodeMirror-cursors { |
|||
visibility: hidden; |
|||
} |
|||
} |
|||
|
|||
/* See issue #2901 */ |
|||
.cm-tab-wrap-hack::after { |
|||
content: ''; |
|||
} |
|||
|
|||
/* Help users use markselection to safely style text background */ |
|||
span.CodeMirror-selectedtext { |
|||
background: none; |
|||
} |
|||
File diff suppressed because one or more lines are too long
@ -0,0 +1,78 @@ |
|||
<template> |
|||
<PageWrapper title="代码编辑器组件示例" contentFullHeight fixedHeight contentBackground> |
|||
<template #extra> |
|||
<RadioGroup button-style="solid" v-model:value="modeValue" @change="handleModeChange"> |
|||
<RadioButton value="application/json"> json数据 </RadioButton> |
|||
<RadioButton value="htmlmixed"> html代码 </RadioButton> |
|||
<RadioButton value="javascript"> javascript代码 </RadioButton> |
|||
</RadioGroup> |
|||
</template> |
|||
<CodeEditor v-model:value="value" :mode="modeValue" /> |
|||
</PageWrapper> |
|||
</template> |
|||
<script lang="ts"> |
|||
import { defineComponent, ref } from 'vue'; |
|||
import { CodeEditor } from '/@/components/CodeEditor'; |
|||
import { PageWrapper } from '/@/components/Page'; |
|||
import { Radio } from 'ant-design-vue'; |
|||
|
|||
const jsonData = |
|||
'{"name":"BeJson","url":"http://www.xxx.com","page":88,"isNonProfit":true,"address":{"street":"科技园路.","city":"江苏苏州","country":"中国"},"links":[{"name":"Google","url":"http://www.xxx.com"},{"name":"Baidu","url":"http://www.xxx.com"},{"name":"SoSo","url":"http://www.xxx.com"}]}'; |
|||
|
|||
const jsData = ` |
|||
(() => { |
|||
var htmlRoot = document.getElementById('htmlRoot'); |
|||
var theme = window.localStorage.getItem('__APP__DARK__MODE__'); |
|||
if (htmlRoot && theme) { |
|||
htmlRoot.setAttribute('data-theme', theme); |
|||
theme = htmlRoot = null; |
|||
} |
|||
})(); |
|||
`; |
|||
|
|||
const htmlData = ` |
|||
<!DOCTYPE html> |
|||
<html lang="en" id="htmlRoot"> |
|||
<head> |
|||
<meta charset="UTF-8" /> |
|||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> |
|||
<meta name="renderer" content="webkit" /> |
|||
<meta |
|||
name="viewport" |
|||
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0" |
|||
/> |
|||
<title><%= title %></title> |
|||
<link rel="icon" href="/favicon.ico" /> |
|||
</head> |
|||
<body> |
|||
<div id="app"> |
|||
</div> |
|||
</body> |
|||
</html> |
|||
`; |
|||
export default defineComponent({ |
|||
components: { CodeEditor, PageWrapper, RadioButton: Radio.Button, RadioGroup: Radio.Group }, |
|||
setup() { |
|||
const modeValue = ref('application/json'); |
|||
const value = ref(jsonData); |
|||
|
|||
function handleModeChange(e: ChangeEvent) { |
|||
const mode = e.target.value; |
|||
if (mode === 'application/json') { |
|||
value.value = jsonData; |
|||
return; |
|||
} |
|||
if (mode === 'htmlmixed') { |
|||
value.value = htmlData; |
|||
return; |
|||
} |
|||
if (mode === 'javascript') { |
|||
value.value = jsData; |
|||
return; |
|||
} |
|||
} |
|||
|
|||
return { value, modeValue, handleModeChange }; |
|||
}, |
|||
}); |
|||
</script> |
|||
Loading…
Reference in new issue