单文件组件(SFC)及语法原创内容,盗版必究。
【作者:唐霜】【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】【原创内容,转载请注明出处】转载请注明出处:www.tangshuang.netVue 和 svelte 都具有自己的文本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。件格式,在 .vue 或 .svelte本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。 文件中,我们描述了一个组件的完整上下文【本文受版权保护】转载请注明出处:www.tangshuang.net。单文件组件这种组织方式特别适合单一功能【本文受版权保护】转载请注明出处:www.tangshuang.net的组件发布,你可以通过比较少的代码量,表【原创内容,转载请注明出处】【原创不易,请尊重版权】达一个 UI 交互要做什么事情。
【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。因此,我在写 sfcjs 时借鉴 sve【原创不易,请尊重版权】【原创不易,请尊重版权】lte 的语法设计,在不改变原始 htm原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。l, js 和 css 语法的基础上,增【原创内容,转载请注明出处】【转载请注明来源】加了一些特定的形式。一个 sfc 包含三本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.net个部分 script, style, h本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】tml,具体如下:
【本文受版权保护】【未经授权禁止转载】转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。<script> let a =10;functionincrease() { a ++; } </script> <style> .foo { font-size: [[a]]px; } </style> <div> <span class="foo">{{a}}</span> <button @click="increase()">inc</button> </div>
这份示例代码中包含了组件内变量的声明和使【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】用、动态 css 语法、动态 html 【原创内容,转载请注明出处】【版权所有,侵权必究】语法。由于 sfcjs 只是一个 POC本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】,很多细节没有深入,所以只能展示一些比较本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net粗浅的例子。
【原创不易,请尊重版权】【未经授权禁止转载】【版权所有,侵权必究】转载请注明出处:www.tangshuang.net我们将上面这段代码放在一个 .htm 文【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。件中,这样编辑器可以帮助我们为代码高亮。本文版权归作者所有,未经授权不得转载。原创内容,盗版必究。这个 .htm 文件即我们的一个组件文件转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。。
本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。【访问 www.tangshuang.net 获取更多精彩内容】【本文受版权保护】基于AMD加载组件本文作者:唐霜,转载请注明出处。
本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net【关注微信公众号:wwwtangshuangnet】原创内容,盗版必究。【未经授权禁止转载】我一开始想直接用 seajs 做加载引擎著作权归作者所有,禁止商业用途转载。【原创内容,转载请注明出处】,但后来觉得没必要,因为我不需要严格的遵著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net循 AMD 规范。但基于其实现原理,我们【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。可以在需要的时候加载 sfc,实现文件异转载请注明出处:www.tangshuang.net【本文首发于唐霜的博客】步加载和组件异步实例化。
【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。【作者:唐霜】【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。在一个组件中引用另外一个组件,需要特殊的【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。引用协议。
【作者:唐霜】【作者:唐霜】本文作者:唐霜,转载请注明出处。【关注微信公众号:wwwtangshuangnet】<script>
import SomeComponent from 'sfc:../components/some-component.htm'
const title = 'xxx'
</script>
<div>
<some-component :title="title"></some-component>
</div>
在 import from 时,使用 s本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netfc: 作为协议前缀,遇到一个路径时就认本文作者:唐霜,转载请注明出处。原创内容,盗版必究。为是一个组件,然后在 html 模板中使【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。用这个组件。SomeComponent 【本文首发于唐霜的博客】【原创不易,请尊重版权】如果依赖了其他组件,它不会立即去请求这些转载请注明出处:www.tangshuang.net【转载请注明来源】组件的 sfc,而是会等到 SomeCo本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】mponent 实例化的时候,再去请求。
【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net本文作者:唐霜,转载请注明出处。运行时编译【未经授权禁止转载】
本文作者:唐霜,转载请注明出处。【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】组件 sfc 的语法显然是无法在浏览器直【转载请注明来源】【关注微信公众号:wwwtangshuangnet】接运行的,我们需要做一个编译,而这个编译转载请注明出处:www.tangshuang.net原创内容,盗版必究。,我们直接在前端做。我们利用 webwo【本文受版权保护】【版权所有】唐霜 www.tangshuang.netrker 或 webassembly 等【本文首发于唐霜的博客】【原创不易,请尊重版权】技术,不占用 js 运行时线程,编译完之【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。后,输出编译好的 js 脚本。输出的脚本【原创内容,转载请注明出处】本文作者:唐霜,转载请注明出处。以 blob 的形式,作为 script原创内容,盗版必究。【本文首发于唐霜的博客】 进行载入,此时,利用 AMD 的 de【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。fine,就可以让这个组件加入到我们的备【原创内容,转载请注明出处】未经授权,禁止复制转载。选组件中。
未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.net整个加载编译过程如下:【版权所有】唐霜 www.tangshuang.net
著作权归作者所有,禁止商业用途转载。未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。【原创不易,请尊重版权】未经授权,禁止复制转载。
这里的问题在于:1. 运行时编译,会不会未经授权,禁止复制转载。【作者:唐霜】性能不好?2. 安全性?
【原创不易,请尊重版权】【版权所有】唐霜 www.tangshuang.net【本文首发于唐霜的博客】【访问 www.tangshuang.net 获取更多精彩内容】我相信你了解过 vite,简单说,vit【版权所有,侵权必究】【版权所有,侵权必究】e 将 bundle 转化为单一文件网络【版权所有,侵权必究】【本文首发于唐霜的博客】,对每个文件进行编译,当该模块被使用时,本文作者:唐霜,转载请注明出处。原创内容,盗版必究。发出 http 请求该文件,http 到原创内容,盗版必究。【本文受版权保护】达服务器时,对该文件进行编译后返回编译后【关注微信公众号:wwwtangshuangnet】【访问 www.tangshuang.net 获取更多精彩内容】的代码。从这个点上讲,运行时编译用的是客【转载请注明来源】【原创内容,转载请注明出处】户端的资源,可能比 vite 还快。相反【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】,前端的性能瓶颈,可能在加载巨大的 bu【原创不易,请尊重版权】未经授权,禁止复制转载。ndle 的时候更明显。至于安全性,在 转载请注明出处:www.tangshuang.net本文作者:唐霜,转载请注明出处。compile 之前做一次 check 【关注微信公众号:wwwtangshuangnet】【转载请注明来源】也是应该的,这看具体场景,因为 sfc.【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.nethtm 的内容不是直接运行的脚本,只有它未经授权,禁止复制转载。本文作者:唐霜,转载请注明出处。被编译为 js 之后,才会真正运行。
未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】利用 web components 的设【本文受版权保护】著作权归作者所有,禁止商业用途转载。计
【访问 www.tangshuang.net 获取更多精彩内容】【作者:唐霜】著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】和 react 要用 render 函数原创内容,盗版必究。原创内容,盗版必究。来启动应用不同,sfcjs 如下启动一个【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】组件:
【未经授权禁止转载】【本文首发于唐霜的博客】【未经授权禁止转载】<sfc-view src="./app.htm"></sfc-view>
理论上,你可以在任意 web 应用中使用【版权所有,侵权必究】【原创内容,转载请注明出处】这个句式来渲染一个 sfcjs 的组件,转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。包括但不限于在 react 或 vue 【作者:唐霜】未经授权,禁止复制转载。中。组件的渲染结果,将被放在该元素的 s【作者:唐霜】【关注微信公众号:wwwtangshuangnet】hadowRoot 中,包含样式。
原创内容,盗版必究。转载请注明出处:www.tangshuang.net【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】样式隔离【访问 www.tangshuang.net 获取更多精彩内容】
【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。【转载请注明来源】未经授权,禁止复制转载。腾讯前端框架 转载请注明出处:www.tangshuang.netOmi【版权所有,侵权必究】 是基于 web components 原创内容,盗版必究。本文作者:唐霜,转载请注明出处。的,可以比较好的隔离样式,你可以借助它开【未经授权禁止转载】未经授权,禁止复制转载。发自己的 custom element 著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】来实现自己的 UI 组件。但是,这里有一本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。个问题在于,如果一个组件依赖于另一个组件原创内容,盗版必究。本文作者:唐霜,转载请注明出处。,那么必须把这两个组件打包在一起,甚至,本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net被依赖的组件在特定条件下并不会被用到。几著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】乎大部分框架和 omi 一样,都不是开箱【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】即用的(除了 jquery 或 alpi【未经授权禁止转载】著作权归作者所有,禁止商业用途转载。ne.js),我们没法马上体验它的开发效原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net果,而且,更要命的是,部分框架具有传染性【转载请注明来源】本文版权归作者所有,未经授权不得转载。,某些情况下,你只需要其中的某一个功能或【转载请注明来源】【访问 www.tangshuang.net 获取更多精彩内容】组件,但是,你不得不在外面给它一个很大的本文版权归作者所有,未经授权不得转载。转载请注明出处:www.tangshuang.net运行时(例如 react-dom),并且【本文受版权保护】【本文受版权保护】它不兼容(或很难)其他的技术栈。而基于 【作者:唐霜】【版权所有】唐霜 www.tangshuang.netweb components 则可以比较【转载请注明来源】著作权归作者所有,禁止商业用途转载。好的实现外围运行时无关,无论你在 rea【作者:唐霜】【版权所有,侵权必究】ct 中,还是 angular 中,都可未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。以使用基于 web components【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】 写的组件。
转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】我在写 sfcjs 时,想到这一点,组件【本文首发于唐霜的博客】原创内容,盗版必究。应该是自治的,开发者不应该去思考,当前这【原创内容,转载请注明出处】原创内容,盗版必究。个组件是否会(在样式上)影响其他组件的运【作者:唐霜】【作者:唐霜】行。你可以看下基于 sfcjs 写的两个本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】组件:
【版权所有,侵权必究】【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】<style>
.bar {
color: #ccc;
}
</style>
<button class="bar">ok</button>
<style>
.bar {
color: #999;
}
</style>
<button class="bar">yes</button>
上面这两个组件都定义了 .bar 这个类本文作者:唐霜,转载请注明出处。【未经授权禁止转载】,但是它们在同一个页面中使用时,不会相互【本文受版权保护】【关注微信公众号:wwwtangshuangnet】污染。
【关注微信公众号:wwwtangshuangnet】本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net【原创不易,请尊重版权】它的原理是,基于 shadowDOM 完原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】成渲染,因此,样式不会对其他元素产生影响【作者:唐霜】【转载请注明来源】。
本文作者:唐霜,转载请注明出处。【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。响应式动态样式转载请注明出处:www.tangshuang.net
【原创内容,转载请注明出处】【作者:唐霜】【未经授权禁止转载】原创内容,盗版必究。通过修改变量可以让布局的部分变更,那样式著作权归作者所有,禁止商业用途转载。【本文受版权保护】呢?在 vue 的一个提案著作权归作者所有,禁止商业用途转载。中,提出可以通过某种方式实现样式的响应式本文版权归作者所有,未经授权不得转载。【本文受版权保护】编程,具体如下:
本文作者:唐霜,转载请注明出处。【未经授权禁止转载】【本文受版权保护】【转载请注明来源】【转载请注明来源】<template>
<div class="text">hello</div>
</template>
<script>
export default {
data() {
return {
color: 'red'
}
}
}
</script>
<style vars="{ color }">
.text {
color: var(--color);
}
</style>
也就是通过在 css 中使用 var 来【本文首发于唐霜的博客】著作权归作者所有,禁止商业用途转载。标记变量。它基于css 变量原创内容,盗版必究。这个被广泛支持和接受的技术,但 vue 本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。的提案我觉得仍然暴露太多实现细节,在 s【作者:唐霜】【作者:唐霜】fcjs 中,结合语法,其响应式写法如下【原创内容,转载请注明出处】【转载请注明来源】:
本文版权归作者所有,未经授权不得转载。【作者:唐霜】【本文首发于唐霜的博客】【版权所有】唐霜 www.tangshuang.net【作者:唐霜】<script>
let age = 10;
function grow(e) {
// change variables may cause rerender
age ++;
}
</script>
<style>
.name {
color: #ffe;
}
.age {
color: rgb(
/* use js expression with `var('{{ ... }}')` */
var('{{ age * 5 > 255 ? 255 : age * 5 }}'),
var('{{ age * 10 > 255 ? 255 : age * 10 }}'),
var('{{ age * 3 > 255 ? 255 : age * 3 }}')
);
/* use variables with [[]] */
font-size: [[age]]px;
}
</style>
在 sfc 文件中,上下文是流畅的一体,【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。在 <script> 中定义著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。的变量,在 style 和 html 中著作权归作者所有,禁止商业用途转载。【本文首发于唐霜的博客】直接使用。当变量变化时,对应的样式值也发【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net生变化。
【版权所有】唐霜 www.tangshuang.net著作权归作者所有,禁止商业用途转载。原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net其具体原理是,我在 shadowRoot【本文受版权保护】【版权所有,侵权必究】 中建立了两块 <style>【本文受版权保护】未经授权,禁止复制转载。; 一块用于提供变量(会被动态更新内部文本文版权归作者所有,未经授权不得转载。【关注微信公众号:wwwtangshuangnet】本),另一块使用这些变量(永远不变)。
转载请注明出处:www.tangshuang.net【关注微信公众号:wwwtangshuangnet】【原创不易,请尊重版权】
在对应的变量发生变化的时候,第一块整个内本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.net容都会被重建,而第二块内容中会使用重建后未经授权,禁止复制转载。【访问 www.tangshuang.net 获取更多精彩内容】的样式重新渲染,从而达到动态更新样式的效【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net果。
【原创内容,转载请注明出处】【版权所有】唐霜 www.tangshuang.net【未经授权禁止转载】【转载请注明来源】【版权所有,侵权必究】无 virtual dom 的响应式【原创不易,请尊重版权】
【原创内容,转载请注明出处】著作权归作者所有,禁止商业用途转载。【版权所有,侵权必究】未经授权,禁止复制转载。【关注微信公众号:wwwtangshuangnet】进入 2021 年,新出现的几个热门框架【未经授权禁止转载】【版权所有】唐霜 www.tangshuang.net都不在基于 virtual dom 实现【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。响应式,一个重要的原因在于 virtua未经授权,禁止复制转载。【作者:唐霜】l dom 的成本巨大,且性能上并不占优【本文首发于唐霜的博客】未经授权,禁止复制转载。。
【未经授权禁止转载】【作者:唐霜】【未经授权禁止转载】转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net和 solidjs 一样,sfcjs 在【作者:唐霜】转载请注明出处:www.tangshuang.net编译时收集每一个 DOM 节点所依赖的变【原创不易,请尊重版权】【作者:唐霜】量,当对应的变量发生变化的时候,去重新计【原创内容,转载请注明出处】【本文受版权保护】算对应的值,并与当前状态进行比较,最后更本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。新 DOM 节点。这里的不同在于两点:1本文作者:唐霜,转载请注明出处。原创内容,盗版必究。. 发生变化的变量对应的 DOM 节点才【原创不易,请尊重版权】著作权归作者所有,禁止商业用途转载。会去计算,其他 DOM 节点即使依赖变量【原创内容,转载请注明出处】【原创内容,转载请注明出处】,但没有变化,不用计算。2. 直接对单个【访问 www.tangshuang.net 获取更多精彩内容】【访问 www.tangshuang.net 获取更多精彩内容】 DOM 节点进行是否需要更新的计算,而【本文首发于唐霜的博客】【未经授权禁止转载】不再拿整个组件的节点树来进行 diff。
转载请注明出处:www.tangshuang.net转载请注明出处:www.tangshuang.net本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】这个实现不算创新,甚至在早几年的时候就有著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】人这么做过。
【转载请注明来源】【本文首发于唐霜的博客】【版权所有,侵权必究】【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。对于 sfcjs 来说,魔法在于,基于原【原创不易,请尊重版权】本文作者:唐霜,转载请注明出处。始语法不需要做过多的编译,和 svelt【访问 www.tangshuang.net 获取更多精彩内容】【本文首发于唐霜的博客】e 不提供(或几乎没有)运行时不同,sf未经授权,禁止复制转载。【作者:唐霜】cjs 在运行时前置了一个很小的响应式内【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。核框架,所有组件的编译结果代码实质上是依【访问 www.tangshuang.net 获取更多精彩内容】本文作者:唐霜,转载请注明出处。赖于这个内核框架的。而这个内核框架在设计本文作者:唐霜,转载请注明出处。【转载请注明来源】 API 的时候,完全是为了搭配编译过程【本文受版权保护】【原创不易,请尊重版权】设计,所以,编译过程,就是把源代码通过匹原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。配、token 化等处理,做了代码转化,【本文受版权保护】转载请注明出处:www.tangshuang.net甚至都没有用到 AST 那一套。
【关注微信公众号:wwwtangshuangnet】著作权归作者所有,禁止商业用途转载。【未经授权禁止转载】【访问 www.tangshuang.net 获取更多精彩内容】原创内容,盗版必究。当然,这样做,并不是为了性能,完全是为了原创内容,盗版必究。【本文受版权保护】尝试一条无 virtual dom 的道本文作者:唐霜,转载请注明出处。【版权所有,侵权必究】路,为了乐趣。
【关注微信公众号:wwwtangshuangnet】【关注微信公众号:wwwtangshuangnet】【转载请注明来源】【关注微信公众号:wwwtangshuangnet】【原创内容,转载请注明出处】
