Vue.js组件模型更新

时间:2017-07-16 16:45:34

标签: javascript vuejs2 vue-component

我在Vue框架中绝对是新手,我需要使用实时BTC / LTC / XRP价格创建可重复使用的组件

对于实时价格我使用Bitstamp websockets API。以下是jQuery的示例用法 - 运行此代码片段,真的很有用。



function seed() {
  console.log('Starting db seed...');

  return Promise.each(initialData, (data) => {
    // path to mongo model js file
    let Model = require(data.model);

    removeModel(Model)
    .then(() => {
      console.log('[' + data.name + '] model removed. ');
      return saveModel(data, Model);
    }).then(() => {
      console.log('[' + data.name + '] model saved');
    }).catch( (err) => {
      console.error('Error seeding db', err);
    });
  });
}

/**
 * Saves model to the database
 * @param {*} data
 * @param {*} Model
 */
function saveModel(data, Model) {
  // path to json data file
  let seedList = require(data.seed);

  return Promise.map(seedList, function(seed) {
    let newItem = new Model(seed);
    return newItem.save({});
  });
}

var bitstamp = new Pusher('de504dc5763aeef9ff52')
var channel = bitstamp.subscribe('live_trades')
            
channel.bind('trade', function (lastTrade) {
  $('p').text(lastTrade.price)
})




如您所见,它非常简单。但是,我需要使用Vue.js组件。所以我创建了它,它也功能齐全:



<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pusher/4.1.0/pusher.min.js"></script>

<h3>BTC/USD price</h3>
<p>loading...</p>
&#13;
var bitstamp = new Pusher('de504dc5763aeef9ff52')

Vue.component('live-price', {
  template: '<div>{{price}}</div>',
  data: function () {
    return {
      price: 'loading...'
    }          
  },
  created: function () {
    this.update(this)
  },
  methods: {
    update: function (current) {
      var pair = current.$attrs.pair === 'btcusd'
        ? 'live_trades'
        : 'live_trades_' + current.$attrs.pair
      var channel = bitstamp.subscribe(pair)

      channel.bind('trade', function (lastTrade) {
        current.price = lastTrade.price
      })
    }
  }
})

new Vue({
  el: '.prices'
})
&#13;
&#13;
&#13;

但是,有很大的优点。我正确使用Vue吗?运行Pusher的理想位置在哪里?在&#34;创建&#34;或&#34;已安装&#34;方法?在&#34;计算&#34;?在&#34;观看&#34;?或者在哪里?我做得对吗?我真的不知道,我从Vue开始......今天:(

2 个答案:

答案 0 :(得分:1)

使用Vue的第一天看起来很不错!我只想做一些改变。

  • 组件正在伸出并使用全局bitstamp。通常使用组件,您希望它们是独立的,而不是通过自身来获取值。为此,将套接字声明为可以传递给组件的属性。
  • 同样,pair作为属性传入,但您不会声明它,而是使用current.$attrs.pair来获取该对。但这并不是很具说服力,并且使其他人更难使用该组件。此外,通过将其设为属性,您可以使用this.pair
  • 来引用它
  • 使用类似套接字的东西时,在使用完毕后,应始终记得清理。在下面的代码中,我添加了 unsubscribe 方法来执行此操作。 beforeDestroy是处理这类事情的典型生命周期钩子。
  • 计算属性对于计算从组件数据派生的值非常有用:您订阅的通道是计算属性。你并不是真的需要来做这件事,但这通常是一种很好的做法。
  • Vue只能绑定到单个DOM元素。您正在使用一个类.prices,在这种情况下可以使用,因为该类只有一个元素,但可能会误导。
  • 最后,创建了一个发起订阅的好地方。

console.clear()
var bitstamp = new Pusher('de504dc5763aeef9ff52')

Vue.component('live-price', {
  props:["pair", "socket"],
  template: '<div>{{price}}</div>',
  data() {
    return {
      price: 'loading...',
      subscription: null
    }          
  },
  created() {
    this.subscribe()
  },
  beforeDestroy(){
    this.unsubscribe()
  },
  computed:{
    channel(){
      if (this.pair === 'btcusd')
        return 'live_trades'
      else
        return 'live_trades_' + this.pair
    }
  },
  methods: {
    onTrade(lastTrade){
      this.price = lastTrade.price
    },
    subscribe() {
      this.subscription = this.socket.subscribe(this.channel)
      this.subscription.bind('trade', this.onTrade)
    },
    unsubscribe(){
      this.subscription.unbind('trade', this.onTrade)
      this.socket.unsubscribe(this.channel)
    }
  }
})

new Vue({
  el: '#prices',
  data:{
    socket: bitstamp
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/pusher/4.1.0/pusher.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>

<section id="prices">
  <live-price pair="btcusd" :socket="bitstamp"></live-price>
  <live-price pair="ltcusd" :socket="bitstamp"></live-price>
  <live-price pair="xrpusd" :socket="bitstamp"></live-price>
</section>

答案 1 :(得分:0)

Rewrited - 现在好吗?

&#13;
&#13;
var config = {
  key: 'de504dc5763aeef9ff52'
}

var store = new Vuex.Store({
  state: {
    pusher: null
  },
  mutations: {
    initPusher (state, payload) {
      state.pusher = new Pusher(payload.key)
    }
  }
})

var livePrice = {
  template: '#live-price',
  props: ['pair'],
  data () {
    return {
      price: 'loading...',
      subscription: null
    }          
  },
  computed: {
    channel () {
      return this.pair === 'btcusd'
        ? 'live_trades'
        : 'live_trades_' + this.pair
    }
  },
  methods: {
    onTrade (lastTrade) {
      this.price = lastTrade.price
    },
    subscribe () {
      this.subscription = this.$store.state.pusher.subscribe(this.channel)
      this.subscription.bind('trade', this.onTrade)
    },
    unsubscribe () {
      this.subscription.unbind('trade', this.onTrade)
      this.$store.state.pusher.unsubscribe(this.channel)
    }
  },
  created () {
    this.subscribe()
  },
  beforeDestroy () {
    this.unsubscribe()
  }
}

new Vue({
  el: '#prices',
  store,
  components: {
    'live-price': livePrice
  },
  created () {
    store.commit({
      type: 'initPusher',
      key: config.key
    })
  }
})
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/pusher/4.1.0/pusher.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.1/vue.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vuex/2.3.1/vuex.min.js"></script>

<section id="prices">
  <live-price pair="btcusd"></live-price>
  <live-price pair="ltcusd"></live-price>
  <live-price pair="xrpusd"></live-price>
</section>

<template id="live-price">
  <div>
    {{price}}
  </div>
</template>
&#13;
&#13;
&#13;