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

VariableAwareInput 变量感知输入

Input 增强版,自动识别 `{{var}}` 模板变量并高亮;未知变量标红波浪线。

基础用法

实现:底层是透明文字的原生 input + 同尺寸 overlay 渲染高亮文本,光标位置完全对齐。 variables 数组里的名字算”已知”用 accent 高亮,其他算”未知”用红色波浪线。

背景 视口
已知变量:base_url · user_id · auth_token
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const value = ref('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
const known = ['base_url', 'user_id', 'auth_token'];
</script>
<template>
  <div style="width: 100%; max-width: 920px;">
    <CfVariableAwareInput v-model="value" :variables="known" placeholder="试试输入 {{base_url}}…" />
    <div style="margin-top: 8px; font-size: 12px; color: var(--fg-3);">
      已知变量:{{ known.join(' · ') }}
    </div>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const value = ref('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
const known = ['base_url', 'user_id', 'auth_token'];
</script>
<template>
  <div style="width: 100%; max-width: 920px;">
    <CfVariableAwareInput v-model="value" :variables="known" placeholder="试试输入 {{base_url}}…" />
    <div style="margin-top: 8px; font-size: 12px; color: var(--fg-3);">
      已知变量:{{ known.join(' · ') }}
    </div>
  </div>
</template>
import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';

export default function Demo() {
  const [value, setValue] = useState('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
  const known = ['base_url', 'user_id', 'auth_token'];
  return (
    <>
      <div style={{ width: "100%", maxWidth: 920 }}>
          <CfVariableAwareInput value={value} onChange={setValue} variables={known} placeholder="试试输入 {{base_url}}…" />
          <div style={{ marginTop: 8, fontSize: 12, color: "var(--fg-3)" }}>
            已知变量:{known.join(' · ')}
          </div>
        </div>
    </>
  );
}
import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';

export default function Demo() {
  const [value, setValue] = useState('{{base_url}}/users/{{user_id}}/orders?token={{auth_token}}');
  const known = ['base_url', 'user_id', 'auth_token'];
  return (
    <>
      <div style={{ width: "100%", maxWidth: 920 }}>
          <CfVariableAwareInput value={value} onChange={setValue} variables={known} placeholder="试试输入 {{base_url}}…" />
          <div style={{ marginTop: 8, fontSize: 12, color: "var(--fg-3)" }}>
            已知变量:{known.join(' · ')}
          </div>
        </div>
    </>
  );
}

变量交互

variables 可以从字符串数组升级为对象数组。输入 {{ 触发候选列表,点击已识别变量打开详情;组件只发出 variable-update / variable-create 事件,不直接保存业务数据。

背景 视口
输入 {{ 触发候选;点击变量查看详情。
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';

const value = ref('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
const lastAction = ref('输入 {{ 触发候选;点击变量查看详情。');
const variables = [
  {
    name: 'base_url',
    label: 'Base URL',
    value: 'https://api.chufix.dev',
    description: '项目级 API 根地址,可在弹层中修改。',
    scope: 'project',
    editable: true,
  },
  {
    name: 'user_id',
    label: 'User ID',
    value: 'u_1024',
    description: '当前登录用户 ID。',
    scope: 'local',
  },
  {
    name: 'token',
    label: 'Auth Token',
    value: 'cf_live_xxx',
    description: '授权令牌,由外层业务控制保存。',
    scope: 'global',
    editable: true,
  },
];
</script>
<template>
  <div style="width: 100%; max-width: 920px;">
    <CfVariableAwareInput
      v-model="value"
      :variables="variables"
      placeholder="输入 {{ 触发变量选择"
      @variable-select="(variable) => lastAction = `插入变量:${variable.name}`"
      @variable-update="(payload) => lastAction = `请求更新 ${payload.name} = ${payload.value}`"
      @variable-create="(payload) => lastAction = `请求创建变量:${payload.name}`"
    />
    <div style="margin-top: 10px; color: var(--fg-3); font-size: 12px;">
      {{ lastAction }}
    </div>
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';

const value = ref('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
const lastAction = ref('输入 {{ 触发候选;点击变量查看详情。');
const variables = [
  {
    name: 'base_url',
    label: 'Base URL',
    value: 'https://api.chufix.dev',
    description: '项目级 API 根地址,可在弹层中修改。',
    scope: 'project',
    editable: true,
  },
  {
    name: 'user_id',
    label: 'User ID',
    value: 'u_1024',
    description: '当前登录用户 ID。',
    scope: 'local',
  },
  {
    name: 'token',
    label: 'Auth Token',
    value: 'cf_live_xxx',
    description: '授权令牌,由外层业务控制保存。',
    scope: 'global',
    editable: true,
  },
];
</script>
<template>
  <div style="width: 100%; max-width: 920px;">
    <CfVariableAwareInput
      v-model="value"
      :variables="variables"
      placeholder="输入 {{ 触发变量选择"
      @variable-select="(variable) => lastAction = `插入变量:${variable.name}`"
      @variable-update="(payload) => lastAction = `请求更新 ${payload.name} = ${payload.value}`"
      @variable-create="(payload) => lastAction = `请求创建变量:${payload.name}`"
    />
    <div style="margin-top: 10px; color: var(--fg-3); font-size: 12px;">
      {{ lastAction }}
    </div>
  </div>
</template>
import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';

export default function Demo() {
  const [value, setValue] = useState('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
  const [lastAction, setLastAction] = useState('输入 {{ 触发候选;点击变量查看详情。');
  const variables = [
    {
      name: 'base_url',
      label: 'Base URL',
      value: 'https://api.chufix.dev',
      description: '项目级 API 根地址,可在弹层中修改。',
      scope: 'project',
      editable: true,
    },
    {
      name: 'user_id',
      label: 'User ID',
      value: 'u_1024',
      description: '当前登录用户 ID。',
      scope: 'local',
    },
    {
      name: 'token',
      label: 'Auth Token',
      value: 'cf_live_xxx',
      description: '授权令牌,由外层业务控制保存。',
      scope: 'global',
      editable: true,
    },
  ];
  return (
    <>
      <div style={{ width: "100%", maxWidth: 920 }}>
          <CfVariableAwareInput value={value} onChange={setValue} variables={variables} placeholder="输入 {{ 触发变量选择" onVariableSelect={(variable) => setLastAction(`插入变量:${variable.name}`)}
            onVariableUpdate={(payload) => setLastAction(`请求更新 ${payload.name} = ${payload.value}`)}
            onVariableCreate={(payload) => setLastAction(`请求创建变量:${payload.name}`)}
          />
          <div style={{ marginTop: 10, color: "var(--fg-3)", fontSize: 12 }}>
            {lastAction}
          </div>
        </div>
    </>
  );
}
import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';

export default function Demo() {
  const [value, setValue] = useState('请求 {{base_url}}/v2/users/{{user_id}}?token={{token}}');
  const [lastAction, setLastAction] = useState('输入 {{ 触发候选;点击变量查看详情。');
  const variables = [
    {
      name: 'base_url',
      label: 'Base URL',
      value: 'https://api.chufix.dev',
      description: '项目级 API 根地址,可在弹层中修改。',
      scope: 'project',
      editable: true,
    },
    {
      name: 'user_id',
      label: 'User ID',
      value: 'u_1024',
      description: '当前登录用户 ID。',
      scope: 'local',
    },
    {
      name: 'token',
      label: 'Auth Token',
      value: 'cf_live_xxx',
      description: '授权令牌,由外层业务控制保存。',
      scope: 'global',
      editable: true,
    },
  ];
  return (
    <>
      <div style={{ width: "100%", maxWidth: 920 }}>
          <CfVariableAwareInput value={value} onChange={setValue} variables={variables} placeholder="输入 {{ 触发变量选择" onVariableSelect={(variable) => setLastAction(`插入变量:${variable.name}`)}
            onVariableUpdate={(payload) => setLastAction(`请求更新 ${payload.name} = ${payload.value}`)}
            onVariableCreate={(payload) => setLastAction(`请求创建变量:${payload.name}`)}
          />
          <div style={{ marginTop: 10, color: "var(--fg-3)", fontSize: 12 }}>
            {lastAction}
          </div>
        </div>
    </>
  );
}

混合状态

已知(accent 高亮)+ 未知(红色波浪线)的组合实例。

背景 视口
src/App.vue
<script setup lang="ts">
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const v1 = ref('valid only: {{base_url}} / {{user_id}}');
const v2 = ref('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
const v3 = ref('all unknown: {{a}} {{b}} {{c}}');
const known = ['base_url', 'user_id'];
</script>
<template>
  <div style="display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 920px;">
    <CfVariableAwareInput v-model="v1" :variables="known" />
    <CfVariableAwareInput v-model="v2" :variables="known" />
    <CfVariableAwareInput v-model="v3" :variables="known" />
  </div>
</template>
<script setup>
import { ref } from 'vue';
import { CfVariableAwareInput } from '@chufix-design/vue';
const v1 = ref('valid only: {{base_url}} / {{user_id}}');
const v2 = ref('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
const v3 = ref('all unknown: {{a}} {{b}} {{c}}');
const known = ['base_url', 'user_id'];
</script>
<template>
  <div style="display: flex; flex-direction: column; gap: 12px; width: 100%; max-width: 920px;">
    <CfVariableAwareInput v-model="v1" :variables="known" />
    <CfVariableAwareInput v-model="v2" :variables="known" />
    <CfVariableAwareInput v-model="v3" :variables="known" />
  </div>
</template>
import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';

export default function Demo() {
  const [v1, setV1] = useState('valid only: {{base_url}} / {{user_id}}');
  const [v2, setV2] = useState('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
  const [v3, setV3] = useState('all unknown: {{a}} {{b}} {{c}}');
  const known = ['base_url', 'user_id'];
  return (
    <>
      <div style={{ display: "flex", flexDirection: "column", gap: 12, width: "100%", maxWidth: 920 }}>
          <CfVariableAwareInput value={v1} onChange={setV1} variables={known} />
          <CfVariableAwareInput value={v2} onChange={setV2} variables={known} />
          <CfVariableAwareInput value={v3} onChange={setV3} variables={known} />
        </div>
    </>
  );
}
import { useState } from 'react';
import { CfVariableAwareInput } from '@chufix-design/react';

export default function Demo() {
  const [v1, setV1] = useState('valid only: {{base_url}} / {{user_id}}');
  const [v2, setV2] = useState('mixed: {{base_url}}/v1/{{token}}/users/{{user_id}}');
  const [v3, setV3] = useState('all unknown: {{a}} {{b}} {{c}}');
  const known = ['base_url', 'user_id'];
  return (
    <>
      <div style={{ display: "flex", flexDirection: "column", gap: 12, width: "100%", maxWidth: 920 }}>
          <CfVariableAwareInput value={v1} onChange={setV1} variables={known} />
          <CfVariableAwareInput value={v2} onChange={setV2} variables={known} />
          <CfVariableAwareInput value={v3} onChange={setV3} variables={known} />
        </div>
    </>
  );
}

API

属性类型默认值说明
modelValue / valuestring''输入值
variables(string | VariableOption)[][]已知变量名或变量对象清单
size'sm' | 'md' | 'lg''md'
variant'outline' | 'filled''outline'
suggestbooleantrue是否在输入 {{ 时展示候选列表
suggestTriggerstring'{{'候选触发文本
interactivebooleantrue是否允许点击变量打开交互弹层
showVariablePopoverbooleantrue是否使用内置变量详情弹层
placeholder / disabled / error
事件 / 扩展说明
variable-select / onVariableSelect从候选列表插入变量时触发
variable-click / onVariableClick点击已识别变量时触发
variable-update / onVariableUpdate内置弹层点击更新时触发,组件不直接保存
variable-create / onVariableCreate点击未知变量的创建入口时触发
Vue #option / React renderVariableOption自定义候选项渲染
Vue #variable-popover / React renderVariablePopover自定义变量详情弹层

反馈与讨论

VariableAwareInput 变量感知输入 的讨论

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