2017-11-07 16 views
4

現在、vue-cli webpackテンプレートに基づいた投票アプリケーションに取り組んでいます。私たちは一貫して保守可能な方法で投票状態を保存し、操作したいので、私たちは州の管理にvuexを使うつもりです。フロントエンドとバックエンドの間の相互作用はウェブソケットに基づいており、以前のプロジェクトでは非常に優れていることが証明されているため、signalrを使用したいと考えています。私たちはvue.jsの新機能を利用しているため、signalr、vuex、vue.jsを完全に統合する方法についてアドバイスが必要です。SignalRとVue.jsとVuexの統合

はのシナリオを説明してみましょう:

フロントエンドは、投票投票がアクティブで、選択した答えを受けることができることを、認識するために私たちのバックエンドからイベントを取得します。一定期間後、結果が利用可能であることをフロントエンドに通知し、ユーザーに表示します。場合によっては、別の投票投票を開くこともあります。ドキュメントが非表示になった場合に切断できることが重要です(ページの可視性API)。

当社のソリューションのアプローチ:一般的に

私は、この目的のために特別なsignal.serviceを実装したいと思います。このサービスは、接続を確立するだけでなく、Webソケット経由でメッセージを送受信する役割も担います。共通のモジュールからvuexストアに変更を加えることはできないので、vuexプラグインが適切であるとわかりました。 vuexプラグインはsignalrをラップする必要があります。

VotingStartEventが届いた場合は、それぞれの質問のロックを解除してユーザーに表示します。ユーザーがその質問に回答した場合は、この質問の新しい状態(回答)をvuexストアにコミットします。私たちのプラグインの中には突然変異のサブスクリプションがあり、このサブスクリプションを使って私たちの投票をバックエンドに送ります。

var plugin = (store) => { 
    // ... 
    store.subscribe((mutation, state) => { 
    console.log('inside subscription'); 
    // if vote has answered state, call connection.send() to submit the message to the backend 
    }); 

    connection.received((message) => { 
    // ... 
    var event = parseEvent(message); 
    if (event.type === START) { 
     store.commit({type: 'voting', item: 'unlocked'}); 
    } 
    // ... 
    }); 
} 

このアプローチは良いですか、改善の余地はありますか?

+0

私は例のSignalRを使用することはできませんが、あなたがしたい場合は、インスピレーションのために、私がここに書くことができます例を働いて、生きて、私はVueのに他のWSライブラリ(プッシャー)を統合していますかVuexでデータを更新します。 – WaldemarIce

+0

プラグインは必要ありません。 SignalRでイベントを受け取ったときにアクションをディスパッチするだけです。 https://stackoverflow.com/questions/44333164/vuex-websockets/44336198 – Bert

+0

@WaldemarIceありがとうございました!短いインスピレーションは素晴らしいでしょう:) – jimmy

答えて

1

Vue.prototype.$pusher = new Pusher('apiKey')のようなプラグインや構造は必要ありません。私はコンポーネント間で共有が必要な他の値と同じようにPusherインスタンスを保持します。そして、VueインスタンスメソッドcreateのPusherを初期化します。これは、最初に初期化する必要がある他のライブラリと同様です。わかりやすくするために、各インスタンスごとに一意であるため、貿易データを意図的にコンポーネントインスタンス内に保持しています。あなたが必要とするものではありません。

var store = new Vuex.Store({ 
 
    state: { 
 
    pusher: null 
 
    }, 
 
    mutations: { 
 
    saveInstance(state, instance) { 
 
     state.pusher = instance 
 
    } 
 
    }, 
 
    actions: { 
 
    initializePusher ({commit}, apiKey) { 
 
     commit('saveInstance', new Pusher(apiKey)) 
 
    } 
 
    } 
 
}) 
 

 
Vue.component('live-price', { 
 
    template: '#live-price', 
 
    props: ['pair'], 
 
    data() { 
 
    return { 
 
     price: 'wait for next trade...', 
 
     channel: null 
 
    } 
 
    }, 
 
    created() { 
 
    this.channel = this.$store.state.pusher.subscribe('live_trades_' + this.pair) 
 
    this.channel.bind('trade', data => this.price = data.price) 
 
    } 
 
}) 
 

 
new Vue({ 
 
    el: '#app', 
 
    store, 
 
    created() { 
 
    this.$store.dispatch('initializePusher', 'de504dc5763aeef9ff52') 
 
    } 
 
})
[v-cloak] { display: none }
<div id="app"> 
 
    <live-price pair="btceur">BITCOIN price in EUR:</live-price> 
 
    <live-price pair="ltceur">LITECOIN price in EUR:</live-price> 
 
    <live-price pair="etheur">ETHEREUM price in EUR:</live-price> 
 
    <live-price pair="xrpeur">RIPPLE price in EUR:</live-price> 
 
</div> 
 

 
<template id="live-price"> 
 
    <p> 
 
    <slot></slot> 
 
    <span v-cloak>{{ price }}</span> 
 
    </p> 
 
</template> 
 

 
<script src="https://unpkg.com/[email protected]/dist/vue.min.js"></script> 
 
<script src="https://unpkg.com/[email protected]/dist/vuex.min.js"></script> 
 
<script src="https://js.pusher.com/4.1/pusher.min.js"></script>

+0

ありがとうございました!興味深いアプローチで、インスタンス内のインスタンスをストア内で保持することを評価します。 – jimmy

+0

@jimmyあなたは歓迎です:)そして明確にするために、私はVuexでインスタンスを保持しています。これは単なる(データ)オブジェクトでもあります。そして、すべての共有データがVuexに属している場合は... :) – WaldemarIce

+0

@jimmy私の答えを受け入れることに多くの感謝:) – WaldemarIce

関連する問題