0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Vue3のComposition APIを使っているとストレスが溜まるのでこの記事で発散することにします

Posted at

Vue3のComposition APIを使っています。
Options APIも使っていましたが、Composition APIはなんかストレスが溜まります。
開発していても「罠」が多くてハマりやすく、あまり気持ちよく開発できていません。

ストレスがたまると健康に悪いので、この記事で発散することにします。

refが意味不明すぎる

データをリアクティブにする方法の1つとしてrefがありますが、これの挙動が謎すぎます。

const ref_data = ref(1)

まあこれはいいです。わかります。データをラップするオブジェクトなんだなと伝わります。

<MyComponent :ref_data="ref_data">

こうするとrefが渡されるかと思いますが、実際は自動アンラップされてNumberが渡されます。
基本的に設計では「ユーザーに隠れてごにょごにょする」という設計は、嫌われることが多いです。
これは「暗黙の了解」の設計で、ユーザーがその設計を学習しないといけません。
この自動アンラップの挙動を知ってから嫌な予感がうっすらしていました。

では次のコードはどうでしょうか。

<input type="text" @input="$emit('something', ref_data)" />

$emit()です。実はこれもref_dataは自動アンラップされます。実際にはref_data.valueが渡されます。
私はこの挙動を知ったとき「ああ、これは君からの挑戦状なんだね?」という感想が湧いてきました。
ユーザーに隠れてごにょごにょするのが大好きなら、君は神秘主義者だね? ということです。

まぁ、これらはまだ私が学習すればいいんです。ここまでは堪忍袋の緒もまだ余裕があります。
しかし次の挙動です。

class Model {
    constructor () {
        this.ref_data = ref(1)
    }
}

こんなモデルを書いたとします。で、使います。

const model = new Model()

<MyComponent :ref_data="model.ref_data" />

これはref_dataは展開されるでしょうか?
正解は「展開されない」です。
modelはリアクティブじゃないため、Vueは自動アンラップを行わないようです。
これを自動アンラップするには

const model = reactive(new Model())

としなければいけません。
しかしどういうわけか、reactive()で包まなくても、

<div>{{ model.ref_data }}</div>

という参照はリアクティブになります。はぁ???

つまりこういうことです。
プレーンなオブジェクトはリアクティブじゃない。リアクティブにするにはreactive()でラップする必要がある。
プレーンなオブジェクトのプロパティをリアクティブにすると、:ref_data="model.ref_data"などのバインドは自動アンラップされないが、{{ model.ref_data }}などの参照はリアクティブになり自動アンラップされる。
親のオブジェクトをリアクティブにすると:ref_data="model.ref_data"も自動アンラップされる。

ちょっといいですか?
私は、Vue3に対する恋心が急激に冷めつつあります。
ずっとVue3で開発してきましたが、どうも最近はソリが合わないようです。
あー!!!!むかつくなぁーーー!!!!がーーー!!!!

0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?