Я пытался понять, как работают веб-компоненты, поэтому я попытался написать небольшое приложение, которое я обслуживал на веб-сервере (протестировано в Chrome, который поддерживает rel = "import")
:
index.html
:
<!DOCTYPE html>
<html>
<head>
<meta charset = "utf-8" />
<link rel = "import" href = "my-app.html" />
</head>
<body>
<my-app />
</body>
</html>
my-app.html
:
<template id = "template">
<div>Welcome to my app!</div>
</template>
<script>
class MyApp extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode: "open"});
const template = document.getElementById("template");
const clone = document.importNode(template.content, true);
shadow.appendChild(clone);
}
}
customElements.define("my-app", MyApp);
</script>
Но, похоже, это не работает. Тег <my-app />
вообще не отображается в DOM, и я получаю эту ошибку в консоли:
Uncaught TypeError: Cannot read property 'content' of null
Что я не могу получить узел template
? Что я делаю неправильно?
Я также хотел бы знать, разрешено ли мне писать HTML-документ без шаблонного кода (doctype, head, body,...), потому что он предназначен для описания компонента, а не всего документа, который будет использоваться как есть. . Разрешено ли это спецификациями HTML5 и/или правильно интерпретируется большинством браузеров?
Спасибо за помощь.
Да, но модули IMO ES6 используются для импорта модулей JS, а не HTML.
Верно. Это означает, что тег <template>
больше не нужен для компонентов. Вы можете создать функцию render()
, которая возвращает литеральную строку шаблона, которая может встраивать ваши данные, или использовать что-то вроде npmjs.com/package/component-build-tools.
Мне становится немного грустно. Во-первых, потому что я предпочитаю синтаксис файла .vue
синтаксису компонента React, а во-вторых, потому что метод render()
возвращает даже не JSX, а строку шаблона, что означает, что в вашей IDE не будет выделений HTML и все такое. .
Находясь внутри шаблона, не используйте глобальное значение document
:
<template id = "template">
<div>Welcome to my app!</div>
</template>
<script>
class MyApp extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({mode: "open"});
// while inside the imported HTML, `currentDocument` should be used instead of `document`
const currentDocument = document.currentScript.ownerDocument;
// notice the usage of `currentDocument`
const template = currentDocument.querySelector('#template');
const clone = document.importNode(template.content, true);
shadow.appendChild(clone);
}
}
customElements.define("my-app", MyApp);
</script>
Демонстрация плункера: https://plnkr.co/edit/USvbddEDWCSotYrHic7n?p=preview
PS: отмечает совместимость с com здесь, хотя я предполагаю, что вы знаете, что импорт HTML будет объявлен устаревшим очень скоро.
Спасибо за Ваш быстрый ответ. Почему импорт HTML устарел? Будет ли чем их заменить?
Если вы используете хром, взгляните на консоль: [Устаревшее] Импорт HTML устарел и будет удален в M73 примерно в марте 2019 года. Вместо этого используйте модули ES. Дополнительные сведения см. в статье chromestatus.com/features/5144752345317376. Альтернативой на данный момент являются модули ES. Это скорее решение на чистом javascript.
Но как мы можем продолжать импортировать HTML-шаблоны?
Подробнее о том, почему здесь: полимер-проект.org/blog/…. В основном это связано с тем, что спецификация никогда не была единообразно реализована основными браузерами, и сообщество пришло к выводу, что до широкого распространения она была плохой.
Вы хотите продолжать использовать HTML-шаблоны или спрашиваете о «новой лучшей» альтернативе?
Мне нравится Vue.js, поэтому я хотел изначально использовать что-то, похожее на синтаксис файла .vue
, но если есть более элегантный способ сделать это, я весь внимание.
Я мог бы указать некоторые ресурсы модуля ES, но я гарантирую, что использование Vue.js будет лучшим решением (лучше документация, больше примеров в Интернете) прямо сейчас. Эти спецификации веб-компонентов часто меняются (например, импорт HTML устарел), и, если у вас нет веских причин (например, упрямый работодатель) для выбора нативных веб-компонентов, я бы полностью остановился на Vue.js. Кроме того, если или когда веб-компоненты станут действительно зрелым стабильным стандартом, наверняка будут способы генерировать/мигрировать веб-компоненты из кода vue.
@acdcjunior На самом деле я пишу эссе об IPFS, протоколе, предназначенном для замены HTTP и полностью бессерверном. Я спрашивал себя, как продолжать создавать шаблоны без веб-серверов, и дело в том, что даже интерфейсные фреймворки, такие как Vue или React, нуждаются в сервере Node. Вот почему я хотел задокументировать собственные решения, такие как веб-компоненты.
Vue/React на самом деле не нуждается в сервере узла. Продуктом приложения vue/react может быть всего один большой файл .js
(также известный как «пакет»), который импортируется на страницу с помощью обычного тега <script>
и включает в себя все (даже встроенные HTML и CSS). Только Vue/React ОЧЕНЬ нужен сервер узла, если вы хотите выполнять рендеринг на стороне сервера, но эта функция не всегда нужна (мягко говоря).
Да, я знаю, особенно Vue можно использовать на стороне браузера, но использование компонентов становится намного сложнее. Короче говоря, вы не можете использовать файлы .vue
в браузере.
имейте в виду, что <link rel = "import">` исчезает и больше не должен использоваться. Модули ES6 — один из способов заменить его.