不只 Vue3 , 尤大在 github 还更新了这个
作者:陈大鱼头 github:KRISACHAN
前言
近期前端最火的话题莫过于 Vue v3.0.0 release 的发布了。
不过除了 Vue 3 之外,鱼头在尤大的 github 上还发现了悄咪咪上线的DEMO - vue-lit 。
下载下来之后发现还挺有意思的,所以就来跟大家一起分享下。
正文
项目 README.md 里有这么一句话:
Proof of concept mini custom elements framework powered by @vue/reactivity and lit-html.
由 @vue/reactivity 和 lit-html 提供支持的概念性迷你 custom elements (自定义标签)框架。
下载下来之后发现这是尤大一个实验性的玩具DEMO(当然后续会发展得如何,那就看尤大了)。
项目目录如下:
在浏览器打开 example.html
,我们能看到:
然后 DEMO 代码如下(由于代码太长,本文仅展示部分代码):
<my-component>my-component>
<script type="module">
import {
defineComponent,
reactive,
html,
onMounted,
onUpdated,
onUnmounted
} from './index.js'
defineComponent('my-component', () => {
const state = reactive({
text: 'hello',
show: true
})
const toggle = () => {
state.show = !state.show
}
const onInput = e => {
state.text = e.target.value
}
return () => html`
<button @click=${toggle}>toggle childbutton>
<p>
${state.text} <input value=${state.text} @input=${onInput}>
p>
${state.show ? html`<my-child msg=${state.text}>my-child>` : ``}
`
})
script>
看到这里就明白了,这是一个让 Web Components
支持类 Vue
语法的小工具。
我们再来看看源码(由于代码太长,本文仅展示除了生命周期以外的核心代码):
import { render } from 'https://unpkg.com/lit-html?module'
import {
shallowReactive,
effect
} from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js'
let currentInstance
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, propDefs, factory) {
if (typeof propDefs === 'function') {
factory = propDefs
propDefs = []
}
customElements.define(
name,
class extends HTMLElement {
static get observedAttributes() {
return propDefs
}
constructor() {
super()
const props = (this._props = shallowReactive({}))
currentInstance = this
const template = factory.call(this, props)
currentInstance = null
const root = this.attachShadow({ mode: 'closed' })
effect(() => {
render(template(), root)
})
}
}
)
}
export * from 'https://unpkg.com/lit-html?module'
export * from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js'
这里我们来介绍下这个DEMO所涉及到的五个概念
@vue/reactivity
这是 Vue3 里比较重要的一个模块,它是 Composition API 的核心,用于实现数据响应。
shallowReactive
shallowReactive()
是 Composition API 之一,用于响应数据的第一层,类似于浅拷贝。
调用方式如下:
import {
shallowReactive,
isReactive
} from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js'
const props = shallowReactive({ n: 1 })
console.log(isReactive(props.n)) // false
console.log(isReactive(props)) // true
如上所示,props
才是一个 reactive
对象,而 props.n
不是
effect
effect()
则是一个观察者,调用方法如下:
import {
effect,
reactive
} from 'https://unpkg.com/@vue/reactivity/dist/reactivity.esm-browser.js'
let dummy
const counter = reactive({ num: 0 })
effect(() => (dummy = counter.num))
console.log(dummy === 0) // true
counter.num = 7
console.log(dummy === 7) // true
lit-html
距 官网 介绍,它是一个高效,富有表现力,可扩展性的 HTML 模板。它支持创建跟更新 DOM,也兼容所有的浏览器。
使用方式如下:
import {
html,
render
} from 'https://unpkg.com/lit-html?module'
let sayHello = (name) => html`<h1>Hello ${name}h1>`
render(sayHello('World'), document.body)
render(sayHello('Everyone'), document.body)
这个时候页面就会渲染出一个
,效果如下:Hello Everyone
还挺好用,不过网上对其褒贬不一,有兴趣的可以去搜索引擎搜一搜,本文不作展开。
Web Components
至于 Web Components 应该是老生常谈的技术了,简单来说就是原生的组件化技术,简单的例子如下:
<h1><context-span>examplecontext-span>h1>
<script src="./wc.js">script>
// wc.js
class ContextSpan extends HTMLElement {
constructor() {
super();
const style = document.createElement('style');
const span = document.createElement('span');
span.textContent = this.textContent;
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(style);
shadowRoot.appendChild(span);
style.textContent = `
span:hover { text-decoration: underline; }
:host-context(h1) { font-style: italic; }
:host-context(h1):after { content: " - 我是一个H1" }
:host { background: rgba(0,0,0,0.1); padding: 2px 5px; }
`;
}
}
customElements.define('context-span', ContextSpan);
效果如下:
vue-lit
我们回到 vue-lit 来,vue-lit 有可能只是尤大一时兴起的玩具,但是也有可能是 vue 结合 原生组件的第一步。
在 Vue 跟 React 此类前端框架出来不久之后,Web Components 就应运而生,虽然直到如今地位还不能跟这些前端框架相比,但是 Web Components 始终是浏览器的一大发展,极有可能就取代众多前端框架成为新的开发模式,毕竟当年 JQuery 大火之后,浏览器也出了许许多多模拟它 API 的原生函数。
所以看到这个工具,鱼头也是非常激动,虽然不确定后续会如何发展,但是对于在 Web Components 里使用 Vue 的这种模式,还是非常期待的。
后记
如果你喜欢探讨技术,或者对本文有任何的意见或建议,非常欢迎加鱼头微信好友一起探讨,当然,鱼头也非常希望能跟你一起聊生活,聊爱好,谈天说地。鱼头的微信号是:krisChans95 也可以扫码关注公众号,订阅更多精彩内容。