You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
介绍了 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.
写在前面
我在尤大的
GitHub
上发现了一个有趣的东西 vue-lit,直觉告诉我这又是一个啥面向未来的下一代 xxx,所以我就点进去看了一眼是啥新玩具。Hello World
看上去是尤大的一个验证性的尝试,看到
custom element
和lit-html
,盲猜一把,是一个可以直接在浏览器中渲染vue
写法的Web Component
的工具。按照尤大给的
Demo
,我们来试一下Hello World
:不用任何编译打包工具,直接打开这个
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
的语法:再看看
lit-html
的语法:我们知道
jsx
是需要编译的它的底层最终还是createElement
....。而lit-html
就不一样了,它是基于tagged template
的,使得它不用编译就可以在浏览器上运行,并且和HTML Template
结合想怎么玩怎么玩,扩展能力更强,不香吗?当然,无论是
jsx
还是lint-html
,这个App
都是需要render
到真实DOM
上。lint-html 实现一个 Button 组件
直接上代码(省略样式代码):
效果:
性能
lit-html
会比React
性能更好吗?这里我没仔细看过源码,也没进行过相关实验,无法下定论。但是可以大胆猜测一下,
lit-html
没有使用类diff
算法而是直接基于相同template
的更新,看上去这种方式会更轻量一点。但是,我们常问的一个问题 “在渲染列表的时候,key 有什么用?”,这个在
lit-html
是不是没法解决了。我如果删除了长列表中的其中一项,按照lit-html
的基于相同template
的更新,整个长列表都会更新一次,这个性能就差很多了啊。lit-element
lit-element 这又是啥呢?
关键词:web components。
例子:
效果:
结论:可以用类
React
的语法写Web Component
。so,
lit-element
是一个可以创建Web Component
的base class
。分析一下上面的 Demo,lit-element
做了什么事情:setter
的state
state
lit-html
渲染元素,并且会创建ShadowDOM
总之,
lit-element
遵守Web Components
标准,它是一个class
,基于它可以快速创建Web Component
。更多关于如何使用
lit-element
进行开发,在这里就不展开说了。Web Components
浏览器原生能力香吗?
说
Web Components
之前我想先问问大家,大家还记得jQuery
吗,它方便的选择器让人难忘。但是后来document.querySelector
这个API
的出现并且广泛使用,大家似乎就慢慢地淡忘了jQuery
。浏览器原生
API
已经足够好用,我们并不需要为了操作DOM
而使用jQuery
。You Dont Need jQuery
再后来,是不是很久没有直接操作过
DOM
了?是的,由于
React
/Vue
等框架(库)的出现,帮我们做了很多事情,我们可以不用再通过复杂的DOM API
来操作DOM
。我想表达的是,是不是有一天,如果浏览器原生能力足够好用的时候,
React
等是不是也会像jQuery
一样被浏览器原生能力替代?组件化
像
React
/Vue
等框架(库)都做了同样的事情,在之前浏览器的原生能力是实现不了的,比如创建一个可复用的组件,可以渲染在DOM
中的任意位置。现在呢?我们似乎可以不使用任意的框架和库,甚至不用打包编译,仅是通过
Web Components
这样的浏览器原生能力就可以创建可复用的组件,是不是未来的某一天我们就抛弃了现在所谓的框架和库,直接使用原生API
或者是使用基于Web Components
标准的框架和库来开发了?我不是一个 Web Components 的无脑吹,只不过,我们需要面向未来编程。
来看看
Web Components
的一些主要功能吧。Custom elements: 自定义元素
自定义元素顾名思义就是用户可以自定义
HTML
元素,通过CustomElementRegistry
的define
来定义,比如:然后就可以直接通过
<my-element />
使用了。根据规范,有两种
Custom elements
:HTML
元素,使用时可以直接<my-element />
HTML
元素,比如通过{ extends: 'p' }
来标识继承自p
元素,使用时需要<p is="my-element"></p>
两种
Custom elements
在实现的时候也有所区别:更多关于 Custom elements
生命周期函数
在
Custom elements
的构造函数中,可以指定多个回调函数,它们将会在元素的不同生命时期被调用。DOM
时DOM
中删除时我们这里留意一下
attributeChangedCallback
,是每当元素的属性发生变化时,就会执行这个回调函数,并且获得元素的相关信息:需要特别注意的是,如果需要在元素某个属性变化后,触发
attributeChangedCallback()
回调函数,你必须监听这个属性:元素的
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
等,不需要任何的工具或者命名的约束。更多关于 Shadow DOM
Templates: 模板
可以通过
<template>
来添加一个Web Component
的Shadow DOM
里的HTML
内容:效果:
我们知道,
<template>
是不会直接被渲染的,所以我们是不是可以定义多个<template>
然后在自定义元素时根据不同的条件选择渲染不同的<template>
?答案当然是:可以。更多关于 Templates
vue-lit
介绍了
lit-html/element
和Web Components
,我们回到尤大这个vue-lit
。首先我们看到在
Vue 3.0
的Release
里有这么一段:意思大概就是说
@vue/reactivity
模块和类似lit-html
的方案配合,也能设计出一个直接访问Vue
响应式系统的解决方案。巧了不是,对上了,这不就是
vue-lit
吗?源码解析
lit-html
提供核心render
能力@vue/reactiity
提供Vue
响应式系统的能力这里稍带解释一下
shallowReactive
和effect
,不展开:shallowReactive:简单理解就是“浅响应”,类似于“浅拷贝”,它仅仅是响应数据的第一层
effect:简单理解就是
watcher
接着往下看:
简化版有助于理解
整体看下来,为了更好地理解,我们不考虑生命周期之后可以简化一下:
也就这几个流程:
Web Components
的Custom Elements
Shadow DOM
的ShadowRoot
节点factory
和内部创建的ShadowRoot
节点交给lit-html
的render
渲染出来回过头来看尤大提供的 DEMO:
my-component
是传入的name
,第二个是一个函数,也就是传入的factory
,其实就是lit-html
的第一个参数,只不过引入了@vue/reactivity
的reactive
能力,把state
变成了响应式。没毛病,和
Vue 3.0 Release
里说的一致,@vue/reactivity
可以和lit-html
配合,使得Vue
和Web Components
结合到一块儿了,是不是还挺有意思。写在最后
可能尤大只是一时兴起,写了这个小玩具,但是可以见得这可能真的是一种大趋势。
猜测不久将来这些关键词会突然就爆发:
Unbundled
/ES Modules
/Web components
/Custom Element
/Shadow DOM
...是不是值得期待一下?
思考可能还比较浅,文笔有限,不足之处欢迎大家指出。
招聘
阿里国际化团队基础架构组招聘前端 P6/P7,base 杭州,基础设施建设,业务赋能... 很多事情可以做。
要求熟悉 工程化/ Node/ React... 可直接发送简历至
yibin.xb@alibaba-inc.com
。The text was updated successfully, but these errors were encountered: