代码编辑器
刀刀
12/31/2024
0 字
0 分钟
在页面中想要效仿 MDN 网站 CSS 模块的效果,用户输入后右侧效果动态修改,渲染最新的效果。
组件封装
询问 ChatGPT,得到的回复是可以使用 NPM 下载的第三方组件 CodeMirror
。由于没有具体的官方文档介绍 Vue
项目如何使用,下面是询问 GPT 后得到的步骤:
下载相关依赖
shellpnpm i codemirror pnpm i vue-codemirror pnpm i @codemirror/lang-css pnpm i @codemirror/lang-javascript pnpm i @codemirror/theme-one-dark
前两个依赖主要是下载第三方组件和
Vue
适配的组件;中间两个是该组件语法高亮的语言;最后一个是皮肤,暗黑模式。新建一个子组件,导入依赖并声明使用组件
vue<script setup> import { Codemirror } from 'vue-codemirror'; const code = defineModel(); const emit = defineEmits(['change']); const handleChange = e => { emit('change', e); } </script> <template> <Codemirror v-model="code" placeholder="暂无数据..." :autofocus="false" :tabSize="2" @change="handleChange"> </Codemirror> </template>
其中,
tabSize
为每行前面缩进几个字符,autofocus
表示是否自动聚焦,code
是父传子双向绑定的数据,修改内容会触发change
事件。设置编辑器的语言和皮肤模式
通过父子传参的形式,动态设置编辑器的高亮语言语法,再和皮肤作为一个数组传递给组件的
extensions
变量。最后设置一下样式即可。vue<script setup> import { Codemirror } from 'vue-codemirror'; import { javascript } from '@codemirror/lang-javascript'; import { css } from '@codemirror/lang-css'; import { vue } from '@codemirror/lang-vue'; import { oneDark } from '@codemirror/theme-one-dark'; import { screenWidth } from "@/store/index.js"; const props = defineProps({ language: { type: String, default: 'css' }, disabled: { type: [String, Boolean], default: false }, style: { type: [Object], default: () => ({}) } }); const emit = defineEmits(['change']); const { language, disabled, style } = toRefs(props); const lang = ref(null); const extensions = ref(null); watch(() => language.value, (newVal) => { lang.value = { javascript, css, vue }[language.value]; extensions.value = [lang.value(), oneDark]; }, { immediate: true }); const code = defineModel(); const comStyle = computed(() => ({ ...style.value, ...{ height: screenWidth.value > 768 ? '300px' : '18.75rem' } })); const handleChange = e => { emit('change', e); } </script> <template> <Codemirror :disabled="disabled" v-model="code" placeholder="暂无数据..." :style="comStyle" :autofocus="false" :indent-with-tab="true" :tabSize="2" :fullScreen="true" :extensions="extensions" @change="handleChange"> </Codemirror> </template>
组件使用
现在封装好了一个 code
组件可以使用了,父组件只需要 v-model
双向绑定代码文本,通过 language
指定代码语言风格即可。示例代码如下:
vue
<script setup>
import Code from './code.vue';
const code = ref('clip-path: polygon(50% 0%, 100% 50%, 50% 100%, 0% 50%)');
</script>
<template>
<Code
class="code"
language="css"
v-model="code">
</Code>
</template>
再搭配一个 DOM 节点,可用于查看设置的样式。效果如下所示: