[Vuejs]-Render Vue component tag added by external code

0๐Ÿ‘

I finally figured it out (thanks to Sphinx comment). I probably should not be using Vue app at all in my case. Instead I should manually create and mount my components like so:

<html>

<head>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<script>
var MyComponent = Vue.component('my-component', {
  // camelCase in JavaScript
  props: ['someTitle'],
  template: '<b>[XYZ {{ someTitle }}]</b>  '
})

function dashToCamelCase( myStr ) {
	return myStr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });
}

function getAttributes ( node ) {
	var i,
		attributeNodes = node.attributes,
		length = attributeNodes.length,
		attrs = {};

	for ( i = 0; i < length; i++ ) attrs[dashToCamelCase(attributeNodes[i].name)] = attributeNodes[i].value;
	return attrs;
}

function renderExisting(componentElementName, componentCreator){
	$(componentElementName).each(function(){
		var props = getAttributes(this)
		var component = componentCreator(props)
		component.$mount(this)
	})
}

function renderNew(appElementId, componentElementName, componentCreator){
	var obs = new MutationObserver(function(mutations, observer) {
	  $.each(mutations, function (i, mutation) {
		var addedNodes = $(mutation.addedNodes);
		var selector = componentElementName
		var filteredEls = addedNodes.find(selector).addBack(selector);
		filteredEls.each(function(){
			var props = getAttributes(this)
			var component = componentCreator(props)
			component.$mount(this)
		});
	  });
	});

	var canvasElement = $(appElementId)[0];
	obs.observe(canvasElement, {childList: true, subtree: true});
}

function setUpRendering(appElementId, componentElementName, componentCreator){
	renderExisting(componentElementName, componentCreator)
	renderNew(appElementId, componentElementName, componentCreator)
}

$(function(){
	setUpRendering('#myApp', 'my-component', (props) => new MyComponent({propsData: props}))
});
</script>

<script>
function addMyTag(){
	$('#myApp').append( '<my-component some-title="' + (new Date()).getTime() + '"></my-component>' )
}
</script>

</head>

<body>

<button onclick='addMyTag()'>Add!</button>

<div id="myApp">
<my-component some-title="aaa"></my-component>
<my-component some-title="bbb"></my-component>
<my-component some-title="ccc"></my-component>
<div>

</body>

</html>

I will be happy to accept a better answer.

๐Ÿ‘คAndrzej Gis

Leave a comment