Без разрешения не может быть воспроизведен, оригинальный адрес: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
.