当前位置: 首页 > news >正文

【小程序 - 大智慧】Expareser 组件渲染框架

5.png


目录

  • 问题思考
  • 课程目标
  • Web Component
    • 类型说明
    • 定义组件
    • 属性添加
  • Shadow DOM
  • Template and Slot
  • Exparser 框架原理
    • 自定义组件
    • 内置组件
  • 下周计划


问题思考

首先,给大家抛出去几个问题:

  1. 前端框架 Vue React 都有自己的组件库,但是并不兼容,那么 不依赖框架能 自定义组件 吗?
  2. 微信小程序开发的时候都会自定义组件是吧,那么调试控制台出现的 shadow-root 是什么,有注意吗?
  3. 微信小程序编写 wxml 的时候,为什么和 html 语法不一致,多出来 view text 这些标签,里面究竟是如何实现的,彼此有什么关联?

课程目标

通过本节课程的学习,希望大家掌握如下的目标:

  1. 弄懂上述问题背后的执行逻辑
  2. 能够利用原生 Web Component 自定义一个简易的组件

Web Component

使用自定义元素 - Web API | MDN

Web Component直译过来就是 web 组件的意思,就是说明离开了前端框架的帮助,我们依然可以用原生组件来进行开发复用。

类型说明

如同官网所说,继承特定元素类得到的组件是 自定义内置元素组件(可以得到特定类型的属性和方法),继承元素基类得到的组件是 独立自定义元素,本质上两种没什么区别,接下来我们重点就放在第二个上面。

定义组件

<button is="my-button-one">内置按钮</button>
<my-button-two></my-button-two>// 01 定义一个内置元素的按钮
class MyButtonOne extends HTMLButtonElement {constructor() {self = super();}// 元素添加到文档调用connectedCallback() {// 1.创建一个 divconst div = document.createElement("div");// 2.设置 div 的样式div.style.width = "100px";div.style.height = "50px";div.style.textAlign = "center";div.style.lineHeight = "50px";div.style.cursor = "pointer";self.style.marginBottom = "20px";// 3.设置 div 的内容div.innerHTML = "自定义按钮";// 4.将 div 添加到页面self.appendChild(div);}
}// 02 定义一个自定义的按钮
class MyButtonTwo extends HTMLElement {constructor() {// 先调用父类构造器,实例化 HTMLElement ,这样才能有 html 元素的基本属性super();}// 元素添加到文档调用connectedCallback() {console.log("自定义元素添加到页面", this);// 1.创建一个 divconst div = document.createElement("div");// 2.设置 div 的样式div.style.width = "100px";div.style.height = "50px";div.style.backgroundColor = "red";div.style.color = "white";div.style.textAlign = "center";div.style.lineHeight = "50px";div.style.cursor = "pointer";// 3.设置 div 的内容div.innerHTML = "自定义按钮";// 4.将 div 添加到页面this.appendChild(div);}// 元素从文档中移除时调用disconnectedCallback() {console.log("自定义元素从页面移除");}// 元素被移动到新文档时调用adoptedCallback() {console.log("自定义元素被移动到新文档");}// 监听属性变化attributeChangedCallback(name, oldValue, newValue) {console.log(`属性 ${name} 已由 ${oldValue} 变更为 ${newValue}`);}
}// 组件注册
customElements.define("my-button-one", MyButtonOne, { extends: "button" });
customElements.define("my-button-two", MyButtonTwo);// 监听组件状态
customElements.whenDefined("my-button-two").then(() => {console.log("my-button-two 组件已定义");
});

自定义组件的命名规则是有限制的:

  • 自定义元素的名称,必须包含短横线(-)。它可以确保html解析器能够区分常规元素和自定义元素,还能确保html标记的兼容性。
  • 自定义元素只能一次定义一个,一旦定义无法撤回。
  • 自定义元素不能单标记封闭。比如 <custom-component />,必须写一对开闭标记。比如 <custom-component></custom-component>

上面两个就是最基本的自定义组件,但是这个也没有样式 class 属性传值 事件方法都没有,下面我们一步步加上。

属性添加

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><style>* {margin: 0;padding: 0;}body {width: 100px;margin: 200px auto;background-color: #f5f5f5;}.my-button-two {width: 180px;height: 50px;background-color: red;color: white;text-align: center;line-height: 50px;cursor: pointer;}</style><my-button-two color="pink" text="Custom Component" @click="clickButton()"></my-button-two><title>02_属性添加</title></head><body><script>// 自定义方法const clickButton = () => {alert("点击了自定义按钮");};class MyButtonTwo extends HTMLElement {// 监控属性变化static observedAttributes = ["color", "text", "@click"];constructor() {// 先调用父类构造器,实例化 HTMLElement ,这样才能有 html 元素的基本属性super();}// 元素添加到文档调用connectedCallback() {// 1.创建一个 divconst div = document.createElement("div");// 2.设置 div 的样式div.className = "my-button-two";// 3.设置 div 的内容const bgColor = this.getAttribute("color");const textValue = this.getAttribute("text");const clickValue = this.getAttribute("@click");// 需要在同一个 js 执行环境内部执行div.addEventListener("click", () => {eval(clickValue);});div.style.backgroundColor = bgColor;div.innerHTML = textValue;// 4.将 div 添加到页面this.appendChild(div);}// 元素从文档中移除时调用disconnectedCallback() {console.log("自定义元素从页面移除");}// 元素被移动到新文档时调用adoptedCallback() {console.log("自定义元素被移动到新文档");}// 监听属性变化attributeChangedCallback(name, oldValue, newValue) {console.log(`属性 ${name} 已由 ${oldValue} 变更为 ${newValue}`);}}customElements.define("my-button-two", MyButtonTwo);// 监听组件状态customElements.whenDefined("my-button-two").then(() => {console.log("my-button-two 组件已定义");});</script></body>
</html>

对着调试控制台我们可以发现,当前 html 写的样式可以影响到组件内部,这并不符合我们之前说的组件和外部彼此 属性隔离 的特点,这就需要了解到下一个概念了。

Shadow DOM

使用影子 DOM - Web API | MDN

影子 DOM(Shadow DOM)允许你将一个 DOM 树附加到一个元素上,并且使该树的内部对于在页面中运行的 JavaScriptCSS 是隐藏的。

在这里插入图片描述

有一些 影子 DOM 术语 需要注意:

  • 影子宿主(Shadow host):影子 DOM 附加到的常规 DOM 节点。
  • 影子树(Shadow tree):影子 DOM 内部的 DOM 树。
  • 影子边界(Shadow boundary):影子 DOM 终止,常规 DOM 开始的地方。
  • 影子根(Shadow root):影子树的根节点。

这里的 影子宿主(Shadow host) 可以选取普通的 div 标签,但是由于我们是自定义元素,这里的 挂载节点 就是 自定义组件 Web Component 了,接下来我们举一个例子:

const shadow = this.attachShadow({ mode: "open" });// 这里的 this 就是标识 自定义组件 DOM 元素
// mode 分为 open closed 表示能否通过 dom.shadowRoot 获取
// 不能获取的话,只能在内部通过 shadow 访问了
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><style>* {margin: 0;padding: 0;}body {width: 100px;margin: 200px auto;background-color: #f5f5f5;}.my-button-two {width: 180px;height: 50px;background-color: red;color: white;text-align: center;line-height: 50px;cursor: pointer;}</style><my-button-two color="pink" text="Custom Component" @click="clickButton()"></my-button-two><title>03_shadow dom</title></head><body><script>// 自定义方法const clickButton = () => {alert("点击了自定义按钮");};class MyButtonTwo extends HTMLElement {// 监控属性变化static observedAttributes = ["color", "text", "@click"];constructor() {// 先调用父类构造器,实例化 HTMLElement ,这样才能有 html 元素的基本属性super();}// 元素添加到文档调用connectedCallback() {// 隔离 DOMconst shadow = this.attachShadow({ mode: "open" });// 1.创建一个 divconst div = document.createElement("div");// 2.设置 div 的样式div.className = "my-button-two";// 3.设置 div 的内容const bgColor = this.getAttribute("color");const textValue = this.getAttribute("text");const clickValue = this.getAttribute("@click");// 需要在同一个 js 执行环境内部执行div.addEventListener("click", () => {eval(clickValue);});div.style.backgroundColor = bgColor;div.innerHTML = textValue;// 4.将 div 添加到页面shadow.appendChild(div);}// 元素从文档中移除时调用disconnectedCallback() {console.log("自定义元素从页面移除");}// 元素被移动到新文档时调用adoptedCallback() {console.log("自定义元素被移动到新文档");}// 监听属性变化attributeChangedCallback(name, oldValue, newValue) {console.log(`属性 ${name} 已由 ${oldValue} 变更为 ${newValue}`);}}customElements.define("my-button-two", MyButtonTwo);// 监听组件状态customElements.whenDefined("my-button-two").then(() => {console.log("my-button-two 组件已定义");});</script></body>
</html>

这里我们可以看到 文档的样式已经无法影响我们的自定义组件了,这是因为被 shadow 阻隔了,接下来就可以继续完善这段逻辑了。

Template and Slot

使用模板和插槽 - Web API | MDN

前端组件开发中有两套我们熟悉的 Template(模板)和 Slot(插槽),接下来就利用这两个功能继续完善一下我们的代码逻辑。

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><style>* {margin: 0;padding: 0;}body {width: 100px;margin: 200px auto;background-color: #f5f5f5;}.my-button-two {width: 180px;height: 50px;background-color: red;color: white;text-align: center;line-height: 50px;cursor: pointer;}</style><template id="button-template"><style>.my-button-two {width: 180px;height: 50px;background-color: red;color: white;text-align: center;line-height: 50px;cursor: pointer;}</style><div class="my-button-two"><slot name="text"></slot></div></template><my-button-two id="my-button-two" color="pink" @click="clickButton()"><span slot="text">Custom Component</span></my-button-two><title>04_Tempalte and Slot</title></head><body><script>// 自定义方法const clickButton = () => {alert("点击了自定义按钮");};class MyButtonTwo extends HTMLElement {// 监控属性变化static observedAttributes = ["color", "text", "@click"];constructor() {// 先调用父类构造器,实例化 HTMLElement ,这样才能有 html 元素的基本属性super();}// 元素添加到文档调用connectedCallback() {// 隔离 DOMconst shadow = this.attachShadow({ mode: "closed" });// 1.获取模板const template = document.querySelector("#button-template");// 2.克隆模板const content = template.content.cloneNode(true);// 3.显示文本const clickValue = this.getAttribute("@click");// 4.执行函数const clickEvent = content.querySelector(".my-button-two");clickEvent.addEventListener("click", () => {eval(clickValue);});// 5.将 template 添加到页面shadow.appendChild(content);}// 元素从文档中移除时调用disconnectedCallback() {console.log("自定义元素从页面移除");}// 元素被移动到新文档时调用adoptedCallback() {console.log("自定义元素被移动到新文档");}// 监听属性变化attributeChangedCallback(name, oldValue, newValue) {console.log(`属性 ${name} 已由 ${oldValue} 变更为 ${newValue}`);}}customElements.define("my-button-two", MyButtonTwo);// 监听组件状态customElements.whenDefined("my-button-two").then(() => {console.log("my-button-two 组件已定义");});</script></body>
</html>

艺龙酒店科技官网

举例 video 标签就是利用这套机制封装的…

Exparser 框架原理

Exparser 是微信小程序的组件组织框架,内置在小程序基础库中,为小程序提供各种各样的组件支撑。内置组件和自定义组件都有 Exparser 组织管理。

Exparser 的组件模型与 WebComponents 标准中的 Shadow DOM 高度相似,Exparser 会维护整个页面的节点树相关信息,包括节点的属性、事件绑定等,相当于一个简化版的 Shadow DOM 实现。Exparser 的主要特点包括以下几点:

  • 基于 Shadow DOM 模型:模型上与 WebComponentsShadow DOM 高度相似,但不依赖浏览器的原生支持,也没有其他依赖库;实现时,还针对性地增加了其他 API 以支持小程序组件编程。
  • 可在纯 JS 环境中运行:这意味着逻辑层也具有一定的组件树组织能力。
  • 高效轻量:性能表现好,在组件实例极多的环境下表现尤其优异,同时代码尺寸也较小。

自定义组件

上图是小程序利用 shadow dom 实现 样式和JS 逻辑隔离的组件,这只是第一层,里面的 view text 也是由 Exparser 从普通 div span 封装得来的,接下来让我们深入了解下:

内置组件

接下来带大家一步步过一遍微信小程序内置组件是如何渲染的

// 1.在微信开发工具找到解析命令 wcc
// wcc 是将 wxml 解析为 js 文件,然后逻辑线程注入 webview 执行的
微信web开发者工具\code\package.nw\node_modules\wcc-exec// 2.将命令文件移动到文件目录下,开始执行解析
./wcc -js index.wxml >> dom.js

  • 可以看到本质上就是一个封装好的 $gwx 函数,它的作用是生成微信自定义的组件和虚拟 dom 节点( diff 算法),用来给后面的 Exparser 生成真实的 DOM 节点
  • 那这个函数是在哪里调用的呢,我们继续向下看
// 1. 调试控制台打开当前页面的 webview
document.getElementsByTagName('webview')
document.getElementsByTagName('webview')[0].showDevTools(true, null)// 2. 可以发现编译后的 wxml 会利用 js 脚本以一定格式插入到页面中执行
var decodeName = decodeURI("./pages/command_component/index.wxml")
var generateFunc = $gwx(decodeName)generateFunc()// 3.传入数据
generateFunc({logs:[1,2,3]})


<view wx:for="{{ logs }}" wx:key="index"><text>{{ item }}</text>
</view>

可以看到如上图所示的虚拟节点数组,接下来我们详细剖析一下

  1. $gwx(decodeName) 不直接返回 dom 树,而是返回一个函数的原因是因为需要动态注入和相关配置,函数能够很好的把控时机
  2. 利用动态传参我们发现,包含循环数组和 key 的会带有 virtual 标识,用来后面的 DIff 算法比较
  3. document.dispatchEvent 触发自定义事件 将 generateFunc 当作参数传递给底层渲染库

  1. 可以看得到无论是 view 还是 text 底层都是通过 div span 的自定义组件构成的
  2. 这一切来源于 Exparser 框架,在 渲染层 会内置一系列方法,大致和上面自定义 web component 一致,进行对组件的定义,注册后将 js 脚本引入页面,那么当前页面就可用了
  3. 接下来带大家进行源码的拆解

下周计划

  1. 继续深入小程序原理(收益不高)
  2. 扩展前端其他的技术方向(感兴趣建议)
    1. 前端组件库实现拆解
    2. 前端调试能力提升
    3. 前端工程化能够了解

相关文章:

【小程序 - 大智慧】Expareser 组件渲染框架

目录 问题思考课程目标Web Component类型说明定义组件属性添加 Shadow DOMTemplate and SlotExparser 框架原理自定义组件内置组件 下周计划 问题思考 首先&#xff0c;给大家抛出去几个问题&#xff1a; 前端框架 Vue React 都有自己的组件库&#xff0c;但是并不兼容&#…...

vue + echarts 快速入门

vue echarts 快速入门 本案例即有nodejs和vue的基础&#xff0c;又在vue的基础上整合了echarts Nodejs基础 1、Node简介 1.1、为什么学习Nodejs(了解) 轻量级、高性能、可伸缩web服务器前后端JavaScript同构开发简洁高效的前端工程化 1.2、Nodejs能做什么(了解) Node 打破了…...

服务器几核几G几M是什么意思?如何选择?

服务器几核几G几M是什么意思&#xff1f;我们建站、搭建网络平台都要用到云服务器&#xff0c;不管在腾讯云、阿里云还是别的云服务平台选购&#xff0c;都会接触到服务器配置。云服务器就是把物理服务器&#xff08;俗称“母鸡”&#xff09;&#xff0c;用虚拟机技术虚拟出多…...

K8S服务发布

一 、服务发布方式对比 二者主要区别在于&#xff1a; 1、部署复杂性&#xff1a;传统的服务发布方式通常涉及手动配置 和管理服务器、网络设置、负载均衡等&#xff0c;过程相对复 杂且容易出错。相比之下&#xff0c;Kubernetes服务发布方式 通过使用容器编排和自动化部署工…...

Allen Institute for Artificial Intelligence (Ai2) 发布开源多模态语言模型 Molmo

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…...

Html CSS 布局,位置处理 居中 对齐

Html CSS 布局&#xff0c;位置处理 1、居中布局 1、div 让内部div居中对齐 html <div class"container"><div class"item">I am centered!</div> </div>style .container {border: 2px solid rgb(75, 70, 74);border-radius:…...

Spring MVC系统学习(二)——Spring MVC的核心类和注解

Spring MVC&#xff08;Model-View-Controller&#xff09;是Spring框架的一个模块&#xff0c;用于构建基于Web的应用程序。它使用模型、视图和控制器分离的设计模式&#xff0c;使得Web开发更加模块化和灵活。在学习Spring MVC时&#xff0c;有几个核心类和注解是非常关键的&…...

conda虚拟环境安装包、依赖同一管理

在 Python 的虚拟环境中&#xff0c;每个环境都是独立的&#xff0c;这意味着即使两个环境需要相同的库&#xff0c;它们也会分别安装各自的副本。这样做是为了避免不同项目之间相互影响&#xff0c;确保每个项目都有一个干净且隔离的环境。 方法一&#xff1a;使用 Conda 的共…...

Unity网络开发记录(四):在unity中进一步封装客户端类

在上一篇文章中&#xff0c;简单的封装了一下服务端中相关的socket对象&#xff0c;为了可以更方便的使用。所以在本篇中&#xff0c;进一步封装一下在unity中的相关客户端类 封装客户端类&#xff0c;首先采用单例模式&#xff0c;然后采用两个队列来存储我们相关的收发信息 p…...

Linux内核中的UART驱动-详解Linux内核UART驱动:结构与功能分析

一、UART概述 UART&#xff08;Universal Asynchronous Receiver/Transmitter&#xff09;&#xff0c;即通用异步收发器&#xff0c;是一种串行通信接口&#xff0c;用于在计算机和外部设备之间传输数据。它特别适用于短距离、低速、串行和全双工的数据传输。在Linux内核中&a…...

威胁检测与防范:如何及时、准确对抗安全风险

随着技术的飞速发展&#xff0c;网络空间中的威胁日益多样化、隐蔽化&#xff0c;给个人、企业乃至国家的信息安全带来诸多挑战。面对严峻的网络威胁&#xff0c;传统的防火墙、入侵检测系统&#xff08;IDS&#xff09;等防御手段虽能在一定程度上抵御外部攻击&#xff0c;但依…...

数据结构串的kmp相关(求next和nextval)

傻瓜版&#xff0c;用来演示手算过程&#xff0c;个人理解用的&#xff0c;仅供参考。...

创建游戏暂停菜单

创建用户控件 设置样式 , 加一层 背景模糊 提升UI菜单界面质感 , 按钮用 灰色调 编写菜单逻辑 转到第三人称蓝图 推荐用 Set Input Mode Game And UI , 只用仅UI的话 增强输入响应不了 让游戏暂停的话也可以用 Set Game Paused , 打勾就是暂停 , 不打勾就是继续游戏 , 然后…...

seata服务端部署

1.下载seata 官网下载地址&#xff1a;http://seata.io/zh-cn/blog/download.html 或者下载 作者已经下载的压缩包1.4.0 注意&#xff01;&#xff01;&#xff01; 要参考对应的版本&#xff0c;否则可能出现无法正常启动的情况。 参考文档 下载完毕后解压压缩文件 2.修改配…...

理解Python闭包概念

闭包并不只是一个python中的概念&#xff0c;在函数式编程语言中应用较为广泛。理解python中的闭包一方面是能够正确的使用闭包&#xff0c;另一方面可以好好体会和思考闭包的设计思想。 1.概念介绍 首先看一下维基上对闭包的解释&#xff1a; 在计算机科学中&#xff0c;闭包…...

51单片机的教室智能照明系统【proteus仿真+程序+报告+原理图+演示视频】

1、主要功能 该系统由AT89C51/STC89C52单片机LCD1602显示模块DS1302时钟模块光照传感器红外传感器温度传感器LED等模块构成。适用于教室灯光全自动控制、教室节能灯控制、教室智能照明等相似项目。 可实现功能: 1、LCD1602实时显示时间、温度、光照强度等信息 2、光照强度传…...

一款资产进行快速存活验证工具

01工具介绍 &#xff08;下载地址见最后&#xff09; 在日常工作的渗透测试过程中&#xff0c;经常会碰到渗透测试项目&#xff0c;而Web渗透测试通常是渗透项目的重点或者切入口。通常拿到正规项目授权后&#xff0c;会给你一个IP资产列表和对应的Web资产地址&#xff0c;这时…...

I/O中断处理过程

中断优先级包括响应优先级和处理优先级&#xff0c;响应优先级由硬件线路或查询程序的查询顺序决定&#xff0c;不可动态改变。处理优先级可利用中断屏蔽技术动态调整&#xff0c;以实现多重中断。下面来看他们如何运用在中断处理过程中&#xff1a; 中断控制器位于CPU和外设之…...

关于PHP 匿名函数在处理数据结构中的应用

PHP 的匿名函数&#xff08;也称为闭包&#xff09;在处理数据结构时非常有用。它们可以在需要一次性函数的情况下使用&#xff0c;例如数组函数的回调、事件处理或作为其他函数的参数。以下是一些常见的应用场景&#xff1a; 数组操作&#xff1a; 使用 array_map、array_fil…...

安卓13默认使用大鼠标 与配置分析 andriod13默认使用大鼠标 与配置分析

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.彩蛋1.前言 android13里面的鼠标貌似比以前版本的鼠标小了,有些客户想要把这个鼠标改大。这个功能,android有现成的,就在这里,设置 =》无障碍 =》色彩和动画 =》 大号鼠标指针。 我们通过…...

Vim 调用外部命令学习笔记

Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

conda相比python好处

Conda 作为 Python 的环境和包管理工具&#xff0c;相比原生 Python 生态&#xff08;如 pip 虚拟环境&#xff09;有许多独特优势&#xff0c;尤其在多项目管理、依赖处理和跨平台兼容性等方面表现更优。以下是 Conda 的核心好处&#xff1a; 一、一站式环境管理&#xff1a…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

第一篇:Agent2Agent (A2A) 协议——协作式人工智能的黎明

AI 领域的快速发展正在催生一个新时代&#xff0c;智能代理&#xff08;agents&#xff09;不再是孤立的个体&#xff0c;而是能够像一个数字团队一样协作。然而&#xff0c;当前 AI 生态系统的碎片化阻碍了这一愿景的实现&#xff0c;导致了“AI 巴别塔问题”——不同代理之间…...

ip子接口配置及删除

配置永久生效的子接口&#xff0c;2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

佰力博科技与您探讨热释电测量的几种方法

热释电的测量主要涉及热释电系数的测定&#xff0c;这是表征热释电材料性能的重要参数。热释电系数的测量方法主要包括静态法、动态法和积分电荷法。其中&#xff0c;积分电荷法最为常用&#xff0c;其原理是通过测量在电容器上积累的热释电电荷&#xff0c;从而确定热释电系数…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...