blog
blog copied to clipboard
petite-vue 快速上手
Vue 可以作为独立的脚本文件使用,无需构建步骤!如果你有一个后端框架,并且它已经渲染了大部分的 HTML,或者你的前端逻辑并不复杂,不需要构建步骤。
所以,Vue 也提供了另一个适用于此类无构建步骤场景的替代版 petite-vue,主要为渐进式增强已有的 HTML 作了特别的优化。功能更加精简,十分轻量。
- 大小只有5.8kb
- Vue 兼容模版语法
- 基于DOM,就地转换
- 响应式驱动
官方地址:https://github.com/vuejs/petite-vue
快速上手
自动初始化
petite-vue 无需构建流程即可使用。只需从 CDN 加载它:
<script src="https://unpkg.com/petite-vue" defer init></script>
<!-- 页面任意位置 -->
<div v-scope="{ count: 0 }">
{{ count }}
<button @click="count++">inc</button>
</div>
- 用 v-scope 标记页面上应由 petite-vue 控制的区域。
- 该 defer 属性使脚本在 HTML 内容被解析后执行。
- 该 init 属性告诉 petite-vue 自动查找和初始化页面上的所有包含 v-scope 的元素。
手动初始化
如果您不想要自动初始化,请删除该 init 属性并将脚本移动到 <body>
末尾:
<script src="https://unpkg.com/petite-vue"></script>
<script>
PetiteVue.createApp().mount()
</script>
或者,使用 ES 模块构建:
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp().mount()
</script>
根作用域
该 createApp 函数接受一个对象参数,是所有表达式的根作用域。
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp({
// exposed to all expressions
count: 0,
// getters
get plusOne() {
return this.count + 1
},
// methods
increment() {
this.count++
}
}).mount()
</script>
<!-- v-scope value can be omitted -->
<div v-scope>
<p>{{ count }}</p>
<p>{{ plusOne }}</p>
<button @click="increment">increment</button>
</div>
注意 v-scope 这里不需要有值,只是作为 petite-vue 处理元素的提示。
显式挂载目标
您可以指定一个挂载目标(选择器或元素)petite-vue 以仅限于页面的该区域:
createApp().mount('#only-this-div')
这也意味着您可以拥有多个 petite-vue 应用程序来控制同一页面上的不同区域:
createApp({
// root scope for app one
}).mount('#app1')
createApp({
// root scope for app two
}).mount('#app2')
生命周期事件
您可以监听每个元素的特殊事件 vue:mounted 和 vue:unmounted
<div
v-if="show"
@vue:mounted="console.log('mounted on: ', $el)"
@vue:unmounted="console.log('unmounted: ', $el)"
></div>
v-effect
用 v-effect 执行响应式内联语句:
<div v-scope="{ count: 0 }">
<div v-effect="$el.textContent = count"></div>
<button @click="count++">++</button>
</div>
effect 响应式地追踪其依赖,并在依赖更改时重新执行,因此每当更改 count 时它都会重新运行。
组件
“组件”的概念在 petite-vue 中有所不同,因为它更加简单。
首先,可以使用函数创建可复用部分的逻辑:
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
function Counter(props) {
return {
count: props.initialCount,
inc() {
this.count++
},
mounted() {
console.log(`I'm mounted!`)
}
}
}
createApp({
Counter
}).mount()
</script>
<div v-scope="Counter({ initialCount: 1 })" @vue:mounted="mounted">
<p>{{ count }}</p>
<button @click="inc">increment</button>
</div>
<div v-scope="Counter({ initialCount: 2 })">
<p>{{ count }}</p>
<button @click="inc">increment</button>
</div>
带有模板的组件
带有模板的组件
如果您还想复用一个模板,您可以使用 $template
属性,该值可以是模板字符串,也可以是 <template>
元素的 ID 选择器:
<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
function Counter(props) {
return {
$template: '#counter-template',
count: props.initialCount,
inc() {
this.count++
}
}
}
createApp({
Counter
}).mount()
</script>
<template id="counter-template">
My count is {{ count }}
<button @click="inc">++</button>
</template>
<!-- reuse it -->
<div v-scope="Counter({ initialCount: 1 })"></div>
<div v-scope="Counter({ initialCount: 2 })"></div>
建议使用该 <template>
方法而不是内联字符串,因为从本地模板克隆元素更高效。
全局状态管理
您可以使用该 reactive 方法来创建全局状态:
<script type="module">
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
const store = reactive({
count: 0,
inc() {
this.count++
}
})
// manipulate it here
store.inc()
createApp({
// share it with app scopes
store
}).mount()
</script>
<div v-scope="{ localCount: 0 }">
<p>Global {{ store.count }}</p>
<button @click="store.inc">increment</button>
<p>Local {{ localCount }}</p>
<button @click="localCount++">increment</button>
</div>
自定义指令
还支持自定义指令,但写法不同:
const myDirective = (ctx) => {
// the element the directive is on
ctx.el
// the raw value expression
// e.g. v-my-dir="x" then this would be "x"
ctx.exp
// v-my-dir:foo -> "foo"
ctx.arg
// v-my-dir.mod -> { mod: true }
ctx.modifiers
// evaluate the expression and get its value
ctx.get()
// evaluate arbitrary expression in current scope
ctx.get(`${ctx.exp} + 10`)
// run reactive effect
ctx.effect(() => {
// this will re-run every time the get() value changes
console.log(ctx.get())
})
return () => {
// cleanup if the element is unmounted
}
}
// register the directive
createApp().directive('my-dir', myDirective).mount()
petite-vue 仅有的特性
- v-scope
- v-effect
- @vue:mounted & @vue:unmounted 事件
不同的行为
- 在表达式中,$el指向指令绑定到的当前元素(而不是组件根元素)
- createApp() 接受全局状态而不是组件
- 组件被简化为函数返回对象
- 自定义指令有不同的语法
vue共用的特性
- {{ }}
- v-bind
- v-on
- v-model
- v-if / v-else / v-else-if
- v-for
- v-show
- v-html
- v-text
- v-pre
- v-once
- v-cloak
- reactive()
- nextTick()
- Template refs
一些特征被丢弃,因为它们在渐进增强的背景下具有相对较低的使用频率。如果你需要这些特性,你可能应该只使用标准的 Vue。
- ref(), computed() 等组合式 API.
- Render functions (petite-vue 没有 virtual DOM)
- Reactivity 响应式数据类型 (Map, Set, .., 为了体积更小而删除)
- Transition, KeepAlive, Teleport, Suspense
- v-for 深解构
- v-on="object" 对象语法
- v-is 动态组件
- v-bind:style 自动前缀