はじめに
JavaScriptでprivateな変数やメソッドが作れるようになったようです。
私は業務でVue.jsを触っているため、「双方向バインディングする場合はどのように書くんだろう?」
と気になったので試してみました。
結果
getterとsetterを用意して、「v-model="クラス名.変数名"」で良いみたいでした。
検証
変数に「#」を付けることでprivateになるようです。
一旦setterは用意せず、以下のようなクラスを作成しました。
module.exports = class Test{
#detail;
#tag;
constructor() {
this.#detail = null;
this.#tag = null;
}
get detail() {
return this.#detail;
}
get tag() {
return this.#tag;
}
};
画面側は以下のように実装しました。
<template>
<div>
<div class="control column">
<base-select v-model="test.tag" :options="testTags"></base-select>
</div>
<div class="control column">
<base-input
v-model="test.detail"
></base-input>
</div>
</div>
</template>
<script>
import BaseSelect from "~/components/BaseSelect.vue";
import BaseInput from "~/components/BaseInput.vue";
export default {
components: {
BaseSelect,
BaseInput
},
data() {
const Test= require("~/server/api/models/test");
return {
testTags: require("~/assets/testTags.json"),
test: new Test(),
};
}
};
</script>
この状態で画面上で値を変更してみると以下のようなエラーが発生します。
TypeError: Cannot set property tag of #<Test> which has only a getter
「setterを用意しないと値がセットできないぞ」ということです。
ということでsetterを用意したところ、想定通りに値を変更することができました。
結果に書いている通り「v-model="クラス名.変数名"」で良いみたいでした。
追加検証
次に「#」を外して同様に実行してみます。
getterもsetterも無い以下のようなクラスを用意します。
module.exports = class Test{
constructor() {
this.detail = null;
this.tag = null;
}
};
画面のコードは同じもので、再度画面から値を変更してみるとエラーも何も発生せず変更することができます。
しかし、クラス内の変数をgetterとsetterを介さず直接操作をすることになってしまいます。(と思っています。)
おわりに
親側にsetterを呼ぶメソッドを書いて、子側でそのメソッドを呼ぶことで値が変更できる、
そんな実装になるのかと思ったのですが、その必要はなくシンプルでよさそうでした。
参考になりましたら幸いです。