123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168 |
- <template>
- <div class="monaco-dialog">
- <t-dialog
- :header="title"
- :visible="visible"
- width="900px"
- :on-confirm="handleOk"
- :on-cancel="cancel"
- :on-close="cancel"
- >
- <t-radio-group
- v-if="options"
- size="small"
- v-model="currentValue"
- :default-value="0"
- @change="changeOption"
- >
- <t-tooltip
- v-for="option in options"
- :content="option.tip"
- placement="top"
- >
- <t-radio-button :value="option.value">
- {{ option.name }}</t-radio-button
- >
- </t-tooltip>
- </t-radio-group>
- <div ref="monacoDom" class="monaco"></div>
- </t-dialog>
- </div>
- </template>
- <script lang="ts">
- export interface monacoOption {
- key: string;
- value?: number | string;
- name?: string;
- tip?: string;
- code?: string;
- language: 'javascript' | 'json' | 'markdown';
- example?: string;
- }
- </script>
- <script setup lang="ts">
- import {
- defineComponent,
- nextTick,
- onMounted,
- onUnmounted,
- PropType,
- reactive,
- ref,
- watch,
- } from 'vue';
- import { monaco } from './customMonaco';
- const props = defineProps({
- visible: {
- type: Boolean,
- require: true,
- },
- title: {
- type: String,
- default: () => {
- return 'JavaScript';
- },
- },
- code: {
- type: String,
- default: () => {
- return '';
- },
- },
- language: {
- type: String,
- default: () => {
- return 'javascript';
- },
- validator: (value: string) => {
- // 这个值必须匹配下列字符串中的一个
- return ['javascript', 'json', 'markdown'].includes(value);
- },
- },
- options: {
- type: Array as PropType<monacoOption[]>,
- },
- });
- const emit = defineEmits(['update:visible', 'changeCode', 'changeOptions']);
- let editor: any = null;
- function handleOk() {
- // 按下确认以后修改外界值
- if (props.options) {
- props.options[currentValue.value].code = editor.getValue();
- emit('changeOptions', props.options);
- emit('update:visible', false);
- } else {
- const code = editor.getValue();
- emit('changeCode', code);
- emit('update:visible', false);
- }
- }
- function cancel() {
- emit('update:visible', false);
- }
- const curTheme = 'vs-dark'; // 暗主题
- const monacoDom: any = ref(null);
- const currentValue = ref(0);
- let beforeValue = 0;
- const changeOption = (e: number) => {
- if (editor && props.options) {
- if (beforeValue !== e) {
- props.options[beforeValue].code = editor.getValue();
- beforeValue = e;
- }
- monaco.editor.setModelLanguage(
- editor.getModel(),
- props.options[e].language || 'javascript'
- );
- editor.setValue(props.options[e].code || props.options[e].example || '');
- }
- };
- watch(
- () => props.visible,
- (newV) => {
- // console.log("props.visible", props.visible);
- if (newV) {
- nextTick(async () => {
- if (!editor) {
- editor = monaco.editor.create(monacoDom.value, {
- theme: curTheme,
- automaticLayout: true,
- language: props.language,
- });
- }
- if (props.options) {
- const option = props.options[currentValue.value];
- editor.setValue(option.code || option.example || '');
- monaco.editor.setModelLanguage(editor.getModel(), option.language);
- } else {
- // 可见状态
- editor.setValue(props.code);
- monaco.editor.setModelLanguage(editor.getModel(), props.language);
- }
- // 格式化
- // setTimeout(() => {
- // editor.getAction(["editor.action.formatDocument"])._run();
- // }, 300);
- });
- }
- }
- );
- onUnmounted(() => {
- editor?.dispose();
- });
- </script>
- <style lang="postcss" scoped>
- .monaco {
- height: 400px;
- }
- </style>
|