Skip to content

Instantly share code, notes, and snippets.

@buhrmi
Last active October 29, 2018 09:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save buhrmi/60f72b5a24d729f4332213dd87bd71a8 to your computer and use it in GitHub Desktop.
Save buhrmi/60f72b5a24d729f4332213dd87bd71a8 to your computer and use it in GitHub Desktop.
Vue ActionCable
// Make a vue component automatically subscribe to a cable and unsubscribe when it's destroyed
// You can use reactive vue state as params. the subscription will be re-established when the param changes.
// Usage //
// new Vue
// data: ->
// something: null
// subscriptions:
// SomeChannel:
// params: ->
// some_param: @some_param
// received: (newData) ->
// @something = newData
const cable = ActionCable.createConsumer(socket_url)
const plugin = {
install(Vue, cable) {
Vue.mixin({
destroyed() {
if (!this._subscriptions) return
Object.keys(this._subscriptions).map((key) => {
this._subscriptions[key].unsubscribe()
})
},
mounted() {
this.$cable = cable
let subscriptionsOptions = this.$options.subscriptions
if (!subscriptionsOptions) return
this._subscriptions = {}
if (typeof subscriptionsOptions == 'function') subscriptionsOptions = subscriptionsOptions()
Object.keys(subscriptionsOptions).map((channelName) => {
let subOptions = subscriptionsOptions[channelName]
if (!subOptions.params) subOptions.params = {}
let paramsFn = subOptions.params
if (typeof paramsFn !== 'function') {
paramsFn = function() { return subOptions.params }
}
this.$watch(paramsFn, function(params) {
if (this._subscriptions[channelName]) this._subscriptions[channelName].unsubscribe()
params.channel = channelName
this._subscriptions[channelName] = this.$cable.subscriptions.create(params, {
received: subOptions.received.bind(this)
})
}, {
immediate: true
})
})
}
})
}
}
Vue.use(plugin, cable)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment