开发预览 更新于 2026-05-10

CodeEditor 代码编辑器

轻量代码编辑容器:textarea + 行号 + Tab 缩进。重型语法/补全请接 Monaco/CodeMirror。

基础用法

定位是”视觉容器 + 轻交互”:行号、Tab 缩进、行尾保持、ARIA 标签齐全;不内置语法高亮。 若需高亮,让消费方在外层裹一个 overlay(参考 VariableAwareInput 的 overlay 技法)。

背景 视口
12345678910
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfCodeEditor } from '@chufix-design/vue';
const code = ref(`function fizzbuzz(n: number) {
  for (let i = 1; i <= n; i++) {
    let out = '';
    if (i % 3 === 0) out += 'Fizz';
    if (i % 5 === 0) out += 'Buzz';
    console.log(out || i);
  }
}

fizzbuzz(15);`);
</script>
<template>
  <CfCodeEditor v-model="code" language="typescript" :rows="12" />
</template>
<script setup>
import { ref } from 'vue';
import { CfCodeEditor } from '@chufix-design/vue';
const code = ref(`function fizzbuzz(n: number) {
  for (let i = 1; i <= n; i++) {
    let out = '';
    if (i % 3 === 0) out += 'Fizz';
    if (i % 5 === 0) out += 'Buzz';
    console.log(out || i);
  }
}

fizzbuzz(15);`);
</script>
<template>
  <CfCodeEditor v-model="code" language="typescript" :rows="12" />
</template>
import { useState } from 'react';
import { CfCodeEditor } from '@chufix-design/react';

export default function Demo() {
  const [code, setCode] = useState(`function fizzbuzz(n: number) {
    for (let i = 1; i <= n; i++) {
      let out = '';
      if (i % 3 === 0) out += 'Fizz';
      if (i % 5 === 0) out += 'Buzz';
      console.log(out || i);
    }
  }

  fizzbuzz(15);`);
  const [code, setCode] = useState(`function fizzbuzz(n: number) {
    for (let i = 1; i <= n; i++) {
      let out = '';
      if (i % 3 === 0) out += 'Fizz';
      if (i % 5 === 0) out += 'Buzz';
      console.log(out || i);
    }
  }

  fizzbuzz(15);`);
  return (
    <>
      <CfCodeEditor value={code} onChange={setCode} language="typescript" rows={12} />
    </>
  );
}
import { useState } from 'react';
import { CfCodeEditor } from '@chufix-design/react';

export default function Demo() {
  const [code, setCode] = useState(`function fizzbuzz(n: number) {
    for (let i = 1; i <= n; i++) {
      let out = '';
      if (i % 3 === 0) out += 'Fizz';
      if (i % 5 === 0) out += 'Buzz';
      console.log(out || i);
    }
  }

  fizzbuzz(15);`);
  const [code, setCode] = useState(`function fizzbuzz(n: number) {
    for (let i = 1; i <= n; i++) {
      let out = '';
      if (i % 3 === 0) out += 'Fizz';
      if (i % 5 === 0) out += 'Buzz';
      console.log(out || i);
    }
  }

  fizzbuzz(15);`);
  return (
    <>
      <CfCodeEditor value={code} onChange={setCode} language="typescript" rows={12} />
    </>
  );
}

readOnly / wrap / 无行号

不同状态组合:只读演示文档、自动换行长文本、无行号紧凑模式。

背景 视口
1234567
1
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfCodeEditor } from '@chufix-design/vue';
const ro = ref(`# read-only 模式
# 输入会被拦截,行号 + 灰底突出 readOnly 状态

const cfg = {
  mode: 'view',
  permissions: ['read'],
};`);
const wrapped = ref('这是一段非常长的文本,用来演示 wrap 模式:当行宽超出容器时会自动软换行而不是横向滚动。在普通 wrap=false 模式下,长行会触发水平滚动条;wrap=true 时则像 prose 一样自然换行,适合用来展示 markdown 草稿、SQL 单行语句等场景。');
const noNumbers = ref('// 不显示行号\nfunction tiny() { return 42; }');
</script>
<template>
  <div style="display: flex; flex-direction: column; gap: 12px;">
    <CfCodeEditor v-model="ro" language="typescript" :rows="5" read-only />
    <CfCodeEditor v-model="wrapped" :rows="4" wrap />
    <CfCodeEditor v-model="noNumbers" :rows="3" :show-line-numbers="false" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfCodeEditor } from '@chufix-design/vue';
const ro = ref(`# read-only 模式
# 输入会被拦截,行号 + 灰底突出 readOnly 状态

const cfg = {
  mode: 'view',
  permissions: ['read'],
};`);
const wrapped = ref('这是一段非常长的文本,用来演示 wrap 模式:当行宽超出容器时会自动软换行而不是横向滚动。在普通 wrap=false 模式下,长行会触发水平滚动条;wrap=true 时则像 prose 一样自然换行,适合用来展示 markdown 草稿、SQL 单行语句等场景。');
const noNumbers = ref('// 不显示行号\nfunction tiny() { return 42; }');
</script>
<template>
  <div style="display: flex; flex-direction: column; gap: 12px;">
    <CfCodeEditor v-model="ro" language="typescript" :rows="5" read-only />
    <CfCodeEditor v-model="wrapped" :rows="4" wrap />
    <CfCodeEditor v-model="noNumbers" :rows="3" :show-line-numbers="false" />
  </div>
</template>
import { useState } from 'react';
import { CfCodeEditor } from '@chufix-design/react';

export default function Demo() {
  const [ro, setRo] = useState(`# read-only 模式
  # 输入会被拦截,行号 + 灰底突出 readOnly 状态

  const cfg = {
    mode: 'view',
    permissions: ['read'],
  };`);
  const [wrapped, setWrapped] = useState('这是一段非常长的文本,用来演示 wrap 模式:当行宽超出容器时会自动软换行而不是横向滚动。在普通 wrap=false 模式下,长行会触发水平滚动条;wrap=true 时则像 prose 一样自然换行,适合用来展示 markdown 草稿、SQL 单行语句等场景。');
  const [noNumbers, setNoNumbers] = useState('// 不显示行号\nfunction tiny() { return 42; }');
  return (
    <>
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          <CfCodeEditor value={ro} onChange={setRo} language="typescript" rows={5} readOnly />
          <CfCodeEditor value={wrapped} onChange={setWrapped} rows={4} wrap />
          <CfCodeEditor value={noNumbers} onChange={setNoNumbers} rows={3} showLineNumbers={false} />
        </div>
    </>
  );
}
import { useState } from 'react';
import { CfCodeEditor } from '@chufix-design/react';

export default function Demo() {
  const [ro, setRo] = useState(`# read-only 模式
  # 输入会被拦截,行号 + 灰底突出 readOnly 状态

  const cfg = {
    mode: 'view',
    permissions: ['read'],
  };`);
  const [wrapped, setWrapped] = useState('这是一段非常长的文本,用来演示 wrap 模式:当行宽超出容器时会自动软换行而不是横向滚动。在普通 wrap=false 模式下,长行会触发水平滚动条;wrap=true 时则像 prose 一样自然换行,适合用来展示 markdown 草稿、SQL 单行语句等场景。');
  const [noNumbers, setNoNumbers] = useState('// 不显示行号\nfunction tiny() { return 42; }');
  return (
    <>
      <div style={{ display: "flex", flexDirection: "column", gap: 12 }}>
          <CfCodeEditor value={ro} onChange={setRo} language="typescript" rows={5} readOnly />
          <CfCodeEditor value={wrapped} onChange={setWrapped} rows={4} wrap />
          <CfCodeEditor value={noNumbers} onChange={setNoNumbers} rows={3} showLineNumbers={false} />
        </div>
    </>
  );
}

API

属性类型默认值说明
modelValue / valuestring''代码内容
languagestring'plaintext'仅作 data-language 透传,不参与渲染
size'sm' | 'md' | 'lg''md'
showLineNumbersbooleantrue
readOnlybooleanfalse
rowsnumber12可见行数
wrapbooleanfalse长行软换
tabSizenumber2Tab 插入空格数;0 表示让 Tab 移动焦点

反馈与讨论

CodeEditor 代码编辑器 的讨论

0
0 / 600
正在加载评论...