Vue.jsで配列のリアクティブに苦労した


はまったなあと思って調べると他にも苦労している人はたくさんいましたね

これは動かない

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html,body,h1,h3 { margin: 0; padding: 0; }
</style>
</head>
<body>
    <div id="app">
        <h1>配列</h1>
        <div>
            <button @click="visibleArray[0] = !visibleArray[0]">A表示切替</button>
            <h3 v-show="visibleArray[0]">A</h3>
        </div>
        <div>
            <button @click="visibleArray[1] = !visibleArray[1]">B表示切替</button>
            <h3 v-show="visibleArray[1]">B</h3>
        </div>
    </div>
<script src="https://npmcdn.com/vue/dist/vue.min.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        visibleArray: [true, false],
    },
});
</script>
</body>
</html>

単純に配列の要素を更新しただけではVue.jsは気付いてくれない。鈍い。
そこでsplice()を使う。

splice()

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html,body,h1,h3 { margin: 0; padding: 0; }
</style>
</head>
<body>
    <div id="app">
        <h1>配列</h1>
        <div>
            <button @click="visibleArray.splice(0,1,!visibleArray[0])">A表示切替</button>
            <h3 v-show="visibleArray[0]">A</h3>
        </div>
        <div>
            <button @click="visibleArray.splice(1,1,!visibleArray[1])">B表示切替</button>
            <h3 v-show="visibleArray[1]">B</h3>
        </div>
    </div>
<script src="https://npmcdn.com/vue/dist/vue.min.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        visibleArray: [true, false],
    },
});
</script>
</body>
</html>

冗長になるが仕方ない。

いっそオブジェクトで

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<style>
html,body,h1,h3 { margin: 0; padding: 0; }
</style>
</head>
<body>
    <div id="app">
        <h1>オブジェクト</h1>
        <div>
            <button @click="visibleObject[0] = !visibleObject[0]">A表示切替</button>
            <h3 v-show="visibleObject[0]">A</h3>
        </div>
        <div>
            <button @click="visibleObject[1] = !visibleObject[1]">B表示切替</button>
            <h3 v-show="visibleObject[1]">B</h3>
        </div>
    </div>
<script src="https://npmcdn.com/vue/dist/vue.min.js"></script>
<script>
new Vue({
    el: '#app',
    data: {
        visibleObject: { 0: true, 1: false },
    },
});
</script>
</body>
</html>

これはこれでもにゃる