You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React SurveyJS通过哪些属性或函数实现Survey Creator设计器与预览/表单库的差异化渲染?

实现SurveyJS自定义React元素的设计器专属装饰项

核心思路

要实现设计器中显示可操作的装饰项(如添加/删除选项),但在预览和实际渲染时隐藏,关键是区分设计器模式和运行模式,分别编写对应的渲染逻辑。

具体实现步骤

    1. 定义自定义问题类型
      先扩展SurveyJS的问题类,添加需要控制的属性(比如选项列表):
    import { Question } from "survey-core";
    
    export class QuestionCustomItem extends Question {
      getType() {
        return "customitem";
      }
    
      // 定义选项列表属性
      get options() {
        return this.getPropertyValue("options", []);
      }
      set options(val) {
        this.setPropertyValue("options", val);
      }
    }
    
    // 注册自定义问题类型及属性
    import { Serializer } from "survey-core";
    Serializer.addClass("customitem", [], null, "question");
    Serializer.addProperty("customitem", {
      name: "options",
      type: "itemvalues",
      category: "general"
    });
    
    1. 编写设计器专属渲染组件
      在设计器中渲染带操作按钮的装饰项,支持添加/删除选项:
    import React from "react";
    import { ReactQuestionFactory } from "survey-react-ui";
    
    const CustomItemDesignerRenderer = (props) => {
      const { question } = props;
    
      const addOption = () => {
        question.options = [...question.options, { value: `opt${question.options.length + 1}`, text: `选项${question.options.length + 1}` }];
      };
    
      const removeOption = (index) => {
        const newOptions = question.options.filter((_, i) => i !== index);
        question.options = newOptions;
      };
    
      return (
        <div className="custom-item-designer">
          <h4>自定义元素(设计器模式)</h4>
          {question.options.map((opt, index) => (
            <div key={index} style={{ display: "flex", gap: "8px", margin: "8px 0" }}>
              <input
                type="text"
                value={opt.text}
                onChange={(e) => {
                  const newOptions = [...question.options];
                  newOptions[index].text = e.target.value;
                  question.options = newOptions;
                }}
              />
              <button onClick={() => removeOption(index)}>删除</button>
            </div>
          ))}
          <button onClick={addOption}>添加选项</button>
        </div>
      );
    };
    
    1. 编写运行时渲染组件
      预览和实际渲染时,仅显示核心内容,隐藏装饰操作项:
    const CustomItemRuntimeRenderer = (props) => {
      const { question } = props;
      return (
        <div className="custom-item-runtime">
          <h4>自定义元素(运行模式)</h4>
          <ul>
            {question.options.map((opt, index) => (
              <li key={index}>{opt.text}</li>
            ))}
          </ul>
        </div>
      );
    };
    
    1. 区分模式注册渲染器
      通过内置标识判断当前环境,注册对应渲染器:
    import { SurveyCreator } from "survey-creator-react";
    
    ReactQuestionFactory.Instance.registerRenderer("customitem", (props) => {
      // 利用SurveyJS内置属性判断是否处于设计模式
      const isDesignMode = !!props.survey?.isDesignMode;
      return isDesignMode ? <CustomItemDesignerRenderer {...props} /> : <CustomItemRuntimeRenderer {...props} />;
    });
    

关键要点

  • 依赖survey.isDesignMode属性区分设计/运行模式,这是SurveyJS原生提供的环境判断标识
  • 自定义属性必须通过Serializer注册,才能在设计器的属性面板中显示和编辑
  • 设计器中的操作直接修改问题属性,这些属性会同步保存到调查JSON中,运行时可直接读取使用

内容的提问来源于stack exchange,提问作者Alex

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 22:52:28