React SurveyJS通过哪些属性或函数实现Survey Creator设计器与预览/表单库的差异化渲染?
实现SurveyJS自定义React元素的设计器专属装饰项
核心思路
要实现设计器中显示可操作的装饰项(如添加/删除选项),但在预览和实际渲染时隐藏,关键是区分设计器模式和运行模式,分别编写对应的渲染逻辑。
具体实现步骤
- 定义自定义问题类型
先扩展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" });- 定义自定义问题类型
- 编写设计器专属渲染组件
在设计器中渲染带操作按钮的装饰项,支持添加/删除选项:
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> ); };- 编写设计器专属渲染组件
- 编写运行时渲染组件
预览和实际渲染时,仅显示核心内容,隐藏装饰操作项:
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> ); };- 编写运行时渲染组件
- 区分模式注册渲染器
通过内置标识判断当前环境,注册对应渲染器:
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
相关产品推荐
相关产品推荐

