css-doodle 组件库
fancy-components 组件库使用
yarn add fancy-components
使用:
import { FcBubbles } from 'fancy-components'
new FcBubbles() //要用哪个就new哪个
new 这里可能会报错eslink,eslintrc.js中处理报错
module.exports = {rules: {'no-new': 'off'}
}
组件使用:
click 这里是个坑。click是一个关键字,要改成大写
// click 这里是个坑。click是一个关键字,要改成大写 <fc-bubbles Click><img src="/vite.svg" class="logo" alt="Vite logo" /></fc-bubbles>
直接使用自定义组件会有警告:
[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.
at <App>
需要配置vite.config.ts
export default defineConfig({plugins: [vue({template: {compilerOptions: {isCustomElement: tag => tag.startsWith('fc-')}}})],
})
到这里就能正确使用了。
web components
HTML IMPORTS 已经废弃。最新使用HTML modules 。
目前还没有浏览器实现
Custom element
customElements.define // 定义组件
customElements.define("word-count", class extends HTMLElement {constructor() {super();this // this=>组件本身}// 此处编写元素功能
})
当然也可以单独声明,单独使用。
class PopupInfo extends HTMLElement {constructor() {super();this.innerHTML = '123'}// 此处编写元素功能
}
customElements.define("popup-info", PopupInfo);
扩展fancy-components.
customElements.get // 获取自定义组件的构造函数
customElements.whendefined // 定义后的回调,是个异步的方法可以用来默认处理还没声明的组件。
配合伪类选择器(:defined)实现组件未编译前的默认展示
customElements.upgrade // 将先创建的element升级成自定义的组件
生命周期回调
定义在自定义元素的类定义中的特殊回调函数,影响其行为:
connectedCallback
:当自定义元素第一次被连接到文档 DOM 时被调用。disconnectedCallback
:当自定义元素与文档 DOM 断开连接时被调用。adoptedCallback
:当自定义元素被移动到新文档时被调用。attributeChangedCallback
:当自定义元素的一个属性被增加、移除或更改时被调用。
attributeChangedCallback不会自动更新需要手动更新,需要搭配observedAttributes 使用
static observedAttributes = ["color", "size"];
再搭配 get set 实现属性
set color (value) => {this.setAttriabute('color', value);
}
get color () => {return this.getAttribute("color")
}
自定义标签里面的 内置元素Safari不支持。要支持可以用profily
// 第三个参数必填否则会报错
<p is="word-count"></p>
// Create a class for the element
class WordCount extends HTMLParagraphElement {constructor() {// Always call super first in constructorsuper();// count words in element's parent elementvar wcParent = this.parentNode;function countWords(node) {var text = node.innerText || node.textContent;return text.split(/\s+/g).length;}var count = "Words: " + countWords(wcParent);// Create a shadow rootvar shadow = this.attachShadow({ mode: "open" });// Create text node and add word count to itvar text = document.createElement("span");text.textContent = count;// Append it to the shadow rootshadow.appendChild(text);// Update count when element content changessetInterval(function () {var count = "Words: " + countWords(wcParent);text.textContent = count;}, 200);}
}// Define the new element
// 第三个参数必填否则会报错
customElements.define("word-count", WordCount, { extends: "p" });
通过js添加到页面。
参考大神张鑫旭的博客:Safari不支持build-in自定义元素的兼容处理 « 张鑫旭-鑫空间-鑫生活
Shadow DOM(影子 DOM)
可以被挂载的 shadow DOM 元素 查看mdn
要注意的是,不是每一种类型的元素都可以附加到 shadow root(影子根)下面。出于安全考虑,一些元素不能使用 shadow DOM(例如<a>),以及许多其他的元素。
var shadowroot = element.attachShadow(shadowRootInit);
// 为新元素创建一个类
class WordCount extends HTMLParagraphElement {constructor() {// 在构造器中先调用一下 supersuper();// 计数器指向元素的父级var wcParent = this.parentNode;function countWords(node) {var text = node.innerText || node.textContent;return text.trim().split(/\s+/g).length;}var count = "Words: " + countWords(wcParent);// 创建一个 shadow rootvar shadow = this.attachShadow({ mode: "open" });// 创建文本节点并向其添加计数器var text = document.createElement("span");text.textContent = count;// 将其添加到 shadow root 上shadow.appendChild(text);// 当元素内容发生变化时更新计数setInterval(function () {var count = "Words: " + countWords(wcParent);text.textContent = count;}, 200);}
}// 定义新元素
customElements.define("word-count", WordCount, { extends: "p" });
HTML template(HTML 模板)
<table id="producttable"><thead><tr><td>UPC_Code</td><td>Product_Name</td></tr></thead><tbody><!-- 现有数据可以可选地包括在这里 --></tbody>
</table><template id="productrow"><tr><td class="record"></td><td></td></tr>
</template>// 通过检查来测试浏览器是否支持 HTML 模板元素
// 用于保存模板元素的内容属性。
if ("content" in document.createElement("template")) {// 使用现有的 HTML tbody 实例化表和该行与模板let t = document.querySelector("#productrow"),td = t.content.querySelectorAll("td");td[0].textContent = "1235646565";td[1].textContent = "Stuff";// 克隆新行并将其插入表中let tb = document.getElementsByTagName("tbody");let clone = document.importNode(t.content, true);tb[0].appendChild(clone);// 创建一个新行td[0].textContent = "0384928528";td[1].textContent = "Acme Kidney Beans";// 克隆新行并将其插入表中let clone2 = document.importNode(t.content, true);tb[0].appendChild(clone2);
} else {// 找到另一种方法来添加行到表,因为不支持 HTML 模板元素。
}