petite-vue简介
1、简介
petite-vue
是一种受Alpine
启发的替代发行版,它针对渐进增强
进行了优化。它提供了与标准Vue相同的模板语法和响应式模型,主要为渐进式增强已有的HTML
作了特别的优化。
1.1、渐进增强?
渐进增强
是一种允许Web
开发人员开始使用HTML
编程并根据需要包含其他技术的方法。您可以开始仅使用 HTML 静态构建网站,然后将交互性或客户端状态添加到页面。
1.2、特点
- 大小只有 5.8kb
- Vue 兼容模版语法
- 基于 DOM,就地转换
- 响应式驱动
- 无需构建
1.3、适用场景
- 前端逻辑不复杂、无需构建的项目
1.4、与Vue的区别
1.4.1、包体积
petite-vue
的包体积只有5.8kb
,而Vue
的包体积有33.7kb
,petite-vue
的包体积是Vue
的6.6%
。
1.4.2、模版语法
作为Vue
本身的一个子集,petite-vue
使用与Vue
大部分相同的语法,如插值语法
和@click事件侦听器
等。
1.4.3、响应式
petite-vue
使用与Vue
相同的响应式系统,这意味着您可以在petite-vue
中使用computed
和watch
等。
1.4.4、组件
petite-vue
不支持组件,因为petite-vue
不使用构建过程。
1.4.5、编译
标准Vue旨在使用构建步骤来构建具有大量交互的单页应用程序(SPA)
。Vue使用渲染函数来替换现有的DOM
模板,而另一方面,petite-vue
遍历现有的DOM
并对其进行变异,因此不需要构建步骤。
2、安装
2.1、自动初始化
petite-vue
无需构建流程即可使用, 只需从CDN
加载:
<body>
<script src="https://unpkg.com/petite-vue" defer init></script>
<div v-scope="{ count: 0 }">
<button @click="count--">-</button>
<span>{{ count }}</span>
<button @click="count++">+</button>
</div>
</body>
2.2、手动初始化
<body>
<div v-scope="{ count: 0 }">
<button @click="count--">-</button>
<span>{{ count }}</span>
<button @click="count++">+</button>
</div>
<script src="https://unpkg.com/petite-vue"></script>
<script>
PetiteVue.createApp().mount()
</script>
</body>
或者可以使用ES
模块
<body>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp().mount()
</script>
<div v-scope="{ count: 0 }">
<button @click="count--">-</button>
<span>{{ count }}</span>
<button @click="count++">+</button>
</div>
</body>
2.3、自定义构建
我们初始化petite-vue
时使用的是简写https://unpkg.com/petite-vue
,这对于原型设计来说很好,但对生产来说不是很好。我们希望避免解析和重定向成本,因此我们将在生产中使用完整的 URL。
- 全局构建生产URL: https://unpkg.com/[email protected]/dist/petite-vue.iife.js 公开 PetiteVue 全局并且还支持自动初始化。
- ESM 构建生产URL: https://unpkg.com/[email protected]/dist/petite-vue.iife.js 必须在
<scripttype="module">
块中使用。
3、自定义挂载语法
3.1、独家功能
3.1.1、v-scope
v-scope
是一个指令,用于标记由控制的页面区域petite-vue。还可以使用该v-scope指令来传递页面特定区域可以访问的状态。
3.1.2、v-effect
v-effect
是一个指令,当数值发生变化时都会重新运行
<input class="edit" v-effect="if(todo === editedTodo) $el.focus();" />
3.1.3、生命周期
- @mounted
- @unmounted
3.2、根作用域
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="vApp" v-cloak>
<p>{{ count }}</p>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
count: 0,
}).mount('#vApp')
</script>
</body>
</html>
3.3、显示挂载
TIP
可以指定一个目标元素挂载
<div id="v-pp" v-cloak>
<p>{{ count }}</p>
</div>
<div id="v-pp2" v-cloak>
<p>{{ count }}</p>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
count: 0,
}).mount('#v-app')
createApp({
count: 0,
}).mount('#v-app2')
</script>
3.4、生命周期
TIP
- @vue:mounted:监听dom挂载
- @vue:unmounted:监听dom卸载
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<div id="app" v-cloak>
<span @vue:mounted="onMounted1($el)">1</span>
<span
v-if="show"
@vue:mounted="onMounted2($el)"
@vue:unmounted="onUnmounted($el)"
>2</span>
<button @click="show = false">销毁span2</button>
</div>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
show: true,
onMounted1(el) {
console.log('onMounted1', el)
},
onMounted2(el) {
console.log('onMounted2', el)
},
onUnmounted(el) {
console.log('onUnmounted', el)
}
}).mount('#app')
</script>
</body>
</html>
WARNING
当使用@mounted
或@unmounted
无效时,可以使用@vue:mounted
或@vue:unmounted
3.5、组件
3.5.1、非template组件
<body>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
// 非模版组件
function Counter3(props) {
return {
count: props.initialCount,
inc() {
this.count++
},
mounted() {
console.log('mounted')
},
}
}
createApp({
Counter3,
}).mount()
</script>
<!-- 复用 -->
<div v-scope="Counter3({ initialCount: 1 })" @vue:mounted="mounted">
<p>{{ count }}</p>
<button @click="inc">increment</button>
</div>
</body>
3.5.2、template模板组件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
function Counter(props) {
return {
$template: '#counter-template',
count: props.initialCount,
increment() {
this.count++
},
decrement() {
this.count--
}
}
}
function Counter2(props) {
return {
$template: '#counter-template2',
msg: props.msg
}
}
createApp({
Counter,
Counter2,
}).mount()
</script>
<template id="counter-template">
<button @click="decrement">-</button>
<span>{{ count }}</span>
<button @click="increment">+</button>
</template>
<template id="counter-template2">
<span>{{ msg }}</span>
</template>
<!-- 复用 -->
<div v-scope="Counter({ initialCount: 1 })"></div>
<div v-scope="Counter({ initialCount: 2 })"></div>
<div v-scope="Counter2({ msg: 'hello' })"></div>
<div v-scope="Counter2({ msg: 'hello2' })"></div>
</body>
</html>
3.7、全局状态管理
<body>
<script type="module">
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
const store = reactive({
count: 0,
increment() {
this.count = this.count + 1
}
})
store.increment()
createApp({
store
}).mount()
</script>
<div v-scope>
<span>{{ store.count }}</span>
</div>
<div v-scope>
<button @click="store.increment">+</button>
</div>
</body>
3.8、自定义指令
<body>
<script type="module">
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
const autoFocus = (ctx) => {
ctx.el.focus()
}
createApp({
}).directive('auto-focus', autoFocus).mount()
</script>
<div v-scope>
<input v-auto-focus />
</div>
</body>
3.9、内置指令
<body>
<script type="module">
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
createApp({
list: [
{ id: 1, name: 'a' },
{ id: 2, name: 'b' },
{ id: 3, name: 'c' }
]
}).mount()
</script>
<div v-scope v-cloak>
<ul>
<li v-for="(item, index) in list" :key="index">{{item.id}}-{{item.name}}</li>
</ul>
</div>
</body>
4、自动挂载语法
TIP
自动初始化,使用v-scope
定义响应式数据
4.1、简单使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
[v-cloak] {
display: none;
}
</style>
</head>
<body>
<script src="https://unpkg.com/petite-vue" defer init></script>
<div v-scope="{ count: 0}" v-cloak>
<p>{{ count }}</p>
<button @click="count--">--</button>
<button @click="count++">++</button>
</div>
</body>
</html>