Skip to content

Instantly share code, notes, and snippets.

@DawidMyslak
Last active November 10, 2021 02:54
Show Gist options
  • Save DawidMyslak/35d4b3293bbf3af68e23f0be2def6a02 to your computer and use it in GitHub Desktop.
Save DawidMyslak/35d4b3293bbf3af68e23f0be2def6a02 to your computer and use it in GitHub Desktop.
Combining Vue.js and Knockout.js together
// skip import for KO (Knockout.js) here, it should be available in global deps
import Vue from 'vue';
import ProjectsConversationWrapper from 'ProjectsConversationWrapper';
import { getProjectConversation } from 'api';
// unique component identifier
const uniqueId = 'chat-project-room';
const bindingHandlerInit = async (element, valueAccessor) => {
const projectId = parseInt(ko.unwrap(valueAccessor()), 10);
// find conversation based on given project ID
const { conversation } = await getProjectConversation(projectId);
const conversationId = conversation.id;
// our reactive data object observed by Vue
const data = {
conversationId,
};
// Vue setup
const vueConfig = {
el: `#${uniqueId}`,
data,
template: '<ProjectsConversationWrapper :conversation-id="conversationId"/>',
components: { ProjectsConversationWrapper },
};
// create new Vue instance
let vm = new Vue(vueConfig);
// destroy Vue instance when KO component is disposed
ko.utils.domNodeDisposal.addDisposeCallback(element, () => {
vm.$destroy();
vm = null;
});
};
// create custom binding
ko.bindingHandlers.chatProjectRoom = {
init: bindingHandlerInit,
};
// register new KO component
ko.components.register(uniqueId, {
viewModel: ({ projectId }) => ({ projectId }),
template: `
<div data-bind="chatProjectRoom: projectId">
<div id="${uniqueId}"></div>
</div>
`,
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment