Без разрешения не может быть воспроизведен, оригинальный адрес:GitHub.com/Axuebian/art…
написать впереди
Днем 18 сентября по пекинскому времени Юда разместил сообщение на Weibo, и было немного людей, которые говорили резко. Увидев это выражение, все поняли, что должно произойти что-то большое. Конечно же, на момент написания этой статьиGitHubЯ посмотрел на это и только что наткнулся на выпуск:
Мы знаем, что общее программное обеспечение с открытым исходным кодомreleaseтолько одинОкончательный версия, взгляните на официальную информацию об этомreleaseВведение версии:
Today we are proud to announce the official release of Vue.js 3.0 "One Piece".
больше об этомreleaseДля получения информации о версии выполните следующие действия:GitHub.com/v UE JS/v UE-вы…
Кроме того, я в ЮтеGitHubнашел еще одну вещь наvue-lit, моя интуиция подсказывает мне, что это еще один ххх следующего поколения, ориентированный на будущее, поэтому я щелкнул и посмотрел, что это была за новая игрушка.
Hello World
Proof of concept mini custom elements framework powered by @vue/reactivity and lit-html.
Похоже на отличную попытку проверки концепции, см.custom elementа такжеlit-html, слепая догадка, это программа, которая может рендериться прямо в браузереvueнаписаноWeb ComponentИнструмент.
упоминается здесь
lit-html, который будет представлен позже.
По словам ЮдыDemo, давай попробуемHello World:
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module">
import {
defineComponent,
reactive,
html,
onMounted
} from 'https://unpkg.com/@vue/lit@0.0.2';
defineComponent('my-component', () => {
const state = reactive({
text: 'Hello World',
});
function onClick() {
alert('cliked!');
}
onMounted(() => {
console.log('mounted');
});
return () => html`
<p>
<button @click=${onClick}>Click me</button>
${state.text}
</p>
`;
})
</script>
</head>
<body>
<my-component />
</body>
</html>
Откройте это напрямую без каких-либо инструментов компиляции и упаковкиindex.html, который выглядит нормально:
!
Как видите, то, что здесь отображается,Web Component,а такжеmountedЖизненный цикл также запускается.
О lit-html и lit-element
Смотретьvue-litПеред этим давайте разбиратьсяlit-htmlа такжеlit-ement, эти две штуки на самом деле уже давно нет, может не все понимают.
lit-html
lit-htmlМногие люди не могут быть знакомы с этим или даже не видели.
Так что же это? ответМеханизм шаблонов HTML.
Если нет ощущения тела, я задаю вопрос,ReactЧто такое основные вещи? Все ответят:jsx,Virtual-DOM,diff, да, это то, что составляетUI = f(data)изReact.
приди и посмотриjsxсинтаксис:
function App() {
const msg = 'Hello World';
return <div>{msg}</div>;
}
посмотри сноваlit-htmlсинтаксис:
function App() {
const msg = 'Hello World';
return html`
<div>${msg}</div>
`;
}
мы знаемjsxЭто последний слой, который должен быть скомпилирован?createElement … а такжеlit-htmlне то же самое, оно основано наtagged template, заставляя его работать в браузере без компиляции, иHTML TemplateСочетание того, как играть и как играть, расширяет возможности сильнее, не так ли ароматно?
Конечно, будь тоjsxещеlint-html,этоAppвсе нужноrenderк реальномуDOMначальство.
lint-html реализует компонент Button
Перейдите непосредственно к коду (опустите код стиля):
<!DOCTYPE html>
<html lang="en">
<head>
<script type="module">
import { html, render } from 'https://unpkg.com/lit-html?module';
const Button = (text, props = {
type: 'default',
borderRadius: '2px'
}, onClick) => {
// 点击事件
const clickHandler = {
handleEvent(e) {
alert('inner clicked!');
if (onClick) {
onClick();
}
},
capture: true,
};
return html`
<div class="btn btn-${props.type}" @click=${clickHandler}>
${text}
</div>
`
};
render(Button('Defualt'), document.getElementById('button1'));
render(Button('Primary', { type: 'primary' }, () => alert('outer clicked!')), document.getElementById('button2'));
render(Button('Error', { type: 'error' }), document.getElementById('button3'));
</script>
</head>
<body>
<div id="button1"></div>
<div id="button2"></div>
<div id="button3"></div>
</body>
</html>
Эффект:
представление
lit-htmlбыло бы лучше, чемReactПроизводительность лучше? Я не читал внимательно исходный код здесь и не проводил соответствующих экспериментов, поэтому не могу сделать вывод.
Но возьми дикую догадку,lit-htmlкласс не используетсяdiffВместо этого алгоритм напрямую основан на том жеtemplate, похоже, этот способ будет немного легче.
Тем не менее, вопрос, который мы часто задаем: «Какая польза от ключа при рендеринге списка?», это вlit-htmlНеужели нельзя решить. Если я удалю один из элементов в длинном списке, следуйтеlit-htmlоснованный на том жеtemplateВесь лонг-лист обновится один раз, а производительность сильно ухудшится.
// TODO: зарыть дыру и посмотреть позже
lit-element
lit-elementЧто это?
Ключевые слова:web components.
пример:
import { LitElement, html } from 'lit-element';
class MyElement extends LitElement {
static get properties() {
return {
msg: { type: String },
};
}
constructor() {
super();
this.msg = 'Hello World';
}
render() {
return html`
<p>${this.msg}</p>
`;
}
}
customElements.define('my-element', MyElement);
Эффект:
В заключение: класс можно использоватьReactграмматика для написанияWeb Component.
so, lit-elementЯвляется ли созданиеWeb Componentизbase class. Проанализируйте приведенную выше демонстрацию,lit-elementЧто сделал:
-
static get properties: Могу
setterизstate -
constructor: инициализировать
state -
render: пройти через
lit-htmlвизуализирует элемент и создастShadowDOM
Вкратце,lit-elementподчинятьсяWeb Componentsстандарт, этоclass, на основе которого можно быстро создатьWeb Component.
Подробнее о том, как использоватьlit-elementДля развития это не будет обсуждаться здесь.
Web Components
Является ли родная возможность браузера ароматной?
СказатьWeb ComponentsПрежде чем я хочу спросить вас всех, вы все еще помнитеjQueryДа, он запоминается своим удобным селектором. но потомdocument.querySelectorэтоAPIпоявился и широко используется, все, кажется, постепенно забываютjQuery.
родной браузерAPIЭто достаточно хорошо для использования, нам это не нужно для работыDOMпри использованииjQuery.
Позже, вы долго не эксплуатировали его напрямую?DOMуже?
Да, из-заReact / VueПоявление рамки (библиотеки) помогло нам сделать много вещей, и мы больше не можем пройти через сложныеDOM APIработатьDOM.
Что я хочу сказать, так это то, что однажды, если собственные возможности браузера будут достаточно хороши для использования,ReactПодождите, будет ли это похожеjQueryЗаменяется ли он родными возможностями браузера?
составной
картинаReact / VueДругие фреймворки (библиотеки) делают то же самое, и нативные возможности браузеров не могли быть реализованы раньше, например, создание многократно используемого компонента, который можно отображать вDOMв любом месте.
что теперь? Кажется, мы можем не использовать произвольные фреймворки и библиотеки или даже упаковывать и компилировать, просто передатьWeb ComponentsТакие нативные возможности браузера позволяют создавать повторно используемые компоненты.Откажемся ли мы сейчас от так называемых фреймворков и библиотек и будем использовать нативные?APIили использовать на основеWeb ComponentsСтандартные фреймворки и библиотеки разрабатывать?
Конечно, будущее неизвестно
Я не безмозглый разоблачитель веб-компонентов, но нам нужно программировать на будущее.
приди и посмотриWeb Componentsнекоторые основные функции.
Пользовательские элементы: пользовательские элементы
Пользовательские элементы, как следует из названия, определяются пользователем.HTMLэлемент, черезCustomElementRegistryизdefineопределить, например:
window.customElements.define('my-element', MyElement);
потом напрямую через<my-element />использовал.
Согласно спецификации их два.Custom elements:
-
Autonomous custom elements: независимый элемент, не наследует
HTMLЭлемент, когда используется напрямую<my-element /> -
Customized buld-in elements: унаследовано от
HTMLэлементы, такие как через{ extends: 'p' }выявить унаследованное отpэлемент, необходимый при использовании<p is="my-element"></p>
дваCustom elementsТакже есть отличия в реализации:
// Autonomous custom elements
class MyElement extends HTMLElement {
constructor() {
super();
}
}
// Customized buld-in elements:继承自 p 元素
class MyElement extends HTMLParagraphElement {
constructor() {
super();
}
}
Подробнее о пользовательских элементах
Функции жизненного цикла
существуетCustom elementsВ конструкторе можно указать несколько функций обратного вызова, которые будут вызываться при разном времени жизни элемента.
-
connectedCallback: элемент сначала вставляется в документ
DOMВремя -
disconnectedCallback: элемент из документа
DOMпри удалении в - adoptedCallback: когда элемент перемещается в новый документ
- attributeChangedCallback: Когда элемент добавляет, удаляет или изменяет свои собственные атрибуты
Давайте обратим внимание здесьattributeChangedCallback, заключается в том, что всякий раз, когда атрибуты элемента изменяются, будет выполняться функция обратного вызова, и будет получена соответствующая информация об элементе:
attributeChangedCallback(name, oldValue, newValue) {
// TODO
}
Важно помнить, что если вам нужноатрибутПосле изменения запуститеattributeChangedCallback()функция обратного вызова, вы должныконтролировать это свойство:
class MyElement extends HTMLElement {
static get observedAttributes() {
return ['my-name'];
}
constructor() {
super();
}
}
элементальmy-nameПри изменении свойства запускается метод обратного вызова.
Shadow DOM
Web ComponentsОчень важная функция, структура и стиль могут быть инкапсулированы внутри компонента, изолированы от остального кода на странице, эта функция черезShadow DOMвыполнить.
оShadow DOM, тут в основном хочу сказатьCSSОсобенности стилевой изоляции.Shadow DOMвнутри и снаружиselectorОни не могут быть получены друг от друга, поэтому нет возможности использовать внешние стили внутри, и, конечно, внешние не могут получить внутренние стили.
Какая от этого польза? фокус, изоляция стиля,Shadow DOMместнымHTMLа такжеCSS, который решает некоторые проблемы со стилем, напримерvueизscopeЧувство элемента, не заботьтесь о внутренней части элементаselectorа такжеCSS ruleБудет ли он перезаписан другими или случайно перезаписан чужими стилями? Следовательно, элементselectorочень простой:title / itemи т. д., без каких-либо ограничений по инструментам или именам.
Шаблоны: Шаблоны
в состоянии пройти<template>добавитьWeb ComponentизShadow DOMвнутреннийHTMLсодержание:
<body>
<template id="my-paragraph">
<style>
p {
color: white;
background-color: #666;
padding: 5px;
}
</style>
<p>My paragraph</p>
</template>
<script>
customElements.define('my-paragraph',
class extends HTMLElement {
constructor() {
super();
let template = document.getElementById('my-paragraph');
let templateContent = template.content;
const shadowRoot = this.attachShadow({mode: 'open'}).appendChild(templateContent.cloneNode(true));
}
}
)
</script>
<my-paragraph></my-paragraph>
</body>
Эффект:
мы знаем,<template>не будет отображаться напрямую, поэтому мы можем определить несколько<template>Затем выберите визуализацию различных элементов в соответствии с различными условиями при настройке элементов.<template>? Ответ, конечно же: да.
vue-lit
представилlit-html/elementа такжеWeb Components, вернемся к Йоде этоvue-lit.
Сначала мы видим вVue 3.0изReleaseЕсть такой абзац:
The @vue/reactivity module exports functions that provide direct access to Vue's reactivity system, and can be used as a standalone package. It can be used to pair with other templating solutions (e.g. lit-html) or even in non-UI scenarios.
Я имею в виду, наверное@vue/reactivityМодули и подобноеlit-htmlсо схемой также можно спроектировать прямой доступVueРешения для адаптивных систем.
Случайность не, да, это неvue-lit?
Анализ исходного кода
import { render } from 'https://unpkg.com/lit-html?module'
import {
shallowReactive,
effect
} from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js'
-
lit-htmlпредоставить ядроrenderспособность -
@vue/reactiityпоставкаVueСила отзывчивой системы
Вот небольшое объяснениеshallowReactiveа такжеeffect, без расширения:
shallowReactive: Простое понимание - это «поверхностный ответ», аналогичный «поверхностному копированию», это только первый уровень данных ответа.
const state = shallowReactive({
a: 1,
b: {
c: 2,
},
})
state.a++ // 响应式
state.b.c++ // 非响应式
effect: Простое пониманиеwatcher
const state = reactive({
name: "前端试炼",
});
console.log(state); // 这里返回的是Proxy代理后的对象
effect(() => {
console.log(state.name); // 每当name数据变化将会导致effect重新执行
});
Затем посмотрите вниз:
export function defineComponent(name, propDefs, factory) {
// propDefs
// 如果是函数,则直接当作工厂函数
// 如果是数组,则监听他们,触发 attributeChangedCallback 回调函数
if (typeof propDefs === 'function') {
factory = propDefs
propDefs = []
}
// 调用 Web Components 创建 Custom Elements 的函数
customElements.define(
name,
class extends HTMLElement {
// 监听 propDefs
static get observedAttributes() {
return propDefs
}
constructor() {
super()
// 创建一个浅响应
const props = (this._props = shallowReactive({}))
currentInstance = this
const template = factory.call(this, props)
currentInstance = null
// beforeMount 生命周期
this._bm && this._bm.forEach((cb) => cb())
// 定义一个 Shadow root,并且内部实现无法被 JavaScript 访问及修改,类似 <video> 标签
const root = this.attachShadow({ mode: 'closed' })
let isMounted = false
// watcher
effect(() => {
if (!isMounted) {
// beforeUpdate 生命周期
this._bu && this._bu.forEach((cb) => cb())
}
// 调用 lit-html 的核心渲染能力,参考上文 lit-html 的 Demo
render(template(), root)
if (isMounted) {
// update 生命周期
this._u && this._u.forEach((cb) => cb())
} else {
// 渲染完成,将 isMounted 置为 true
isMounted = true
}
})
}
connectedCallback() {
// mounted 生命周期
this._m && this._m.forEach((cb) => cb())
}
disconnectedCallback() {
// unMounted 生命周期
this._um && this._um.forEach((cb) => cb())
}
attributeChangedCallback(name, oldValue, newValue) {
// 每次修改 propDefs 里的参数都会触发
this._props[name] = newValue
}
}
)
}
// 挂载生命周期
function createLifecycleMethod(name) {
return (cb) => {
if (currentInstance) {
;(currentInstance[name] || (currentInstance[name] = [])).push(cb)
}
}
}
// 导出生命周期
export const onBeforeMount = createLifecycleMethod('_bm')
export const onMounted = createLifecycleMethod('_m')
export const onBeforeUpdate = createLifecycleMethod('_bu')
export const onUpdated = createLifecycleMethod('_u')
export const onUnmounted = createLifecycleMethod('_um')
// 导出 lit-hteml 和 @vue/reactivity 的所有 API
export * from 'https://unpkg.com/lit-html?module'
export * from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js'
Упрощенная версия полезна для понимания
Глядя в целом, для лучшего понимания, мы можем упростить его, не рассматривая жизненный цикл:
import { render } from 'https://unpkg.com/lit-html?module'
import {
shallowReactive,
effect
} from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js'
export function defineComponent(name, factory) {
customElements.define(
name,
class extends HTMLElement {
constructor() {
super()
const root = this.attachShadow({ mode: 'closed' })
effect(() => {
render(factory(), root)
})
}
}
)
}
Только эти процессы:
- Создайте
Web ComponentsизCustom Elements - Создавать
Shadow DOMизShadowRootузел - будет передан в
factoryи созданный внутриShadowRootПередача узлаlit-htmlизrenderвыносить
Оглядываясь назад на DEMO, предоставленное Youda:
import {
defineComponent,
reactive,
html,
} from 'https://unpkg.com/@vue/lit'
defineComponent('my-component', () => {
const msg = 'Hello World'
const state = reactive({
show: true
})
const toggle = () => {
state.show = !state.show
}
return () => html`
<button @click=${toggle}>toggle child</button>
${state.show ? html`<my-child msg=${msg}></my-child>` : ``}
`
})
my-componentприближаетсяname, вторая — функция, т. е. входящаяfactory, по фактуlit-htmlПервый параметр просто вводит@vue/reactivityизreactiveспособность ставитьstateстал отзывчивым.
нет проблем, иVue 3.0 ReleaseСогласованный,@vue/reactivityможет иlit-htmlсотрудничать, чтобыVueа такжеWeb ComponentsИнтересно их собрать.
напиши в конце
Может быть, Youda просто написал эту маленькую игрушку по прихоти, но видно, что это действительно может быть большой тенденцией.
Угадайте, что эти ключевые слова внезапно взорвутся в ближайшем будущем:Unbundled / ES Modules / Web components / Custom Element / Shadow DOM...
Стоит ли ждать?
Мышление может быть относительно поверхностным, а письмо ограничено, и вы можете указать на недостатки.
Прием на работу
Международная команда Alibaba по инфраструктуре набирает внешних специалистов P6/P7, базу в Ханчжоу, строительство инфраструктуры, расширение возможностей бизнеса... Многое можно сделать.
Требуется знакомство с Engineering/Node/React... Вы можете отправить свое резюме прямо наyibin.xb@alibaba-inc.com.