petite-vue是Vue对于渐进增强进行优化的一种distribution(没想好怎么翻译)。它提供了与标准Vue相同的模板语法和响应式性心智模型,它是专门为在由服务器渲染具有少量交互的页面而存在的。服务端渲染一般会有注水(hydrate)过程,而在petite-vue要做的事情比较简单,被称为"洒水(sprinkling)"
多说无益,直接举例
我们可以直接创建一个html文件,把下面简单的几行代码粘贴进去:
<div v-scope="{ count: 0 }">
{{ count }}
<button @click="count++">加1</button>
</div>
<script src="https://unpkg.com/petite-vue" init></script>
打开这个文件后,页面呈现出一个数字0,和一个加1按钮,每次点击按钮,数字便会累加1, 对于这几行代码,用过Vue的同学一眼就能看懂,其实就是一个Vue模板,上面绑定了button的click事件, 每次点击的时候,count就++。
正常我们写Vue的时候,都会从new Vue或者createApp开始,但是上面没有显式的js代码,这是怎么回事呢?
事实上,我们看到script标签上多了一个init属性,这就是用于自动初始化Vue的标识,然后通过div标签上的v-scope属性来声明 数据,div就变成了一个Vue组件。
手动初始化
上面在script标签上使用init属性后,petite-vue会自动初始化,然后我们也可以通过全局暴露的PetiteVue属性进行手动初始化:
<div v-scope="{ count: 0 }">
{{ count }}
<button @click="count++">inc</button>
</div>
<script src="https://unpkg.com/petite-vue"></script>
<script>
PetiteVue.createApp().mount()
</script>
上面代码中我们使用PetiteVue手动初始化,而数据仍定义在v-scope中,其实我们也可以把数据初始化在createApp中:
PetiteVue.createApp({
count: 0
}).mount()
另外petite-vue还支持手动指定挂载点,也支持初始化多个应用,更简单的组件复用,全局状态管理,指令等, 具体可以去查看README自己尝试。
再看看,面向模板的声明式编程
以前我们写一个Vue组件,通常需要定义data、method、lifecycle、effect、watch等等, 而现在我们要实现一些简单的逻辑时,这些东西都可以直接写在模板上,而不用写一行额外的js:
<div
v-scope="{ count: 0 }"
@mounted="console.log('mounted on: ', $el)"
>
<p v-effect="$el.textContent = count"></p>
<button @click="count++">inc</button>
</div>
<script src="https://unpkg.com/petite-vue" init></script>
上面我们为最外层div添加了@mounted属性,这个就是被挂载的生命周期,属性值就是我们要做的具体逻辑,其中el也就代表的是 这个p元素。
与之相似的Alpine
README中有说到petite-vue与一个叫Alpine[2]框架的相似性,感兴趣同学可以过去看看,笔者简单看了看 Alpine这东西果然和petite-vue非常相似:
<div x-data="{ open: false }">
<button @click="open = true">Expand</button>
<span x-show="open">
Content...
</span>
</div>
<script src="//unpkg.com/alpinejs"></script>
上面是Alpine的逻辑,实现一个点击按钮可以展示或隐藏Content的功能, 两个框架都将关注点放在了模板上,而Alpine的功能会更多一些,也更重。petite-vue基于@vue/reactivity实现,非常轻量,大约只有5~7kb。