Vue.js/ファイラーっぽいUIを作ってみる/150_データを取ってくるようにする

Vue.js/ファイラーっぽいUIを作ってみる/150_データを取ってくるようにする

今までだとデータを直書きしていたが、それを外部から取ってくるようにする。

Vue.js ではこのような裏の通信は axios というライブラリを使うそうなのでそれを使う。 CDN から読み込んでおく。

index.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Hello</title>
    <link rel="stylesheet" type="text/css" href="index.css" />
    <script src="https://unpkg.com/vue@latest"></script>
    <script src="https://unpkg.com/vuex@latest"></script>
    <!-- ↓ コレ -->
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="data.js"></script>
    <script src="ItemName.js"></script>
    <script src="File.js"></script>
    <script src="RootFolder.js"></script>
    <script src="Folder.js"></script>
</head>
<body>

data.js から store 部分だけ切り出す。data の中身は変数に入れずにむき出し状態にしておく。

data.js
{
    id: 1, name: "", type: "folder",
    isOpen: true,
    items: [
        // 中略
    ],
    editId: null
}

そして store に action と mutation を実装する

var store = new Vuex.Store({
    state: {},
    mutations: {
        // 中略
        updateAll: function(state, data){
            Vue.set(state, "id", data.id);
            Vue.set(state, "name", data.name);
            Vue.set(state, "items", data.items);
            Vue.set(state, "editId", data.editId);
        }
    },
    // 中略
    actions: {
        // 中略
        initState: function(context, callback){
            axios
                .get('data.json', {responseType: 'json'})
                .then(function (res){
                    context.commit('updateAll', res.data);
                    callback();
                })
                .catch(function (err){
                    console.log(err);
                });
        }
    }
}); 

このような形で作る。state の部分には最初は空のオブジェクトを突っ込んでいる。

そして一番のポイントは updateAll である。set というメソッドで1階層目のデータを1つ1つ移植している。 Vue のデータバインディングのキモは変化の追跡にあるのだが、state の中身を丸ごと初期のモノから変えてしまうと、 その追跡の関係性が切れてしまうようなのだ。

なのでこのような個別で入れ直すという作業が必要になる。 このへんは公式にも何か奥歯に物が挟まったような、どうにも納得できないような記述がされていて、 このへんはおそらくまだうまいこと仕組みができていないのだろう。 特に、こいつは1階層目だけ登録したらそれで OK みたいなのだ。 下位の階層は特に何もしてなくても普通に動作している。

action 部分では axios を使って通信部分を書いている。 今回はサーバ無しで単にファイルを置いているだけなので、レスポンスの形式が無い。 なので、強制的に JSON に解釈するようにしている。

そこから mutation を呼び出している。

res.data の中身はその時点でJSのオブジェクトになっているのでそれをそのまま渡している。 とりあえずあとで処理を挟みたい時用に callback もうけつけてみた。

axios は Promise を使って簡単に書けるのでよい

最後にこいつをキックしてやる

var vm = new Vue({
    el: "#app",
    store: store,
    computed: {
        rootItems: function(){
            return this.$store.state.items;
        }
    },
    methods: {
        init: function(){
            this.$store.dispatch('initState', ()=>{});
        }
    }
});
vm.init();
javascript/vuejs/create_filer_like_ui/150_get_data.txt · 最終更新: 2018-11-26 18:15 by ore