Skip to content

Commit 1992ad6

Browse files
committed
tweak docs
1 parent 7d5597d commit 1992ad6

File tree

6 files changed

+154
-38
lines changed

6 files changed

+154
-38
lines changed

README.md

Lines changed: 132 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,54 @@
1-
# petite-vue (WIP)
1+
# petite-vue
22

3-
A subset of Vue optimized for progressive enhancement.
3+
`petite-vue` is a subset of Vue optimized for progressive enhancement. It provides the same template syntax and reactivity mental model with standard Vue. However, it is specifically optimized for "sprinkling" small amount of interactions on an existing HTML page rendered by a server framework.
44

5-
- 5.5kb w/ most non-component features
5+
- 5.5kb min+brotli w/ most non-component features
66
- DOM-based, mutates in place
77
- Driven by `@vue/reactivity`
88

99
## Usage
1010

11+
`petite-vue` has one special directive: `v-scope` that is not present in standard Vue. Use it to mark regions on the page that should be controlled by `petite-vue`:
12+
1113
```html
12-
<script type="module">
13-
import { createApp } from 'petite-vue'
14-
createApp().mount()
15-
</script>
14+
<script src="https://unpkg.com/petite-vue" defer init></script>
1615

17-
<div v-scope="{ text: 'hello', open: true }">
18-
{{ text }}
19-
<input v-model="text" v-if="open" />
20-
<button @click="open = !open">toggle</button>
16+
<!-- anywhere on the page -->
17+
<div v-scope="{ count: 0 }">
18+
{{ count }}
19+
<button @click="count++">inc</button>
2120
</div>
2221
```
2322

24-
### Reusing Logic
23+
The `defer` attribute makes the script execute after HTML content is parsed, and `init` tells `petite-vue` to automatically query and initialize all elements that have `v-scope` on the page.
2524

26-
There are no components, but logic can be shared across the app or encapsulated in setup-like functions:
25+
### Manual Init
26+
27+
If you don't want the auto init, remove the `init` attribute and move the scripts to end of `<body>`:
28+
29+
```html
30+
<script src="https://unpkg.com/petite-vue"></script>
31+
<script>
32+
PetiteVue.createapp().mount()
33+
</script>
34+
```
35+
36+
Or, use the ES modules build:
37+
38+
```html
39+
<script type="module">
40+
import { createApp } from 'https://unpkg.com/petite-vue?module'
41+
createApp().mount()
42+
<script>
43+
```
44+
45+
### Global Data
46+
47+
The `createApp` function accepts a data object that serves as the root scope for all expressions. This can be used for simple global state management:
2748
2849
```html
2950
<script type="module">
30-
import { createApp, reactive } from 'petite-vue'
51+
import { createApp, reactive } from 'https://unpkg.com/petite-vue?module'
3152
3253
const store = reactive({
3354
count: 0,
@@ -36,42 +57,122 @@ There are no components, but logic can be shared across the app or encapsulated
3657
}
3758
})
3859
39-
function ComponentLike(count) {
60+
createApp({
61+
// exposed to all expressions
62+
store
63+
}).mount()
64+
</script>
65+
66+
<div v-scope="{ localCount: 0 }">
67+
<p>Global {{ store.count }}</p>
68+
<button @click="store.inc">increment</button>
69+
70+
<p>Local {{ localCount }}</p>
71+
<button @click="localCount++">increment</button>
72+
</div>
73+
```
74+
75+
### Reusing Logic
76+
77+
There are no components, but logic can be shared across the app or encapsulated in setup-like functions:
78+
79+
```html
80+
<script type="module">
81+
import { createApp } from 'https://unpkg.com/petite-vue?module'
82+
83+
function ComponentLike(props) {
4084
return {
41-
count,
85+
count: props.initialCount,
4286
inc() {
4387
this.count++
4488
}
4589
}
4690
}
4791
4892
createApp({
49-
// exposed to all expressions
50-
store,
5193
ComponentLike
5294
}).mount()
5395
</script>
5496

55-
<div v-scope="ComponentLike(10)">
56-
<p>Global {{ store.count }}</p>
57-
<button @click="store.inc">increment</button>
58-
59-
<p>Local {{ count }}</p>
97+
<div v-scope="ComponentLike({ initialCount: 10 })">
98+
<p>{{ count }}</p>
6099
<button @click="inc">increment</button>
61100
</div>
62101
```
63102

64-
## Differences
103+
### Custom Directives
104+
105+
Custom directives are also supported but with a different interface:
106+
107+
```js
108+
const myDirective = (ctx) => {
109+
// the element the directive is on
110+
ctx.el
111+
// the raw value expression
112+
// e.g. v-my-dir="x" then this would be "x"
113+
ctx.exp
114+
// v-my-dir:foo -> "foo"
115+
ctx.arg
116+
// v-my-dir.mod -> { mod: true }
117+
ctx.modifiers
118+
// evaluate the expression and get its value
119+
ctx.get()
120+
// evaluate arbitrary expression in current scope
121+
ctx.get(`${ctx.exp} + 10`)
122+
123+
// run reactive effect
124+
ctx.effect(() => {
125+
// this will re-run every time the get() value changes
126+
console.log(ctx.get())
127+
})
128+
129+
return () => {
130+
// cleanup if the element is unmounted
131+
}
132+
}
133+
134+
// register the directive
135+
createApp().directive('my-dir', myDirective).mount()
136+
```
137+
138+
This is how `v-html` is implemented:
139+
140+
```js
141+
const html = ({ el, get, effect }) => {
142+
effect(() => {
143+
el.innerHTML = get()
144+
})
145+
}
146+
```
65147

66-
Custom directive interface is different. (TODO document)
148+
## Supported Features
149+
150+
- `{{ }}` text bindings
151+
- `v-bind` (including `:` shorthand and class/style special handling)
152+
- `v-on` (including `@` shorthand and all modifiers)
153+
- `v-model` (all input types + non-string `:value` bindings)
154+
- `v-if` / `v-else` / `v-else-if`
155+
- `v-for`
156+
- `v-show`
157+
- `v-html`
158+
- `v-text`
159+
- `v-pre`
160+
- `v-cloak`
161+
- `reactive()`
162+
- Custom directives (see above).
67163

68164
## Not Supported
69165

70-
- `ref`
71-
- Reactivity for Collection Types (Map, Set, etc.)
72-
- Components
166+
Some features are dropped because they have a relatively low size/utility ratio in the context of progressive enhancement. If you need these features, you should probably just use standard Vue.
167+
168+
- `ref()`, `computed()` etc.
169+
- Components (see "Reuse Logic" section above)
170+
- Template refs (just use selectors)
171+
- Render functions (`petite-vue` has no virtual DOM)
172+
- Reactivity for Collection Types (Map, Set, etc., removed for smaller size)
73173
- Transition, KeepAlive, Teleport, KeepAlive
74-
- `v-on` object syntax
174+
- `v-for` deep destructure
175+
- `v-on="object"`
75176
- `v-once`
76-
- `v-is`
77-
- style auto-prefixing
177+
- `v-is` & `<component :is="xxx">`
178+
- `v-bind:style` auto-prefixing

index.html

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<style>
2-
a {
3-
font-size: 18px;
4-
}
2+
a {
3+
font-size: 18px;
4+
}
55
</style>
66
<ul>
77
<li><a href="/demos/data.html">v-scope</a></li>
@@ -11,4 +11,9 @@
1111
<li><a href="/demos/for.html">v-for</a></li>
1212
<li><a href="/demos/model.html">v-model</a></li>
1313
<li><a href="/demos/reuse.html">Logic Reuse</a></li>
14-
</ul>
14+
</ul>
15+
16+
<div v-scope="{ count: 0 }">
17+
{{ count }}
18+
<button @click="count++">inc</button>
19+
</div>

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44
"files": [
55
"dist"
66
],
7-
"main": "dist/vue-lite.umd.js",
7+
"main": "dist/petite-vue.umd.js",
8+
"unpkg": "dist/petite-vue.iife.js",
9+
"jsdelivr": "dist/petite-vue.iife.js",
810
"module": "./dist/vue-lite.es.js",
911
"exports": {
1012
".": {

src/directives/text.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { isObject } from '@vue/shared'
22
import { Directive } from '.'
33

4-
export const text: Directive<Text> = ({ el, exp, get, effect }) => {
4+
export const text: Directive<Text> = ({ el, get, effect }) => {
55
effect(() => {
66
el.data = toDisplayString(get())
77
})

src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,9 @@
11
export { createApp } from './app'
22
export { reactive, effect } from '@vue/reactivity'
3+
4+
import { createApp } from './app'
5+
6+
let s
7+
if ((s = document.currentScript) && s.hasAttribute('init')) {
8+
createApp().mount()
9+
}

vite.config.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export default defineConfig({
77
// minify: false,
88
lib: {
99
entry: resolve(__dirname, 'src/index.ts'),
10-
name: 'PetiteVue'
10+
name: 'PetiteVue',
11+
formats: ['es', 'umd', 'iife']
1112
},
1213
rollupOptions: {
1314
plugins: [

0 commit comments

Comments
 (0)