Vue3을 사용하여 웹 구성 요소를 구축하는 방법은 무엇입니까? 다음 글에서는 Vue3로 웹 컴포넌트를 구축하는 방법을 소개하겠습니다. 도움이 되셨으면 좋겠습니다!
가끔은 프레임워크 독립적인 구성 요소를 작성하고 싶지만 네이티브나 Jquery를 사용하여 작성하고 싶지 않으며 스타일 충돌도 피하고 싶습니다. 그것. 하지만 지금의 Web Components는 아직 유연성이 부족하여 사용하기 불편한 부분이 많습니다. MVVM과 함께 사용할 수 있다면 좋겠습니다. Angular는 오래 전부터 구성 요소를 웹 구성 요소로 만드는 것을 지원했습니다. Vue3 3.2+는 마침내 웹 구성 요소로 구성 요소를 만드는 것을 지원합니다. 최근에 우연히 댓글 플러그인을 재구성하고 싶어서 한번 시도해 봤습니다.
vue는 vue 구성 요소를 HTMLElement로 확장된 사용자 정의 함수 생성자로 변환하는 defineCustomElement 메서드를 제공합니다. 사용법은 기본적으로 defineComponent 매개 변수 API와 동일합니다. [관련 권장 사항: vuejs 동영상 튜토리얼]
import { defineCustomElement } from 'vue' const MyVueElement = defineCustomElement({ // 在此提供正常的 Vue 组件选项 props: {}, emits: {}, template: `...`, // defineCustomElement 独有特性: CSS 会被注入到隐式根 (shadow root) 中 styles: [`/* inlined css */`] }) // 注册 Web Components customElements.define('my-vue-element', MyVueElement)
단일 파일을 사용해야 하는 경우 @vitejs/plugin-vue@^1.4.0 또는 vue-loader@^16.5.0 또는 더 높은 버전의 도구. 일부 파일만 사용해야 하는 경우 접미사를 .ce.vue로 변경할 수 있습니다. 모든 파일 Web Components을 빌드해야 하는 경우 @vitejs/plugin-vue@^1.4.0 또는 vue-loader@^16.5.0의 customElement 구성 항목을 활성화할 수 있습니다. 이렇게 하면 .ce.vue 접미사를 사용할 필요가 없습니다.
vue는 모든 props를 사용자 정의 요소 개체의 속성에 매핑하고 사용자 정의 요소 태그의 속성도 매핑합니다.
<com-demo></com-demo> props:{ type:String }
HTML의 속성은 문자열만 가능하기 때문에 Vue는 기본 유형(Boolean, Number) 외에도 매핑 중에 유형 변환을 도와줍니다.
사용자 정의 요소에서 setup의 this.$emit 또는 emit을 통해 발생하는 이벤트는 기본 CustomEvents로 전달됩니다. 추가 이벤트 매개변수(페이로드)는 CustomEvent 객체의 세부정보 속성에 배열로 노출됩니다.
컴포넌트 작성 시 vue처럼 사용할 수 있지만 기본 슬롯 구문만 사용할 수 있으므로 범위 슬롯은 더 이상 지원되지 않습니다.
중첩된 하위 컴포넌트를 사용할 경우 기본적으로 하위 컴포넌트의 스타일이 추출되지 않는 함정이 있습니다.
상위 컴포넌트
<template> <div>{{ title }}</div> <childer></childer> </template> <script> import Childer from "./childer.vue" export default { components: { Childer }, data() { return { title: "父组件" } }, } </script> <style> .title { padding: 10px; background-color: #eee; font-weight: bold; } </style>
하위 컴포넌트
<template> <div>{{ title }}</div> </template> <script> export default { data() { return { title: "子组件" } }, } </script> <style> .childer { padding: 10px; background-color: #222; color: #fff; font-weight: bold; } </style>
하위 컴포넌트의 스타일은 삽입되지 않았지만 스타일 격리 식별자 data-v-5e87e937이 생성된 것을 볼 수 있습니다. 앞으로 Vue 공식에서 이 버그를 고칠지는 모르겠습니다
컴포넌트를 보면 하위 컴포넌트의 스타일이 추출된 것을 볼 수 있으니 직접 인젝션만 하면 됩니다.
하위 컴포넌트 스타일을 추출하여 상위 컴포넌트에 삽입합니다. 이 구현을 참고하세요
import ComDemo from '~/demo/index.vue' const deepStylesOf = ({ styles = [], components = {} }) => { const unique = array => [...new Set(array)]; return unique([...styles, ...Object.values(components).flatMap(deepStylesOf)]); } // 将子组件样式插入到父组件里 ComDemo.styles = deepStylesOf(ComDemo) !customElements.get('com-demo') && customElements.define('com-demo', defineCustomElement(ComDemo))
하위 컴포넌트 스타일 문제를 완벽하게 해결
defineCustomElement 빌드된 컴포넌트 customElement에 메서드를 걸려면 Vue 소스 코드를 살펴보세요. _def(생성자), _instance(컴포넌트 인스턴스)만 있습니다. 구성 요소 내에서 dom._instance.proxy.fun() 메서드를 호출하려는 경우 정말 우아하지 않게 느껴집니다.
물론 dom.fun()을 사용하지 않고 구성 요소에서 노출된 메서드를 일반 DOM처럼 직접 사용할 수 있기를 바랍니다. defineCustomElement를 약간 확장했습니다.
import { VueElement, defineComponent } from 'vue' const defineCustomElement = (options, hydate) => { const Comp = defineComponent(options); class VueCustomElement extends VueElement { constructor(initialProps) { super(Comp, initialProps, hydate); if (Comp.methods) { Object.keys(Comp.methods).forEach(key => { // 将所有非下划线开头方法 绑定到 元素上 if(!/^_/.test(key)){ this[key] = function (...res) { if (this._instance) { // 将方法thi改为 组件实例的proxy return Comp.methods[key].call(this._instance.proxy, ...res) } else { throw new Error('未找到组件实例') } } } }) } } } VueCustomElement.def = Comp; return VueCustomElement; }
일반적으로 말해서 여전히 많은 함정이 있습니다. 상대적으로 간단한 크로스 프레임워크 플러그인만 빌드해야 한다면 이 방법을 사용하여 웹 구성 요소를 빌드하는 것도 좋은 솔루션입니다.
더 많은 프로그래밍 관련 지식을 보려면 프로그래밍 소개를 방문하세요! !
위 내용은 Vue3를 사용하여 웹 구성요소를 구축하는 방법에 대해 이야기해 보겠습니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!