Blockly自定义块

  • 路由
    • 下一篇
    • 历史回顾
      • Babylon.js部分
      • Blockly部分
  • 前言
  • 最终实现效果
  • 本文实现效果
  • 完整代码
  • 代码分解
    • 0.代码块前置知识
      • 0.1 汉化
      • 0.2 预置块
      • 0.3 不同样式块含义
        • 0.3.1 连接方式
        • 0.3.2 输入方式
        • 0.3.2 输入类型
      • 0.4 代码块构建代码块
    • 1. 自定义块
      • 1.1 定义块行为
      • 1.2 注册块
      • 1.2 定义块生成代码
      • 1.3 引入块
  • 后续计划
    • Blockly
  • 开源项目GitHub链接
  • 资源下载链接
  • 你的点赞是我继续编写的动力

路由

下一篇

  • Vue实现图形化积木式编程(十一) ---- Blockly插件使用

历史回顾

Babylon.js部分

  • Vue实现图形化积木式编程(一) ---- Babylon.js基础场景搭建
  • Vue实现图形化积木式编程(二) ---- Babylon.js加载模型到场景中
  • Vue实现图形化积木式编程(三) ---- Babylon.js点击拖拽移动模型
  • Vue实现图形化积木式编程(四) ---- Babylon.js实现碰撞效果
  • Vue实现图形化积木式编程(五) ---- Babylon.js自定义启动界面
  • Vue实现图形化积木式编程(六) ---- Babylon.js相机控制与相机动画
  • Vue实现图形化积木式编程(七) ---- babylonjs-gui 按钮实现
  • Vue实现图形化积木式编程(八) ---- 将3d界面放入可拖动窗口中

Blockly部分

  • Vue实现图形化积木式编程(九) ---- Blockly代码块编辑区域基本场景搭建

前言

前段时间想要做一个web端的图形化积木式编程(类似少儿编程)的案例,网上冲浪了一圈又一圈,终于技术选型好,然后代码一顿敲,终于出来了一个雏形。

TIPS:该案例设计主要参考iRobot Coding,只用做学习用途,侵删。

https://code.irobot.com/#/

最终实现效果

本文实现效果

  • Blockly自定义块

完整代码

  • Blockly自定义块
<template><div id="blockly"><!-- 工作区 --><div id="blocklyDiv" ref="blocklyDiv" style="height: 500px; width: 800px;"></div><button style="position: fixed;left: 50px;top: 10px;" @click="block2code">生成代码</button><!-- 代码显示区 --><div style="background-color: lightgrey;width: 800px;text-align: left"><pre v-html="code?code:'请点击生成代码按钮'"></pre></div><button style="position: fixed;left: 150px;top: 10px;" @click="runCode">执行代码</button></div>
</template><script>
import Blockly from 'blockly'
import BlocklyJS from 'blockly/javascript';
import './customBlock'
export default {name: "blocklyClass1",data() {return {code:'',options: {horizontalLayout: true,//工具箱水平toolboxPosition: "end",//工具箱在底部toolbox: {"kind": "flyoutToolbox","contents": [{"kind": "block","type": "while_program_start",},{"kind": "block","type": "move",},{"kind": "block","type": "turn",},{"kind": "block","type": "arc"},{"kind": "block","type": "draw"},{"kind": "block","type": "pencilcolor"},{"kind": "block","type": "controls_repeat_ext"},{"kind": "block","type": "controls_whileUntil"},{"kind": "block","type": "controls_for"},{"kind": "block","type": "controls_if"},{"kind": "block","type": "logic_compare"},{"kind": "block","type": "logic_operation"},{"kind": "block","type": "logic_negate"},{"kind": "block","type": "logic_boolean"},{"kind": "sep","gap": "32"},{"kind": "block","blockxml": "<block type='math_number'><field name='NUM'>10</field></block>"},{"kind": "block","type": "math_arithmetic"},{"kind": "block","type": "math_single"},{"kind": "block","type": "text"},{"kind": "block","type": "text_length"},{"kind": "block","type": "text_print"},{"kind": "block","type": "variables_get"},{"kind": "block","type": "variables_set"},]}}}},mounted() {Blockly.inject(this.$refs.blocklyDiv, this.options);},methods:{/*** block代码块转为代码*/block2code(){this.code = BlocklyJS.workspaceToCode(this.$refs.blocklyDiv.workspace)},/*** 执行生成代码*/runCode(){if(!this.code){alert('请先点击生成代码');return}eval(this.code)},},
}
</script><style scoped>
#blockly {position: absolute;left: 50px;top: 50px;bottom: 0;width: calc(100vw - 50px);height: calc(100vh - 50px);display: flex;flex-direction: column;
}
</style>
  • 封装的自定义块方法 - customBlock.js
import * as Blockly from 'blockly/core'import * as hans from 'blockly/msg/zh-hans'Blockly.setLocale(hans);//汉化/*** 自定义组件注册*/
Blockly.defineBlocksWithJsonArray([//事件{"type": "while_program_start","message0": "当程序运行 %1 %2","args0": [{"type": "input_dummy"},{"type": "input_statement","name": "while_content"}],"previousStatement": null,"nextStatement": null,"colour": "#609FD6","strokeColour": "#4088C8","tooltip": "123","helpUrl": "1"},//指令{"type": "move","message0": "移动 %1 CM","args0": [{"type": "field_input","name": "move_distance","text": "50"}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""},{"type": "turn","message0": "向 %1 %2","args0": [{"type": "field_dropdown","name": "dirction","options": [["左转","0"],["右转","1"]]},{"type": "field_angle","name": "degree","angle": 90}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""},{"type": "arc","message0": "弧形 %1 %2 ,半径 %3 CM","args0": [{"type": "field_dropdown","name": "dirction","options": [["向左","0"],["向右","1"]]},{"type": "field_angle","name": "degree","angle": 90},{"type": "field_number","name": "radius","value": 50,"min": 1,"max": 100}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""},{"type": "draw","message0": "设置 %1","args0": [{"type": "field_dropdown","name": "pencilState","options": [[{"src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFIGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDgtMjNUMTE6Mzk6NTQrMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTA4LTIzVDExOjUxOjAxKzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTA4LTIzVDExOjUxOjAxKzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOmVkZGRkMGNlLTU4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","width": 50,"height": 50,"alt": "pencil down"},"1"],[{"src": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAACXBIWXMAAAsTAAALEwEAmpwYAAAFIGlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS42LWMxNDUgNzkuMTYzNDk5LCAyMDE4LzA4LzEzLTE2OjQwOjIyICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOmRjPSJodHRwOi8vcHVybC5vcmcvZGMvZWxlbWVudHMvMS4xLyIgeG1sbnM6cGhvdG9zaG9wPSJodHRwOi8vbnMuYWRvYmUuY29tL3Bob3Rvc2hvcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxOSAoTWFjaW50b3NoKSIgeG1wOkNyZWF0ZURhdGU9IjIwMjEtMDgtMjNUMTE6NDA6MTErMDg6MDAiIHhtcDpNb2RpZnlEYXRlPSIyMDIxLTA4LTIzVDExOjUyOjA2KzA4OjAwIiB4bXA6TWV0YWRhdGFEYXRlPSIyMDIxLTA4LTIzVDExOjUyOjA2KzA4OjAwIiBkYzpmb3JtYXQ9ImltYWdlL3BuZyIgcGhvdG9zaG9wOkNvbG9yTW9kZT0iMyIgcGhvdG9zaG9wOklDQ1Byb2ZpbGU9InNSR0IgSUVDNjE5NjYtMi4xIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjU3Y2UzN2ViLTQ0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","width": 50,"height": 50,"alt": "pencil up"},"0"]]}],"previousStatement": null,"nextStatement": null,"colour": "#81C679","tooltip": "","helpUrl": ""},{"type": "pencilcolor","message0": "设置笔颜色: 红 %1 绿 %2 蓝 %3","args0": [{"type": "field_number","name": "red","value": 100,"min": 0,"max": 255},{"type": "field_number","name": "green","value": 100,"min": 0,"max": 255},{"type": "field_number","name": "blue","value": 100,"min": 0,"max": 255}],"previousStatement": null,"nextStatement": null,"colour": "#81C679","tooltip": "","helpUrl": ""}]
);/*** 自定义组件生成代码* @param block* @returns {string}*/
Blockly.JavaScript['while_program_start'] = function (block) {blockvar while_content = Blockly.JavaScript.statementToCode(block, 'while_content');var code = 'robot.init();\n'+ while_content +'robot.stop();\n';return code;
};Blockly.JavaScript['move'] = function (block) {var text_move_distance = block.getFieldValue('move_distance');var code = 'robot.move(' + text_move_distance + ');\n';return code;
};Blockly.JavaScript['turn'] = function (block) {var dropdown_dirction = block.getFieldValue('dirction');var angle_degree = block.getFieldValue('degree');var code = 'robot.turn(' + dropdown_dirction + ', ' + angle_degree + ');\n';return code;
};Blockly.JavaScript['arc'] = function (block) {var dropdown_dirction = block.getFieldValue('dirction');var angle_degree = block.getFieldValue('degree');var radius = block.getFieldValue('radius');var code = 'robot.arc(' + dropdown_dirction + ', ' + angle_degree + ',' + radius + ');\n';return code;
};Blockly.JavaScript['draw'] = function (block) {var dropdown_pencilstate = block.getFieldValue('pencilState');var code = 'robot.drawable(' + dropdown_pencilstate + ');\n';return code;
};Blockly.JavaScript['pencilcolor'] = function (block) {var number_red = block.getFieldValue('red') / 255.0;var number_green = block.getFieldValue('green') / 255.0;var number_blue = block.getFieldValue('blue') / 255.0;var code = 'await robot.pencilcolor(' + number_red + ',' + number_green + ',' + number_blue + ');\n';return code;
};

代码分解

自定义块主要分3部分:
1、定义块行为
2、注册块
3、定义块生成代码
4、引入块

0.代码块前置知识

0.1 汉化

import * as hans from 'blockly/msg/zh-hans'
Blockly.setLocale(hans);//汉化

0.2 预置块

  • Blockly原本已经预置了很多代码块了

  • 逻辑块(logic_compare、logic_operation、logic_negate、logic_boolean)

  • 循环控制块(controls_repeat_ext、controls_whileUntil、controls_if)

  • 数学模块(math_number、math_arithmetic、math_single)

  • 文本模块(text、text_length、text_print)

  • 变量块(variables_get、variables_set)

0.3 不同样式块含义

0.3.1 连接方式

  • 上下连接

以javascript为例,在一个事件循环中,代码块会顺序执行(不包含异步代码块),代码块之间就是上下连接方式

let loop = 10//上连接为空,下连接为print
print('hello world')//上连接为赋值语句,下连接为for循环代码块
for(let i = 0; i < 10; i++){...}//上连接为print,下连接为while循环代码块
while(loop){...}//上连接为for循环代码块,下连接为空
  • 左连接

左连接可以理解为其为输出
任何值的输出都使用左连接方式,如(数字模块输出数字、文本模块输出文本、逻辑模块输出真假)

0.3.2 输入方式

输入方式,即函数传入的参数
输入的连接方式不一样,日常使用中感觉不出区别
输入可以现在输入的类型,如if、when模块的外接类型输入限制了类型只能为逻辑模块

  • 内联

  • 外接

0.3.2 输入类型

输入的模块的类型分为值输入和块输入

  • 值输入(数字、文本、逻辑)

  • 块输入(代码块)

0.4 代码块构建代码块

  • Blockly预置的很多代码块基本符合日常编程的各种使用场景,而其更出色的地方在于其能自定义代码块,而且是通过代码块来生成代码块

官方的自定义代码块链接:自定义代码块构建工具
工具的食用方法可参考大佬文章:blockly构建自定义块及其工具

  • 而在本文中的案例中,控制小车的移动等操作,小车的动作是依次执行的,其实用得最多是上下连接的代码块,该代码块中包含内联的一个或多个值输入:

  • 对应的构造如下:

  • 还有就是小车启动的函数,用的是上下连接的代码块,该代码块中包含外接的块输入:

  • 对应的构造如下,其中空输入只是为了在其中填入文本让其能单独一行显示(好看一点):

1. 自定义块

  • 熟悉Block Definition的生成规则当然是最好的了,但是官方提供的代码块构建工具,进行了可视化预览、定义配置、块的生成代码,极大方便了我们的开发。
  • 所以自定义块的流程变得很简单啦
    1、通过toolbox提供的各种工具块,拖动到编辑区,根据自己的需求区构建自定义块。
    2、通过预览区实时查看自定义块是否达到预期效果
    3、达到预期效果后,将定义配置区中的JSON配置信息在项目中使用Blockly.defineBlocksWithJsonArray的方法注册自定义块
    4、如果是需要生成JavaScript代码,生成代码区选择JavaScript,然后将代码复制到项目中
    5、最后就是将代码块引入到toolbox工具箱中

1.1 定义块行为

  • 定义块行为就是上面所说的编辑区编辑块规则,或者熟悉Block Definition的同学通过块定义的规则编写JSON格式文本,从而形成块的形状(其形状基本是决定了请行为和功能)

1.2 注册块

  • 将定义配置区中的JSON配置信息在项目中使用Blockly.defineBlocksWithJsonArray的方法注册自定义块
/*** 自定义组件注册*/Blockly.defineBlocksWithJsonArray([//当程序运行代码块{"type": "while_program_start","message0": "当程序运行 %1 %2","args0": [{"type": "input_dummy"},{"type": "input_statement","name": "while_content"}],"previousStatement": null,"nextStatement": null,"colour": "#609FD6","strokeColour": "#4088C8","tooltip": "123","helpUrl": "1"},//弧度移动代码块{"type": "arc","message0": "弧形 %1 %2 ,半径 %3 CM","args0": [{"type": "field_dropdown","name": "dirction","options": [["向左","0"],["向右","1"]]},{"type": "field_angle","name": "degree","angle": 90},{"type": "field_number","name": "radius","value": 50,"min": 1,"max": 100}],"previousStatement": null,"nextStatement": null,"colour": "#F7D233","strokeColour": "#CCAD2B","tooltip": "","helpUrl": ""}]);

1.2 定义块生成代码

  • 生成代码区选择JavaScript,然后将代码复制到项目中,其中代码已经写好了变量的获取方式,返回值就是生成的代码,我们需要编写的就是返回值的内容。
  • 而对于控制小车对象而言,笔者这里统一使用robot对象,然后调用对象中的各种方法,如下面代码中拼接出来的代码为robot.arc('方向','弧的角度','弧的半径')
/*** 弧度运动自定义块* @param block* @returns {string}*/
Blockly.JavaScript['arc'] = function(block) {var dropdown_dirction = block.getFieldValue('dirction');var angle_degree = block.getFieldValue('degree');var radius = block.getFieldValue('radius');// TODO: Assemble JavaScript into code variable.var code = 'robot.arc(' + dropdown_dirction + ', ' + angle_degree + ',' + radius + ');\n';return code;
};
  • 如下代码是控制程序生命周期的,拼接出来的代码为
robot.init();
...(控制小车运动的代码块)
robot.stop();
/***程序启动自定义块* @param block* @returns {string}*/
Blockly.JavaScript['while_program_start'] = function (block) {blockvar while_content = Blockly.JavaScript.statementToCode(block, 'while_content');var code = 'robot.init();\n' +while_content +'robot.stop();\n';return code;
};

1.3 引入块

  • 将自定义块引入到toolbox工具箱中
data() {options: {toolbox: {"kind": "flyoutToolbox","contents": [{"kind": "block","type": "while_program_start",},{"kind": "block","type": "arc"},...]}}},
mounted() {//注入选项Blockly.inject(this.$refs.blocklyDiv, this.options);},

后续计划

Blockly

  • blockly第三方组件使用
  • 小车控制方法的封装
  • 接入js-interpreter,步骤运行block块
  • …(想到啥写啥)

开源项目GitHub链接

https://github.com/Wenbile/Child-Programming-Web

资源下载链接

  • Vue前端源码
  • ThinkJS后端源码

你的点赞是我继续编写的动力

Vue实现图形化积木式编程(十)相关推荐

  1. Vue实现图形化积木式编程(十二)

    执行Blockly生成代码 路由 下一篇 历史回顾 Babylon.js部分 Blockly部分 前言 最终实现效果 本文内容 实现思路 问题分析 问题 原因 不优雅解决 优雅解决 完整代码 后续计划 ...

  2. Vue实现图形化积木式编程(十三)

    步骤运行代码块高亮 路由 历史回顾 Babylon.js部分 Blockly部分 前言 最终实现效果 本文内容 实现 1. 安装依赖 2. 简化语法 3. 引入js解析器 4. 运行代码 5. 加入高 ...

  3. Vue实现图形化积木式编程(十一)

    Blockly插件使用 路由 下一篇 历史回顾 Babylon.js部分 Blockly部分 前言 最终实现效果 本文内容 安装 使用 后续计划 开源项目GitHub链接 资源下载链接 你的点赞是我继 ...

  4. Vue实现图形化积木式编程(一)

    Babylon.js基础场景搭建 路由 前言 最终实现效果 本文实现效果 技术选型 1.前端 2.后端 完整代码 代码分解 0.npm安装相关依赖 1.引入模块 2.场景初始化 3.ArcRotate ...

  5. Vue实现图形化积木式编程(二)

    Babylon.js加载模型到场景中 路由 下一篇 历史回顾 前言 最终实现效果 本文实现效果 完整代码 操作分解(Babylon.js模型格式转换与导入) 0.在开源模型网上下载一个模型/自己制作一 ...

  6. 原创教程:下载和安装“图形化积木Python编程”海龟编辑器

    一.简介 Python编辑器是一款界面简单充满童趣的Python编程软件,该软件普遍适用于低龄化用户,帮助培养用户对代码编程的兴趣:众所周知编写代码是比较枯燥的事情,所以学起来更是如此,为解决这一难题 ...

  7. python积木式编程_TurnipBit—MicroPython开发板:从积木式编程语言开始学作小小创客...

    编程.建模.制做动画和游戏--这些当初咱们默认只有成年人玩得转的事情,如今早已经被无数小孩子给颠覆甚至玩出新境界了.热爱科技和动手的"创客"(Maker)如今在全世界都煊赫一时.今 ...

  8. 竞赛无人机搭积木式编程——以2022年TI电赛送货无人机一等奖复现为例学习(7月B题)

    在学习本教程前,请确保已经学习了前4讲中无人机相关坐标系知识.基础飞行控制函数.激光雷达SLAM定位条件下的室内定点控制.自动飞行支持函数.导航控制函数等入门阶段的先导教程. 同时用户在做二次开发自定 ...

  9. python积木式编程_【发现教育版亮点之美】3D One还能这么玩:“趣味编程”建模让你脑洞大开...

    原标题:[发现教育版亮点之美]3D One还能这么玩:"趣味编程"建模让你脑洞大开 "[有奖征文]发现3D One教育版亮点之美"教育版功能文章征集活动已经告一 ...

最新文章

  1. 正则表达式模式修正符
  2. 码云gitee最大文件限制
  3. CentOS7中多台服务器配置SSH免密钥登录
  4. 全面改进Transformer类预训练模型,自然语言任务超越BERT
  5. AtCoder 2305 [AGC010D] Decrementing(博弈)
  6. 训练深度学习_深度学习训练tricks整理1
  7. 用java实现云计算的两种趋势性方法
  8. nginx之反向代理服务器
  9. 乱谈卡巴CCTV黄金时段广告
  10. (原)使用vectot的.end()报错:iterators incompatible
  11. php bc 比较,php BC高精确度函数库
  12. BLOB:大数据,大对象,在数据库中用来存储超长文本的数据,例如图片等
  13. Linux系统下init进程的前世今生
  14. 信息系统分析与设计 第三章 信息系统建设概论
  15. 生产企业全流程生产管控_如何通过创建流程使生产率提高10倍
  16. xcopy 跳过已经存在的_视频课怎么区分数学一二三?考研英语怎么复习?恋练有词句子部分直接跳过?...
  17. 物联网毕设分享 STM32 wifi照明控制系统 - 智能路灯(毕设分享)
  18. 【数学建模】熵值法与多指标评价系统
  19. 2020春招---飞鱼科技 一面面经
  20. sja1000 中断_SJA1000PeliCAN模式下自收发问题

热门文章

  1. [问题已处理]-mac安装cobra失败
  2. 微信小程序-一个跑步app
  3. 联通物联卡哪里可以购买 哪家好
  4. 远程进服务器怎么全屏显示,远程服务器如何全屏显示
  5. 统计学笔记——统计基础(协方差,相关系数,决定系数)
  6. 豆瓣首席架构师洪强宁谈Python语言
  7. 什么是堡垒机?堡垒机的作用?
  8. 【JS】iframe 嵌入页面用法
  9. Altium designer中蛇形线走法和操作说明
  10. Linux 下的DNW