web-dev-qa-db-ja.com

vue.js / vue-routerの初期ロード時にすべてのサーバー側データをロードする方法は?

現在、WordPress REST= API、vue-routerを使用して、単一の小さなページサイトのページ間を移行しています。ただし、 AJAX REST APIを使用したサーバーへの呼び出し、データはロードされますが、ページが既にレンダリングされた後にのみです。

vue-router documentation は、各ルートに移動する前後にデータをロードする方法に関する洞察を提供しますが、最初のページのロード時にすべてのルートおよびページデータをロードする方法を知りたいのですが、ルートがアクティブ化されるたびにデータをロードする必要性を回避します。

注、データをacfプロパティに読み込んでから、.vueを使用するファイルコンポーネントthis.$parent.acfs

main.jsルーターコード:

const router = new VueRouter({
    routes: [
        { path: '/', component: Home },
        { path: '/about', component: About },
        { path: '/tickets', component: Tickets },
        { path: '/sponsors', component: Sponsors },
    ],
    hashbang: false
});

exports.router = router;

const app = new Vue({
    router,
    data: {
        acfs: ''
    },
    created() {
        $.ajax({
            url: 'http://localhost/placeholder/wp-json/acf/v2/page/2',
            type: 'GET',
            success: function(response) {
                console.log(response);
                this.acfs = response.acf;
                // this.backgroundImage = response.acf.background_image.url
            }.bind(this)
        })
    }
}).$mount('#app')

Home.vueコンポーネントコード:

export default {
    name: 'about',
    data () {
        return {
            acf: this.$parent.acfs,
        } 
    },
}

何か案は?

27
10000RubyPools

さて、私はついにこのことを理解しました。私がしているのは、ルートvueインスタンスがインスタンス化されている_main.js_ファイル内で同期ajaxリクエストを呼び出し、リクエストされたデータにデータプロパティを割り当てることです:

main.js

_let acfData;

$.ajax({
    async: false,
    url: 'http://localhost/placeholder/wp-json/acf/v2/page/2',
    type: 'GET',
    success: function(response) {
        console.log(response.acf);
        acfData = response.acf;
    }.bind(this)
})  

const router = new VueRouter({
    routes: [
        { path: '/', component: Home },
        { path: '/about', component: About },
        { path: '/tickets', component: Tickets },
        { path: '/sponsors', component: Sponsors },
    ],
    hashbang: false
});

exports.router = router;

const app = new Vue({
    router,
    data: {
        acfs: acfData 
    },
    created() {

    }
}).$mount('#app')
_

ここから、個々の_.vue_ファイル/コンポーネント内のプルされたデータを次のように使用できます。

_export default {
    name: 'app',
    data () {
    return {
        acf: this.$parent.acfs,
    }
},
_

最後に、同じ_.vue_テンプレート内のデータを次のようにレンダリングします。

_<template>
  <transition
      name="home"
      v-on:enter="enter"
      v-on:leave="leave"
      v-bind:css="false"
      mode="out-in"
    >
    <div class="full-height-container background-image home" v-bind:style="{backgroundImage: 'url(' + this.acf.home_background_image.url + ')'}">
      <div class="content-container">
        <h1 class="white bold home-title">{{ acf.home_title }}</h1>
        <h2 class="white home-subtitle">{{ acf.home_subtitle }}</h2>
        <div class="button-block">
          <a href="#/about"><button class="white home-button-1">{{ acf.link_title_1 }}</button></a>
          <a href="#/tickets"><button class="white home-button-2">{{ acf.link_title_2 }}</button></a>
        </div>
      </div>
    </div>
  </transition>
</template>
_

取り去る最も重要な情報は、beforeRouteEnter (to, from, next)のようなものを使用してルートが訪問されるたびに比べて、すべてのACFデータが最初にのみONCEと呼ばれることです。その結果、必要に応じてスムーズなページ遷移を取得できます。

これが同じ問題に遭遇した人の助けになることを願っています。

2
10000RubyPools

私のアプローチは、ストアとメインの構築を遅らせることですVue my AJAX呼び出しが返されるまで。

store.js

import Vue from 'vue';
import Vuex from 'vuex';
import actions from './actions';
import getters from './getters';
import mutations from './mutations';

Vue.use(Vuex);

function builder(data) {
  return new Vuex.Store({
    state: {
      exams: data,
    },
    actions,
    getters,
    mutations,
  });
}

export default builder;

main.js

import Vue from 'vue';
import VueResource from 'vue-resource';
import App from './App';
import router from './router';
import store from './store';

Vue.config.productionTip = false;

Vue.use(VueResource);

Vue.http.options.root = 'https://miguelmartinez.com/api/';

Vue.http.get('data')
  .then(response => response.json())
  .then((data) => {
    /* eslint-disable no-new */
    new Vue({
      el: '#app',
      router,
      store: store(data),
      template: '<App/>',
      components: { App },
    });
  });

AngularやExtJSなどの他のフレームワークでこのアプローチを使用しました。

42
Miguel

Vue Routerのドキュメントのこのセクションを確認してください

https://router.vuejs.org/guide/advanced/data-fetching.html

そのため、最初にエンドポイントからデータを取得するメソッドを作成し、ウォッチャーを使用してルートを監視する必要があります。

export default {
    watch: {
        '$route': 'fetchItems'
    },
    methods: {
        fetchItems() {
          // fetch logic
        }
    }
}

WP Rest APIで作業しているので、Githubのレポジトリを自由に確認してください https://github.com/bedakb/vuewp/blob/master/public/app/ themes/vuewp/app/views/PostView.vue#L39

3
Belmin Bedak

ナビゲーションガード を使用できます。

特定のコンポーネントでは、次のようになります。

_export default {
    beforeRouteEnter (to, from, next) {
        // my ajax call
    }
};
_

すべてのコンポーネントにナビゲーションガードを追加することもできます。

_router.beforeEach((to, from, next) => {
    // my ajax call
});
_

覚えておくべきことの1つは、ナビゲーションガードが非同期であるため、データの読み込みが完了したときにnext()コールバックを呼び出す必要があることです。私のアプリの実際の例(ガード機能が別のファイルにある場合):

_export default function(to, from, next) {
    Promise.all([
        IngredientTypes.init(),
        Units.init(),
        MashTypes.init()
    ]).then(() => {
        next();
    });
};
_

もちろん、successコールバックでnext()を呼び出す必要があります。

2
mingos