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

谷歌有趣的网站/太原seo优化

谷歌有趣的网站,太原seo优化,游戏云电脑,wordpress页面之间如何跳转一、什么是web components 开发项目的时候为什么不手写原生 JS,而是要用现如今非常流行的前端框架,原因有很多,例如: 良好的生态数据驱动试图模块化组件化等 Web Components 就是为了解决“组件化”而诞生的,它是浏…

一、什么是web components

开发项目的时候为什么不手写原生 JS,而是要用现如今非常流行的前端框架,原因有很多,例如:

  • 良好的生态
  • 数据驱动试图
  • 模块化
  • 组件化

Web Components 就是为了解决“组件化”而诞生的,它是浏览器原生支持的组件化,不依赖任何库、依赖和打包工具就可以在浏览器中运行。

Vue、React 的组件化并不是真正的组件化,虽然写代码时写的是确实的组件化代码,但是编译后就不再是组件化了。

例如用 Vue + ElementUI 开发的应用,ElementUI 的组件都是 el 开头的,如 <el-button>,但编译后显示在页面上的就不再是 <el-button> 标签了。

这有点类似于 CSS 预处理器(如 Sass、Less),那些在开发阶段编译的变量(如 $color: red;)其实并不是真正的变量,而是伪变量。在编译过后就没有变量的概念了,所以很难和 JS 通信。

例如有一个需求,在页面上给用户提供一个输入框,用户输入什么颜色(如 red、#ff00000),网站就会变成相应颜色的主题色,可是在我们获取到用户输入后,却没有变法将它们赋值给 Sass 变量上去。因为 Sass 代码在编译后已经变成了 CSS 代码,没有 Sass 变量了,例如 color: $color; 编译为 color: red;。

所以此时就需要一个浏览器原生就支持的,不需要编译就能够运行的变量,于是 CSS 变量就出现了(--color: red;color: var(--color)),可以非常方便地与 JS 进行通信,因为它是浏览器级别地原生变量。
同理,框架的组件化也不是真正的标准,每家都用自己的组件化标准,这就导致了生态的分裂,而且这些框架的组件化也都是靠编译才能实现的,并且非常依赖于这个框架,是一种共生的关系,就像使用 Vue 时,后缀以 .vue 结尾的文件,根本没有办法在浏览器中运行,必须下载 Node、Webpack、vue-loader 等工具进行打包,但还是无法在脱离 Vue 这个框架的安装包的情况下进行运行。

通常来说,浏览器厂商会吸收一些前端非常流行框架之中的可取之处,然后推动其成为标准,并在浏览器中原生实现这些功能,最经典的莫过于 jQuery 的 $() 选择器。

“都 21 世纪了,还提 jQuery?”

尽管这几年风生水起的 Vue 和 React 加剧了 jQuery 的没落,但全世界仍有超过 6600 万个网站在使用 jQuery,同时 jQuery 也给业界留下了产生深远影响的遗产,W3C 就仿照$()函数实现了 querySelector() querySelectorAll() 方法。

而讽刺的是,也正是这两个原生方法的出现,大大加快了 jQuery 的没落,因为它们取代了 jQuery 最常用的功能之一:快捷的选择 DOM 元素。

那么浏览器原生支持的组件化会取代现在所流行的库或框架么?

那么事实真的是这样么,其实不然。

Web Components 与如今非常流行的 MVVM 框架是一种共存的关系,而不是一种互斥的关系,就像 Sass 变量和 CSS 变量,两者可以非常完美的互补,而不是说用了 CSS 变量就不能用 Sass 变量。

再者来说,我们用那些 MVVM 框架也并不仅仅只是为了它们的组件化功能,虽然组件化是其中非常重要的一项功能,但是还有页面路由、数据绑定、模块化、CSS 预处理器、虚拟 DOM、Diff 算法,以及各种庞大的生态等功能。

Web Components 要解决的仅仅只是组件化的这么一项功能。

React 和 Web Components 为了解决不同的问题而生。Web Components 为可复用组件提供了强大的封装,而 React 则提供了声明式的解决方案,使 DOM 与数据保持同步。两者旨在互补。作为开发人员,可以自由选择在 Web Components 中使用 React,或者在 React 中使用 Web Components,或者两者共存。
—— 《Web Components – React》

我们认为 Vue 和 Web Components 主要是互补的技术。Vue 为使用和创建定制元素提供了出色的支持。无论你是将自定义元素集成到现有的 Vue 应用程序中,还是使用 Vue 来构建和分发自定义元素都很方便。
—— 《Vue 与 Web Components | Vue.js》

Web Components 是一个浏览器原生支持的组件化方案,允许你创建新的自定义、可封装、可重用的HTML 标记。不用加载任何外部模块,直接就可以在浏览器中跑。

它的出现原因?因为早期组件生态很乱,有各种各样的框架和库,都有各自的规范,导致一个团队切换框架很困难 。为了解决这种分化的形式,让 Web 组件模型统一化,所以才有了Web Components规范的出现。目标是提供一种权威的、浏览器能理解的方式来创建组件。

为什么要学习它?用一句话总结就是回顾历史展望未来。

2011年提出Web Components概念,React诞生

2013年 Chrome 和 Opera 又联合提出了推出的 V0 版本的 Web Components 规范,React开源

2014年Vue诞生

2016年Web Components 推进到了 V1 版本

由于浏览器兼容性、和主流框架开发效率等等问题导致现在几乎使用不到它,但我们可以学习它的思想,也许未来就会变的有用?

Web Components 由三种技术组成

Custom Elements

可以创建一个自定义标签。根据规范,自定义元素的名称必须包含连词线”-“,用与区别原生的 HTML 元素。

<body><user-card></user-card><script>class UserCard extends HTMLElement {constructor() {super();var el = document.createElement('p');el.classList.add('name');el.innerText = 'User Name';this.append(el);}}window.customElements.define('user-card', UserCard);</script>
</body>

在这里插入图片描述

class UserButton extends HTMLButtonElement {constructor() {super();}
}customElements.define('user-button', UserButton, { extends: "button" });
<button is="user-button"></button>

使用生命周期回调函数
在custom element的构造函数中,可以指定多个不同的回调函数,它们将会在元素的不同生命时期被调用:

  • connectedCallback:当 custom element首次被插入文档DOM时,被调用。
  • disconnectedCallback:当 custom element从文档DOM中删除时,被调用。
  • adoptedCallback:当 custom element被移动到新的文档时,被调用。
  • attributeChangedCallback: 当 custom element增加、删除、修改自身属性时,被调用。

Shadow DOM

经常写video,audio等html元素在带的控制条或者模块,但是这这些模块哪里来的用什么实现的

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
隐藏有点深刻,难以发现。

那什么是影子DOM

  1. 影子dom这个东西的存在,主要解决dom树建立时能够实现维护自身边界的问题。这么说有点像vue的scope保证自身不会被外来修饰入侵或者污染。
  2. 影子dom将对应的dom信息隐藏起来依然能在html文档里渲染出来。但不能通过普通的js方法获取到dom信息
  3. 影子dom事件捕获遵从常规dom事件,在影子dom内部依然传递,同时也遵从事件冒泡,向整个文档的dom上传递事件。

创建影子树
通过createShadowRoot创建影子树root节点

<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 80px;width: 80px;background-color: red;}</style>
</head>
<body><div id="box" class="box"></div>
</body>
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('style', 'height: 40px; width: 40px; background-color: blue');shadowRoot.appendChild(children);
</script>
</html>

在这里插入图片描述
再给影子树节点添加css时不能用过class或者元素选择来添加,否则无效果

<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 80px;width: 80px;background-color: red;}.children {height: 40px;width: 40px;background-color: blue;}div {height: 40px;width: 40px;background-color: blue;}</style>
</head>
<body><video src="test.mp4" height="200px" controls></video><audio src="mp3.mp3" controls></audio><canvas></canvas><div id="box" class="box"></div>
</body>
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children');shadowRoot.appendChild(children);
</script>
</html>

在这里插入图片描述
通过class选择dom时需要将style也放入影子节点里

<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children')shadowRoot.innerHTML += '<style>.children { height: 40px; width: 40px; background-color: blue;}</style>';shadowRoot.appendChild(children);
</script>

不能直接获得影子DOM
通过js常规方法不能直接获取到dom节点

	var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children');children.setAttribute('id', 'children');shadowRoot.appendChild(children);// 获得影子dom// 通过idvar getShadowRootById = document.getElementById('children');console.log(getShadowRootById)// 通过节点选择console.log('---------------')var getShadowRootByDomBox = document.body.firstChild.nextSibling; // 获得到box//var getShadowRootByDom = getShadowRootByDomBox.firstChildvar getShadowRootByDom = getShadowRootByDomBox.firstElementChild;console.log(getShadowRootByDom)

在这里插入图片描述
影子dom事件绑定
在createElement时拿到的元素,添加addEventListener事件

	var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得root//var showRoot = $box.webkitGetShadowRoot() // webkit 支持var children = document.createElement('div');children.setAttribute('class', 'children')shadowRoot.innerHTML += '<style>.children { height: 40px; width: 40px; background-color: blue;}</style>';shadowRoot.appendChild(children);children.addEventListener('click', function(e) {console.log(e)})

利用content元素select属性将目标内容匹配到template中指定位置,并且目标内容只能在影子元素里

<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 160px;width: 160px;background-color: red;}.children {height: 80px;width: 80px;background-color: blue;}.test-content {background-color: yellow;}</style>
</head>
<body><div id="box" class="box"><div class="test-content">我接着测试</div></div><template class="root-tlp"><style>.test-ctn {color: white;}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".test-content"></content></template>
</body>
<script>var $box = document.getElementById('box');var shadowRoot = $box.createShadowRoot(); // 获得rootvar children = document.createElement('div');var template = document.querySelector('.root-tlp');shadowRoot.appendChild(document.importNode(template.content, true));document.addEventListener('click', function() {console.log('test-content')})
</script>
</html>

在这里插入图片描述
CSS 选择器:
:host, :host(), :host-context()
:host

<template class="root-tlp"><style>.test-ctn {color: white;}:host {font-weight: bold;}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".test-content"></content></template>

在这里插入图片描述
:host()选择器,选择影子dom宿主元素

<body><div id="box" class="box"><div class="test-content">我接着测试</div></div><template class="root-tlp"><style>.test-ctn {color: white;}:host {font-weight: bold;}:host(.box) {color: blue;}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".test-content"></content></template>
</body>

在这里插入图片描述
:host-context()与后代选择器表达式一起使用,以仅选择特定祖先内部的自定义元素的实例

<!DOCTYPE html>
<html>
<head><title>影子dom</title><link rel="dns-prefetch" href="//dfhs.tanx.com"><style>.box {height: 160px;width: 160px;}.children {height: 80px;width: 80px;}</style>
</head>
<body><div id="box" class="test"><div class="box-content" id="box-content"><div class="box-ctn">213</div></div></div><template class="root-tlp"><style>.test-ctn {color: white;}:host {font-weight: bold;}:host(.box-content) {color: blue;background-color:red;}:host-context(.test) {height:  300px;background-color: blueviolet}</style><div><div class="test-ctn" id="test">测试</dt></div><content select=".box-ctn"></content></template>
</body>
<script>var $box = document.getElementById('box-content');var shadowRoot = $box.createShadowRoot(); // 获得rootvar children = document.createElement('div');var template = document.querySelector('.root-tlp');shadowRoot.appendChild(document.importNode(template.content, true));
</script>
</html>

在这里插入图片描述

templates and slots

可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。

  1. 被使用前不会被渲染。
  2. 被使用前对页面其他部分没有影响,脚本不会运行,图像不会加载,音频不会播放。
<body><p>会影响外部样式</p><template id="my-paragraph"><style>p{color: red;}</style><p>My paragraph</p></template><my-paragraph></my-paragraph><script>customElements.define('my-paragraph',class extends HTMLElement {constructor() {super();let template = document.getElementById('my-paragraph');let templateContent = template.content.cloneNode(true);this.appendChild(templateContent);}})</script>
</body>

在这里插入图片描述
slot的使用:

<body><style>p{color: blueviolet;}</style><p>会影响外部样式</p><template id="my-paragraph"><style>p{color: red;}</style><p>My paragraph</p><slot name="my-text">My default text</slot></template><my-paragraph><p slot="my-text">slot text</p></my-paragraph><script>customElements.define('my-paragraph',class extends HTMLElement {constructor() {super();let template = document.getElementById('my-paragraph');let templateContent = template.content.cloneNode(true);this.attachShadow({mode: 'open'}).appendChild(templateContent);}})</script>
</body>

在这里插入图片描述
下面挑选了市面上既好玩,颜值又高的组件库来体验以下 Web Components:

  • css-doodle:直译 - css 涂鸦
  • fancy-components:直译 - 花式组件库,可惜没有官方文档

二、css-doodle

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>css-doodle</title><script src="https://cdnjs.cloudflare.com/ajax/libs/css-doodle/0.6.1/css-doodle.min.js"></script><style>html, body {height: 100%;margin: 0;overflow: hidden;}</style>
</head>
<body><css-doodle>:doodle {@grid: 20 / 100vmax;background: #12152f;}::after {content: '\@hex(@rand(0x2500, 0x257f))';font-size: 5vmax;color: hsla(@rand(360), 70%, 70%, @rand(.9))}</css-doodle>
</body>
</html>

在这里插入图片描述

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>css-doodle</title><script src="https://cdnjs.cloudflare.com/ajax/libs/css-doodle/0.6.1/css-doodle.min.js"></script><style>html, body {width: 100%;height: 100%;margin: 0;overflow: hidden;background: #011627;display: grid;place-items: center;/* 公众号:前端学不动 搜:居中篇 */}</style>
</head>
<body><css-doodle>:doodle {@grid: 1x1x100 / 100vmin;animation: r 23s linear infinite}@size: 100% 50%;position: absolute;top: 25%;transform: rotate(@r(360deg));perspective: @r(100px, 200px);::after {content: '';position: absolute;@size: @r(.5vmin, 5vmin);color: @p(#fdfffc, #2ec4b6, #e71d36, #ff9f1c);background: currentColor;box-shadow: @m2(0 0 1.2vmin currentColor);animation: cycle @r(2s) linear infinite;--trans: scaleX(@r(1, 5)) translateZ(@r(10vmin, 20vmin));transform: rotateY(0) @var(--trans)}:empty::after { display: none }@keyframes cycle {to {transform: rotateY(@p(-1turn, 1turn)) @var(--trans)}}@keyframes r {to { transform: rotate(1turn) }}</css-doodle>
</body>
</html>

在这里插入图片描述

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>css-doodle</title><script src="https://unpkg.com/css-doodle@0.34.5/css-doodle.min.js"></script><style>html, body {width: 100%;height: 100%;margin: 0;overflow: hidden;background: radial-gradient(#459dc1, #070729);display: grid;place-items: center;/* 公众号:前端学不动 搜:居中篇 */}</style>
</head>
<body><css-doodle><!-- css-doodle.com -->:doodle {@grid: 80x1 / 100vw 100vh;@min-size: 100px;filter: url(#filter);animation: r 23s linear infinite}@size: 100% 50%;position: absolute;top: 25%;transform: rotate(@r(360deg));perspective: 130px;::after {content: '';position: absolute;@size: @r(10px);background: #fff;box-shadow: @m3(0 0 calc(.5vmin + 5px) #fff);animation: cycle @r(2s, 8s) linear infinite;animation-delay: -@r(100s);--trans: scaleX(@r(.1, 5)) translateZ(105px);transform: rotateY(0) @var(--trans)}@keyframes cycle {to {transform: rotateY(@p(-1turn, 1turn)) @var(--trans)}}@keyframes r {to { transform: rotate(@p(-1turn, 1turn)) }}</css-doodle><svg style="width: 0; height: 0;"><filter id="filter"><feGaussianBlur in="SourceGraphic" stdDeviation="5" result="blur"></feGaussianBlur><feColorMatrix in="blur" mode="matrix" values="1 0 0 0 00 1 0 0 00 0 1 0 00 0 0 18 -7"result="goo"  ></feColorMatrix><feBlend in="SourceGraphic" in2="goo"></feBlend></filter></svg>
</body>
</html>

在这里插入图片描述

三、fancy-components

https://github.com/fancy-components/fancy-components

<!DOCTYPE html>
<html lang="en">
<head><title>fancy-components</title><style>* { padding: 0; margin: 0; }html, body { height: 100%; }body {display: grid;place-items: center;background: #3f2766;}fc-3d-btn {--color: #6e50a6;--shadow-color: rgba(255, 255, 255, .4);--inset-shadow-color: #315;--inset-shadow-color-active: rgba(49, 23, 7, .9);--cover-color: rgba(0, 0, 0, .4);}</style>
</head>
<body><div><!-- html 只支持小写标签,不支持驼峰命名法 --><fc-input white placeholder="Username"></fc-input><br /><fc-input white disabled value="fancy components" placeholder="Username"></fc-input><br /><fc-btn>fancy-components</fc-btn><br /><fc-warp-btn></fc-warp-btn><br /><fc-3d-btn></fc-3d-btn><br /><fc-underline-btn></fc-underline-btn><br /><fc-pixel-btn></fc-pixel-btn><br /><fc-parentheses-btn></fc-parentheses-btn><br /><fc-round-btn></fc-round-btn><br /><fc-arrow-btn></fc-arrow-btn><br /><fc-bubbles click><fc-parentheses-btn>撒花</fc-parentheses-btn></fc-bubbles></div><script type="module">import { FcTypingInput } from 'http://unpkg.com/fancy-components'import { FcDblWarpBtn } from 'http://unpkg.com/fancy-components'import { FcWarpBtn } from 'http://unpkg.com/fancy-components'import { Fc3DBtn } from 'http://unpkg.com/fancy-components'import { FcUnderlineBtn } from 'http://unpkg.com/fancy-components'import { FcPixelBtn } from 'http://unpkg.com/fancy-components'import { FcParenthesesBtn } from 'http://unpkg.com/fancy-components'import { FcRoundBtn } from 'http://unpkg.com/fancy-components'import { FcArrowBtn } from 'http://unpkg.com/fancy-components'import { FcBubbles } from 'http://unpkg.com/fancy-components'// 注册组件// 可以传递一个重命名组件名的字符串,必须是小写,且用 `-` 连接// 不传参数默认组件名就是 fc-typing-inputnew FcTypingInput('fc-input')new FcDblWarpBtn('fc-btn')new FcWarpBtn()new Fc3DBtn()new FcUnderlineBtn()new FcPixelBtn()new FcParenthesesBtn()new FcRoundBtn()new FcArrowBtn()new FcBubbles()</script>
</body>
</html>

在这里插入图片描述

四、在脚手架中使用 Web Components 组件库

Vue 2 中使用

npm i -g @vue/cli
vue create vue2-app
cd vue2-app
npm i fancy-components
npm run serve
// src\main.js
import Vue from 'vue'
import App from './App.vue'
import { FcBubbles } from 'fancy-components'// 禁用 no-new 校验规则
/* eslint-disable no-new */
new FcBubbles()Vue.config.productionTip = falsenew Vue({render: h => h(App)
}).$mount('#app')
<!-- src\App.vue -->
<template><div id="app"><fc-bubbles click><img alt="Vue logo" src="./assets/logo.png"></fc-bubbles><!-- <FcBubbles click><img alt="Vue logo" src="./assets/logo.png"></FcBubbles> --></div>
</template>
...

Web Components 原生组件的地位和 HTML 标签的地位是相同的,大写的驼峰命名组件会被当做 Vue 组件,原生组件要和 HTML 标签一样,不要写成驼峰命名。React 框架中也一样。

Vue CLI 旧版本中使用 Web Components 控制台可能会发出警告,原因是 Vue 将 原生组件当作 Vue 组件去判断,警告组件没有注册,解决办法就是配置 ignoredElements 让 Vue 忽略原生组件:

Vue.config.ignoredElements = [// 正则匹配/^fc-/,// 或字符串'css-coodle'
]

Vue 3 中使用

vue create vue3-app
cd vue3-app
npm i fancy-components
npm run serve
// src\main.js
import { createApp } from 'vue'
import App from './App.vue'
import { FcBubbles } from 'fancy-components'/* eslint-disable no-new */
new FcBubbles()createApp(App).mount('#app')
<!-- src\App.vue -->
<template><fc-bubbles click><img alt="Vue logo" src="./assets/logo.png"></fc-bubbles><HelloWorld msg="Welcome to Your Vue.js App"/>
</template>

使用上如 Vue2 一样,但实际上会报错:

[Vue warn]: Failed to resolve component: fc-bubbles
If this is a native custom element, make sure to exclude it from component resolution via compilerOptions.isCustomElement.

原因与 Vue CLI 旧版本创建的 Vue2 应用一样,解决办法依然是配置忽略原生组件(自定义元素),参考:Vue 与 Web Components

// vue.config.js
module.exports = {chainWebpack: config => {config.module.rule('vue').use('vue-loader').tap(options => ({...options,compilerOptions: {// 将所有 fc- 开头的标签名都视为自定义元素isCustomElement: tag => tag.startsWith('fc-')}}))}
}

重启应用,警告已经不见了,但是点击仍然没有生效,打开 Element 面板发现组件的 click 属性并没有添加上,而其他属性如 click1 可以添加,这可能是因为 Vue3 认为 click 是一个不能直接添加的关键字,测试发现只需将 click 改成大写 Click 即可添加上。

<fc-bubbles Click><img alt="Vue logo" src="./assets/logo.png"></fc-bubbles>

在 Vite 中使用 Web Components 组件库

# npm 6.x
npm create vite@latest vite-vue-app
√ Select a framework: » vue
√ Select a variant: » vuecd vite-vue-app
npm install
npm i fancy-components
npm run dev
// src/main.js
import { createApp } from 'vue'
import App from './App.vue'
import { FcBubbles } from 'fancy-components'new FcBubbles()createApp(App).mount('#app')
<!-- src\App.vue -->
<!-- 注意 Click 大写 -->
<fc-bubbles Click><img alt="Vue logo" src="./assets/logo.png" /></fc-bubbles>

还要配置忽略的自定义元素:

// vite.config.js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'// https://vitejs.dev/config/
export default defineConfig({plugins: [vue({template: {compilerOptions: {// 将所有 fc- 开头的标签名都视为自定义元素isCustomElement: tag => tag.startsWith('fc-')}}})]
})

不需要重启即可生效。

相关文章:

Web Components学习(1)

一、什么是web components 开发项目的时候为什么不手写原生 JS&#xff0c;而是要用现如今非常流行的前端框架&#xff0c;原因有很多&#xff0c;例如&#xff1a; 良好的生态数据驱动试图模块化组件化等 Web Components 就是为了解决“组件化”而诞生的&#xff0c;它是浏…...

Element-UI实现复杂table表格结构

Element-UI组件el-table用于展示多条结构类似的数据&#xff0c;可对数据进行排序、筛选、对比或其他自定义操作。将使用到以下两项&#xff0c;来完成今天demo演示&#xff1a;多级表头&#xff1a;数据结构比较复杂的时候&#xff0c;可使用多级表头来展现数据的层次关系。合…...

Azure AD 与 AWS 单一帐户SSO访问集成,超详细讲解,包括解决可能出现的错误问题

本教程介绍如何将 AWS Single-Account Access 与 Azure Active Directory (Azure AD) 相集成。 将 AWS Single-Account Access 与 Azure AD 集成后&#xff0c;可以&#xff1a; 在 Azure AD 中控制谁有权访问 AWS Single-Account Access。让用户使用其 Azure AD 帐户自动登录…...

lvgl 笔记 按钮部件 (lv_btn) 和 开关部件 (lv_switch)

按钮基础使用方法&#xff1a; lv_btn 和 lb_obj 使用方法一样&#xff0c;只是外表并不相同&#xff0c;基础创建方法只需一行代码。 lv_obj_t* btn lv_btn_create(lv_scr_act()); 添加大小和位置&#xff1a; lv_obj_t* btn lv_btn_create(lv_scr_act()); lv_obj_set_s…...

Python高频面试题——生成器(最通俗的讲解)

生成器定义在 Python 中&#xff0c;使用了 yield 的函数被称为生成器&#xff08;generator&#xff09;。跟普通函数不同的是&#xff0c;生成器是一个返回迭代器的函数&#xff0c;只能用于迭代操作&#xff0c;更简单点理解生成器就是一个迭代器。 在调用生成器运行的过程中…...

品牌软文怎么写?教你几招

软文是什么&#xff1f;软文的本质就是广告&#xff0c;当然不是明晃晃的推销&#xff0c;而是自然隐晦地植入产品信息&#xff0c;引导更多用户自愿下单。 品牌软文对于写手的经验、内容的质量要求都相对较高&#xff0c;否则写出来的软文无法达到预期的效果。品牌软文怎么写…...

Kubernetes (k8s) 污点(Taint)介绍、示例

Kubernetes (k8s) 污点&#xff08;Taint&#xff09; 是一种机制&#xff0c;用于标记一个节点&#xff08;Node&#xff09;不可被调度的状态。它可以将一个污点标记添加到节点上&#xff0c;以防止 Pod 被调度到该节点上。污点可以用于实现各种策略&#xff0c;例如分离故障…...

Docker学习(二十一)构建 java 项目基础镜像

目录1.下载 JDK 包2.编写 Dockerfile3.构建镜像4.创建容器测试1.下载 JDK 包 JDK各版本官网下载地址&#xff1a; https://www.oracle.com/java/technologies/downloads/archive/#JavaSE 这里我们以 JDK 8u351 为例&#xff0c;点击 Java SE (8U211 and later)。 点击下载 jd…...

python中的上下文原理

目录with语句上下文管理器原理自定义上下文管理器contextmanager 装饰器with语句 在我们日常使用场景中&#xff0c;经常会操作一些资源&#xff0c;比如文件对象、数据库连接、Socket连接等&#xff0c;资源操作完了之后&#xff0c;不管操作的成功与否&#xff0c;最重要的事…...

可复用测试用例描述要素

测试用例的输入、操作、预期结果和评估标准、前提条件是测试用例不可少的要素&#xff0c;但对于可复用测试用例而言&#xff0c;这是不够的。本文在文献规定的测试用例要素基础上&#xff0c;增加了新的内容。从而从多个角度完整地对可复用测试用例进行了描述&#xff0c;为可…...

lnmp中遇到open_basedir配置无效问题

在使用LNMP包安装PHP时&#xff0c;发现直接修改php.ini的配置是无法生效的&#xff0c;其原因竟然是因为nginx的配置文件&#xff0c;覆盖了php.ini的配置。 解决&#xff1a; 1、找到nginx的open_basedir配置文件&#xff1a;&#xff08;下面是我的文件地址&#xff09; …...

SpringBoot【知识加油站】---- REST开发

SpringBoot【知识加油站】---- REST开发1. REST 简介2. REST 风格3. RESTful 入门案例1. REST 简介 REST&#xff1a;Representaional State Transfer&#xff0c;表现形式状态转换 传统风格资源描述形式 http://localhost/user/getById?id1 http://localhost/user/saveUser…...

三 Go的语言容器

1. 数组 数组是一个由固定长度的特定类型元素组成的序列&#xff0c;一个数组可以由零个或多个元素组成。因为数组的长度是固定的&#xff0c;所以在Go语言中很少直接使用数组 声明语法&#xff1a; var 数组变量名 [元素数量]Typepackage main import ("fmt" ) fu…...

2023年全国最新会计专业技术资格精选真题及答案16

百分百题库提供会计专业技术资格考试试题、会计考试预测题、会计专业技术资格考试真题、会计证考试题库等&#xff0c;提供在线做题刷题&#xff0c;在线模拟考试&#xff0c;助你考试轻松过关。 一、单选题 1.下列各项关于会计监督职能的表述中&#xff0c;正确的是&#xff…...

模板进阶(仿函数,特化等介绍)

非类型模板参数 模板参数有类型形参和非类型形参&#xff1b; 类型形参&#xff1a;使用typename或者class修饰的参数类型名称 非类型形参&#xff1a;一个普通常量作为模板参数形参&#xff0c;不能为浮点数&#xff0c;字符类型以及类对象&#xff1b; #include<iostrea…...

Beats:在 Docker 中同时部署 Metricbeat 和 Elasticsearch

在本教程中&#xff0c;我们将部署一个 metricbeat 来监控正在运行的容器的健康状况和系统指标。 为什么需要监控&#xff0c;为什么需要 Metricbeat&#xff1f; 一个常见的问题&#xff0c;但很少有人回答。 首先&#xff0c;无论我们部署的是 docker 容器还是老式的金属箱&…...

编码技巧——Redis Pipeline

本文介绍Redis pipeline相关的知识点及代码示例&#xff0c;包括Redis客户端-服务端的一次完整的网络请求、pipeline与client执行多命令的区别、pipeline与Redis"事务"、pipeline的使用代码示例&#xff1b; pipeline与client执行多命令的区别 Redis是一种基于客户…...

ArcGIS制图技巧:制图入门与点、线、面状符号制作

目的&#xff1a; 1、了解地图制作目的&#xff1b; 2、了解在ArcMap平台中制作地图大致过程。 3、掌握地形图生成的操作&#xff1b; 4、掌握地形图的正确输出方法。 5、理解点状符号、线状符号、面状符号的基本概念&#xff1b; 6、理解地形点状符号、线状符号、面状符…...

Java基础 关于字典数据维护接口设计

开发环境 Eclipse2022JDK1.8 目录 1. 概述 2. 实现步骤 2.1 定义通用接口 2.2 定义实体类 2.3 接口扩展 2.4 接口实现 2.5 功能测试 3. 结语 1. 概述 每一个信息系统或多或少都带有一些数据字典&#xff0c;在维护上&#xff0c;基本上分为增删改查&#xff0c;也就是对数据…...

从零开始学架构——复杂度来源

复杂度来源——高性能 对性能孜孜不倦的追求是整个人类技术不断发展的根本驱动力。例如计算机,从电子管计算机到晶体管计算机再到集成电路计算机,运算性能从每秒几次提升到每秒几亿次。但伴随性能越来越高&#xff0c;相应的方法和系统复杂度也是越来越高。现代的计算机CPU集成…...

什么时候需要分表分库?

在当今互联网时代&#xff0c;海量数据基本上是每一个成熟产品的共性&#xff0c;特别是在移动互联网产品中&#xff0c;几乎每天都在产生数据&#xff0c;例如&#xff0c;商城的订单表、支付系统的交易明细以及游戏中的战报等等。对于一个日活用户在百万数量级的商城来说&…...

冰刃杀毒工具使用实验(29)

实验目的 &#xff08;1&#xff09;学习冰刃的基本功能&#xff1b; &#xff08;2&#xff09;掌握冰刃的基本使用方法&#xff1b;预备知识 windows操作系统的基本知识&#xff0c;例如&#xff1a;进程、网络、服务和文件等的了解。 冰刃是一款广受好评的ARK工…...

聊聊图像分割的DICE和IOU指标

目录 1. 介绍 2. dice 和 iou 的联系 3. 代码实现 3.1 dice 3.2 iou 3.3 test 3.4 dice 和 iou 的关系曲线 4. 代码 1. 介绍 dice 和 iou 都是衡量两个集合之间相似性的度量 dice计算公式&#xff1a; iou计算公式&#xff1a; iou的集合理解&#xff1a; iou 其实就…...

软件设计师教程(十)计算机系统知识-结构化开发

软件设计师教程 软件设计师教程&#xff08;一&#xff09;计算机系统知识-计算机系统基础知识 软件设计师教程&#xff08;二&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;三&#xff09;计算机系统知识-计算机体系结构 软件设计师教程&#xff08;…...

链表OJ之 快慢指针法总结

欢迎来到 Claffic 的博客 &#x1f49e;&#x1f49e;&#x1f49e; 前言&#xff1a; 快慢指针指的是每次指针移动的步长&#xff0c;是解决链表相关的题目的一大利器&#xff0c;下面我将以例题的形式讲解快慢指针法。 目录 一. 链表的中间结点 思路&#xff1a; 代码实…...

C++STL详解(五)——list的介绍与使用

文章目录list的介绍list的使用list的定义方法list迭代器失效问题list插入和删除inserteraselist迭代器的使用begin&#xff0c;end 和 rbegin&#xff0c;rendlist元素访问front 和 backlist容量控制与数据清理resizeclearlist操作函数spliceremove 和 remove_ifuniquemergerev…...

进程和进程的调度

今天,为大家带来进程和进程的调度的学习 1.认识计算机 2.什么是操作系统 3.什么是进程 4.进程管理 5.进程的属性 6.进程的调度 7.进程调度的过程 8.内存分配 1.认识计算机 计算机的组成有五大部分 1.CPU(是计算机的大脑,负责逻辑运算和控制) 2.内存 3.外存 4.输入…...

TypeScript 深度剖析:TypeScript 的理解?与 JavaScript 的区别?

一、是什么 TypeScript 是 JavaScript 的类型的超集&#xff0c;支持ES6语法&#xff0c;支持面向对象编程的概念&#xff0c;如类、接口、继承、泛型等 超集&#xff0c;不得不说另外一个概念&#xff0c;子集&#xff0c;怎么理解这两个呢&#xff0c;举个例子&#xff0c;如…...

美颜SDK关键技术讲解——人脸识别与人脸美化

拍摄&#xff0c;自从智能手机普及之后就已经不再是小众爱好&#xff0c;使用手机拍摄记录生活几乎成了人们的日常。在巨量的需求下&#xff0c;美颜工具、美颜SDK已经被广泛应用于各大视频拍摄平台。虽然经常听到美颜SDK&#xff0c;但是大多数人并不了解它&#xff0c;下文小…...

Linux下C/C++ 网络扫描(主机扫描技术)

主机扫描是网络扫描的基础&#xff0c;通过对目标网络中主机IP地址的扫描&#xff0c;从一堆主机中扫描出存活的主机&#xff0c;然后以他们为目标进行后续的攻击。一般会借助于ICMP、TCP、UDP等协议的工作机制&#xff0c;检查打开的进程&#xff0c;开放的端口号等等。 主机…...