😂

Vue.js を始めてからいちばん最初に知りたかった provide inject 機能を5年後に知った人

2022/07/07に公開

親子関係を表わすコードを Ruby で書くとこんな感じになる

class Parent
end

class Child
  def initialize(base)
    @base = base
  end
end

parent = Parent.new
child = Child.new(parent)

Vue.js もそれと同じでよかった
世界中の人が使う汎用性の高いコンポーネントを作っているのではなく、自分だけが使うアプリのなかで、そこだけでしか使わないコンポーネントの、その下にぶら下がる、再利用など考える余地もない子コンポーネントに、親のポインタをそのまま渡せればよかった
しかしマニュアルを読んでも読んでも双方向データバインディングや $emit のことばかりでよくわからなかった
ググっても v-bind と $emit を駆使した必要最低限のデータリレーを正義とするような記事や、密結合にしたら死ぬんかよっていうようなコードで溢れ返っていた
Vuex にも期待したが明後日の方を向いていた
で、こりゃそもそも無理なんかもしれんなと調べるのを止めてしまった (反省)
そこで自力で捻り出したのがこれ

Parent.vue
<template>
<Child :base="this" />
</template>

<script>
import Child from "./Child.vue"
export default {
  components: {
    Child,
  },
  data() {
    return {
      counter: 0,
    }
  },
}
</script>
Child.vue
<template>
<button @click="base.counter += 1">{{base.counter}}</button>
</template>

<script>
export default {
  props: ["base"],
}
</script>

こんな書き方をしていいのか? this とかビューの中で渡しちゃっていいのか? こんな書き方してる人見たことないぞ。誰かにバレたら袋叩きに遭うんじゃないか? と、不安を抱えながら5年間この方法で書いていた
そして最近 provide と inject っていうのを知った
書き直すとこうなった

Parent.vue
<template>
<Child />
</template>

<script>
import Child from "./Child.vue"
export default {
  components: {
    Child,
  },
  data() {
    return {
      counter: 0,
    }
  },
  provide() {
    return {
      base: this,
    }
  },
}
</script>
Child.vue
<template>
<button @click="base.counter += 1">{{base.counter}}</button>
</template>

<script>
export default {
  inject: ["base"],
}
</script>

それもっと早く知りたかった

Discussion

ログインするとコメントできます