Vue.jsと比べて超軽量のpetite-vueの使い方

petite-vueとは

超軽量版Vue.js

作者はVue.jsと同じくEvan Youで特徴は以下の通り。

  • 約5.8KB
  • DOMベース
  • @vue/reactivityで動作

Vue.jsにはないディレクティブとイベントがある。

  • v-scope
  • v-effect
  • @mounted & @unmounted events

使い方はCDNから読み込んでv-scopeや@clickなどをコード内に記述する。

<script src="https://unpkg.com/petite-vue" defer init></script>

<div v-scope="{ count: 0 }">
  {{ count }}
  <button @click="count++">inc</button>
</div>

petite-vue sample 1

scriptタグにinitが付いているが、initで初期化しない場合はPetiteVue.createApp().mount()を使用する。

<script src="https://unpkg.com/petite-vue"></script>
<script>
PetiteVue.createApp().mount()
</script>

ES moduleを使う場合はこうなる。

<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'
createApp().mount()
</script>

バージョンの指定方法

https://unpkg.com/petite-vue だと最新バージョンを読み込むので本番などは以下のようにバージョンを指定して読み込む。

ES moduleだとURLが異なる点に注意。

Global build
https://unpkg.com/petite-vue@0.2.2/dist/petite-vue.iife.js

ES module
https://unpkg.com/petite-vue@0.2.2/dist/petite-vue.es.js

mountする要素の指定

Vue.jsと同じくmountする要素は指定できる。

createApp({
  // root scope for app one
}).mount('#app1')

createApp({
  // root scope for app two
}).mount('#app2')

Lifecycle Events

@mount, @unmountedでライフサイクルイベントを取得できる。

<div
  @mounted="console.log('mounted on: ', $el)"
  @unmounted="console.log('unmounted: ', $el)"
></div>

v-effect

petite-vueはv-effectが追加されていてifを入れてこのように使うことができる。

<script src="https://unpkg.com/petite-vue" defer init></script>

<div v-scope="{ count: 0 }">
  <div v-effect="if ($el.textContent < 5) {$el.textContent = count}"></div>
  <button @click="count++">++</button>
</div>

petite-vue sample 2

ifを使用せず$el.textContent = countだけならVue.jsと同じくv-textも使用可能。

<script src="https://unpkg.com/petite-vue" defer init></script>

<div v-scope="{ count: 0 }">
  <div v-text="count"></div>
  <button @click="count++">+1</button>
</div>

petite-vue sample 3

Components

コンポーネントはこのように作成する。

<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 })" @mounted="mounted">
  <p>{{ count }}</p>
  <button @click="inc">+1</button>
</div>

<div v-scope="Counter({ initialCount: 2 })">
  <p>{{ count }}</p>
  <button @click="inc">+1</button>
</div>

petite-vue sample 4

ES moduleを使用しない場合は以下のようになる。

<script src="https://unpkg.com/petite-vue" defer init></script>
<script defer>
function Counter(props) {
  return {
    count: props.initialCount,
    inc() {
      this.count++
    },
    mounted() {
      console.log(`I'm mounted!`)
    }
  }
}
</script>

<div v-scope="Counter({ initialCount: 1 })" @mounted="mounted">
  <p>{{ count }}</p>
  <button @click="inc">+1</button>
</div>

<div v-scope="Counter({ initialCount: 2 })">
  <p>{{ count }}</p>
  <button @click="inc">+1</button>
</div>

petite-vue sample 5

Components with Template

コンポーネントはテンプレートも使用可能。

<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">+1</button>
</template>

<div v-scope="Counter({ initialCount: 1 })"></div>
<div v-scope="Counter({ initialCount: 2 })"></div>

petite-vue sample 6

Global State Management

localとは別にglobalのデータを保持。

<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">+1</button>

  <p>Local {{ localCount }}</p>
  <button @click="localCount++">+1</button>
</div>

petite-vue sample 7

Vueとの互換

petite-vueはVueと同じくこれらが使用可能。

  • {{ }} text bindings
  • v-bind (including : shorthand and class/style special handling)
  • v-on (including @ shorthand and all modifiers)
  • v-model (all input types + non-string :value bindings)
  • 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との非互換

petite-vueはVueとは違いこれらが使用不可。

  • ref(), computed() etc.
  • Render functions (petite-vue has no virtual DOM)
  • Reactivity for Collection Types (Map, Set, etc., removed for smaller size)
  • Transition, KeepAlive, Teleport, Suspense
  • v-for deep destructure
  • v-on="object"
  • v-is & <component :is="xxx">
  • v-bind:style auto-prefixing

computed()が使えないと不便に見えるが、createApp内でgetを使えばcomputed()の代わりになる。

<script type="module">
import { createApp } from 'https://unpkg.com/petite-vue?module'

createApp({
  message: 'Hello',
  get reversedMessage() {
    return this.message.split('').reverse().join('')
  },
}).mount()
</script>

<div v-scope>
  <p>{{ message }}</p>
  <p>{{ reversedMessage }}</p>
</div>

petite-vue sample get

vuejs / petite-vue のExample