添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
  • 块由三个组件组成:
  1. 块定义对象:定义块的外观和行为,包括文本、颜色、字段和连接。
  2. 工具箱引用:对工具箱 XML 中块类型的引用,因此用户可以将其添加到工作区。
  3. 生成器函数:生成此块的代码字符串。它总是用 JavaScript 编写,即使目标语言不是 JavaScript。
<




    
xml  style="height: 100%">
  <category name="自定义">
        <block type="custom_text_block"></block>
    </category>
</xml>

注意block type 为 custom_text_block

  • 初始化 custom_text_block 块
initCustomTectBlock () {
  Blockly.Blocks['custom_text_block'] = {
     init: function() {
       this.appendDummyInput()
           .appendField(new Blockly.FieldLabelSerializable("名称"), "TEXT_NAME")
           .appendField(new Blockly.FieldTextInput("张三丰"), "TEXT_INPUT");
       this.setOutput(true, null);
       this.setColour(105);
       this.setTooltip("");
       this.setHelpUrl("");

代码直接复制开发工具中对应的javascript 代码即可
在这里插入图片描述

  • 效果如下
    在这里插入图片描述

  • 整体代码示例

<template>
  <div id="blocklyDiv" style="height: 800px; width: 100%;"></div>
</template>
<script>
  import Blockly from 'blockly';
  import * as Ch from 'blockly/msg/zh-hans';
  Blockly.setLocale(Ch);
  export default {
    data () {
      return {
        workspace: null,
        toolboxXml: `
          <xml  style="height: 100%">
               <category name="自定义">
                    <block type="custom_text_block"></block>
                </category>
    mounted () {
      this.workspace = Blockly.inject('blocklyDiv', { toolbox:  this.toolboxXml});
      this.initCustomTectBlock();
    methods: {
      initCustomTectBlock () {
        Blockly.Blocks['custom_text_block'] = {
          init: function() {
            this.appendDummyInput()
                .appendField(new Blockly.FieldLabelSerializable("名称"), "TEXT_NAME")
                .appendField(new Blockly.FieldTextInput("张三丰"), "TEXT_INPUT");
            this.setOutput(true, null);
            this.setColour(105);
            this.setTooltip("");
            this.setHelpUrl("");
</script>
</script>

自定义主题

主题名称为 CUSTOM_THEME

customTheme () {
  Blockly.Themes.CUSTOM_THEME = Blockly.Theme.defineTheme('CUSTOM_THEME', {
    'base': Blockly.Themes.Classic,
    'categoryStyles': {
      'custom_category': {
        'colour': "#5ba5a5"                     // 工具箱颜色标识
    'blockStyles': {
      // 块样式目前由四个字段组成:colourPrimary、colourSecondary、colorTertiary 和 hat。
      'custom_text_blocks': {                   
        'colourPrimary': "#5ba5a5",             //块的背景色,可以用色调或十六进制值定义
        'colourSecondary':"#5ba5a5",            // 如果块是阴影块,则使用此颜色
        'colourTertiary':"#C5EAFF"              // 块的边框颜色
    'componentStyles': {
      'workspaceBackgroundColour': '#131313',   // 工作区背景色
      'toolboxBackgroundColour': '#2f2e2b',     // 工具箱背景色
      'toolboxForegroundColour': '#f5f5f5',     // 工具箱类别文字颜色
      'flyoutBackgroundColour': '#252526',      // 弹出背景颜色
      'flyoutForegroundColour': '#333',         // 弹出标签文本颜色
      'flyoutOpacity': 1,                       // 弹出不透明度
      'scrollbarColour': '#dcdcdc',             // 滚动条颜色
      'scrollbarOpacity': 0.4,                  // 滚动条不透明度
      'insertionMarkerColour': '#f5f5f5',       // 插入标记颜色(不接受颜色名称)
      'insertionMarkerOpacity': 0.3,            // 插入标记不透明度
      'cursorColour': '#f5f5f5',                // 键盘导航模式下显示的光标颜色
  });
 

blockStyles样式定义完成需要在 Blockly.Blocks['custom_text_block']方法中加入this.setStyle("custom_text_blocks");即可显示该样式。

Blockly.inject('blocklyDiv', {




    
 toolbox:  this.toolboxXml, theme: Blockly.Themes.CUSTOM_THEME});
  • 效果如下
    根据需求定义
  • 代码示例
<template>
    <div id="blocklyDiv" style="height: 800px; width: 100%;"></div>
</template>
<script>
  import Blockly from 'blockly';
  import * as Ch from 'blockly/msg/zh-hans';
  Blockly.setLocale(Ch);
  export default {
    data () {
      return {
        workspace: null,
        toolboxXml: `
          <xml  style="height: 100%">
               <category name="自定义" categorystyle="custom_category">
                    <block type="custom_text_block"></block>
                </category>
    mounted () {
      this.customTheme();
      this.workspace = Blockly.inject('blocklyDiv', { toolbox:  this.toolboxXml, theme: Blockly.Themes.CUSTOM_THEME});
      this.initCustomTectBlock();
    methods: {
      initCustomTectBlock () {
        Blockly.Blocks['custom_text_block'] = {
          init: function() {
            this.appendDummyInput()
                .appendField(new Blockly.FieldLabelSerializable("名称"), "TEXT_NAME")
                .appendField(new Blockly.FieldTextInput("张三丰"), "TEXT_INPUT");
            this.setOutput(true, null);
            this.setTooltip("");
            this.setHelpUrl("");
            this.setStyle('custom_text_blocks')
      customTheme () {
        Blockly.Themes.CUSTOM_THEME = Blockly.Theme.defineTheme('CUSTOM_THEME', {
          'base': Blockly.Themes.Classic,
          'categoryStyles': {
            'custom_category': {
              'colour': "#5ba5a5"                     // 工具箱颜色标识
          'blockStyles': {
          	// 块样式目前由四个字段组成:colourPrimary、colourSecondary、colorTertiary 和 hat。
            'custom_text_blocks': {                   
              'colourPrimary': "#5ba5a5",             //块的背景色,可以用色调或十六进制值定义
              'colourSecondary':"#5ba5a5",            // 如果块是阴影块,则使用此颜色
              'colourTertiary':"#C5EAFF"              // 块的边框颜色
          'componentStyles': {
            'workspaceBackgroundColour': '#131313',   // 工作区背景色
            'toolboxBackgroundColour': '#2f2e2b',     // 工具箱背景色
            'toolboxForegroundColour': '#f5f5f5',     // 工具箱类别文字颜色
            'flyoutBackgroundColour': '#252526',      // 弹出背景颜色
            'flyoutForegroundColour': '#333',         // 弹出标签文本颜色
            'flyoutOpacity': 1,                       // 弹出不透明度
            'scrollbarColour': '#dcdcdc',             // 滚动条颜色
            'scrollbarOpacity': 0.4,                  // 滚动条不透明度
            'insertionMarkerColour': '#f5f5f5',       // 插入标记颜色(不接受颜色名称)
            'insertionMarkerOpacity': 0.3,            // 插入标记不透明度
            'cursorColour': '#f5f5f5',                // 键盘导航模式下显示的光标颜色
        });
</script>

自定义工具箱

  • 定义工具箱
<xml  style="height: 100%">
 	<category name="创建" custom="CREATE_TYPED_VARIABLE"></category>
</xml>

注意 custom="CREATE_TYPED_VARIABLE"这是唯一标识,注册与给定键CREATE_TYPED_VARIABLE关联的回调函数,该回调函数中创建该工具箱内按钮。

  • 注册工具箱
registerToolboxCategory () {
	this.workspace.registerToolboxCategoryCallback( 'CREATE_TYPED_VARIABLE', this.createFlyout);
  	this.registerButton();
// 创建变量
createFlyout (workspace) {
	  let xmlList = [];
	  const button = document.createElement('button');
	  button.setAttribute('text', '添加变量块');
	  button.setAttribute('callbackKey', 'ADD_VAR_BLOCK');
	  xmlList.push(button);
	  const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace);
	  xmlList = blockList.concat(xmlList);
	  return xmlList;

注意 ADD_VAR_BLOCK"这是唯一标识,注册与给定键ADD_VAR_BLOCK关联的回调函数,该回调函数进一步处理需求。

  • 注册工具箱内按钮
registerButton () {
  this.workspace.registerButtonCallback




    
( 'ADD_VAR_BLOCK', this.buttonClickCallbackEvent);
buttonClickCallbackEvent (e) {
  console.log(e);
  • 效果如下
    在这里插入图片描述

  • 示例演示

    样式请自行忽略

    通过点击工具箱内按钮并弹框且添加变量

    效果图1:
    点击左侧添加变量块显示弹框
    效果图2:输入123 点击添加生成左侧效果

  • 示例演示完整代码

<template>
  <div class="blockly-contant">
    <div id="blocklyDiv" style="height: 800px; width: 100%;"></div>
    <el-dialog
        title="添加块"
        :visible.sync="dialogVisible"
        :close-on-click-modal="false"
        :close-on-press-escape="false"
      <el-form label-position="top" label-width="80px" :model="formLabelAlign">
        <el-form-item label="变量名">
          <el-input v-model="formLabelAlign.name"></el-input>
        </el-form-item>
      </el-form>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="addBlockEvent">添 加</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
  import Blockly from 'blockly';
  import * as Ch from 'blockly/msg/zh-hans';
  Blockly.setLocale(Ch);
  export default {
    data () {
      return {
        workspace: null,
        dialogVisible: false,
        toolboxXml: `
          <xml  style="height: 100%">
             <category name="创建" custom="CREATE_TYPED_VARIABLE"></category>
        formLabelAlign: {
          name: ''
    mounted () {
      this.workspace = Blockly.inject('blocklyDiv', { toolbox:  this.toolboxXml});
      this.registerToolboxCategory();
    methods: {
      // 注册工具箱
      registerToolboxCategory () {
        this.workspace.registerToolboxCategoryCallback( 'CREATE_TYPED_VARIABLE', this.createFlyout);
        this.registerButton();
      // 注册工具箱内按钮
      registerButton () {
        this.workspace.registerButtonCallback( 'ADD_VAR_BLOCK', this.buttonClickCallbackEvent);
      // 工具箱内按钮生成
      createFlyout (workspace) {
        let xmlList = [];
        const button = document.createElement('button');
        button.setAttribute('text', '添加变量块');
        button.setAttribute('callbackKey', 'ADD_VAR_BLOCK');
        xmlList.push(button);
        const blockList = Blockly.VariablesDynamic.flyoutCategoryBlocks(workspace);
        xmlList = blockList.concat(xmlList);
        return xmlList;
      // 按钮点击事件
      buttonClickCallbackEvent (e) {
        this.dialogVisible = true;
      // 点击添加
      addBlockEvent () {
        let name = this.formLabelAlign.name;
        this.createVariable(name)
      // 创建变量块
      createVariable (name) {
        let [text, type, msg] = [this.getValidInput(name), '', ''];
        if (text) {
          const existing = Blockly.Variables.nameUsedWithAnyType(text, this.workspace);
          if (existing) {
            if (existing.type === type) {
              msg = Blockly.Msg['VARIABLE_ALREADY_EXISTS'].replace( '%1', existing.name);
            } else {
              msg = Blockly.Msg['VARIABLE_ALREADY_EXISTS_FOR_ANOTHER_TYPE'];
              msg = msg.replace('%1', existing.name).replace('%2',  this.getDisplayName(existing.type));
            this.$message({message: msg, type: 'warning'})
          } else {
            this.workspace.createVariable(text, type);
        if (!msg) {
          this.workspace.createVariable(text, type);
          this.dialogVisible = false;
      // 类型判断
      getDisplayName(type) {
        for (let i = 0; i < this.types_.length; i++) {
          const typeNames = this.types_[i];
          if (type === typeNames[1]) {
            return typeNames[0];
        return '';
      // 获取名称
      getValidInput(newVar) {
        if (newVar) {
          newVar = newVar.replace(/[\s\xa0]+/g, ' ').trim();
          if (newVar === Blockly.Msg['RENAME_VARIABLE'] ||
              newVar === Blockly.Msg['NEW_VARIABLE']) {
            newVar = null;
        return newVar;
</script>
<style>
  .blockly-contant /deep/ .el-dialog {
    text-align: left !important;
</style>
                    vue + blockly 自定义块、工具箱、主题自定义块建议使用  Blockly Developer Tools 方便而且选择多样,随时生成块代码。自定义块块由三个组件组成:块定义对象:定义块的外观和行为,包括文本、颜色、字段和连接。工具箱引用:对工具箱 XML 中块类型的引用,因此用户可以将其添加到工作区。生成器函数:生成此块的代码字符串。它总是用 JavaScript 编写,即使目标语言不是 JavaScript。通过   Blockly Developer Tools 
(2条消息) blockly研究(二)自定义svg图形_听闻青春丶-CSDN博客
(2条消息) blockly研究(三)自定义生成代码_听闻青春丶-CSDN博客
(2条消息) vue + blockly 示例_范百岁-CSDN博客
(2条消息) vue集成blockly的踩坑之旅_zsr0526的博客-CSDN博客
(3条消息) Vue实现图形化积木式编程(一)_温温温B的博客-CSDN博客_vue 积木
import Blockly from 'blockly';
import * as Ch from 'blockly/msg/zh-hans';   // 中文
<template>
    <button @click="getJavascriptCode">获取javascri
https://itbilu.com/other/relate/Ek5ePdjdX.html#configure-fixed-size
https://www.npmjs.com/package/blockly
请结合以上文档来看这篇博客
初步搭建blockly:
npm install blockly 如果安装失败,请删除n
				
1. Blockly Developer Tools Demo在线版: https://blockly-demo.appspot.com/static/demos/toolbox/index.html 注意:国内可能被墙导致该网址访问不了,可按如下步骤安装Blockly Developer Tools离线版。 2.Blockly Developer Tools 的Github仓库地址: https://github.com/google/blockly-devtools 下载zip打包文件..
2.动画效果 如果直接用数据驱动,动画比较僵硬,建议使用一些弹性动画效果 如果拖拽函数使用html5,拖动函数,不好用,而且拖起来有个很难看的一,不方便自定义;建议自己改用onmouesemove / start / end来原生书写 移动时建议transform加上一个动画延迟,这样会有一些缓冲的效果,不生硬,而且动画渲染更流畅;如在拖曳元素上加上过渡时间:50ms; 3.数据存储方式 我这里是用json存储到本地存储里面,保存时再序列化到放置,每一个可以拖拽的(上下拖拽)。上下调整是改变transform:'translateY('+ wrap.originTop +'px)';原理就是 请访问我们的以获取大多数插件的交互式演示。 Blockly有一个活跃的。 请顺道打个招呼。 尽早向我们展示您的原型; 总的来说,我们有很多经验,可以提供一些提示,以节省您的时间。 我们会积极监控论坛,通常会在2个工作日内回答问题。 阿帕奇2.0 filteredItems() { return this.items.filter(item => { return Object.values(item).some(value => { return String(value).toLowerCase().includes(this.searchText.toLowerCase()) mounted() { // Fetch items from backend API fetch('/api/items') .then(response => response.json()) .then(data => { this.items = data </script> Spring Boot Controller 代码: @RestController @RequestMapping("/api") public class ItemController { @Autowired private ItemRepository itemRepository; @GetMapping("/items") public List<Item> getItems() { return itemRepository.findAll(); @PostMapping("/items/search") public List<Item> searchItems(@RequestBody Map<String, String> searchParams) { String searchText = searchParams.get("searchText"); return itemRepository.search(searchText); @Repository public interface ItemRepository extends JpaRepository<Item, Long> { @Query("SELECT i FROM Item i WHERE LOWER(i.name) LIKE %:searchText% OR LOWER(i.email) LIKE %:searchText%") List<Item> search(@Param("searchText") String searchText); 以上是使用 Vue 和 Spring Boot 实现自定义查询列表的开发代码示例。希望对你有所帮助!