1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798 |
- <template>
- <textarea ref="codeMirrorRef"></textarea>
- </template>
- <script>
- import { ref, onMounted, watch, markRaw, nextTick } from 'vue'
- import CodeMirror from 'codemirror'
- import 'codemirror/lib/codemirror.css'
- import 'codemirror/mode/javascript/javascript'
- import 'codemirror/mode/xml/xml'
- import 'codemirror/mode/sql/sql'
- import 'codemirror/addon/hint/show-hint'
- import 'codemirror/addon/hint/sql-hint'
- import 'codemirror/addon/hint/show-hint.css'
- import 'codemirror/theme/dracula.css'
- import 'codemirror/theme/3024-day.css'
- export default {
- name: 'CipCodeMirror',
- inheritAttrs: false,
- props: {
- modelValue: [String, Object],
- readonly: {
- type: Boolean,
- default: false
- },
- type: {
- type: String,
- default: 'json'
- },
- height: {
- type: String,
- default: 'auto'
- },
- theme: { // 主题,需要额外引入
- type: String,
- default: 'dracula'
- }
- },
- emits: ['update:modelValue'],
- setup (props, { emit }) {
- const codeMirrorRef = ref()
- const codeMirror = ref()
- const getCodeMirrorInstance = () => {
- const instance = CodeMirror.fromTextArea(codeMirrorRef.value, {
- value: formatterValue(props.modelValue),
- mode: `text/${props.type === 'json' ? 'javascript' : props.type}`,
- theme: props.theme,
- indentUnit: 4,
- lineNumbers: true,
- lineWrapping: false,
- readOnly: props.readonly,
- singleCursorHeightPerLine: false,
- extraKeys: {}
- })
- instance.setSize(props.width ?? '100%', props.height ?? 'auto')
- instance.on('change', (instance, obj) => {
- const { origin } = obj
- const value = instance.getValue()
- codeMirror.value.save()
- if (origin !== 'setValue') { // 非setValue导致的更新才emit
- emit('update:modelValue', value)
- }
- })
- return instance
- }
- const formatterValue = (val) => {
- if (props.type === 'json' && val) {
- let data = val
- if (typeof val === 'string') {
- data = JSON.parse(data)
- }
- return JSON.stringify(data, null, 2) ?? ''
- } else {
- return val
- }
- }
- onMounted(() => {
- codeMirror.value = markRaw(getCodeMirrorInstance())
- watch(() => props.modelValue, (val, oldVal) => {
- const codeMirrorValue = codeMirror.value?.getValue()
- if (codeMirrorValue === val) return
- console.log(formatterValue(val))
- codeMirror.value.setValue(formatterValue(val))
- nextTick(() => {
- codeMirror.value.refresh()
- })
- }, {
- immediate: true
- })
- })
- return {
- codeMirrorRef
- }
- }
- }
- </script>
|