建设一站式服务网站类似设计师联盟的网站
- 作者: 五速梦信息网
- 时间: 2026年04月20日 10:43
当前位置: 首页 > news >正文
建设一站式服务网站,类似设计师联盟的网站,做网站要多少像素,企业网站备案要关站吗一、什么是web components 开发项目的时候为什么不手写原生 JS#xff0c;而是要用现如今非常流行的前端框架#xff0c;原因有很多#xff0c;例如#xff1a; 良好的生态数据驱动试图模块化组件化等 Web Components 就是为了解决“组件化”而诞生的#xff0c;它是浏…一、什么是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 元素。 bodyuser-card/user-cardscriptclass 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 isuser-button/button 使用生命周期回调函数 在custom element的构造函数中可以指定多个不同的回调函数它们将会在元素的不同生命时期被调用 connectedCallback当 custom element首次被插入文档DOM时被调用。disconnectedCallback当 custom element从文档DOM中删除时被调用。adoptedCallback当 custom element被移动到新的文档时被调用。attributeChangedCallback: 当 custom element增加、删除、修改自身属性时被调用。 Shadow DOM 经常写videoaudio等html元素在带的控制条或者模块但是这这些模块哪里来的用什么实现的 隐藏有点深刻难以发现。 那什么是影子DOM 影子dom这个东西的存在主要解决dom树建立时能够实现维护自身边界的问题。这么说有点像vue的scope保证自身不会被外来修饰入侵或者污染。影子dom将对应的dom信息隐藏起来依然能在html文档里渲染出来。但不能通过普通的js方法获取到dom信息影子dom事件捕获遵从常规dom事件在影子dom内部依然传递同时也遵从事件冒泡向整个文档的dom上传递事件。 创建影子树 通过createShadowRoot创建影子树root节点 !DOCTYPE html html headtitle影子dom/titlelink reldns-prefetch href//dfhs.tanx.comstyle.box {height: 80px;width: 80px;background-color: red;}/style /head bodydiv idbox classbox/div /body scriptvar \(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 headtitle影子dom/titlelink reldns-prefetch href//dfhs.tanx.comstyle.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 bodyvideo srctest.mp4 height200px controls/videoaudio srcmp3.mp3 controls/audiocanvas/canvasdiv idbox classbox/div /body scriptvar \)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也放入影子节点里 scriptvar \(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 headtitle影子dom/titlelink reldns-prefetch href//dfhs.tanx.comstyle.box {height: 160px;width: 160px;background-color: red;}.children {height: 80px;width: 80px;background-color: blue;}.test-content {background-color: yellow;}/style /head bodydiv idbox classboxdiv classtest-content我接着测试/div/divtemplate classroot-tlpstyle.test-ctn {color: white;}/styledivdiv classtest-ctn idtest测试/dt/divcontent select.test-content/content/template /body scriptvar \)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 classroot-tlpstyle.test-ctn {color: white;}:host {font-weight: bold;}/styledivdiv classtest-ctn idtest测试/dt/divcontent select.test-content/content/template :host()选择器选择影子dom宿主元素 bodydiv idbox classboxdiv classtest-content我接着测试/div/divtemplate classroot-tlpstyle.test-ctn {color: white;}:host {font-weight: bold;}:host(.box) {color: blue;}/styledivdiv classtest-ctn idtest测试/dt/divcontent select.test-content/content/template /body :host-context()与后代选择器表达式一起使用以仅选择特定祖先内部的自定义元素的实例 !DOCTYPE html html headtitle影子dom/titlelink reldns-prefetch href//dfhs.tanx.comstyle.box {height: 160px;width: 160px;}.children {height: 80px;width: 80px;}/style /head bodydiv idbox classtestdiv classbox-content idbox-contentdiv classbox-ctn213/div/div/divtemplate classroot-tlpstyle.test-ctn {color: white;}:host {font-weight: bold;}:host(.box-content) {color: blue;background-color:red;}:host-context(.test) {height: 300px;background-color: blueviolet}/styledivdiv classtest-ctn idtest测试/dt/divcontent select.box-ctn/content/template /body scriptvar \)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 可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用。 被使用前不会被渲染。被使用前对页面其他部分没有影响脚本不会运行图像不会加载音频不会播放。 bodyp会影响外部样式/ptemplate idmy-paragraphstylep{color: red;}/stylepMy paragraph/p/templatemy-paragraph/my-paragraphscriptcustomElements.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的使用 bodystylep{color: blueviolet;}/stylep会影响外部样式/ptemplate idmy-paragraphstylep{color: red;}/stylepMy paragraph/pslot namemy-textMy default text/slot/templatemy-paragraphp slotmy-textslot text/p/my-paragraphscriptcustomElements.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 headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlecss-doodle/titlescript srchttps://cdnjs.cloudflare.com/ajax/libs/css-doodle/0.6.1/css-doodle.min.js/scriptstylehtml, body {height: 100%;margin: 0;overflow: hidden;}/style /head bodycss-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 headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlecss-doodle/titlescript srchttps://cdnjs.cloudflare.com/ajax/libs/css-doodle/0.6.1/css-doodle.min.js/scriptstylehtml, body {width: 100%;height: 100%;margin: 0;overflow: hidden;background: #011627;display: grid;place-items: center;/* 公众号前端学不动 搜居中篇 */}/style /head bodycss-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 headmeta charsetUTF-8meta http-equivX-UA-Compatible contentIEedgemeta nameviewport contentwidthdevice-width, initial-scale1.0titlecss-doodle/titlescript srchttps://unpkg.com/css-doodle0.34.5/css-doodle.min.js/scriptstylehtml, body {width: 100%;height: 100%;margin: 0;overflow: hidden;background: radial-gradient(#459dc1, #070729);display: grid;place-items: center;/* 公众号前端学不动 搜居中篇 */}/style /head bodycss-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-doodlesvg stylewidth: 0; height: 0;filter idfilterfeGaussianBlur inSourceGraphic stdDeviation5 resultblur/feGaussianBlurfeColorMatrix inblur modematrix values1 0 0 0 00 1 0 0 00 0 1 0 00 0 0 18 -7resultgoo /feColorMatrixfeBlend inSourceGraphic in2goo/feBlend/filter/svg /body /html三、fancy-components https://github.com/fancy-components/fancy-components !DOCTYPE html html langen headtitlefancy-components/titlestyle* { 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 bodydiv!-- html 只支持小写标签不支持驼峰命名法 --fc-input white placeholderUsername/fc-inputbr /fc-input white disabled valuefancy components placeholderUsername/fc-inputbr /fc-btnfancy-components/fc-btnbr /fc-warp-btn/fc-warp-btnbr /fc-3d-btn/fc-3d-btnbr /fc-underline-btn/fc-underline-btnbr /fc-pixel-btn/fc-pixel-btnbr /fc-parentheses-btn/fc-parentheses-btnbr /fc-round-btn/fc-round-btnbr /fc-arrow-btn/fc-arrow-btnbr /fc-bubbles clickfc-parentheses-btn撒花/fc-parentheses-btn/fc-bubbles/divscript typemoduleimport { FcTypingInput } from http://unpkg.com/fancy-componentsimport { FcDblWarpBtn } from http://unpkg.com/fancy-componentsimport { FcWarpBtn } from http://unpkg.com/fancy-componentsimport { Fc3DBtn } from http://unpkg.com/fancy-componentsimport { FcUnderlineBtn } from http://unpkg.com/fancy-componentsimport { FcPixelBtn } from http://unpkg.com/fancy-componentsimport { FcParenthesesBtn } from http://unpkg.com/fancy-componentsimport { FcRoundBtn } from http://unpkg.com/fancy-componentsimport { FcArrowBtn } from http://unpkg.com/fancy-componentsimport { 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 – templatediv idappfc-bubbles clickimg altVue logo src./assets/logo.png/fc-bubbles!– FcBubbles clickimg altVue 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 – templatefc-bubbles clickimg altVue logo src./assets/logo.png/fc-bubblesHelloWorld msgWelcome 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 Clickimg altVue logo src./assets/logo.png/fc-bubbles 在 Vite 中使用 Web Components 组件库
npm 6.x
npm create vitelatest 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-componentsnew FcBubbles()createApp(App).mount(#app) !– src\App.vue – !– 注意 Click 大写 – fc-bubbles Clickimg altVue 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-)}}})] }) 不需要重启即可生效。
相关文章
-
建设一个中英文双版的网站wordpress源码 优惠券
建设一个中英文双版的网站wordpress源码 优惠券
- 技术栈
- 2026年04月20日
-
建设一个小说网站要多少钱广西建设网官网办事大厅桂建云
建设一个小说网站要多少钱广西建设网官网办事大厅桂建云
- 技术栈
- 2026年04月20日
-
建设一个微信小说网站四平网站公司
建设一个微信小说网站四平网站公司
- 技术栈
- 2026年04月20日
-
建设医院网站ppt模板下载张家港安监站网址
建设医院网站ppt模板下载张家港安监站网址
- 技术栈
- 2026年04月20日
-
建设银信用卡网站首页深圳网站建设推荐
建设银信用卡网站首页深圳网站建设推荐
- 技术栈
- 2026年04月20日
-
建设银行 贷款 查询 网站网站首页文件名通常是
建设银行 贷款 查询 网站网站首页文件名通常是
- 技术栈
- 2026年04月20日
