探索Web Components
title: 探索Web Components
date: 2024/6/16
updated: 2024/6/16
author: cmdragon
excerpt:
这篇文章介绍了Web Components技术,它允许开发者创建可复用、封装良好的自定义HTML元素,并直接在浏览器中运行,无需依赖外部库。通过组合HTML模板、Shadow DOM、自定义元素和HTML imports,Web Components增强了原生DOM的功能,提高了组件化开发的封装性和可维护性,同时支持组件的生命周期管理和高级设计模式,有利于提升网页应用的性能和开发效率。
categories:
- 前端开发
tags:
- Web Components
- 原生DOM
- 封装性
- 组件化
- 生命周期
- 高级设计
- 性能优化


扫码关注或者微信搜一搜:编程智域 前端至全栈交流与成长
第1章:引言
Web Components的起源与发展
Web Components是一种基于Web标准的新兴技术,旨在解决Web应用程序开发中的可重用组件化问题。Web
Components的核心思想是,将HTML、CSS和JavaScript结合起来,实现可重用、可组合和可封装的组件。
Web Components的起源可以追溯到2011年,由W3C(万维网联盟)提出的一个名为Web Components Specifications(Web
Components规范)的项目。该项目包括四个主要模块:
- Templates and Slots(模板和插槽):提供一种在HTML中声明模板的方式,并在组件中使用插槽来实现内容分发。
- Shadow DOM(影子DOM):提供一种在组件内部创建独立的DOM树,与外部DOM树隔离开来,实现样式和内容的封装。
- Custom Elements(自定义元素):提供一种在HTML中定义和注册新元素的方式,扩展HTML标准元素集。
- Decorators(装饰器):提供一种在组件生命周期中添加额外功能的方式,如属性观察器、事件监听器和生命周期回调。
为什么选择Web Components
Web Components具有以下优点:
- 可重用性:组件可以在不同的项目中重用,提高开发效率和一致性。
- 可组合性:组件可以嵌套和组合,构建更加复杂的UI。
- 可封装性:组件可以在内部实现细节上进行隔离,提高可维护性和可测试性。
- 与现有Web技术的兼容性:Web Components基于Web标准,与HTML、CSS和JavaScript高度兼容。
第2章:基础知识
Web Components概述
Web Components是一系列不同的技术,允许你创建可重用的自定义元素,并且包含了自定义的样式和行为。这些自定义元素可以像标准HTML元素一样使用,并且可以在任何地方重用。Web
Components主要由以下三个技术组成:
- Custom Elements(自定义元素):允许你定义新的HTML元素,这些元素可以包含自己的HTML结构、CSS样式和JavaScript行为。
- Shadow DOM(影子DOM):提供了一种封装方式,使得自定义元素可以拥有自己的DOM树,与页面的其他部分隔离开来,防止样式冲突。
- HTML Templates(HTML模板):提供了一种声明性的方式来定义HTML结构,可以在运行时插入到文档中。
- HTML Imports(HTML导入):允许你导入HTML文档作为模块,虽然这个特性已经被废弃,但它的理念被其他模块化方案所继承。
HTML、CSS和JavaScript基础知识
在深入Web Components之前,你需要具备一定的HTML、CSS和JavaScript基础知识。以下是这些技术的简要概述:
- HTML:超文本标记语言,用于创建网页的结构和内容。
- CSS:层叠样式表,用于设置网页元素的样式,如颜色、字体和布局。
- JavaScript:一种编程语言,用于实现网页的交互性和动态内容。
Shadow DOM和模板模式
Shadow DOM:
Shadow DOM是Web
Components的核心技术之一,它允许你将一个隐藏的、独立的DOM树附加到一个元素上。这个DOM树被称为“影子DOM”,它与主DOM树(即页面上的其他元素)是隔离的。这意味着影子DOM内的样式和行为不会影响到页面上的其他元素,反之亦然。这种隔离性使得Web
Components能够封装自己的样式和行为,而不必担心与其他元素的冲突。
模板模式:
模板模式是Web
Components中用于创建自定义元素的一种方式。它允许你定义一个HTML模板,这个模板包含了自定义元素的HTML结构。然后,你可以使用JavaScript来实例化这个模板,并将其附加到DOM中。模板模式通常与Shadow
DOM结合使用,以实现自定义元素的封装和样式隔离。
通过结合使用Shadow DOM和模板模式,你可以创建出功能强大、可重用的Web Components,这些组件可以在不同的项目中重复使用,并且能够保持自己的样式和行为。
第3章:基础组件开发
template元素和slot的使用
template元素在Web Components中扮演了重要角色,它允许你定义组件的结构和内容。template
标签内可以包含HTML结构,这些结构会被复制到每个组件实例中。slot
元素则用于定义组件内部可以接收内容的地方,外部可以将内容插入到这些slot中,实现了组件的可扩展性。标准中文电码查询 | 一个覆盖广泛主题工具的高效在线平台 (cmdragon.cn)
例如:
<template><div><slot name="header">Default Header</slot><p>Content goes here</p><slot name="footer">Default Footer</slot></div>
</template>
在这个例子中,header和footer是slot,外部可以传递自定义内容替换它们。
custom-element定义与注册
custom-element是Web Components的核心,用于创建自定义的HTML元素。定义一个custom-element通常需要以下步骤:
-
使用
<custom-element>标签定义元素:<custom-element name="my-component"></custom-element> -
实现
connectedCallback和可能的其他生命周期方法,如disconnectedCallback、attributeChangedCallback等:class MyComponent extends HTMLElement {constructor() {super();this.attachShadow({ mode: 'open' });}connectedCallback() {// 在这里添加组件的初始化代码}// 其他生命周期方法... }customElements.define("my-component", MyComponent); -
在
connectedCallback中,将自定义元素的shadowRoot(暗影根)添加到模板中:connectedCallback() {this.shadowRoot.appendChild(this.templateContent); }// 假设templateContent是template元素的内容 const templateContent = document.querySelector('template');
style和link元素在组件中的应用
style元素用于定义组件的样式,通常放在<custom-element>标签内部,或作为<style>标签的外部链接(<link rel="stylesheet">
)。外部样式可以通过import导入到组件内部,这样可以保持样式和组件的封装。
<!-- 内部样式 -->
<style>/* ... */
</style><!-- 外部链接 -->
<link rel="stylesheet" href="styles.css">
在组件内部,可以使用this.shadowRoot来访问和操作样式。例如,添加样式到组件的暗影根:
class MyComponent extends HTMLElement {connectedCallback() {this.shadowRoot.appendChild(this.styleElement);}// ...constructor() {super();this.styleElement = document.createElement('style');this.styleElement.textContent = `/* ... */`;}
}
这样,外部样式可以影响到组件的渲染,同时保持了组件的封装性。
第4章:原生组件与Web Components的对比
原生DOM元素的特性
原生DOM元素是HTML5中直接提供的,它们具有以下特性:
- 简单易用:直接操作DOM元素,API直观,易于学习和使用。
- 广泛支持:所有现代浏览器都内置了对DOM的支持。
- 性能:对于简单的操作,DOM操作通常很快,但复杂操作可能导致性能问题,特别是当涉及到大量元素时。
- 事件处理:DOM提供了丰富的事件模型,可以直接监听和响应元素的事件。
- 样式控制:可以直接通过
style属性或者CSS类来控制元素的样式。
Web Components的优势和局限性
优势:
- 封装性:Web Components提供了一种将HTML、CSS和JavaScript封装在一起的方式,提高了代码的复用性和维护性。
- 组件化:组件可以独立于页面,可以被多个页面复用,减少了代码冗余。
- 自定义元素:可以创建自定义的HTML元素,扩展HTML元素库。
- 数据绑定:通过
<template>和<slot>,可以实现数据驱动的组件结构。
局限性:
- 学习曲线:Web Components的API和概念可能对初学者来说较难理解和掌握。
- 浏览器支持:虽然大部分现代浏览器支持,但一些旧版本浏览器可能不支持,需要使用polyfills或polymer库来弥补。
- 性能:对于复杂的组件,如果处理不当,可能会有性能问题,尤其是在处理大量数据时。
- 工具链:虽然有工具如Web Components Workbox等来优化,但整体工具链相比React、Vue等库可能不够成熟。
兼容性问题与解决方案
- 浏览器兼容性:使用
@webcomponents/webcomponentsjs库或者polyfills(如custom-elements-es5-adapter
)来提供向后兼容性,确保在不支持Web Components的浏览器中运行。 - polyfills:对于一些新特性(如Shadow DOM、HTML Templates等),可以使用polyfills来提供支持。
- Babel和TypeScript:使用这些工具可以将新特性转换为旧版本浏览器可以理解的代码。
- 测试:确保在各种浏览器和版本上进行充分的测试,确保组件的兼容性。
总的来说,Web Components提供了一种更现代、更模块化的开发方式,但开发者需要在兼容性、学习成本和工具成熟度之间权衡。
第5章:自定义元素API
自定义元素API:生命周期方法
在Web Components中,自定义元素有以下几个关键的生命周期方法:
- createdCallback: 当元素被创建(但可能尚未插入到文档中)时调用。这是初始化元素内部状态和处理数据的好时机。
class MyCustomElement extends HTMLElement {createdCallback() {// 初始化元素内部状态}
}
- attachedCallback: 当元素被插入到文档中时调用。这时可以绑定事件和处理DOM操作。
attachedCallback() {this.addEventListener('click', this.handleClick);
}
- detachedCallback: 当元素从文档中移除时调用,可以在这里清理资源。
- attributeChangedCallback: 当元素的属性被修改时调用,可以更新内部状态。
attributeChangedCallback(name, oldValue, newValue) {// 更新属性值
}
- connectedCallback: 在元素被连接到DOM树中(可能是通过
<slot>插入)时调用。
属性绑定和事件处理
- 属性绑定:可以使用
<template>元素的<slot>和<slot-scope>来实现数据绑定,或者使用this.set方法来设置和监听属性。
this.set('myProperty', newValue);
- 事件处理:通过
addEventListener方法添加事件监听器,事件处理函数通常在this上下文中。
addEventListener('click', (event) => {// 处理点击事件
});
与外部数据交互
- 数据绑定:可以使用
<template>和<slot>来绑定外部数据,或者通过@property装饰器声明响应式属性。
@property({ type: String, reflect: true })
myData;
- 事件通信:自定义元素可以通过
customEvent来触发自定义事件,外部可以通过addEventListener监听这些事件。
this.dispatchEvent(new CustomEvent('myCustomEvent', { detail: data }));
- 数据交互API:使用
fetch、XMLHttpRequest或Web API(如localStorage、IndexedDB)来获取和存储数据。
第6章:高级组件设计
高阶组件(Higher-Order Components, HOCs)
高阶组件(HOCs)是React中用于重用组件逻辑的高级技术。HOC是一个函数,它接受一个组件并返回一个新的组件。HOC可以用来封装组件,使其更易于重用和测试。
示例代码:
import React from 'react';// 定义一个HOC
function withSubscription(WrappedComponent, selectData) {// ...并返回一个新组件...return class extends React.Component {constructor(props) {super(props);this.handleChange = this.handleChange.bind(this);this.state = {data: selectData(DataSource, props)};}componentDidMount() {// ...那数据源...并订阅变化...DataSource.addChangeListener(this.handleChange);}componentWillUnmount() {DataSource.removeChangeListener(this.handleChange);}handleChange() {this.setState({data: selectData(DataSource, this.props)});}render() {// ...并将新的数据传递给被包装的组件!return <WrappedComponent data={this.state.data} {...this.props} />;}}
}
集成状态管理(如Redux或Vue.js)
状态管理库(如Redux)可以帮助管理大型应用程序的状态,使其更易于维护和测试。Redux是一个可预测的状态容器,用于JavaScript应用。
示例代码:
import { createStore } from 'redux';// 创建一个reducer
function todos(state = [], action) {switch (action.type) {case 'ADD_TODO':return state.concat([action.text]);default:return state;}
}// 创建store
let store = createStore(todos);// 添加一个todo
store.dispatch({type: 'ADD_TODO',text: 'Read the docs'
});// 打印state
console.log(store.getState());
使用Shadow DOM实现封装和样式隔离
Shadow DOM提供了一种封装Web组件的方式,可以隔离样式和行为,防止与其他组件冲突。
示例代码:
class MyElement extends HTMLElement {constructor() {super();// 创建一个shadow rootthis.attachShadow({ mode: 'open' });// 添加一些内容this.shadowRoot.innerHTML = `<h1>Hello, World!</h1>`;}
}// 定义custom element
customElements.define('my-element', MyElement);
通过以上方法,可以设计出更高级、更易于维护和测试的组件
第7章:复用与模块化
元素的rel="import"和模块导入
HTML Imports是HTML和JavaScript的一种模块格式,允许在HTML文档中导入外部资源。可以使用元素的rel="import"属性来导入模块。
示例代码:
<head><link rel="import" href="my-module.html">
</head>
<body><my-element></my-element>
</body>
Web Components库和框架(如Polymer、lit-element等)
Web Components是一种模块化的方法,用于构建可重用和可组合的UI组件。可以使用各种Web Components库和框架来简化开发过程。
示例代码:
// Polymer
import { PolymerElement, html } from '@polymer/polymer';class MyElement extends PolymerElement {static get template() {return html`<div>Hello, World!</div>`;}
}customElements.define('my-element', MyElement);// lit-element
import { LitElement, html } from 'lit-element';class MyElement extends LitElement {render() {return html`<div>Hello, World!</div>`;}
}customElements.define('my-element', MyElement);
Web Components的模块化最佳实践
为了确保Web Components的可重用性和可维护性,需要遵循一些最佳实践。
- 组件应该是可重用的:组件应该是独立的、可重用的,并且不应该依赖于特定的应用程序状态。
- 组件应该是可组合的:组件应该可以与其他组件组合在一起,以创建更大的组件。
- 组件应该是可测试的:组件应该是可测试的,可以通过单元测试和集成测试来验证其功能。
- 组件应该是可维护的:组件应该易于理解和维护,并且应该遵循一致的编码风格和架构。
- 组件应该是可访问的:组件应该遵循可访问性的最佳实践,以确保所有用户都可以使用它们。
通过遵循这些最佳实践,可以确保Web Components的可重用性和可维护性,并使得应用程序更加模块化和可扩展。
第8章:现代Web开发中的Web Components
Web Components与现代Web框架的集成
现代Web框架(如Angular、React、Vue)虽然各自有其独特的组件系统,但它们也支持与Web Components的集成,以利用Web
Components的可重用性和模块化优势。以下是一些集成方式:
- Angular: Angular通过
ng-content和@Input、@Output等特性,可以方便地使用Web Components。可以将Web
Components作为Angular组件的一部分,或者在Angular应用中作为自定义元素使用。 - React: React通过
forwardRef和useRef等API,可以与自定义元素(Custom Elements)配合使用。通过React.forwardRef将Web
Components包装成React组件,可以在React应用中直接使用。 - Vue: Vue通过
v-bind、v-on等指令,可以与自定义元素或使用Vue.extend创建的组件一起工作。Vue的Composition API也可以与Web
Components无缝集成。
Web Components在服务端渲染(SSR)中的应用
服务端渲染(SSR)是现代Web开发中的一种策略,它允许在服务器端生成完整的HTML,然后发送到客户端,提高首屏加载速度。对于Web
Components,SSR需要特别处理,因为它们依赖于浏览器环境来创建和渲染。
- 使用服务器端库:一些库(如
@webcomponents/web-component-server)提供了服务端渲染Web
Components的能力,它允许在服务器上创建虚拟DOM,然后在客户端上进行渲染。 - 预渲染:在客户端首次渲染时,可以将组件的HTML结构和数据一起发送到客户端,然后在客户端通过JavaScript初始化这些组件。
- 状态管理:确保在服务器端和客户端之间同步状态,因为Web Components可能依赖于组件内部的状态。
在SSR中使用Web Components时,需要考虑到浏览器环境和服务器环境的差异,确保组件可以在两种环境下正确工作。同时,由于Web
Components的模块化特性,它们通常更容易适应SSR的场景。
相关文章:
探索Web Components
title: 探索Web Components date: 2024/6/16 updated: 2024/6/16 author: cmdragon excerpt: 这篇文章介绍了Web Components技术,它允许开发者创建可复用、封装良好的自定义HTML元素,并直接在浏览器中运行,无需依赖外部库。通过组合HTML模…...
摄影师在人工智能竞赛中与机器较量并获胜
摄影师在人工智能竞赛中与机器较量并获胜 自从生成式人工智能出现以来,由来已久的人机大战显然呈现出一边倒的态势。但是有一位摄影师,一心想证明用人眼拍摄的照片是有道理的,他向算法驱动的竞争对手发起了挑战,并取得了胜利。 迈…...
CMU最新论文:机器人智慧流畅的躲避障碍物论文详细讲解
CMU华人博士生Tairan He最新论文:Agile But Safe: Learning Collision-Free High-Speed Legged Locomotion 代码开源:Code: https://github.com/LeCAR-Lab/ABS B站实际效果展示视频地址:bilibili效果地址 我会详细解读论文的内容,让我们开始吧…...
Spring中自定义注解进行类方法增强
说明 说到对类方法增强,第一时间想到自定义注解,通过aop切面进行实现。这是一种常用做法,但是在某些场景下,如开发公共组件,定义aop切面可能不是最优方案。以后通过原生aop方式,自定义注解,对类…...
TS:元组
问: 解释下什么是元组 回答: 元组(Tuple)是一种数据结构,类似于数组,但与数组不同的是,元组中的元素类型可以各不相同,且元组的长度是固定的。元组在许多编程语言中都有实现,包括 TypeScript…...
微服务 | Springboot整合Dubbo+Nacos实现RPC调用
官网:Apache Dubbo 随着互联网技术的飞速发展,越来越多的企业和开发者开始关注微服务架构。微服务架构可以将一个大型的应用拆分成多个独立、可扩展、可维护的小型服务,每个服务负责实现应用的一部分功能。这种架构方式可以提高开发效率&…...
读书的意义
...
第66集《摄大乘论》
请大家打开《讲义》第二二二页: 庚九、念(分二:辛一正念法身;辛二兼显净土) 辛一、正念法身(分二:壬一征;壬二释) 壬一、征 这个是讲到十门分别(二0三页),分别清净法身的第九段,讲到念&…...
VMware 桥接网络突然无法上网
VMware 桥接网络突然无法上网 0. 问题1. 解决方法 0. 问题 昨天,VMware 桥接网络正常使用,今天突然无法上网。 1. 解决方法 打开VMware的虚拟网络编辑器,将桥接模式的网络从“自动”改成你要使用的网卡,问题解决。 完成&#…...
面试题——Redis
★1.简述一下缓存穿透,缓存击穿,缓存雪崩 ? 缓存穿透:大量恶意请求一个不存在的数据,使得压力绕过Redis缓存层打到数据库,造成数据库瘫痪 处理:①设置黑名单,维护一个可能存在也可能不存在的黑名单数据列表,对请求进行过滤(简单高效) ②布隆过滤器,会出现误删,且相对麻烦(不…...
Java——构造器(构造方法)和 this
一、什么是构造器 构造器(Constructor)是Java类的一种特殊方法,用于初始化对象的状态。构造器在创建对象时被调用,可以对对象的成员变量进行初始化。 我之前的文章《Java——类和对象-CSDN博客》中也提到了构造器。 二、构造器…...
MySQL-连接查询
049-内连接之等值连接 案例:查询每个员工所在的部门名称,要求显示员工名、部门名。 select e.ename, d.dname from emp e inner join dept d on e.deptnod.deptno;注意:inner可以省略 select e.ename, d.dname from emp e join dept d on…...
适合小白学习的项目1832javaERP管理系统之仓库采购管理Myeclipse开发mysql数据库servlet结构java编程计算机网页项目
一、源码特点 java erp管理系统之仓库采购管理是一套完善的web设计系统,对理解JSP java编程开发语言有帮助采用了serlvet设计,系统具有完整的源代码和数据库,系统采用web模式,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Mye…...
分布式技术导论 — 探索分析从起源到现今的巅峰之旅(分布式技术)
分析探索从起源到现今的巅峰之旅 背景介绍数据可伸缩性案例 计算可伸缩性案例 代价和权衡分布式的代价分布式的权衡权衡策略 分布式技术方向数据系统运算系统 分布式数据系统Partition(分区)Round-Robin(轮询)局限性 Range&#x…...
基于Python+OpenCV+SVM车牌识别系统(GUI界面)【W3】
简介: 随着交通管理的日益复杂化和智能化需求的增加,车牌识别系统在安防、智慧交通管理等领域中扮演着重要角色。传统的车牌识别系统主要基于图像处理和模式识别技术,随着计算机视觉技术的发展,基于Python、OpenCV和机器学习算法的…...
ansible.cfg forks参数
在Ansible的配置文件ansible.cfg中,forks参数是一个非常关键的设置,它控制了Ansible执行任务时的并发连接数,直接影响到Ansible执行 playbook 或 ad-hoc 命令时的速度和效率。 意义与作用 并发控制:当你使用Ansible来管理多台主…...
Web前端写随机抽奖:技术与创意的碰撞
Web前端写随机抽奖:技术与创意的碰撞 在Web前端的世界里,随机抽奖功能不仅是一种常见的交互元素,更是技术与创意的完美结合。下面,我们将从四个方面、五个方面、六个方面和七个方面,深入探讨Web前端实现随机抽奖的技术…...
Centos系统yum安装mysql数据库
安装之前需要将系统自带的mariadb-libs软件包删除。 检查是否存在mariadb-libs包。 yum list installed|grep mariadb-libs 删除mariadb-libs包 yum -y remove mariadb-libs 声明: 系统:CentOS-7-x86_64-DVD-2009 安装为最小化安装,没…...
使用Selenium进行Web自动化:详细操作指南
使用Selenium进行Web自动化:详细操作指南 引言 Selenium是一个广泛使用的开源工具,用于自动化Web浏览器的操作。无论你是进行自动化测试,还是需要抓取网页数据,Selenium都是一个非常有用的工具。本文将详细介绍Selenium的一些常见用法,包括输入框设置值、文件上传、单选…...
手机照片免费数据恢复软件EasyRecovery2024免费版下载
大家好!今天我要给大家推荐一款非常棒的软件——EasyRecovery。相信大家都知道,电脑中的重要文件一旦丢失,对我们的工作和学习都会产生很大的影响。 而EasyRecovery软件就是专门解决这个问题的利器!它能够帮助我们快速、有效地恢…...
Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误
HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误,它们的含义、原因和解决方法都有显著区别。以下是详细对比: 1. HTTP 406 (Not Acceptable) 含义: 客户端请求的内容类型与服务器支持的内容类型不匹…...
阿里云ACP云计算备考笔记 (5)——弹性伸缩
目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
cf2117E
原题链接:https://codeforces.com/contest/2117/problem/E 题目背景: 给定两个数组a,b,可以执行多次以下操作:选择 i (1 < i < n - 1),并设置 或,也可以在执行上述操作前执行一次删除任意 和 。求…...
工业自动化时代的精准装配革新:迁移科技3D视觉系统如何重塑机器人定位装配
AI3D视觉的工业赋能者 迁移科技成立于2017年,作为行业领先的3D工业相机及视觉系统供应商,累计完成数亿元融资。其核心技术覆盖硬件设计、算法优化及软件集成,通过稳定、易用、高回报的AI3D视觉系统,为汽车、新能源、金属制造等行…...
css3笔记 (1) 自用
outline: none 用于移除元素获得焦点时默认的轮廓线 broder:0 用于移除边框 font-size:0 用于设置字体不显示 list-style: none 消除<li> 标签默认样式 margin: xx auto 版心居中 width:100% 通栏 vertical-align 作用于行内元素 / 表格单元格ÿ…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?
现有的 Redis 分布式锁库(如 Redisson)相比于开发者自己基于 Redis 命令(如 SETNX, EXPIRE, DEL)手动实现分布式锁,提供了巨大的便利性和健壮性。主要体现在以下几个方面: 原子性保证 (Atomicity)ÿ…...
Unity中的transform.up
2025年6月8日,周日下午 在Unity中,transform.up是Transform组件的一个属性,表示游戏对象在世界空间中的“上”方向(Y轴正方向),且会随对象旋转动态变化。以下是关键点解析: 基本定义 transfor…...
