Web Components学习(2)-语法
一、Web Components 对 Vue 的影响
尤雨溪在创建 Vue 的时候大量参考了 Web Components 的语法,下面写个简单示例。
首先写个 Vue 组件 my-span.vue:
<!-- my-span.vue -->
<template><span>my-span</span>
</template><script>
export default {}
</script><style>
span {color: purple;
}
</style>
这是很标准的 Vue 组件,不过非常遗憾的是 HTML 文件并不能有效的利用这个 vue 文件,如果想让它能够正确运行,还需要下载 node、webpack、vue-loader 将其打包,而且它只能在 Vue 的项目中使用,也就是必须依赖 Vue 的安装包。如果在 React、Angular 甚至 jQuery 项目中,这个组件就不能用了。
但是以前只需要将它稍稍修改一下,它就会变成 Web Components 文件,能够直接在浏览器中运行。
只需要修改 <script> 中的 JS 代码和文件后缀:
<!-- my-span.html -->
<template><span>my-span</span>
</template><script>
// 获取 DOM 元素
const dom = document.currentScript.ownerDocument.querySelector('template').content// 有点像 React 定义组件的写法
class MySpan extends HTMLElement {constructor() {super()this.attachShadow({ mode: 'open' }).appendChild(dom)}
}// 注册组件
customElements.define('my-span', MySpan)
</script><style>
span {color: purple;
}
</style>
使用 HTML Imports 在 HTML 页面中引入组件:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title><!-- HTML Imports --><link rel="import" href="my-span.html">
</head>
<body><my-span></my-span>
</body>
</html>
但是现在 HTML Imports 已废弃(被 ES Modules 的代替),所以不能使用这种方式了。
如果还想要以独立模块的方式引入,那么就要通过 JS 生成 HTML 和 CSS:
// my-span.js
class MySpan extends HTMLElement {constructor() {super()this.render()}// 生成 HTML 和 CSSrender() {const shadow = this.attachShadow({ mode: 'open' })const dom = document.createElement('span')const style = document.createElement('style')dom.textContent = 'my-span'style.textContent = `span {color: purple;}`shadow.appendChild(style)shadow.appendChild(dom)}
}// 注册组件
customElements.define('my-span', MySpan)
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title><!-- HTML Imports(已废弃) --><!-- <link rel="import" href="my-span.html"> --><!-- ES Modules --><script type="module" src="my-span.js"></script>
</head>
<body><my-span></my-span>
</body>
</html>
注意:使用 ES Modules 和 HTML Imports 一样,都要开启一个 Web 服务,直接打开 HTML 文件,会以文件协议(file://)的方式打开,控制台会报跨域错误。可以使用 vscode 的 Live Server 插件打开 HTML。或者不使用 ES Modules:
<script src="my-span.js"></script>
也可以提前在 HTML 页面中通过
<template>原生标签写好 DOM 结构,然后在组件中通过 DOM API 获取模板内容,不过这样并没有将组件作为独立的模块分离出来。
如果想使用插槽,只需要将 <slot /> 添加进去:
const dom = document.createElement('span')
const style = document.createElement('style')
// dom.textContent = 'my-span'
dom.innerHTML = '<slot>默认内容</slot>'
style.textContent = `span {color: purple;}
`
使用上也和 Vue 一样:
<!-- 默认内容 -->
<my-span></my-span>
<!-- 自定义内容 -->
<my-span>自定义内容</my-span>
如果想使用具名插槽(多个插槽):
const dom = document.createElement('span')
const style = document.createElement('style')
// dom.textContent = 'my-span'
dom.innerHTML = `<slot>默认内容</slot><slot name="content">默认内容</slot>
`
style.textContent = `span {color: purple;}
`
使用:
<my-span><h1>默认插槽</h1><h2 slot="content">另一个插槽</h2>
</my-span>
Vue 新语法已经建议使用 v-slot,而 Web Components 还是 slot。
二、HTML Imports
Web Components 的历史
Web Components 不是一门单一的技术,而是四门技术的组合,这四门技术分别是:
- HTML Imports
- HTML templates
- Custom Elements
- Shadow DOM
HTML Imports
HTML Imports 就是上面示例中的 用来引入另一个 HTML 文件。
可惜 HTML Imports 已经被废弃,如果想正常使用 HTML Imports 代码查看效果,可以安装低版本浏览器,例如 Chrome 79:

通过上面的示例可以看到 HTML Imports 很好用,为什么会被废弃?这就要讲讲 Web Components 的前世今生了。
很多人都认为 Google 是一个比 IE 还“遵纪守法”的好公民,因为它一直遵守 W3C、ECMA 的标准,才可以得以干掉 IE 成为浏览器市场的占有率之王。
其实 Google 可不老实,它经常会倒逼标准的形成。比方说 Google 自己实现了一个 CSS 属性,那时候 W3C 并没有发布标准,于是它就在自己自创的属性前加个前缀 -webkit-,这代表只是它自己浏览器的实验性属性,并没有破坏标准私自发布属性。
可是开发者觉得这个属性真的很好用,可以实现很酷炫的效果,其他浏览器的厂商有的是觉得这个属性确实很不错,而有的是感觉到了压力,总而言之,所有浏览器厂商最终都实现了这个属性,为了表示自己也没有破坏标准私自发布属性,大家都默默地在这个属性前面加上自己浏览器内核的前缀,像 -moz-、-ms-、-o-。
虽然这个属性没有在 W3C 等机构成为标准,但它已经成为了**“事实标准”**,世界各地的开发者们也都已经用这个属性实现出来成千上万个网站了,最终也不得不把它标为标准。于是 Google 最终自己研究出来的属性就这样成为了标准。大家再也不用写那么烦人的前缀了。Web Components 也正是基于这样的一种情况下诞生的。
话说在 2011 年的时候 Google 就推出了 Web Components 的概念,当时前端还没有**“模块化”的概念,甚至都没有“前端”**的概念,这个时期 Google 就已经敏锐的察觉到前端需要组件化,但最开始他们也只是提出了这个概念,并没有开发出真正能用的前端组件化。
2015 年 Web Components 终于能用了,所以网上开始有人介绍 Web Components,这也是为什么网上大部分 Web Components 文章都是 2015 - 2016 写的(内容还包括 HTML Imports)。
那么为什么这么多年过去了,Web Components 还没有火起来呢?
因为 Google 的做法引起了其他浏览器厂商的不满,凭什么这么重要的新功能就你一家说了算,平时你实现的 CSS3 属性啥的,我们睁一只眼闭一只眼也就算了,可 Web Components 是非常重大的一项功能,API 长什么样子都是你自己定,我们不同意。于是 Web Components 的第一版,也就是 V0,就只有 Google 自己实现了。
Google 也意识到,虽然自己目前市场占有率全球称霸,但只要其它浏览器不支持还是不会有人用,毕竟大家都要考虑兼容性的问题,不可能只考虑用 Google 内核的用户上网才能够看到效果,其它浏览器就不管。
所以 Google 决定,和其它主流浏览器厂商一起讨论一下,在讨论中大家就产生了激烈的分歧,比如苹果系统的浏览器 Safari 觉得 Shadow DOM 应该始终保持封闭以保证独立性,而 Google 则认为要始终保持开放,让用户能够访问到,不然 Web Components 组件库在用户的眼中始终是一个无法窥视内部构造的黑盒;还有火狐浏览器觉得马上要出 ES6 了,HTML Imports 不用实现,先看看 ES6 的模块化怎么样,感觉它也能代替 HTML Imports 的功能。
于是根据各个浏览器厂商的不满,又修订了第二个版本:V1,这正是目前使用的版本。就在各大浏览器厂商不断扯皮的过程中,三大框架崛起了:Angular、React、Vue,它们都有组件化的功能,于是其它浏览器厂商实现 Web Components 的动力就有点不足了,本来实现起来就挺复杂的,现在更不想实现了。
但是几年过后,大家发现浏览器真的需要一个原生的组件化技术,开发者们也一直都在询问到底为什么就是不实现 Web Components。
基于种种压力之下,Safari 在 2017 年实现了 Web Components,当然只实现了一部分,因为他们至今都不是很认同 Google 的 is 属性(类似 Vue 的 is 属性),所以他们就是不实现,反正 Web Components 还没有成为标准(2017 年),这也不算不遵守规范。
而火狐则是在 2018 年实现的 Web Components。
微软的 Edge 浏览器现在改用 Google 的内核了,IE 就不要提了。
Opera 也早就改用 Google 内核了。
至此所有浏览器都实现了 Web Components,不过它终究还是来的太晚了点,三大框架早已瓜分了市场,形成了三足鼎立的局面。但之后随着时间的推移,三大框架有可能会用 Web Components 去实现自己底层的组件化系统。
而 Vue CLI 早就实现了能将 Vue 组件编译成 Web Components 的功能。
而且一些组件库为了能够跨框架运行,也是采用了 Web Components 来实现,比如 Taro 3 为了能够让写不同框架的的人都能用上组件,特意采用了 Web Components 来实现的基础组件。
既然 HTML Imports 已经废弃,这里也不再学习它的具体用法。但可以介绍一下它的下一代技术 HTML Modules。
下面是一个无法运行的示例:
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Document</title>
</head>
<body><script type="module">import A from './component.html'</script>
</body>
</html>
<!-- component.html -->
<template></template><script type="module"></script>
目前还没有任何浏览器实现了这一提案,所以上例代码无法演示,而且这种写法目前来说争议非常大,因为在<script>标签里引入了一个 HTML 文件,之所以要这么做,是因为 <template> 通常就是用来引入到 JS 文件里使用的。
下面介绍 Web Components 中最重要的一项技术,同时也是所有浏览器都没有提出反对意见,一致通过的一项技术 —— Custom Elements(自定义元素)。
Shadow DOM 和 HTML templates( and slots) 目前主流浏览器也同样支持,通常都会应用于 Custom Elements,前者是用于封装独立于主文档的 DOM,后者类似 Vue 的 Slot,本文不作详解。
Custom Elements 自定义元素
MDN:使用 custom elements
基础使用
window 全局对象上有一个 customElements 提供自定义元素支持,它包含四个 API:
- define:注册/定义自定义元素
- get:获取自定义元素的构造函数
- whenDefined:
- upgrade:
- define 示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Custom Elements</title></head><body><!-- 使用元素 --><long-time-no-see></long-time-no-see><!-- 不能写成自闭和标签,浏览器会当作起始标签包裹后面的全部内容 --><!-- <long-time-no-see /> --><script>// 注册组件(自定义元素)window.customElements.define(// 参数1:元素名,必须包含一个短横线,以区分原生元素'long-time-no-see',// 参数2:用于定义元素行为的类(类似 React 中的类组件),必须继承自 HTMLElementclass extends HTMLElement {constructor() {super()// custome elements 类中的 this 指向组件本身console.log(this)this.innerHTML = '<h1>好久不见</h1>'this.onclick = () => alert('你还好吗')}})// 多次注册相同名称的组件会报错:// the name "long-time-no-see" has already been used with this registry// window.customElements.define('long-time-no-see', class extends HTMLElement {})// 获取自定义元素的构造函数console.log(customElements.get('long-time-no-see'))// 如果获取的是一个并没有被定义的元素,则返回 undefined// 使用场景1:用于判断组件是否已被注册过// 使用场景2:扩展第三方组件console.log(customElements.get('long-time-no-see1'))</script></body>
</html>
get 示例
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Custom Elements</title></head><body><!-- 扩展第三方组件 --><my-bubbles click>我扩展的 bubbles</my-bubbles><script type="module">import { FcBubbles } from 'https://unpkg.com/fancy-components'// 注册组件new FcBubbles()// 获取第三方组件的构造函数,用于继承扩展const FcBubblesConstructor = customElements.get('fc-bubbles')customElements.define('my-bubbles',class extends FcBubblesConstructor {constructor() {super()this.onclick = () => console.log('自定义点击事件')}})</script></body>
</html>
whenDefined 示例
通常都会将
当渲染引擎读取到自定义元素的时候,并不知道它是什么元素(此时注册脚本还没执行),一般来说当渲染引擎碰到一个不认识的元素的时候,会认为这是一个无效的元素。
不过自定义元素的命名规则要求必须包含短横杠 -,是为了和原生元素区分开,所有当渲染引擎看到一个不认识的元素,但是名称中带有横杠连字符,会将它认为是一个未定义的自定义元素,不会当作一个无效元素。当执行到注册自定义元素的代码时,就会将之前未定义的元素标记为定义的元素。
定义的元素对应的伪类选择器就是 :defined,未定义的元素对应的伪类选择器就是 :not(:defined)
通过这个伪类选择器,可以在定义元素之前的空白时间内,设置自定义元素的加载样式。
whenDefine 是元素定义后触发的回调,通常用于异步注册组件的时候:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Custom Elements</title><style>:not(:defined) {width: 120px;height: 60px;background: gray linear-gradient(-60deg, transparent, transparent 20%, white 40%, transparent 60%) 0 / 300%;border-radius: 15px;animation: loading 2s infinite;display: grid;place-items: center;}@keyframes loading {to {background-position: 300% 0;}}</style></head><body><long-time-no-see>Loading</long-time-no-see><script>// 模拟 JS 代码执行延迟setTimeout(() => {customElements.define('long-time-no-see',class extends HTMLElement {})}, 3000)// 返回一个 PromisecustomElements.whenDefined('long-time-no-see').then(() => {document.querySelector('long-time-no-see').innerHTML = '好久不见'}).catch(err => console.log(err))</script></body>
</html>
upgrade 示例
upgrade 是升级的意思,如果在定义元素之前先使用 JS 创建了元素,则元素实例并不是继承的定义元素行为的类,可以使用 upgrade 将其升级为期望的样子:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>Custom Elements</title></head><body><script>// 先使用 JS 创建自定义元素const el = document.createElement('vue-react')// 再注册自定义元素class VueReact extends HTMLElement {}customElements.define('vue-react', VueReact)// 返回 falseconsole.log(el instanceof VueReact)// 升级元素customElements.upgrade(el)// 返回 trueconsole.log(el instanceof VueReact)</script></body>
</html>

生命周期
我们经常会在组件的初始阶段设置监听器,在组件的挂载阶段获取 DOM 元素,在组件的更新阶段发送一些 ajax 请求,在组件的卸载阶段做一些清理操作(例如移除定时器)。
Web Components 的生命周期比 Vue 和 React 的都要少。
下面通过 Vue 的生命周期来对比 Web Components 的生命周期:

connectedCallback vs mounted
Vue 和 React 都是靠一个根元素(Root)来实现的,默认 Vue 里是一个 id 为 app 的元素,React 中是一个 id 为 root 的根元素:
<div id="app"></div>
一开始 DOM 都是空的,是靠 JavaScript 动态生成的 DOM,然后再往里填充:
const component = document.createElement('h1')
它需要挂载到 HTML 页面上才能显示:
const root = document.getElementById('app')
root.append(component)
所以这个过程叫挂载,而对应的生命周期命名为 mounted。
而自定义元素组件通常是先在 HTML 中编写组件,浏览器会先解析到它:
<life-cycle></life-cycle>
然后浏览器继续解析到定义它的 JS 代码时,就会将其与 JS 定义的元素(构造函数中的 this)进行连接:
customElements.define('life-cycle', class extends HTMLElement {})
这个连接的过程和 Vue、React 挂载的过程有很大的区别,所以它叫 connectedCallback。
adoptedCallback 示例
adopt 是收养的意思,DOM API document.adoptNode可以剪切文档(包括另一个文档)中的节点,可以通过它将其它文档上的节点剪切到当前文档中使用,这个过程可以成为“收养(adopt)”,例如:
<!-- iframe.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>iframe</title>
</head>
<body><h1>我来自 iframe</h1>
</body>
</html>
<!-- index.html -->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /></head><body><iframe src="./iframe.html"></iframe><script>const iframe = document.querySelector('iframe')iframe.onload = () => {const dom = iframe.contentDocument.querySelector('h1')// 剪切元素const adoptDom = document.adoptNode(dom)// 添加到当前文档document.body.append(adoptDom)}</script></body>
</html>
注意:要开启一个 web 服务访问页面,否则获取不到 iframe 的内容。并且要访问 iframe 的内容还要符合同源要求。
而 Web Components 的 adoptedCallback 生命周期回调指的是元素被移动(剪切)到新的文档时被调用,正符合这个场景:
<!-- iframe.html -->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><title>iframe</title></head><body><life-cycle>我来自 iframe</life-cycle><script>customElements.define('life-cycle',class extends HTMLElement {constructor() {super()// 相当于 Vue3 的 setupconsole.log('constructor')}connectedCallback() {// 相当于 Vue 的 mountedconsole.log('connected')}disconnectedCallback() {// 相当于 Vue 的 unmountedconsole.log('disconnected')}adoptedCallback() {console.log('adopted')}})</script></body>
</html>
<!-- index.html -->
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /></head><body><iframe src="./iframe.html"></iframe><script>const iframe = document.querySelector('iframe')iframe.onload = () => {const dom = iframe.contentDocument.querySelector('life-cycle')// 剪切元素const adoptDom = document.adoptNode(dom)// 添加到当前文档document.body.append(adoptDom)}</script></body>
</html>
该示例可以查看不同生命周期函数触发的时机。
相关文章:
Web Components学习(2)-语法
一、Web Components 对 Vue 的影响 尤雨溪在创建 Vue 的时候大量参考了 Web Components 的语法,下面写个简单示例。 首先写个 Vue 组件 my-span.vue: <!-- my-span.vue --> <template><span>my-span</span> </template>…...
Lesson 9.2 随机森林回归器的参数
文章目录一、弱分类器的结构1. 分枝标准与特征重要性2. 调节树结构来控制过拟合二、弱分类器的数量三、弱分类器训练的数据1. 样本的随机抽样2. 特征的随机抽样3. 随机抽样的模式四、弱分类器的其他参数在开始学习之前,先导入我们需要的库。 import numpy as np im…...
Kubernetes Secret简介
Secret概述 前面文章中学习ConfigMap的时候,我们说ConfigMap这个资源对象是Kubernetes当中非常重要的一个对象,一般情况下ConfigMap是用来存储一些非安全的配置信息,如果涉及到一些安全相关的数据的话用ConfigMap就非常不妥了,因…...
Redis 哨兵(Sentinel)
文章目录1.概述2. 没有哨兵下主从效果3.搭建多哨兵3.1 新建目录3.2 复制redis3.3 复制配置文件3.4 修改配置文件3.5 启动主从3.6 启动三个哨兵3.7 查看日志3.8 测试宕机1.概述 在redis主从默认是只有主具备写的能力,而从只能读。如果主宕机,整个节点不具…...
精读笔记 - How to backdoor Federated Learning
文章目录 精读笔记 - How to backdoor Federated Learning1. 基本信息2. 系统概要3. 攻击模型3.1 问题形式化定义3.1.1 前提假设3.1.2 攻击目标3.2 创新点3.2.1 Semantic Backdoor3.2.2 攻击方法4. 实验验证4.1 图像分类4.2 实验操作4.2.1 超参数设置4.2.2 衡量标准4.3 结果分析…...
即时通讯系列-N-客户端如何在推拉结合的模式下保证消息的可靠性展示
结论先行 原则: server拉取的消息一定是连续的原则: 端侧记录的消息的连续段有两个作用: 1. 记录消息的连续性, 即起始中间没有断层, 2. 消息连续, 同时意味着消息是最新的,消息不是过期的。同…...
关于js数据类型的理解
目录标题一、js数据类型分为 基本数据类型和引用数据类型二、区别:传值和传址三、深浅拷贝传值四、数据类型的判断一、js数据类型分为 基本数据类型和引用数据类型 1、基本数据类型 Number、String、Boolean、Null、undefined、BigInt、Symbol 2、引用数据类型 像对…...
大一上计算机期末考试考点
RGB颜色模型也称为相加混色模型 采样频率大于或等于原始声音信号最高频率的两倍即可还原出原始信号. 声音数字化过程中,采样是把时间上连续的模拟信号在时间轴上离散化的过程。 量化的主要工作就是将幅度上连续取值的每一个样本转换为离散值表示。 图像数字化过…...
微搭问搭001-如何清空表单的数据
韩老师,我点关闭按钮后,弹窗从新打开,里面的数据还在,这个可以从新打开清除不? 点关闭的时候清掉 就是清楚不掉也?咋清掉 清掉表单内容有属性可以做到? $page.widgets.id**.value “” 就可以实…...
Windows7,10使用:Vagrant+VirtualBox 安装 centos7
一、Vagrant,VirtualBox 是什么二、版本说明1、win7下建议安装版本2、win10下建议安装版本三、Windows7下安装1、安装Vagrant2、安装VirtualBox3、打开VirtualBox,配置虚拟机默认安装地址四、windows7下载.box文件,安装centos 71、下载一个.b…...
基于JavaEE开发博客系统项目开发与设计(附源码)
文章目录1.项目介绍2.项目模块3.项目效果1.项目介绍 这是一个基于JavaEE开发的一个博客系统。实现了博客的基本功能,前台页面可以进行文章浏览,关键词搜索,登录注册;登陆后支持对文章进行感谢、评论;然后还可以对评论…...
Android Framework——zygote 启动 SystemServer
概述 在Android系统中,所有的应用程序进程以及系统服务进程SystemServer都是由Zygote进程孕育(fork)出来的,这也许就是为什么要把它称为Zygote(受精卵)的原因吧。由于Zygote进程在Android系统中有着如此重…...
在ubuntu上搭建SSH和FTP和NFS和TFTP
一、SSH服务搭建使用如下命令安装 SSH 服务;ssh 的配置文件为/etc/ssh/sshd_config,使用默认配置即可。sudo apt-get install openssh-server开启 SSH 服务以后我们就可以在 Windwos 下使用终端软件登陆到 Ubuntu,比如使用 Mobaxterm。二、FT…...
ThinkPHP 6.1 模板篇之文件加载
本文主要讲述模板中如何使用包含文件、引入css/js文件及路径优化。 包含文件 使用{include}标签来加载公用重复的文件,比如头部、尾部和导航部分 包含用法 1.创建公用文件 在模版 view 目录创建一个 common公共目录,分别创建 header、footer 和 nav …...
操作系统内核与安全分析课程笔记【1】链表、汇编与makefile
文章目录链表循环双向链表哈希链表其他链表汇编内联汇编扩展内联汇编makefile链表 链表是linux内核中关键的数据结构。在第二次课中,重点介绍了循环双向链表和哈希链表。这两种链表都在传统的双向链表的基础之上进行了针对效率的优化。(ps:这部分可以通…...
华为OD机试题 - 九宫格按键输入(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 华为OD机试题 最近更新的博客使用说明本篇题解:九宫格按键输入题目输入输出示例一输入输出说明示例二输入输出说…...
PMSM控制_foc 控制环路
整个系统的控制过程有以下部分,以无感FOC,双电阻电流采样,控制周期为 10KHz 为例: 1、在每隔一个 PWM 周期采样一次两相电流 2、进行 FOC 的计算 (1)clarke 变换,将电流变换至静止坐标系下的 Ia…...
Linux 练习七 (IPC 共享内存)
文章目录System V 共享内存机制:shmget shmat shmdt shmctl案例一:有亲缘关系的进程通信案例二:非亲缘关系的进程通信内存写端write1.c内存读端read1.c案例三:不同程序之间的进程通信程序一,写者shmwr.c程序二…...
【数据库原理复习】ch4 完整性约束 SQL定义
这里写目录标题基本概念实体完整性参照完整性违规处理用户自定义完整性约束条件定义完整性约束命名字句基本概念 完整性约束主要包括 实体完整性参照完整性用户自定义完整性 实体完整性 关系模型中实体完整性通常在建表时候添加primary key完成 # primary key定义 create …...
【2023年的就业形势依旧严峻】
2023年口罩放开的第一年,也是第一个招聘会,挤满了求职者和用人单位,大多数都是想着重新开始,抓住金三银四的好时机,找到心仪的工作和符合岗位要求的人才,一起整装出发。我们理想的状态是,经济已…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
label-studio的使用教程(导入本地路径)
文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
python/java环境配置
环境变量放一起 python: 1.首先下载Python Python下载地址:Download Python | Python.org downloads ---windows -- 64 2.安装Python 下面两个,然后自定义,全选 可以把前4个选上 3.环境配置 1)搜高级系统设置 2…...
大语言模型如何处理长文本?常用文本分割技术详解
为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...
[10-3]软件I2C读写MPU6050 江协科技学习笔记(16个知识点)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
