尽管Web Components的规格和实现可能并不被认为是成熟的,但仍然有一些有趣的组件和项目,你可能会发现有用于自己的目的。 说到这一点,Vue仍然提供了大量的平凡的Web组件。 (事实上,你甚至可以使用Vue制作Web Components(https://andsky.com/tech/tutorials/vuejs-custom-elements)。
准备
(本指南假定您已启动一个快速的 Vue.js 项目,使用 vue-cli和webpack-simple
模板。
让我们先创建一个简单的网页组件,以尽可能少的代码来说明属性和事件。
看: ** 标记段落! ** 基本上,它是一个段落的包装器. 你通过内容
属性设置了其文本内容。 哦,它每隔半秒都会发出一个标记
事件。
1[label ticking-paragraph.html]
2<template id="x-ticking-paragraph">
3 <style>
4 p {
5 color: #42b983;
6 }
7 </style>
8 <p id="renderTarget">
9 </p>
10</template>
11
12<script>
13 const currentScript = document.currentScript;
14
15 customElements.define('x-ticking-paragraph', class extends HTMLElement {
16 static get observedAttributes() { return ['contents'] }
17
18 constructor() {
19 super();
20 let shadowRoot = this.attachShadow({mode: 'open'});
21 const template = currentScript.ownerDocument.querySelector('#x-ticking-paragraph');
22 const instance = template.content.cloneNode(true);
23 shadowRoot.appendChild(instance);
24
25 this.contents = '';
26
27 setInterval(() => {
28 this.dispatchEvent(new Event('tick'));
29 }, 500);
30 }
31
32 set contents(value) {
33 this._contents = value;
34 this.shadowRoot.getElementById('renderTarget').innerText = this._contents;
35 }
36
37 get contents() {
38 return this._contents;
39 }
40
41 attributeChangedCallback(name, oldValue, newValue) {
42 this[name] = newValue;
43 }
44 });
45</script>
我在这里使用旧的HTML导入元件风格,因为它感觉更优雅......对于一个更文明的时代。
我不打算在这里解释这一切,相反,如果你想看看如何为现代时代TM创建一个更合适的Web组件,我们已经(也涵盖了)(https://alligator.io/web-components/your-first-custom-element/)。
好吧,所以现在我们需要以某种方式将其加载到页面上,我们也将沿途抓取一个多文件,这样它可以在更多的浏览器中运行,而不仅仅是Chrome。
1[label ticking-paragraph.html]
2<!DOCTYPE html>
3<html lang="en">
4 <head>
5 <meta charset="utf-8">
6 <title>Vue + Web Components</title>
7 <!-- Web Components Polyfill -->
8 <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.13/webcomponents-lite.js"></script>
9 <!-- Loading our component -->
10 <link rel="import" href="./ticking-paragraph.html">
11 </head>
12 <body>
13 <div id="app"></div>
14 <script src="/dist/build.js"></script>
15 </body>
16</html>
现在,我们已经完成了这一切,我们终于可以使用Vue中的组件,正如本段落后面的标题所述。
在视野中使用您的组件
真正的唯一事情,我们必须做,使Vue工作这个组件是白名单它在Vue.config.ignoredElements. 这只是告诉Vue元素 / 组件来自一个Vue不知道的来源,并防止编译器抱怨。
1[label src/main.js]
2import Vue from 'vue';
3import App from './App.vue';
4
5Vue.config.ignoredElements = [
6 'x-ticking-paragraph'
7]
8
9new Vue({
10 el: '#app',
11 render: h => h(App)
12});
现在,像任何其他组件一样使用该组件! 反作用保持不受影响!
1[label src/App.vue]
2<template>
3 <div id="app">
4 <h1>Vue ❤ Web Components</h1>
5 <x-ticking-paragraph :contents="paragraphContents" @tick="logTick"></x-ticking-paragraph>
6 </div>
7</template>
8
9<script>
10export default {
11 data() {
12 return {
13 paragraphContents: `I'm data from Vue rendering in a Web Component!`
14 }
15 },
16
17 methods: {
18 logTick() {
19 console.log(`The paragraph ticked again. >_>`)
20 }
21 }
22}
23</script>
最好的部分是,您不需要对 Web Component 或 Vue 应用程序进行任何更改,以某种方式迫使它们一起工作。 它直接起作用! 事实上,您甚至可以集成内部使用其他框架的元素,如 Polymer 或 React。
现在,这对你来说是多么有用,完全取决于你是否正在(或想要)与Vue一起使用Web组件。