VueJS - Render dynamically passed template in component - javascript

I am using VueJS 2 to build a drag-and-drop layout builder. One of the requirements of that project is to be able to have some components that will allow for custom content to live inside (they will be just a wrapper around that content). And to be really concrete, I am trying to pass in and render another drag-and-drop zone which is implemented in a draggable component.
Basically, I want to pass a VueJS template to the component via a prop and have that template rendered inside of the component. This is necessary because I do not want the UI to limit the needs of the developer and therefore need this to be really extensible.
In the following trivial example I would like the "ui-element" to render the content prop inside of it and use the other prop as a data input.
<ui-element
:content="<draggable :name="contentData"></draggable>"
contentData="col1"
>
</ui-element>
Since just outputting the template will escape it, and v-html directive will treat it as regular HTML and not a template I am lost, not really sure how to get this done.
I spent about an hour or more googling but no luck. Which leaves me to three options:
1) I'm the first one to need this complex use case (unlikely)
2) Doing this is stupid on so many levels that no-one even bothered (if so, please let me know how to get this result in a smarter way)
3) There is a special uber-cool JS term for this which I simply do not know and that made my search attempts futile

You'd want to use slots instead.
In your ui-element component, define a slot like so:
<template>
<div>
<slot name="content"></slot>
</div>
</template>
Then you could pass in the draggable component like so:
<ui-element contentData="col1">
<draggable :name="contentData" slot="content"></draggable>
</ui-element>
Here's a very basic fiddle example of a slot.

Related

Is there a way to compile react components to html before build time?

I have a function that takes dom elements and operate on them. It is called pageTransition, and it takes two div elements, and performs a transition animation from the one to the other.
function pageTransition(div1, div2){//do the transition}
for example i can call this function like,
pageTransition (document.body.querySelector("#div1"), document.body.querySelector("#div2"))
That is simple, but let us say I want to pass React class components as my div elements. And that isn't possible because react components are class's not html elements. One quick reminder, this react components in the end will be compiled to div elements with some content during build time. I know I could get around this by doing this
...//the react class
render(
return (
<div id="div1">...</div>//this will allow me to call the above function with the same parameters
)
).
But I was just wondering if there was a magic way to compile this react classes before build time, so rather than giving the id's to the returned div's I was wondering if I could do something like this pageTransition(compile(reactClass), compile(reactClass));
The solution will depend on your intended purpose for pageTransition.
However, there are three potential options you may want to look into:
Statically render a React component into html markup or a string: https://reactjs.org/docs/react-dom-server.html#rendertostaticmarkup
Render two div elements in html and use a React portal to manage what is being rendered in the those divs. This could potentially replace what you are doing in pageTransition. https://reactjs.org/docs/portals.html
Use a ref to access the DOM element that is built from the React component: https://reactjs.org/docs/refs-and-the-dom.html
If you explain what pageTransition does it might help me find a solution for you.

How to deal with components inside dynamic html strings in Sapper & Svelte?

I am trying to make my first Sapper site and I'm populating the content similarly to how it's done in the template here.
My problem is that I want to allow usage of custom components in the content of {#html post.html}. Currently it doesn't work, the HTML is just inserted there without being treated like a component, even if I import the component in [slug].html and it works if used directly somewhere besides that {#html post.html}.
The behaviour is kind of expected as the content is fetched after svelte has finished it's work, but I am not sure what should I do then. I want a couple of custom components like <FancyButton> to be usable in the user generated content.
Can I ask the [slug].html component to look at the post.html or just whole content after insertion and create an instance of child component wherever it should be? Or should I somehow compile the string beforehand on the server?

Angular2 pass html to component

I am trying to create a component which displays a code example for a given component. The component shall be passed as HTML to the code-example component and be rendered once normally but also have its code displayed below.
When trying to fetch the code from <ng-content> in ngOnInit, Angular already started rendering the component, which means that I do not get the original code between the tags.
Passing the code via input does not work out, as the components may use single and double quotes which will cause problems when binding the data.
What I also tried is passing the code escaped to the component like
<code-example>
<component></component>
</code-example>
To unescape it and render it afterwards, which did not work out for me as I had trouble adding this pre-defined element to the DOM in a way that Angular renders it as a component.
Are there any other methods of dealing with this problem that I might be missing?
As #Timothy suggested you may try the <pre> tag.
If you also want to highlight the syntax of your code I can recommend a third party module called ng2-prism.
This is a library that supports multiple languages and is quite easy to use.

Add arbitrary Vue.js components to parent component

I'm using Vue.js to build ui for my html5 game. I have a case where I want to define ui-containers which essentially just group other ui-components and position them to somewhere on screen. So I could have something like this going on:
<ui-container>
<ui-component1></ui-component1>
<ui-component2></ui-component2>
<ui-component3></ui-component3>
</ui-container>
Where I need to add and remove those components dynamically based on data-model which represents the content of the container. The problem is that I'd like to keep ui-container generic, so that I can append any Vue-component to it without having information in template about which components there might be.
I googled and found this example which concerns injecting components dynamically: http://forum.vuejs.org/topic/349/injecting-components-to-the-dom
While the data-driven version in example was easy to make and understand, it uses v-for for tag and therefore requires one to know before hand the type of child-component.
So question is, how I can generalize that example to work with any component dynamically? Should my data-model have the type of component or tag name of it and then interpolate it in v-for? Or is there existing mechanism for this kind of requirement?
You can use special is attribute to dynamically set the type of a component. Here are the docs. The code will look somewhat like:
<div id="app">
<div v-for="component in components" :is="component.type" :value="component.value"></div>
</div>
Working fiddle to play with: Dynamic Vue.js components

Adding content to react elements

I am new to react.js and I have heard that this js library reacts badly to anything that modifies it's component structure.
Is there any specific procedure to add content into react elements using Jquery. For example, if we want to add content into react's div field, can we directly use Jquery append method to insert text to that div or is there any other way to implement things?.
The idea is that you either use a traditional approach, or you ditch jQuery and use react and this means using the react rendering tree, probably build tasks, client-side router/SPA.
You should not modify the DOM generated by react components from outside it since it maintains an internal state and a virtual DOM that would become out of sync. You either use one ecosystem or another; they are two very different approaches to writing a website.
If you want to introduce react on a small part of the website first, I would suggest to gather all your data with jquery and then transmit the data into the react component.
Roughly
// gather data with jquery or whatever
var data_array = gatherData();
ReactDOM.render(<MyCustomComponent data={data_array}/>, $('#my-react-root')[0])
Rendering changes during runtime can be managed the same way. Just gather the data again and change the state of the react component accordingly.
If you don't want to extract the data or the html is to complex, you can use dangerouslySetInnerHTML to just path a plain text html string.
From the docs:
<div dangerouslySetInnerHTML={{__html: getMarkup()}} />
Best wishes
Andreas

Categories

Resources