2017-01-10 6 views
8

私は現在、WordPress REST APIとvue-routerを使用して、小さな単一ページサイトのページ間を移行しています。ただし、REST APIを使用してサーバーにAJAX呼び出しを行うと、データはロードされますが、ページが既にレンダリングされた後にのみ表示されます。最初のvue.js/vue-routerの負荷でサーバー側のデータをすべてロードする方法は?

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, 
     } 
    }, 
} 

任意のアイデア?

答えて

1

Githubのhttps://github.com/bedakb/vuewp/blob/master/public/app/themes/vuewp/app/views/PostView.vue#L39に私のレポをチェックすること自由に感じ、私は最終的に出てこの事を考え出し。私がやっているすべては私のルートVUEインスタンスがインスタンス化され、私のmain.jsファイル内の同期AJAX要求を呼び出し、およびようにデータプロパティに要求されたデータを代入されます。

メイン。ここから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テンプレート内のデータをレンダリングします:

取り除く最も重要な情報は、すべてのACFデータが1度だけ呼び出されていることです最初は、beforeRouteEnter (to, from, next)のようなものを使用してルートを訪れるたびに比較されます。その結果、私は必要に応じて滑らかで滑らかなページ遷移を得ることができます。

これは、誰でも同じ問題を抱える人に役立ちます。

1

navigation guardsを使用できます。特定のコンポーネントで

、それは次のようになります。

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

をまた、すべてのコンポーネントにナビゲーションガードを追加することができます覚えて

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

ことの一つは、ナビゲーションガードが非同期であるということです、データのロードが完了したらnext()コールバックを呼び出す必要があります。私のアプリ(ガード機能は別のファイルに存在する場所)から実際の例:お使いの場合には

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

、あなたはもちろん、successコールバックでnext()をコールする必要があると思います。あなたのVueのルータのドキュメントでは、このセクション

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

だから最初

+0

私は 'router.beforeEach()'を使用している場合、どこでAJAX応答データを保存する必要がありますか? '$ route.params'のようにそれを格納しなければならないルートオブジェクトがありますか? – 10000RubyPools

+0

また、ページ間を行き来するときに複数回ではなく、1回だけデータが読み込まれるようにする方法はありますか? – 10000RubyPools

+0

私はそれにサービスクラスを使います( 'IngredientTypes'など)。彼らはデータを保存し、どのコンポーネントもそれらを使用することができます。データがすでに格納されている場合、別の要求を送信するのではなく、ただちに解決済みの約束を返すだけです。私はまた、理論的にはあなたが何をしているかを達成するのに役立つかもしれない、vuexと呼ばれる国家管理のためのツールがあることを知っていますが、私はそれを使用していないので、 – mingos

1

チェックは、あなたのエンドポイントからデータを取得した後、ルートを見るために、ウォッチャーを使用する方法を記述する必要があります。

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

あなたはWPのREST APIを使用して作業しているので、よし

8

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

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 }, 
    }); 
    }); 

Iは、角やExtJSのような他のフレームワークと、このアプローチを使用しています。

+0

これはかなり賢いです。 – rhyek

+0

素晴らしい - ありがとう。私は12時間でWebpack/Vue/vue-cliを学んだが、Vuexが理解して3日間は正しく働くことができなかった。これまで。ニースの答え@Miguel –

+0

ニース!私もこれをしました...私はそれが良い練習であるかどうかわからなかったので私はここにいますが、他の誰かがその良いアイデアを考えるのは良いことです。 – Phil

関連する問題